summaryrefslogtreecommitdiff
path: root/ld
diff options
context:
space:
mode:
authorSzabolcs Nagy <szabolcs.nagy@arm.com>2023-01-18 12:56:46 +0000
committerSzabolcs Nagy <szabolcs.nagy@arm.com>2023-03-23 12:49:32 +0000
commit15b4f66b0a9a3be6caf1898d22a13c39e662006f (patch)
tree8b5660b277c55c9af5d9f91f2e7ae7389f344d37 /ld
parent557a2f28224738382d55c7c1a8aa00587d424b13 (diff)
downloadbinutils-gdb-15b4f66b0a9a3be6caf1898d22a13c39e662006f.tar.gz
bfd: aarch64: Fix stubs that may break BTI PR30076
Insert two stubs in a BTI enabled binary when fixing long calls: The first is near the call site and uses an indirect jump like before, but it targets the second stub that is near the call target site and uses a direct jump. This is needed when a single stub breaks BTI compatibility. The stub layout is kept fixed between sizing and building the stubs, so the location of the second stub is known at build time, this may introduce padding between stubs when those are relaxed. Stub layout with BTI disabled is unchanged.
Diffstat (limited to 'ld')
-rw-r--r--ld/testsuite/ld-aarch64/aarch64-elf.exp3
-rw-r--r--ld/testsuite/ld-aarch64/bti-far-1.d83
-rw-r--r--ld/testsuite/ld-aarch64/bti-far-2.d62
-rw-r--r--ld/testsuite/ld-aarch64/bti-far.ld15
-rw-r--r--ld/testsuite/ld-aarch64/bti-far.s29
5 files changed, 192 insertions, 0 deletions
diff --git a/ld/testsuite/ld-aarch64/aarch64-elf.exp b/ld/testsuite/ld-aarch64/aarch64-elf.exp
index 48c8c12ef8f..80662de7e44 100644
--- a/ld/testsuite/ld-aarch64/aarch64-elf.exp
+++ b/ld/testsuite/ld-aarch64/aarch64-elf.exp
@@ -461,6 +461,9 @@ run_dump_test "bti-warn"
run_dump_test "weak-tls"
run_dump_test "undef-tls"
+run_dump_test "bti-far-1"
+run_dump_test "bti-far-2"
+
if { ![skip_sframe_tests] } {
run_dump_test "sframe-simple-1"
}
diff --git a/ld/testsuite/ld-aarch64/bti-far-1.d b/ld/testsuite/ld-aarch64/bti-far-1.d
new file mode 100644
index 00000000000..d2dbc9db110
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/bti-far-1.d
@@ -0,0 +1,83 @@
+#name: Check linker stubs with indirect calls handle BTI (shared lib).
+#source: bti-far.s
+#target: [check_shared_lib_support]
+#as: -mabi=lp64
+#ld: -shared -T bti-far.ld
+#objdump: -dr
+
+[^:]*: *file format elf64-.*aarch64
+
+
+Disassembly of section \.plt:
+
+0000000000018000 <\.plt>:
+ 18000: d503245f bti c
+ 18004: a9bf7bf0 stp x16, x30, \[sp, #-16\]!
+ 18008: 900000d0 adrp x16, 30000 <_GLOBAL_OFFSET_TABLE_>
+ 1800c: f9400e11 ldr x17, \[x16, #24\]
+ 18010: 91006210 add x16, x16, #0x18
+ 18014: d61f0220 br x17
+ 18018: d503201f nop
+ 1801c: d503201f nop
+
+0000000000018020 <foo@plt>:
+ 18020: 900000d0 adrp x16, 30000 <_GLOBAL_OFFSET_TABLE_>
+ 18024: f9401211 ldr x17, \[x16, #32\]
+ 18028: 91008210 add x16, x16, #0x20
+ 1802c: d61f0220 br x17
+ 18030: 14000004 b 18040 <__foo_bti_veneer\+0x8>
+ 18034: d503201f nop
+
+0000000000018038 <__foo_bti_veneer>:
+ 18038: d503245f bti c
+ 1803c: 17fffff9 b 18020 <foo@plt>
+
+Disassembly of section \.text:
+
+0000000000020000 <_start>:
+ 20000: 97ffe008 bl 18020 <foo@plt>
+ 20004: 94000007 bl 20020 <___veneer>
+ 20008: 94000001 bl 2000c <baz>
+
+000000000002000c <baz>:
+ 2000c: d65f03c0 ret
+ 20010: 1400000a b 20038 <___veneer\+0x18>
+ 20014: d503201f nop
+
+0000000000020018 <___bti_veneer>:
+ 20018: d503245f bti c
+ 2001c: 17fffffc b 2000c <baz>
+
+0000000000020020 <___veneer>:
+ 20020: 90091910 adrp x16, 12340000 <foo>
+ 20024: 91012210 add x16, x16, #0x48
+ 20028: d61f0200 br x16
+ \.\.\.
+
+Disassembly of section \.far:
+
+0000000012340000 <foo>:
+ 12340000: 9400000c bl 12340030 <___veneer>
+
+0000000012340004 <bar>:
+ 12340004: 9400000b bl 12340030 <___veneer>
+ 12340008: 94000004 bl 12340018 <__foo_veneer>
+ 1234000c: 00000000 udf #0
+ 12340010: 14000010 b 12340050 <___bti_veneer\+0x8>
+ 12340014: d503201f nop
+
+0000000012340018 <__foo_veneer>:
+ 12340018: 90f6e6d0 adrp x16, 18000 <\.plt>
+ 1234001c: 9100e210 add x16, x16, #0x38
+ 12340020: d61f0200 br x16
+ \.\.\.
+
+0000000012340030 <___veneer>:
+ 12340030: 90f6e710 adrp x16, 20000 <_start>
+ 12340034: 91006210 add x16, x16, #0x18
+ 12340038: d61f0200 br x16
+ \.\.\.
+
+0000000012340048 <___bti_veneer>:
+ 12340048: d503245f bti c
+ 1234004c: 17ffffee b 12340004 <bar>
diff --git a/ld/testsuite/ld-aarch64/bti-far-2.d b/ld/testsuite/ld-aarch64/bti-far-2.d
new file mode 100644
index 00000000000..b859e6ce399
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/bti-far-2.d
@@ -0,0 +1,62 @@
+#name: Check linker stubs with indirect calls handle BTI (exe).
+#source: bti-far.s
+#as: -mabi=lp64
+#ld: -T bti-far.ld
+#objdump: -dr
+
+[^:]*: *file format elf64-.*aarch64
+
+
+Disassembly of section \.text:
+
+0000000000020000 <_start>:
+ 20000: 9400000e bl 20038 <__foo_veneer>
+ 20004: 94000007 bl 20020 <___veneer>
+ 20008: 94000001 bl 2000c <baz>
+
+000000000002000c <baz>:
+ 2000c: d65f03c0 ret
+ 20010: 14000010 b 20050 <__foo_veneer\+0x18>
+ 20014: d503201f nop
+
+0000000000020018 <___bti_veneer>:
+ 20018: d503245f bti c
+ 2001c: 17fffffc b 2000c <baz>
+
+0000000000020020 <___veneer>:
+ 20020: 90091910 adrp x16, 12340000 <foo>
+ 20024: 9100e210 add x16, x16, #0x38
+ 20028: d61f0200 br x16
+ \.\.\.
+
+0000000000020038 <__foo_veneer>:
+ 20038: 90091910 adrp x16, 12340000 <foo>
+ 2003c: 91006210 add x16, x16, #0x18
+ 20040: d61f0200 br x16
+ \.\.\.
+
+Disassembly of section \.far:
+
+0000000012340000 <foo>:
+ 12340000: 94000008 bl 12340020 <___veneer>
+
+0000000012340004 <bar>:
+ 12340004: 94000007 bl 12340020 <___veneer>
+ 12340008: 97fffffe bl 12340000 <foo>
+ 1234000c: 00000000 udf #0
+ 12340010: 1400000c b 12340040 <___bti_veneer\+0x8>
+ 12340014: d503201f nop
+
+0000000012340018 <__foo_bti_veneer>:
+ 12340018: d503245f bti c
+ 1234001c: 17fffff9 b 12340000 <foo>
+
+0000000012340020 <___veneer>:
+ 12340020: 90f6e710 adrp x16, 20000 <_start>
+ 12340024: 91006210 add x16, x16, #0x18
+ 12340028: d61f0200 br x16
+ \.\.\.
+
+0000000012340038 <___bti_veneer>:
+ 12340038: d503245f bti c
+ 1234003c: 17fffff2 b 12340004 <bar>
diff --git a/ld/testsuite/ld-aarch64/bti-far.ld b/ld/testsuite/ld-aarch64/bti-far.ld
new file mode 100644
index 00000000000..214b8cb919e
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/bti-far.ld
@@ -0,0 +1,15 @@
+OUTPUT_ARCH(aarch64)
+ENTRY(_start)
+SECTIONS
+{
+ . = 0x10000;
+ .rela.plt : { *(.rela.plt) *(.rela.iplt) }
+ . = 0x18000;
+ .plt : { *(.plt) *(.iplt) }
+ . = 0x20000;
+ .text : { *(.text) }
+ . = 0x30000;
+ .got : { *(.got) *(.got.plt) }
+ . = 0x12340000;
+ .far : { *(.far) }
+}
diff --git a/ld/testsuite/ld-aarch64/bti-far.s b/ld/testsuite/ld-aarch64/bti-far.s
new file mode 100644
index 00000000000..20cffd225cb
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/bti-far.s
@@ -0,0 +1,29 @@
+ .text
+ .global _start
+ .type _start, %function
+_start:
+ bl foo
+ bl bar
+ bl baz
+baz:
+ ret
+
+ .section .far,"ax",@progbits
+ .global foo
+ .type foo, %function
+foo:
+ bl baz
+bar:
+ bl baz
+ bl foo
+
+ .section .note.gnu.property,"a"
+ .align 3
+ .word 4
+ .word 16
+ .word 5
+ .string "GNU"
+ .word 0xc0000000
+ .word 4
+ .word 1
+ .align 3