EmbeddedRelated.com
Forums
Memfault Beyond the Launch

Gnu LD generating bad addresses for PowerPC

Started by David R Brooks February 22, 2005
I am using the GCC tools to generate code for a MPC563 PowerPC.
Software versions (as reported by the -v options):
 AS  GNU assembler version 2.15.91 (powerpc-eabi) using BFD version
     2.15.91 20040904
 LD  GNU ld version 2.15.91 20040904

The program code is trivial:
        .global  _BEGIN
        .section ".text"

_BEGIN:
        addis   %r2, %r0, _BEGIN@ha
        addi    %r2, %r2, _BEGIN@l

When the project is linked with .text at address 0x307000, this works
correctly, generating the hex. longs
  3C400030
  38427000
which corresponds to _BEGIN at 0x307000, as expected.

Now here's the bug:
If the object file is re-linked with .text at 0x308000, the following
incorrect code is generated:
  3C400031
  38428000
which puts _BEGIN at 0x318000, not 0x308000 as it should be.

This is the linker script:
  MEMORY
  {
    RAM (w) : ORIGIN = $(RAMBASE), LENGTH = 0x3C00
  }
  SECTIONS
  {
    ENTRY(_BEGIN)
    . = $(RAMBASE) ;
    .text ALIGN(4) : { *(.text)   } >RAM
  }

with $(RAMBASE) set to 0x307000 or 0x308000 as required.

There is nothing "magic" about 0x307000, other addresses show the same
effect. The rule seems to be that if address bit 0x00008000 is set,
then 0x00008000 gets added to the address by the linker.

You can download the original source, Makefile, etc. from
 http://members.iinet.net.au/~daveb/buffer/fault.zip

TIA

On Tue, 22 Feb 2005 18:19:51 +0800, David R Brooks wrote:

> _BEGIN: > addis %r2, %r0, _BEGIN@ha > addi %r2, %r2, _BEGIN@l > > When the project is linked with .text at address 0x307000, this works > correctly, generating the hex. longs > 3C400030 > 38427000 > which corresponds to _BEGIN at 0x307000, as expected. > > Now here's the bug: > If the object file is re-linked with .text at 0x308000, the following > incorrect code is generated: > 3C400031 > 38428000 > which puts _BEGIN at 0x318000, not 0x308000 as it should be.
Did you actually see this value (0x318000) appear in output/debugger ? ISTM the generated code is ok: addi will sign extend the immediate argument and the @ha adjusts for this, e.g. lis r2, 0x0031 { r2 = 0x00310000 } addi r2, r2, 0x8000 { r2 = r2 + sign-extend(0x8000) = 0x00310000 + 0xffff8000 = 0x00308000 } so the outcome should be as expected. BTW: follow up to comp.sys.powerpc.tech Rob Windgassen
Thanks Rob. Yes, I see it now (egg on face dept. :)
I had looked at a static disassembly of the code, & noticed the
difference from the compiler output. I had forgotten that addi does
sign extension.

Rob Windgassen <rwindgas@xs-FOUR-all.nl> wrote:

:On Tue, 22 Feb 2005 18:19:51 +0800, David R Brooks wrote:
:
:> _BEGIN:
:>         addis   %r2, %r0, _BEGIN@ha
:>         addi    %r2, %r2, _BEGIN@l
:> 
:> When the project is linked with .text at address 0x307000, this works
:> correctly, generating the hex. longs
:>   3C400030
:>   38427000
:> which corresponds to _BEGIN at 0x307000, as expected.
:> 
:> Now here's the bug:
:> If the object file is re-linked with .text at 0x308000, the following
:> incorrect code is generated:
:>   3C400031
:>   38428000
:> which puts _BEGIN at 0x318000, not 0x308000 as it should be.
:
:Did you actually see this value (0x318000) appear in output/debugger ?
:ISTM the generated code is ok: addi will sign extend the immediate
:argument and the @ha adjusts for this, e.g.
:
:         lis  r2, 0x0031        { r2 = 0x00310000 }
:         addi r2, r2, 0x8000    { r2 = r2 + sign-extend(0x8000)
:                                     = 0x00310000 + 0xffff8000
:                                     = 0x00308000 }
:
:so the outcome should be as expected.
:
:BTW: follow up to comp.sys.powerpc.tech
:
:
:Rob Windgassen


Memfault Beyond the Launch