Skip to content

Commit

Permalink
Fixed for veneers generated by linker for interworking
Browse files Browse the repository at this point in the history
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

```
  • Loading branch information
nikarh committed Jun 1, 2023
1 parent 2dc7942 commit 2c28624
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 1 deletion.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,7 @@ function(toolchain_deps toolchain_deps_dir toolchain_install_dir toolchain_suffi
patch -d <SOURCE_DIR> -p3 -t -N < ${PROJECT_SOURCE_DIR}/patches/binutils/0001-vita.patch
&& patch -d <SOURCE_DIR> -p1 -t -N < ${PROJECT_SOURCE_DIR}/patches/binutils/0002-fix-broken-reloc.patch
&& patch -d <SOURCE_DIR> -p3 -t -N < ${PROJECT_SOURCE_DIR}/patches/binutils/0003-fix-elf-vaddr.patch
&& patch -d <SOURCE_DIR> -p3 -t -N < ${PROJECT_SOURCE_DIR}/patches/binutils/0004-fix-interworking-veneers.patch
CONFIGURE_COMMAND ${compiler_flags} ${wrapper_command} <SOURCE_DIR>/configure
--build=${build_native}
--host=${toolchain_host}
Expand Down
2 changes: 1 addition & 1 deletion patches/binutils/0002-fix-broken-reloc.patch
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ diff -urN binutils-2.31.1.orig/bfd/elf32-arm.c binutils-2.31.1/bfd/elf32-arm.c
@@ -13517,6 +13517,7 @@
else
unwind_type = 2;

+ elide = 0;
if (elide && !bfd_link_relocatable (info))
{
Expand Down
13 changes: 13 additions & 0 deletions patches/binutils/0004-fix-interworking-veneers.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
diff --git a/ld/emultempl/armelf.em b/ld/emultempl/armelf.em
index a9ac12d6..627c9086 100644
--- a/src/binutils/ld/emultempl/armelf.em
+++ b/src/binutils/ld/emultempl/armelf.em
@@ -41,7 +41,7 @@ static struct elf32_arm_params params =
BFD_ARM_STM32L4XX_FIX_NONE, /* stm32l4xx_fix */
0, /* no_enum_size_warning */
0, /* no_wchar_size_warning */
- 0, /* pic_veneer */
+ 1, /* pic_veneer */
-1, /* fix_cortex_a8 */
1, /* fix_arm1176 */
-1, /* merge_exidx_entries */

0 comments on commit 2c28624

Please sign in to comment.