+  linaro-toolchain

Hello Ulrich,

I want to revisit this old thread. Sorry for the sloppy follow-up. But,
this time around I have more data.

On Tue, Mar 15, 2011 at 9:00 PM, Ulrich Weigand
<ulrich.weig...@de.ibm.com> wrote:
> Aneesh V <ane...@ti.com> wrote:
>
>> I was trying to build u-boot in Thumb2 for OMAP4. Everything was fine
>> until I added some patches recently. One of these patches introduced an
>> API (let's say foo()) that has a weakly linked alias(let's say
>> __foo()) and a strongly linked implementation(the real foo()) in an
>> assembly file.
>>
>> Although I give -mthumb and -mthumb-interwork for all the files,
>> apparently GCC generates ARM code for assembly files. In the final
>> image foobar() calls foo() using a BL. Since foobar() is in Thumb and
>> foo() in ARM, it ends up crashing. Looks like foobar() assumed foo()
>> to be Thumb because __foo() is Thumb.
>
> I'm unable to reproduce this.  Do you have a complete test case?
>
> I've tried with the following small example:
>
> foo1.c:
>
> extern void foo (void) __attribute__ ((weak, alias ("__foo")));
>
> void __foo (void)
> {
> }
>
> int main (void)
> {
>  foo ();
> }
>
> foo2.S:
>        .text
>        .align  2
>        .global foo
>        .type   foo, %function
> foo:
>        push    {r7}
>        add     r7, sp, #0
>        mov     sp, r7
>        pop     {r7}
>        bx      lr
>        .size   foo, .-foo
>
> When building just "gcc foo1.c", I get:
>
> 0000835c <__foo>:
>    835c:       b480            push    {r7}
>    835e:       af00            add     r7, sp, #0
>    8360:       46bd            mov     sp, r7
>    8362:       bc80            pop     {r7}
>    8364:       4770            bx      lr
>    8366:       bf00            nop
>
> 00008368 <main>:
>    8368:       b580            push    {r7, lr}
>    836a:       af00            add     r7, sp, #0
>    836c:       f7ff fff6       bl      835c <__foo>
>    8370:       4618            mov     r0, r3
>    8372:       bd80            pop     {r7, pc}
>
> When building both files "gcc foo1.c foo2.S", I get instead:
>
> 00008368 <main>:
>    8368:       b580            push    {r7, lr}
>    836a:       af00            add     r7, sp, #0
>    836c:       f000 e802       blx     8374 <foo>
>    8370:       4618            mov     r0, r3
>    8372:       bd80            pop     {r7, pc}
>
> 00008374 <foo>:
>    8374:       e92d0080        push    {r7}
>    8378:       e28d7000        add     r7, sp, #0
>    837c:       e1a0d007        mov     sp, r7
>    8380:       e8bd0080        pop     {r7}
>    8384:       e12fff1e        bx      lr
>
>
> So it seems to me the linker is handling this correctly ...
>
> (This is on Ubuntu Natty using system gcc and binutils.)

I could reproduce the problem on older tool-chain(Sourcery G++ Lite
2010q1-202) [1]  with a modified version of your sample code:

a.c:
====
extern void foo (void) __attribute__ ((weak, alias ("__foo")));

void __foo (void)
{
}

extern void call_foo(void);

int main (void)
{
  call_foo ();
}

b.S:
====
.text
.align  2
.global foo
foo:
        push    {r7}
        add     r7, sp, #0
        mov     sp, r7
        pop     {r7}
        bx      lr
        .size   foo, .-foo

c.S
.text
.align  2

.global call_foo
call_foo:
        bl      foo
        bx      lr

.global __aeabi_unwind_cpp_pr0
__aeabi_unwind_cpp_pr0:
        bx      lr

Now, I build them using the following commands, which is similar to
what U-Boot does:

arm-none-linux-gnueabi-gcc -mthumb -mthumb-interwork -c a.c
arm-none-linux-gnueabi-gcc -mthumb -mthumb-interwork -c b.S
arm-none-linux-gnueabi-gcc -mthumb -mthumb-interwork -c c.S
arm-none-linux-gnueabi-ld -r a.o -o alib.o
arm-none-linux-gnueabi-ld -r b.o -o blib.o
arm-none-linux-gnueabi-ld -r c.o -o clib.o
arm-none-linux-gnueabi-ld --start-group clib.o  alib.o blib.o
--end-group -o a.out
armobjdump -S --reloc a.out

You will get something like:
00008094 <call_foo>:
    8094:       fa000006        blx     80b4 <foo>
    8098:       e12fff1e        bx      lr

Please note that that the 'blx' is not correct. Now, do the following change:

diff --git a/b.S b/b.S
index e0f2de9..96dba1f 100644
--- a/b.S
+++ b/b.S
@@ -1,5 +1,6 @@
 .text
 .align  2
+.type foo, %function
 .global foo
 foo:
        push    {r7}

And build it again the same way and you will see:
00008094 <call_foo>:
    8094:       eb000006        bl      80b4 <foo>
    8098:       e12fff1e        bx      lr

I can't reproduce this on Linaro GCC 2012.01, so looks like the problem
is solved in recent tool-chains. However, sadly I could reproduce a
different but similar problem with Linaro GCC 2012.01. This time the
call is from C(Thumb) to assembly(ARM) and no weakly linked symbols are
involved.

