[U-Boot] [Patch 1/2] MIPS: fix a latent bug on initialize $gp

Daniel Schwierzeck daniel.schwierzeck at gmail.com
Wed Nov 28 14:33:10 CET 2012


2012/11/26 Zhi-zhou Zhang <zhizhou.zh at gmail.com>:
> On Sun, Nov 25, 2012 at 09:30:54PM +0100, Daniel Schwierzeck wrote:
>> 2012/11/24 Zhi-zhou Zhang <zhizhou.zh at gmail.com>:
>> > If bal is 8 bytes aligned, the _gp will not be 8 bytes aligned.
>> > then the following ld insntrustion generates a Adel exception.
>> > So here make _gp be always aligned in 8 bytes.
>>
>> which toolchain do you use? Actually _gp is aligned to 16 bytes in the
>> linker script.
>> Thus the instruction "ld gp, 0(ra)" and the address loaded into gp is
>> always aligned to 8 bytes.
>> This works at least with ELDK-5.2.1 and a self-built gcc-4.7.2.
> Thanks for review.
> I have do a simple test by modify this snip as following:
> .align 3
>   //nop
>   nop
>   bal     1f
>   nop
> .dword  _gp
> 1:
>   ld      gp, 0(ra)
> Qemu give me a Adel exception:
> (qemu) info registers
> pc=0xffffffffbfc00688 HI=0x0000000000000000 LO=0x0000000000000000 ds
> 0098 0000000000000000 0
> GPR00: r0 0000000000000000 at 000000001000009f v0 0000000000000000 v1
> 0000000000000000
> GPR04: a0 0000000000000000 a1 0000000000000000 a2 0000000000000000 a3
> 0000000000000000
> GPR08: t0 0000000000000000 t1 0000000000000000 t2 0000000000000000 t3
> 0000000000000000
> GPR12: t4 0000000000000002 t5 0000000000000000 t6 0000000000000000 t7
> 0000000000000000
> GPR16: s0 0000000000000000 s1 0000000000000000 s2 0000000000000000 s3
> 0000000000000000
> GPR20: s4 0000000000000000 s5 0000000000000000 s6 0000000000000000 s7
> 0000000000000000
> GPR24: t8 0000000000000000 t9 0000000000000000 k0 0000000000000000 k1
> 0000000000000000
> GPR28: gp 0000000000000000 sp 0000000000000000 s8 0000000000000000 ra
> ffffffffbfc00544
> CP0 Status  0x10400082 Cause   0x00000410 EPC    0xffffffffbfc00550
>     Config0 0x80004482 Config1 0xfea3519b LLAddr 0x0000000000000000
>
> We can also see the arrange with objdump:
> ffffffffbfc00538:       00000000        nop
> ffffffffbfc0053c:       04110004        bal     ffffffffbfc00550
> ffffffffbfc00540:       00000000        nop
> ffffffffbfc00544:       00000000        nop
> ffffffffbfc00548:       bfc36ed0        cache   0x3,28368(s8)
> ffffffffbfc0054c:       ffffffff        sd      ra,-1(ra)
> ffffffffbfc00550:       dffc0000        ld      gp,0(ra)
>
> It shows that although _gp is aligned to 8 bytes. but it's not in the
> address of 0(ra).

I did some experiments too and now I understand your problem. If you put
additional instructions before "bal 1f", the compiler puts a nop between bal
and _gp to fill the gap in order to keep _gp aligned. But then the link address
of bal that will be stored in the gp register points to the additional
nop and not
to _gp as it was intended. I can't reproduce this with MIPS32.
Maybe this is a compiler bug.

I pushed a modified version of your patch to
git://git.denx.de/u-boot-mips.git [1].
Could you check if this is okay for you?

[1] http://git.denx.de/?p=u-boot/u-boot-mips.git;a=commitdiff;h=4bb639edce852c8ed2ae3219e436845495270453

-- 
Best regards,
Daniel


More information about the U-Boot mailing list