Created attachment 7843 [details] test to reproduce While working on the attribute_target GCC attribute, I find myself calling a static THUMB function while in ARM mode, or vice versa. (this works fine when functions are .global) Using the attached .s example, with foo: .thumb_func .type bar, %function the relocations are in the object 00000000 <main>: 00000000 <main>: 0: ebfffffe bl 0 <main> 0: R_ARM_CALL foo 4: ebfffffe bl 0 <main> 4: R_ARM_CALL bar is resolved in the final binary as: Disassembly of section .text: 00008018 <main>: 8018: eb000085 bl 8234 <bar> 801c: fa000084 blx 8234 <bar> instead of bl <foo> What is surprising is that the linker correctly patches the BL/BLX instructions, itś just the address that is wrong. I´m wondering if this can be fixed in the linker machinery to handle interwork or have the assembly emit a R_ARM_THM_CALL reloc assembled/linked with : arm-none-eabi-gcc 1.s -o 1.u
Encoding a BFD_RELOC_ARM_PCREL_BLX instead of a BFD_RELOC_ARM_PCREL_CALL for static calls between arm to thumb fixed the problem.
Created attachment 7866 [details] tentative patch
Created attachment 7867 [details] New test compiles with arm-none-eabi-gcc -march=armv7-a 1.s previous objdump was : 801c: eb00008a bl 824c <foo> 8020: e1a03000 mov r3, r0 8024: fa00008c blx 825c <rab+0x4> 8028: e0833000 add r3, r3, r0 802c: eb000089 bl 8258 <rab> now : 801c: eb00008a bl 824c <foo> 8020: e1a03000 mov r3, r0 8024: fa00008a blx 8254 <bar> 8028: e0833000 add r3, r3, r0 802c: eb000089 bl 8258 <rab>
Created attachment 7868 [details] the c input causing the situation, for reference (need attribute target support)
(In reply to Christian Bruel from comment #1) > Encoding a BFD_RELOC_ARM_PCREL_BLX instead of a BFD_RELOC_ARM_PCREL_CALL for > static calls between arm to thumb fixed the problem. That sounds wrong. Which architecture revision are you targeting?
(In reply to Richard Earnshaw from comment #5) > (In reply to Christian Bruel from comment #1) > > Encoding a BFD_RELOC_ARM_PCREL_BLX instead of a BFD_RELOC_ARM_PCREL_CALL for > > static calls between arm to thumb fixed the problem. > > That sounds wrong. it is indeed, fixed locally but many other regressions. > > Which architecture revision are you targeting? v7 and v5
> What is surprising is that the linker correctly patches the BL/BLX instructions, itś just the address that is wrong. I´m wondering if this can be fixed in the linker machinery to handle interwork or have the assembly emit a R_ARM_THM_CALL reloc I think you're being confused by the disassembler. The two symbols are at the same address (there's no code in between the two); so the disassembler just picks one of them to print out. I still don't see anything wrong with what's being generated by the assembler/linker.
sorry, the first test was only illustrative, but not completed. the fact that the addresses are the same is just because I reduced the code. Here is the complete attachment, here the code is : 00008240 <foo>: 8240: e30b3178 movw r3, #45432 ; 0xb178 8244: e3e0207e mvn r2, #126 ; 0x7e 8248: e3403001 movt r3, #1 824c: e5933000 ldr r3, [r3] 8250: e5c32000 strb r2, [r3] 8254: e12fff1e bx lr 00008258 <bar>: 8258: 4770 bx lr 825a: bf00 nop and main calls : 00008018 <main>: 8018: e92d4010 push {r4, lr} 801c: fa000093 blx 8270 <atexit+0x14> 8020: eb000086 bl 8240 <foo> 8024: e3a00000 mov r0, #0 8028: e8bd8010 pop {r4, pc} so bl bar is in the .o 4: eb000004 bl 30 <bar+0x18> 4: R_ARM_CALL bar instead of just bl 30 <0x18> looks like a wrong addend to the start of the section. to reproduce: arm-none-eabi-gcc -march=armv7-a 2.s -c -o 1.o arm-none-eabi-objdump -dr 1.o | grep bar arm-none-eabi-gcc -march=armv7-a 2.s -o 1.u arm-none-eabi-objdump -dr 1.u
Created attachment 7903 [details] complete runable assembly
in the .o dump bar is at .text 00000000 <foo>: ... 00000018 <bar>: but the call to bar resolves: 4: eb000004 bl 30 <bar+0x18> 4: R_ARM_CALL bar why the +0x18 addend ? it shoud be either bl <foo+0x18> or just (prefered) bl <bar>
gcc 6.0.0 fixed to resolve interwork static thumb2 calls, so the linker fixup is not needed anymore.