This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: ld emitting blx immdetiate for Cortex M3


On Fri, Mar 16, 2012 at 01:04:53PM +0000, Benjamin Hase wrote:
> 
> Am 16.03.2012 um 13:09 schrieb Matthew Gretton-Dann:
> 
> > On Fri, Mar 16, 2012 at 08:34:46AM +0000, Benjamin Hase wrote:
> >> Hi all,
> >>
> >> the following simple program causes the linker to emit 'blx immediate':
> >>
> >> #include <stdlib.h>
> >>
> >> int main(int argc, char **argv)
> >> {
> >>      int x = atoi("123");
> >>      return x;
> >> }
> >>
> >> compilation with
> >>
> >> % arm-none-eabi-gcc -o toolchain-test.elf -Wall -nostartfiles -msoft-float -mlittle-endian -Wl,-t -mthumb -mcpu=cortex-m3 -Wl,--entry=main main.c
> >> /Users/benjamin/sat_bleeding/bin/../lib/gcc/arm-none-eabi/4.6.3/../../../../arm-none-eabi/bin/ld: mode armelf
> >> /var/folders/6r/jwq4v3_56p19hr18dyx7wcjh0000gn/T//ccANJypP.o
> >> (/Users/benjamin/sat_bleeding/bin/../lib/gcc/arm-none-eabi/4.6.3/../../../../arm-none-eabi/lib/thumb/libc.a)lib_a-atoi.o
> >> (/Users/benjamin/sat_bleeding/bin/../lib/gcc/arm-none-eabi/4.6.3/../../../../arm-none-eabi/lib/thumb/libc.a)lib_a-strtol.o
> >> (/Users/benjamin/sat_bleeding/bin/../lib/gcc/arm-none-eabi/4.6.3/../../../../arm-none-eabi/lib/thumb/libc.a)lib_a-ctype_.o
> >> (/Users/benjamin/sat_bleeding/bin/../lib/gcc/arm-none-eabi/4.6.3/../../../../arm-none-eabi/lib/thumb/libc.a)lib_a-impure.o
> >> (/Users/benjamin/sat_bleeding/bin/../lib/gcc/arm-none-eabi/4.6.3/thumb/libgcc.a)_udivsi3.o
> >> (/Users/benjamin/sat_bleeding/bin/../lib/gcc/arm-none-eabi/4.6.3/thumb/libgcc.a)_dvmd_tls.o
> >>
> >> arm-none-eabi-objdump -d shows in strtol_r (which is internally called from newlib) blx instructions:
> >>
> >>    80a2:       1c30            adds    r0, r6, #0
> >>    80a4:       4651            mov     r1, sl
> >>    80a6:       f000 e910       blx     82c8 <__aeabi_uidivmod>
> >>    80aa:       1c30            adds    r0, r6, #0
> >>    80ac:       4689            mov     r9, r1
> >>    80ae:       4651            mov     r1, sl
> >>    80b0:       f000 e88c       blx     81cc <__aeabi_uidiv>
> >>    80b4:       2603            movs    r6, #3
> >
> > Take a look at __aeabi_uidivmod and __aeabi_uidiv - I think you will find
> > that they are in ARM state, and so the BLX is valid.
> 
> Is it possible to recognize for which state functions are compiled? I tried objdump -x (full output below),
> but I am not sure how to interpret this and if it can be seen at all???
> 
> RELOCATION RECORDS FOR [.text]:
> OFFSET   TYPE              VALUE
> 0000005e R_ARM_THM_CALL    __aeabi_uidivmod
> 00000068 R_ARM_THM_CALL    __aeabi_uidiv
> 00000160 R_ARM_ABS32       __ctype_ptr__

If you want to know whether a function is ARM or Thumb state use readelf -s.
If the FUNC symbol has an odd value then it is in Thumb state, if it is even
its in ARM state.

On an image based on your test case I get the following:

$ arm-none-readelf -s t.axf | grep FUNC
    40: 000082f8     8 FUNC    LOCAL  DEFAULT    1 ____aeabi_idiv0_from_arm
    44: 000081d4   252 FUNC    GLOBAL DEFAULT    1 __udivsi3
    47: 000081b5    32 FUNC    GLOBAL DEFAULT    1 strtol
    48: 00008035    16 FUNC    GLOBAL DEFAULT    1 _atoi_r
    51: 000082f1     2 FUNC    WEAK   DEFAULT    1 __aeabi_ldiv0
    53: 00008001    36 FUNC    GLOBAL DEFAULT    1 main
    54: 000081d4     0 FUNC    GLOBAL DEFAULT    1 __aeabi_uidiv
    55: 00008045   368 FUNC    GLOBAL DEFAULT    1 _strtol_r
    58: 000082d0    32 FUNC    GLOBAL DEFAULT    1 __aeabi_uidivmod
    62: 00008025    16 FUNC    GLOBAL DEFAULT    1 atoi
    64: 000082f1     2 FUNC    WEAK   DEFAULT    1 __aeabi_idiv0

So strtol, _atoi_r, __aeabi_ldiv0, main, strtol_r, atoi, __aeabi_idiv0 are
Thumb state entry points, and all the other function entry points are in ARM
state.

If you are reading disassembled code (objdump -d) Thumb code will look like:

    8038:       230a            movs    r3, #10
    803a:       f000 f803       bl      8044 <_strtol_r>

That is the encoding is displayed as one or two 16-bit values

ARM state code will look like:

    81d8:       012fff1e        bxeq    lr

That is the encoding is displayed as one 32-bit value.

> > This is because you have not set up your multilibs correctly for Cortex-M3
> > and so (at a guess) you have linked v7-M code against v4-T code containing
> > ARM state code.  The linker will not complain about this as it views the two
> > as being compatible - the linker has no idea about which core you are
> > targeting your image at.
> There are two questions for me:
> a) it seems as if the linker tries to do the right thing, the used libraries are below thumb/,
>    according to the linker trace. That, of course, does not ensure the libraries itself are right???
> b) If the linker is allowed to change opcodes (as it looks like in this example), shouldn't
>    he know about which opcodes are allowed? And this is architecture dependent IMHO.
> 
> >
> > Configuring and building a suitable toolchain for this is non-trivial.
> >
> > The following website gives a pre-built GCC 4.6 based toolchain with Cortex-M
> > libraries.  It also gives instructions for how to build such a toolchain
> > from scratch if the options provided are not suitable for you.
> A link would have been nice :-)

Sorry - I shouldn't send emails immediately before lunch :-).  Here you go:

https://launchpad.net/gcc-arm-embedded

Thanks,

Matt

-- 
Matthew Gretton-Dann
Principal Engineer, PD Software, ARM Ltd.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]