Hello,

We encountered a linking error in 11.1 and 11.2 of the ARM GNU Toolchain. There 
seems to be a bug in encodings of calls using blx when jumping from thumb to 
arm instructions. When the jump is exactly 2^24 + 2, the jump turns into a jump 
of 2 instead of an indirect jump. If the jump is shorter, a direct jump is 
generated correctly. If the jump is longer, an indirect jump is generated 
correctly.

The bug can be reproduced for example on the ARM GNU Toolchain version 
11.2-2022.02 for the AArch32 bare-metal target (arm-none-eabi) available for 
x86_64 Linux hosted cross toolchains here: Arm GNU Toolchain | Arm GNU 
Toolchain Downloads - Arm 
Developer<https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/downloads>.

A small example for triggering this bug for the above toolchain is as follows. 
For other versions of the toolchain, the example needs to be tweaked, because 
it is sensitive to code size, which typically differs between versions.

```cpp
__attribute__((target("arm"))) int __attribute__ ((noinline)) f();

#define DIRECT_CALL \
                          asm ("NOP");

#define ERROR_CALL \
                          DIRECT_CALL \
                          asm ("NOP"); \
                          asm ("NOP"); \
                          asm ("NOP"); \
                          asm ("NOP");

#define INDIRECT_CALL \
                          ERROR_CALL \
                          asm ("NOP"); \
                          asm ("NOP"); \
                          asm ("NOP");

__attribute__((target("thumb"))) int main()
{
                          asm ("NOP");
                          asm ("NOP");
                          f();
                          //DIRECT_CALL
                          ERROR_CALL
                          //INDIRECT_CALL

                          int k = f();
                          return k;
}

#define SIZE_DATA 0xfffe38
int x[SIZE_DATA >> 2] __attribute__((section(".text"))); // fill in memory to 
make main() and f() almost 2^24 bytes apart.

__attribute__((target("arm"))) int __attribute__ ((noinline)) f()
{
                          x[(SIZE_DATA >> 2) - 1] = 12;
                          static int i = 0;
                          i++;
                          asm ("NOP");
                          return i + x[(SIZE_DATA >> 2) - 1]; // make sure 
nothing is optimized
}
```

The bug goes away if `ERROR_CALL` is replaced by either of the commented parts 
`//DIRECT_CALL` or `//INDIREC_CALL`.

If the above code is in a file called test.cpp, then the bug shows up when it 
is compiled with:
arm-none-eabi-g++ -std=gnu++17 -mcpu=cortex-a9 -mfpu=vfpv3 -fdata-sections 
-ffunction-sections -mfloat-abi=hard -O3 -save-temps=obj -fverbose-asm 
--specs=nosys.specs test.cpp

Now if one disassembles the output using `arm-none-eabi-objdump -d a.out > 
a.s`, then the resulting file a.s contains the following encoding of the first 
call to f():
8036: f000 e800 blx 8038 <main+0x8>

This instruction represents a jump of two jumps forward to the address 8036 to 
8038, which is wrong.


Best regards,

Jori Bomanson| Software Designer
+358 50 5058809| jori.boman...@huld.io<mailto:jori.boman...@huld.io>

Huld Espoo | Keilasatama 5, 02150 Espoo
[cid:image001.png@01D827F7.41361B60]<https://eur03.safelinks.protection.outlook.com/?url=https%3A%2F%2Fhuld.io%2F&data=04%7C01%7C%7C4a2ee0b6310b41575ab908d87b1c0bc7%7C2a82d2e0be594e30a9834919d6a291b2%7C0%7C0%7C637394707679827363%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=pN1%2FQyZmaloxVjHzKH%2B7UMdcRAhIUQ97Z4xMe0gOcPI%3D&reserved=0>
Huld - Beyond Tomorrow
huld.io<https://eur03.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.huld.io%2F&data=04%7C01%7C%7C4a2ee0b6310b41575ab908d87b1c0bc7%7C2a82d2e0be594e30a9834919d6a291b2%7C0%7C0%7C637394707679837356%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=1AWcoV%2BRJgFIK2jbQ9s%2Bj7%2BCD24u1NvE10uhzfXVjBg%3D&reserved=0>
 | 
Facebook<https://eur03.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.facebook.com%2Fhuldofficial%2F&data=04%7C01%7C%7C4a2ee0b6310b41575ab908d87b1c0bc7%7C2a82d2e0be594e30a9834919d6a291b2%7C0%7C0%7C637394707679837356%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=7n6OoDtFXH6cYRtE5tjTBdYJSClG6zgN%2BLu3x8P961E%3D&reserved=0>
 | 
LinkedIn<https://eur03.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.linkedin.com%2Fcompany%2Fhuld%2F&data=04%7C01%7C%7C4a2ee0b6310b41575ab908d87b1c0bc7%7C2a82d2e0be594e30a9834919d6a291b2%7C0%7C0%7C637394707679847353%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=ymVClF5JKsS9HpHzcYe552UY1cSPloqATSb66gbu%2BYA%3D&reserved=0>
 | 
Twitter<https://eur03.safelinks.protection.outlook.com/?url=https%3A%2F%2Ftwitter.com%2Fhuldofficial&data=04%7C01%7C%7C4a2ee0b6310b41575ab908d87b1c0bc7%7C2a82d2e0be594e30a9834919d6a291b2%7C0%7C0%7C637394707679857354%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=LGVW89rNN%2BHRcb0Oq%2FVlUdo3QYEWVuuOZVBzLGUarJo%3D&reserved=0>

Reply via email to