[U-Boot] relocation problem on powerpc

Chris Packham judge.packham at gmail.com
Tue Sep 9 01:07:51 CEST 2014


Hi Jocke,

On Tue, Sep 9, 2014 at 12:22 AM, Joakim Tjernlund
<joakim.tjernlund at transmode.se> wrote:
>>
>> >
>> > There are some disadvantages to living in a weird timezone, mostly
>> > that you end up having conversations with yourself.
>> >
>> > On Mon, Sep 8, 2014 at 4:32 PM, Chris Packham
> <judge.packham at gmail.com>
>> wrote:
>> > > Hi All,
>> > >
>> > > I have come across what I think is a relocation problem for powerpc.
>> > >
>> > > I've added the following to ArpTimeoutCheck
>> > >
>> > > +       printf("NetArpWaitTimerStart = %ld\n",
> NetArpWaitTimerStart);
>> > > +       printf("&NetArpWaitTimerStart = %p\n",
> &NetArpWaitTimerStart);
>> > > +       printf("NetArpWaitTry = %d\n", NetArpWaitTry);
>> > > +       printf("&NetArpWaitTry = %p\n", &NetArpWaitTry);
>> > > +       printf("NetArpWaitTxPacketSize = %d\n",
>> NetArpWaitTxPacketSize);
>> > > +       printf("&NetArpWaitTxPacketSize = %p\n",
>> &NetArpWaitTxPacketSize);
>> > >
>> > > Which yields the following output
>> > >
>> > >   NetArpWaitTimerStart = 0
>> > >   &NetArpWaitTimerStart = f00000d0
>> > >   NetArpWaitTry = 1
>> > >   &NetArpWaitTry = 7ffb0058
>> > >   NetArpWaitTxPacketSize = 42
>> > >   &NetArpWaitTxPacketSize = 7ffb0078
>> > >
>> > > That looks to me like NetArpWaitTimerStart hasn't been relocated for
>> > > some reason. Looking at my u-boot.map NetArpWaitTimerStart is the
> last
>> > > item in the .sbss section
>> > >
>> > > Here's the relevant snippets for the variables I'm displaying
>> > >
>> > >  0x00000000f0000058                NetArpWaitTry
>> > >  0x00000000f0000078                NetArpWaitTxPacketSize
>> > >  0x00000000f00000d0                NetArpWaitTimerStart
>> > >
>> > > The actual problem for me is that ARPs timeout and various network
>> > > things fail. Has anyone got any clues as to why this one particular
>> > > variable isn't getting relocated.
>> > >
>> > > Thanks,
>> > > Chris
>> > >
>> > > More info:
>> > >   I'm building P2041RDB_config
>> > >
>> > >   $ git describe
>> > >   v2014.10-rc2-15-g2ec8915
>> > >
>> > >   => version
>> > >   U-Boot 2014.10-rc2-00015-g2ec8915-dirty (Sep 08 2014 - 16:18:42)
>> > >   powerpc-e500-linux-gnu-gcc (Gentoo 4.6.3-r1 p1.9, pie-0.5.2) 4.6.3
>> > >   GNU ld (GNU Binutils) 2.21
>> >
>> > I'm not confident enough to say it's a fix but the following seems to
>> > solve the relocation problem for NetArpWaitTimerStart.
>> >
>> > diff --git a/arch/powerpc/cpu/mpc85xx/u-boot.lds
>> > b/arch/powerpc/cpu/mpc85xx/u-boot.lds
>> > index 2cf0b25..36711b0 100644
>> > --- a/arch/powerpc/cpu/mpc85xx/u-boot.lds
>> > +++ b/arch/powerpc/cpu/mpc85xx/u-boot.lds
>> > @@ -54,7 +54,7 @@ SECTIONS
>> >      _FIXUP_TABLE_ = .;
>> >      KEEP(*(.fixup))
>> >    }
>> > -  __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
>> > +  __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2);
>> >    __fixup_entries = (. - _FIXUP_TABLE_) >> 2;
>>
>> This looks like the correct fix, The relevant code that uses
>> __got2_entries is in start.S:
>>
>> in_ram:
>>
>>         /*
>>          * Relocation Function, r12 point to got2+0x8000
>>          *
>>          * Adjust got2 pointers, no need to check for 0, this code
>>          * already puts a few entries in the table.
>>          */
>>         li      r0,__got2_entries at sectoff@l
>>         la      r3,GOT(_GOT2_TABLE_)
>>         lwz     r11,GOT(_GOT2_TABLE_)
>>         mtctr   r0
>>         sub     r11,r3,r11
>>         addi    r3,r3,-4
>> 1:      lwzu    r0,4(r3)
>>         cmpwi   r0,0
>>         beq-    2f
>>         add     r0,r0,r11
>>         stw     r0,0(r3)
>> 2:      bdnz    1b
>>
>> bdnz does decrement then test for zero so __got2_entries should hold the
>
>> number of entries to relocate.
>>
>> Seems like most(all?) ppc cpu has this error.
>
> Looking at u-boot.lds:
>  .reloc   :
>   {
>     _GOT2_TABLE_ = .;
>     KEEP(*(.got2))
>     KEEP(*(.got))
>     PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
>     _FIXUP_TABLE_ = .;
>     KEEP(*(.fixup))
>   }
>   __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
>   __fixup_entries = (. - _FIXUP_TABLE_) >> 2;
>
>
> There is something more to this error. Since _GLOBAL_OFFSET_TABLE_  is
> defined to
> _GLOBAL_OFFSET_TABLE_ = . + 4
> there is one extra entry added( for brlr insn inserted by the linker) so
> something is
> amiss here, is there a brlr insns at _GLOBAL_OFFSET_TABLE_-4 in your
> u-boot?
>
>  Jocke
>

