[PATCH] ld: fix alignment issue for ARM thumb long branch stub using PureCode section
Torbjörn SVENSSON
torbjorn.svensson@foss.st.com
Tue Dec 17 18:01:41 GMT 2024
Ok for trunk?
--
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 | 1 +
ld/testsuite/ld-arm/arm-elf.exp | 3 ++
...rcall-thumb2-purecode-consecutive-veneer.d | 33 +++++++++++++++++++
...rcall-thumb2-purecode-consecutive-veneer.s | 28 ++++++++++++++++
ld/testsuite/ld-arm/farcall-thumb2-purecode.d | 2 +-
5 files changed, 66 insertions(+), 1 deletion(-)
create mode 100644 ld/testsuite/ld-arm/farcall-thumb2-purecode-consecutive-veneer.d
create mode 100644 ld/testsuite/ld-arm/farcall-thumb2-purecode-consecutive-veneer.s
diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
index a4c23216c68..b22ca579493 100644
--- a/bfd/elf32-arm.c
+++ b/bfd/elf32-arm.c
@@ -2630,6 +2630,7 @@ 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 */
};
/* V4T Thumb -> Thumb long branch stub. Using the stack is not
diff --git a/ld/testsuite/ld-arm/arm-elf.exp b/ld/testsuite/ld-arm/arm-elf.exp
index 7fa4520fb15..784416174f0 100644
--- a/ld/testsuite/ld-arm/arm-elf.exp
+++ b/ld/testsuite/ld-arm/arm-elf.exp
@@ -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 .var=0x2000 --section-start .foo=0x01001FFF" "" "" {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
index 00000000000..595b30ebc0e
--- /dev/null
+++ b/ld/testsuite/ld-arm/farcall-thumb2-purecode-consecutive-veneer.d
@@ -0,0 +1,33 @@
+.*: file format .*
+
+Disassembly of section .text:
+
+00001000 <bar>:
+ 1000: 4770 bx lr
+
+Disassembly of section .var:
+
+00002000 <var>:
+ 2000: 4770 bx lr
+
+Disassembly of section .foo:
+
+01001fff <__data_start\+0xfffffd>:
+ \.\.\.
+
+01002000 <_start>:
+ 1002000: f000 f808 bl 1002014 <__bar_veneer>
+ 1002004: f000 f800 bl 1002008 <__var_veneer>
+
+01002008 <__var_veneer>:
+ 1002008: f242 0c01 movw ip, #8193 @ 0x2001
+ 100200c: f2c0 0c00 movt ip, #0
+ 1002010: 4760 bx ip
+ 1002012: bf00 nop
+
+01002014 <__bar_veneer>:
+ 1002014: f241 0c01 movw ip, #4097 @ 0x1001
+ 1002018: f2c0 0c00 movt ip, #0
+ 100201c: 4760 bx ip
+ 100201e: 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
index 00000000000..228aaa18e3a
--- /dev/null
+++ b/ld/testsuite/ld-arm/farcall-thumb2-purecode-consecutive-veneer.s
@@ -0,0 +1,28 @@
+@ 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
+bar:
+ bx lr
+
+@ We will place the section .section at 0x2000.
+
+ .section .var, "0x20000006"
+ .type var, %function
+var:
+ bx lr
+
+@ We will place the section .foo at 0x02001014.
+
+ .section .foo, "0x20000006"
+_start:
+ bl bar
+ bl var
diff --git a/ld/testsuite/ld-arm/farcall-thumb2-purecode.d b/ld/testsuite/ld-arm/farcall-thumb2-purecode.d
index 451832678e9..00a070eed5b 100644
--- a/ld/testsuite/ld-arm/farcall-thumb2-purecode.d
+++ b/ld/testsuite/ld-arm/farcall-thumb2-purecode.d
@@ -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
\.\.\.
--
2.25.1
More information about the Binutils
mailing list