a.c:
====
int main (void)
{
  foo ();
}

b.S:
====
.text
.align  2
.global foo
foo:
        push    {r7}
        add     r7, sp, #0
        mov     sp, r7
        pop     {r7}
        bx      lr
        .size   foo, .-foo

.global __aeabi_unwind_cpp_pr0
__aeabi_unwind_cpp_pr0:
        bx      lr

arm-linux-gnueabi-gcc -mthumb -mthumb-interwork -c a.c
arm-linux-gnueabi-gcc -mthumb -mthumb-interwork -c b.S
arm-linux-gnueabi-ld -r a.o -o alib.o
arm-linux-gnueabi-ld -r b.o -o blib.o
arm-linux-gnueabi-ld --start-group alib.o blib.o --end-group -o a.out
arm-linux-gnueabi-objdump -S --reloc a.out

gives:
    8076:       af00            add     r7, sp, #0
    8078:       f000 f802       bl      8080 <foo>
    807c:       4618            mov     r0, r3

It should have been "blx        8080 <foo>", isn't it? Again, %function
solves it.

I agree that not marking the assembly functions ' %function' is a problem
in the code, so it's not a critical bug. But I would've been happier if
the linker refused to link it rather than branching with the wrong
instruction. Isn't that a problem?

Problem No:2
*************
Linaro GCC 2012.01 is giving a new problem w.r.to Thumb build
that is not existing in Sourcery G++ Lite 2010q1-202. However, I
couldn't reproduce this problem with a small program like above. So,
let me give you reference to the original u-boot code that shows the
problem and steps to reproduce it.

tree: git://github.com/aneeshv/u-boot.git
branch: thumb

The above branch has mainline u-boot with 4 additional patches from me
for enabling Thumb build. You can build it like this:

make CROSS_COMPILE=arm-linux-gnueabi- ARCH=arm distclean
make CROSS_COMPILE=arm-linux-gnueabi- ARCH=arm omap4_sdp4430

This builds two images u-boot and u-boot-spl. SPL is a tiny u-boot that
runs from internal RAM and loads the u-boot to SDRAM. Now, please have
a look at the map file of u-boot-spl which is at: spl/u-boot-spl.map

I see the following in my map file:

/spl/u-boot-spl.map:
=================
 .rodata.wkup_padconf_array_essential_4460
                0x40309583        0x4 board/ti/sdp4430/libsdp4430.o
                0x40309583                wkup_padconf_array_essential_4460
 .rodata.wkup_padconf_array_essential
                0x40309587        0xc board/ti/sdp4430/libsdp4430.o
                0x40309587                wkup_padconf_array_essential
 .rodata.core_padconf_array_essential
                0x40309593       0x60 board/ti/sdp4430/libsdp4430.o
                0x40309593                core_padconf_array_essential

Please note that the .rodata symbols have odd addresses. These arrays
actually need to be aligned at least to half-word boundary. In fact, in
the image I verified that they are put at even addresses. So, the
symbols have been kept as real address +1. I understand that this is
the convention for Thumb functions. I guess the tool-chain did it for
data too?? And I am getting unaligned access aborts on accessing them.

I notice that this doesn't happen with all .rodata. symbols in the
image. I couldn't see any difference between working and non-working
files nor any difference in the command used to build them!

Well, this doesn't happen if I don't use "-fdata-sections" in gcc
options. So, apply the following patch and you will see that those
symbols have even addresses now.

diff --git a/config.mk b/config.mk
index ddaa477..723286a 100644
--- a/config.mk
+++ b/config.mk
@@ -190,7 +190,7 @@ CPPFLAGS := $(DBGFLAGS) $(OPTFLAGS) $(RELFLAGS)             
\

 # Enable garbage collection of un-used sections for SPL
 ifeq ($(CONFIG_SPL_BUILD),y)
-CPPFLAGS += -ffunction-sections -fdata-sections
+CPPFLAGS += -ffunction-sections
 LDFLAGS_FINAL += --gc-sections
 endif


/spl/u-boot-spl.map:
=================
 .rodata        0x40309204      0x38c board/ti/sdp4430/libsdp4430.o
                0x40309204                core_padconf_array_essential
                0x40309264                wkup_padconf_array_essential
                0x40309270                wkup_padconf_array_essential_4460
                0x40309274                core_padconf_array_non_essential
                0x40309540                wkup_padconf_array_non_essential
                0x40309588                wkup_padconf_array_non_essential_4430

Will you be able to look into these?

Thanks,
Aneesh

[1] Sourcery G++ Lite 2010q1-202
arm-none-linux-gnueabi-gcc (Sourcery G++ Lite 2010q1-202) 4.4.1
GNU ld (Sourcery G++ Lite 2010q1-202) - binutils 2.19.51.20090709

[2] Linaro 4.6-2012.01
arm-linux-gnueabi-gcc (crosstool-NG linaro-1.13.1-2012.01-20120125 -
        Linaro GCC 2012.01) 4.6.3 20120105 (prerelease)
GNU ld (crosstool-NG linaro-1.13.1-2012.01-20120125 - Linaro GCC 2012.01) 2.22

_______________________________________________
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev

Reply via email to