Here's some more info from a build without any of my modifications.

  $ git describe
  v2014.10-rc2-12-g0b703db

  $ powerpc-e500-linux-gnu-gcc --version
  powerpc-e500-linux-gnu-gcc (Gentoo 4.6.3-r1 p1.9, pie-0.5.2) 4.6.3

  $ grep '_GOT2_TABLE_\|_GLOBAL_OFFSET_TABLE_\|__got2_entries' u-boot.map
  0x00000000effb5100                _GOT2_TABLE_ = .
  0x00000000effb7d38                _GLOBAL_OFFSET_TABLE_
  0x00000000effb7d48                PROVIDE (_GLOBAL_OFFSET_TABLE_, (. + 0x4))
  0x0000000000000b0d                __got2_entries =
(((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 0x2) - 0x1)

  $ gdb-multiarch u-boot
  (gdb) disassemble /r 0xeffb5100,0xeffb7d48
  Dump of assembler code from 0xeffb5100 to 0xeffb7d48:
     0xeffb5100 <_GOT2_TABLE_+0>: ef fb 51 00     .long 0xeffb5100
     0xeffb5104 <_GOT2_TABLE_+4>: ef fb 7d 44     dtstsf  cr7,f27,f15
     0xeffb5108 <_GOT2_TABLE_+8>: ef f4 00 00     .long 0xeff40000
     0xeffb510c <_GOT2_TABLE_+12>:        ef f4 01 00     .long 0xeff40100
    <snip>
     0xeffb7d30 <_GOT2_TABLE_+11312>:     ef f6 6e 74     .long 0xeff66e74
     0xeffb7d34 <_GOT2_TABLE_+11316>:     f0 00 00 d0     psq_st  f0,208(r0),0,0
     0xeffb7d38 <_GLOBAL_OFFSET_TABLE_+0>:        00 00 00 00     .long 0x0
     0xeffb7d3c <_GLOBAL_OFFSET_TABLE_+4>:        00 00 00 00     .long 0x0
     0xeffb7d40 <_GLOBAL_OFFSET_TABLE_+8>:        00 00 00 00     .long 0x0
     0xeffb7d44 <_FIXUP_TABLE_+0>:        ef fb 99 d4     .long 0xeffb99d4

So no there is no brlr at the end of the table.

Also I think the __got2_entries calculation does not take into account
the +0x4, ((0xeffb7d38-0xeffb5100)>>2)-1) = 0xb0d


More information about the U-Boot mailing list