Skip to content

Commit bbf1c99

Browse files
committed
Fixed for veneers generated by linker for interworking
A compiler can do tail call optimizations, emitting R_ARM_JUMP24 relocation instead of a normal call. If this call has interworking (was from arm function to a thumb function or vice versa), binutils produces a veneer, because it needs to do a switch. By default these veneers do jumps to an absolute address. This patch forces ld to produce veneers for position independent binaries. tldr; no need for `--no-optimize-sibling-calls` anymore, sibling calls will ✨ work ✨ An example of veneer before this patch: ``` 81000010 <__func_thumb_from_arm>: 81000010: e51ff004 ldr pc, [pc, #-4] @ 0x81000014 <$d> 81000014 <$d>: 81000014: 01 00 00 81 .word 0x81000001 ``` and after: ``` 81000010 <__func_thumb_from_arm>: 81000010: e59fc004 ldr r12, [pc, #4] @ 0x8100001c <$d> 81000014: e08fc00c add r12, pc, r12 81000018: e12fff1c bx r12 8100001c <$d>: 8100001c: e5 ff ff ff .word 0xffffffe5 ```
1 parent 2dc7942 commit bbf1c99

File tree

3 files changed

+15
-1
lines changed

3 files changed

+15
-1
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,7 @@ function(toolchain_deps toolchain_deps_dir toolchain_install_dir toolchain_suffi
301301
patch -d <SOURCE_DIR> -p3 -t -N < ${PROJECT_SOURCE_DIR}/patches/binutils/0001-vita.patch
302302
&& patch -d <SOURCE_DIR> -p1 -t -N < ${PROJECT_SOURCE_DIR}/patches/binutils/0002-fix-broken-reloc.patch
303303
&& patch -d <SOURCE_DIR> -p3 -t -N < ${PROJECT_SOURCE_DIR}/patches/binutils/0003-fix-elf-vaddr.patch
304+
&& patch -d <SOURCE_DIR> -p3 -t -N < ${PROJECT_SOURCE_DIR}/patches/binutils/0004-fix-interworking-veneers.patch
304305
CONFIGURE_COMMAND ${compiler_flags} ${wrapper_command} <SOURCE_DIR>/configure
305306
--build=${build_native}
306307
--host=${toolchain_host}

patches/binutils/0002-fix-broken-reloc.patch

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ diff -urN binutils-2.31.1.orig/bfd/elf32-arm.c binutils-2.31.1/bfd/elf32-arm.c
44
@@ -13517,6 +13517,7 @@
55
else
66
unwind_type = 2;
7-
7+
88
+ elide = 0;
99
if (elide && !bfd_link_relocatable (info))
1010
{
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
diff --git a/ld/emultempl/armelf.em b/ld/emultempl/armelf.em
2+
index a9ac12d6..627c9086 100644
3+
--- a/src/binutils/ld/emultempl/armelf.em
4+
+++ b/src/binutils/ld/emultempl/armelf.em
5+
@@ -41,7 +41,7 @@ static struct elf32_arm_params params =
6+
BFD_ARM_STM32L4XX_FIX_NONE, /* stm32l4xx_fix */
7+
0, /* no_enum_size_warning */
8+
0, /* no_wchar_size_warning */
9+
- 0, /* pic_veneer */
10+
+ 1, /* pic_veneer */
11+
-1, /* fix_cortex_a8 */
12+
1, /* fix_arm1176 */
13+
-1, /* merge_exidx_entries */

0 commit comments

Comments
 (0)