[lld] [LLD][AArch64] Add test for missing AArch64 BTI thunk (PR #116665)

Peter Smith via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 19 02:05:59 PST 2024


https://github.com/smithp35 updated https://github.com/llvm/llvm-project/pull/116665

>From 96e35d7794401eff8836ba51e338d1e065e89138 Mon Sep 17 00:00:00 2001
From: Peter Smith <peter.smith at arm.com>
Date: Mon, 18 Nov 2024 17:20:34 +0000
Subject: [PATCH 1/2] [LLD][AArch64] Add test for missing AArch64 BTI thunk

A follow up to PR #116402 to add a regression test. The original
change fixed the reproducer but that was not suitable to use as
a regression test.

This test case will fail with a LLD prior to #116402.

The disassembly for the thunk that starts as a short thunk but
is later a long thunk isn't quite right. It is missing a $d
mapping symbol. I think this can be fixed, but I've not done
that in this patch to keep it test only. It is not a regression
introduced in #116402.

I've also removed a spurious --threads=1 I noticed in the original
test aarch64-thunk-bti.s
---
 lld/test/ELF/aarch64-thunk-bti-multipass.s | 112 +++++++++++++++++++++
 lld/test/ELF/aarch64-thunk-bti.s           |   2 +-
 2 files changed, 113 insertions(+), 1 deletion(-)
 create mode 100644 lld/test/ELF/aarch64-thunk-bti-multipass.s

diff --git a/lld/test/ELF/aarch64-thunk-bti-multipass.s b/lld/test/ELF/aarch64-thunk-bti-multipass.s
new file mode 100644
index 00000000000000..a4dd0ed1bf3c35
--- /dev/null
+++ b/lld/test/ELF/aarch64-thunk-bti-multipass.s
@@ -0,0 +1,112 @@
+// REQUIRES: aarch64
+// RUN: rm -rf %t && split-file %s %t && cd %t
+// RUN: llvm-mc -filetype=obj -triple=aarch64 asm -o a.o
+// RUN: ld.lld --script=lds a.o -o out.exe
+// RUN: llvm-objdump -d --no-show-raw-insn out.exe | FileCheck %s
+
+/// Test that a thunk that at creation time does not need to use a BTI
+/// compatible landing pad, but due to other thunk insertion ends up
+/// out of short-branch range so a BTI thunk is required after all.
+
+//--- asm
+.section ".note.gnu.property", "a"
+.p2align 3
+.long 4
+.long 0x10
+.long 0x5
+.asciz "GNU"
+
+/// Enable BTI.
+.long 0xc0000000 // GNU_PROPERTY_AARCH64_FEATURE_1_AND.
+.long 4
+.long 1          // GNU_PROPERTY_AARCH64_FEATURE_1_BTI.
+.long 0
+
+.section .text.0, "ax", %progbits
+.balign 0x1000
+.global _start
+.type _start, %function
+_start:
+/// Call that requires a thunk.
+ bl fn1
+/// padding so that we require thunks that can be placed after this section.
+/// The thunks are close enough to the target to be short.
+ .space 0x1000
+/// Thunk for call to fn1 will be placed here. Initially it is in short Thunk
+/// range of fn1, but due to a thunk added after a later section it won't be
+/// and will need a long branch thunk, which in turn needs a BTI landing pad.
+
+// CHECK-LABEL: <_start>:
+// CHECK-NEXT: 10001000: bl  0x10002004 <__AArch64AbsLongThunk_fn1>
+
+/// FIXME, the 2nd ldr and udf are a result of mapping symbols being generated
+/// on Thunk insertion. When that is fixed in lld they will be data statements
+/// like in __AArch64AbsLongThunk_far below.
+// CHECK-LABEL: <__AArch64AbsLongThunk_fn1>:
+// CHECK-NEXT: 10002004: ldr     x16, 0x1000200c <__AArch64AbsLongThunk_fn1+0x8>
+// CHECK-NEXT:           br      x16
+// CHECK-NEXT:           ldr     w0, 0x1000260c <__AArch64AbsLongThunk_fn1+0x608>
+// CHECK-NEXT:           udf     #0x0
+
+
+.section .text.1, "ax", %progbits
+.balign 0x1000
+.global farcall
+.type farcall, %function
+farcall:
+/// Call that requires a thunk.
+ bl far
+/// Section is aligned to 0x1000 boundary with size multipe of 0x1000.
+.space 0x1000 - (. - farcall)
+/// Thunk for call to far will be placed here. This will force text.2
+/// on to the next alignment boundary, moving it further away from the
+/// thunk inserted in the .text_low output section.
+
+// CHECK-LABEL: <farcall>:
+// CHECK-NEXT: 18001000: bl      0x18002000 <__AArch64AbsLongThunk_far>
+
+// CHECK-LABEL: <__AArch64AbsLongThunk_far>:
+// CHECK-NEXT: 18002000: ldr     x16, 0x18002008 <__AArch64AbsLongThunk_far+0x8>
+// CHECK-NEXT:           br      x16
+// CHECK-NEXT:           00 00 00 30   .word   0x30000000
+// CHECK-NEXT:           00 00 00 00   .word   0x00000000
+
+.section .text.2, "ax", %progbits
+.balign 0x1000
+.global fn1
+.type fn1, %function
+fn1:
+ ret
+
+.section .text.far, "ax", %progbits
+.type far, %function
+.global far
+far:
+ ret
+
+// CHECK-LABEL: <__AArch64BTIThunk_fn1>:
+// CHECK-NEXT: 18003000: bti     c
+// CHECK-NExT:           b       0x18004000 <fn1>
+
+// CHECK-LABEL: <fn1>:
+// CHECK-NEXT: 18004000: ret
+
+// CHECK-LABEL: <__AArch64BTIThunk_far>:
+// CHECK-NEXT: 30000000: bti     c
+
+// CHECK-LABEL: <far>:
+// CHECK-NEXT: 30000004: ret
+
+//--- lds
+PHDRS {
+  low PT_LOAD FLAGS(0x1 | 0x4);
+  mid PT_LOAD FLAGS(0x1 | 0x4);
+  high PT_LOAD FLAGS(0x1 | 0x4);
+}
+SECTIONS {
+  .rodata 0x10000000 : { *(.note.gnu.property) } :low
+  .text_low : { *(.text.0) } :low
+  .text 0x18001000 : { *(.text.1) } :mid
+  .text_aligned : { *(.text.2) } :mid
+  .text_high 0x30000000 : { *(.text.far) } :high
+}
diff --git a/lld/test/ELF/aarch64-thunk-bti.s b/lld/test/ELF/aarch64-thunk-bti.s
index a16e1569f358e3..a447fe4ee9274c 100644
--- a/lld/test/ELF/aarch64-thunk-bti.s
+++ b/lld/test/ELF/aarch64-thunk-bti.s
@@ -1,7 +1,7 @@
 // REQUIRES: aarch64
 // RUN: rm -rf %t && split-file %s %t && cd %t
 // RUN: llvm-mc -filetype=obj -triple=aarch64 asm -o a.o
-// RUN: ld.lld --threads=1 --shared --script=lds a.o -o out.so --defsym absolute=0xf0000000
+// RUN: ld.lld --shared --script=lds a.o -o out.so --defsym absolute=0xf0000000
 // RUN: llvm-objdump -d --no-show-raw-insn out.so | FileCheck %s
 // RUN: llvm-objdump -d --no-show-raw-insn out.so | FileCheck %s --check-prefix=CHECK-PADS
 // RUN: llvm-mc -filetype=obj -triple=aarch64 shared -o shared.o

>From 96b83e34b814a76d254579dc2541a14396f01215 Mon Sep 17 00:00:00 2001
From: Peter Smith <peter.smith at arm.com>
Date: Tue, 19 Nov 2024 09:34:36 +0000
Subject: [PATCH 2/2] [LLD][AArch64] Address review comments

Improve comment to explain padding and change out.exe to out.
---
 lld/test/ELF/aarch64-thunk-bti-multipass.s | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/lld/test/ELF/aarch64-thunk-bti-multipass.s b/lld/test/ELF/aarch64-thunk-bti-multipass.s
index a4dd0ed1bf3c35..6569d6d00ec37f 100644
--- a/lld/test/ELF/aarch64-thunk-bti-multipass.s
+++ b/lld/test/ELF/aarch64-thunk-bti-multipass.s
@@ -1,8 +1,8 @@
 // REQUIRES: aarch64
 // RUN: rm -rf %t && split-file %s %t && cd %t
 // RUN: llvm-mc -filetype=obj -triple=aarch64 asm -o a.o
-// RUN: ld.lld --script=lds a.o -o out.exe
-// RUN: llvm-objdump -d --no-show-raw-insn out.exe | FileCheck %s
+// RUN: ld.lld --script=lds a.o -o out
+// RUN: llvm-objdump -d --no-show-raw-insn out | FileCheck %s
 
 /// Test that a thunk that at creation time does not need to use a BTI
 /// compatible landing pad, but due to other thunk insertion ends up
@@ -29,8 +29,9 @@
 _start:
 /// Call that requires a thunk.
  bl fn1
-/// padding so that we require thunks that can be placed after this section.
-/// The thunks are close enough to the target to be short.
+/// padding so that the thunk for fn1 is placed after this section is
+/// sufficiently close to the target to be within short range, but only
+/// just so that a small displacement will mean a long thunk is needed.
  .space 0x1000
 /// Thunk for call to fn1 will be placed here. Initially it is in short Thunk
 /// range of fn1, but due to a thunk added after a later section it won't be



More information about the llvm-commits mailing list