[ARM] Wrong BLX destination

Christophe Lyon christophe.lyon@linaro.org
Wed Mar 9 08:07:00 GMT 2016


On 8 March 2016 at 00:11, Simon Marchi <simon.marchi@polymtl.ca> wrote:
> Hi,
>
> I noticed a behavior I can't explain while playing with gas and ld on ARM, I
> thought this list would be the best place to ask for help.  There is nothing
> mission-critical, I would just like an explanation to satisfy my curiosity.
>
> My initial question was if it was possible to have a BLX instruction (the
> version that takes a an immediate value) that jumps from ARM code to Thumb
> code, to an address that is not a multiple of 4.  The ARM instruction set
> seems to support it (because of the H bit in the instruction's encoding), so
> I wanted to try to make gas generate it.
>
> It seems like C functions (even in Thumb mode) are always placed on PCs
> multiples of four, so I decided to generate symbols by hand in assembly.  I
> just want to see the generated instruction, I don't intend to run it, so the
> data at these location is garbage.
>
> So I made this little test.S:
>
>   .arm
>
>   hello1:
>   .hword 0x1111
>
>   hello2:
>   .hword 0x2222
>
>   hello3:
>   .hword 0x3333
>
>   # Space things out a bit
>   .fill 20, 4, 0
>
>   .align 4
>
>   blx hello1
>   blx hello2
>   blx hello3
>
> I compile it like this (main.c is just an empty main function):
>
>   gcc -g3 -O0  main.c test.S
>
> This is the relevant disassembly:
>
>   000083d0 <hello1>:
>       83d0:       1111            asrs    r1, r2, #4
>
>   000083d2 <hello2>:
>       83d2:       2222            movs    r2, #34 ; 0x22
>
>   000083d4 <hello3>:
>       83d4:       3333            adds    r3, #51 ; 0x33
>           ...
>       8426:       0000            .short  0x0000
>       8428:       e320f000        nop     {0}
>       842c:       e320f000        nop     {0}
>       8430:       faffffe6        blx     83d0 <hello1>
>       8434:       fbffffe5        blx     83d2 <hello2>
>       8438:       faffffe5        blx     83d4 <hello3>
>       843c:       e320f000        nop     {0}
>
> Everything looks good, we can see that the call to hello2 points indeed to
> an address that isn't a multiple of 4.
>
> I then tried to do the same thing, except I placed the target symbols in
> another compilation unit (IOW, ld is now involved in linking/patching the
> instructions).  So I now have test.S with only the calls:
>
>   .arm
>
>   .align 4
>
>   blx hello1
>   blx hello2
>   blx hello3
>
>   # Space things out a bit
>   .fill 20, 4, 0
>
> and test2.S with the labels:
>
>   .arm
>
>   .global hello1
>   .global hello2
>   .global hello3
>
>   hello1:
>   .hword 0x1111
>
>   hello2:
>   .hword 0x2222
>
>   hello3:
>   .hword 0x3333
>
>   # Space things out a bit
>   .fill 20, 4, 0
>
> This is the resulting disassembly:
>
>       83d0:       fa000016        blx     8430 <hello1>
>       83d4:       fa000015        blx     8430 <hello1>  <---- WRONG TARGET
>       83d8:       fa000015        blx     8434 <hello3>
>           ...
>       842c:       e320f000        nop     {0}
>
>   00008430 <hello1>:
>       8430:       22221111        eorcs   r1, r2, #1073741828     ;
> 0x40000004
>
>   00008432 <hello2>:
>       8432:       33332222        teqcc   r3, #536870914  ; 0x20000002
>
>   00008434 <hello3>:
>       8434:       00003333        andeq   r3, r0, r3, lsr r3
>
> As you can see, the second blx instruction points to hello1, whereas it
> should point to hello2.
>
> Do you know if this is the intended behavior, and if so, what explains it?
> Is there some alignment requirements that differs in both cases?
>

Hi,

I haven't looked at this for a while, but:
- which relocations are encoded by gas? (objdump -r). I suspect you
have the ARM version of call (as opposed to the thumb one)
- I think you have to use the .thumb_func assembly directive right
before helloX definition, and probably give it a function type too

The linker will take care of making the call point to the right
address, provided it has the right relocations.

Christophe.

> Thanks!
>
> Simon



More information about the Binutils mailing list