]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
ld: fix alignment issue for ARM thumb long branch stub using PureCode section
authorTorbjörn SVENSSON <torbjorn.svensson@foss.st.com>
Tue, 17 Dec 2024 17:56:10 +0000 (18:56 +0100)
committerTorbjörn SVENSSON <torbjorn.svensson@foss.st.com>
Thu, 23 Jan 2025 09:36:03 +0000 (10:36 +0100)
When pure-code option is activated. The linker creates for M-profile architecures
a 2-bytes branch instruction. This causes the section alignment to be set to 2-byte
alignment instead of 4-byte alignment. This is a problem for long branch stub
without pure-code section as it contains a 32-bit address as data, which is expected
to be 4-byte aligned. Hence creating a long branch stub for PureCode section followed
by a long branch stub will result in a misalignment for the 32-bit address.

An easy fix is to add a nop instruction after the branch to keep the section alignment
to 4 bytes.

Signed-off-by: Torbjörn SVENSSON <torbjorn.svensson@foss.st.com>
Co-authored-by: Guillaume VACHERIAS <guillaume.vacherias@st.com>
bfd/elf32-arm.c
ld/testsuite/ld-arm/arm-elf.exp
ld/testsuite/ld-arm/farcall-thumb2-purecode-consecutive-veneer.d [new file with mode: 0644]
ld/testsuite/ld-arm/farcall-thumb2-purecode-consecutive-veneer.s [new file with mode: 0644]
ld/testsuite/ld-arm/farcall-thumb2-purecode.d

index 8865befc06c37d2b548ec054b19cd95ec239e003..10c93e229b6fbb2f7aa69711932a79b440913f69 100644 (file)
@@ -2630,6 +2630,8 @@ static const insn_sequence elf32_arm_stub_long_branch_thumb2_only_pure[] =
   THUMB32_MOVW (0xf2400c00),        /* mov.w ip, R_ARM_MOVW_ABS_NC */
   THUMB32_MOVT (0xf2c00c00),        /* movt  ip, R_ARM_MOVT_ABS << 16 */
   THUMB16_INSN (0x4760),            /* bx   ip */
+  THUMB16_INSN (0xbf00),            /* nop */
+  /* The nop is added to ensure alignment of following stubs in the section.  */
 };
 
 /* V4T Thumb -> Thumb long branch stub. Using the stack is not
index be49d8fc6e527529d6cc90662ddac199235f36f8..cacd3bddfd46dc78125dc25eff00ff752d8acd93 100644 (file)
@@ -604,6 +604,9 @@ set armeabitests_nonacl {
     {"Thumb2 purecode farcall" "-Ttext 0x1000 --section-start .foo=0x2001020" "" "" {farcall-thumb2-purecode.s}
      {{objdump -d farcall-thumb2-purecode.d}}
      "farcall-thumb2-purecode"}
+     {"Thumb2 purecode farcall consecutive veneer" "-Ttext 0x1000 --section-start .foo=0x2001020" "" "" {farcall-thumb2-purecode-consecutive-veneer.s}
+     {{objdump -d farcall-thumb2-purecode-consecutive-veneer.d}}
+     "farcall-thumb2-purecode-consecutive-veneer"}
 
     {"Thumb-ARM farcall" "-Ttext 0x1c01010 --section-start .foo=0x2001014" "" "-W" {farcall-thumb-arm.s}
      {{objdump -d farcall-thumb-arm.d}}
diff --git a/ld/testsuite/ld-arm/farcall-thumb2-purecode-consecutive-veneer.d b/ld/testsuite/ld-arm/farcall-thumb2-purecode-consecutive-veneer.d
new file mode 100644 (file)
index 0000000..b89da03
--- /dev/null
@@ -0,0 +1,28 @@
+.*:     file format .*
+
+Disassembly of section .text:
+
+00001000 <bar>:
+    1000:      4770            bx      lr
+
+00001002 <baz>:
+    1002:      4770            bx      lr
+
+Disassembly of section .foo:
+
+02001020 <_start>:
+ 2001020:      f000 f802       bl      2001028 <__bar_veneer>
+ 2001024:      f000 f806       bl      2001034 <__baz_veneer>
+
+02001028 <__bar_veneer>:
+ 2001028:      f241 0c01       movw    ip, #4097       @ 0x1001
+ 200102c:      f2c0 0c00       movt    ip, #0
+ 2001030:      4760            bx      ip
+ 2001032:      bf00            nop
+
+02001034 <__baz_veneer>:
+ 2001034:      f241 0c03       movw    ip, #4099       @ 0x1003
+ 2001038:      f2c0 0c00       movt    ip, #0
+ 200103c:      4760            bx      ip
+ 200103e:      bf00            nop
+       \.\.\.
diff --git a/ld/testsuite/ld-arm/farcall-thumb2-purecode-consecutive-veneer.s b/ld/testsuite/ld-arm/farcall-thumb2-purecode-consecutive-veneer.s
new file mode 100644 (file)
index 0000000..ee3d6c1
--- /dev/null
@@ -0,0 +1,25 @@
+@ Test to ensure that a purecode Thumb2 call exceeding 4Mb generates a stub.
+
+       .global _start
+       .syntax unified
+       .arch armv7-m
+       .thumb
+       .thumb_func
+
+@ We will place the section .text at 0x1000.
+
+       .section .text, "0x20000006"
+       .type bar, %function
+       .type baz, %function
+bar:
+       bx lr
+
+baz:
+       bx lr
+
+@ We will place the section .foo at 0x02001014.
+
+       .section .foo, "0x20000006"
+_start:
+       bl bar
+       bl baz
index 451832678e9cc576f0e9c777c060459abc9b19d1..00a070eed5b635b0bf9c060b1902f04a61c82fd4 100644 (file)
@@ -16,7 +16,7 @@ Disassembly of section .foo:
  2001028:      f241 0c01       movw    ip, #4097       @ 0x1001
  200102c:      f2c0 0c00       movt    ip, #0
  2001030:      4760            bx      ip
- 2001032:      0000            movs    r0, r0
+ 2001032:      bf00            nop
  2001034:      0000            movs    r0, r0
        \.\.\.