Skip to content

Commit b616262

Browse files
[LLD][ELF][AArch64] Change the semantics of -z pac-plt.
Summary: Generate PAC protected plt only when "-z pac-plt" is passed to the linker. GNU toolchain generates when it is explicitly requested[1]. When pac-plt is requested then set the GNU_PROPERTY_AARCH64_FEATURE_1_PAC note even when not all function compiled with PAC but issue a warning. Harmonizing the warning style for BTI/PAC/IBT. Generate BTI protected PLT if case of "-z force-bti". [1] https://www.sourceware.org/ml/binutils/2019-03/msg00021.html Reviewers: peter.smith, espindola, MaskRay, grimar Reviewed By: peter.smith, MaskRay Subscribers: tatyana-krasnukha, emaste, arichardson, kristof.beyls, MaskRay, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D74537
1 parent 8ffea27 commit b616262

File tree

6 files changed

+76
-42
lines changed

6 files changed

+76
-42
lines changed

lld/ELF/Arch/AArch64.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -601,8 +601,10 @@ AArch64BtiPac::AArch64BtiPac() {
601601
// the function in an executable being taken by a shared library.
602602
// FIXME: There is a potential optimization to omit the BTI if we detect
603603
// that the address of the PLT entry isn't taken.
604+
// The PAC PLT entries require dynamic loader support and this isn't known
605+
// from properties in the objects, so we use the command line flag.
604606
btiEntry = btiHeader && !config->shared;
605-
pacEntry = (config->andFeatures & GNU_PROPERTY_AARCH64_FEATURE_1_PAC);
607+
pacEntry = config->zPacPlt;
606608

607609
if (btiEntry || pacEntry) {
608610
pltEntrySize = 24;

lld/ELF/Driver.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1736,21 +1736,23 @@ template <class ELFT> static uint32_t getAndFeatures() {
17361736
for (InputFile *f : objectFiles) {
17371737
uint32_t features = cast<ObjFile<ELFT>>(f)->andFeatures;
17381738
if (config->zForceBti && !(features & GNU_PROPERTY_AARCH64_FEATURE_1_BTI)) {
1739-
warn(toString(f) + ": -z force-bti: file does not have BTI property");
1739+
warn(toString(f) + ": -z force-bti: file does not have "
1740+
"GNU_PROPERTY_AARCH64_FEATURE_1_BTI property");
17401741
features |= GNU_PROPERTY_AARCH64_FEATURE_1_BTI;
17411742
} else if (config->zForceIbt &&
17421743
!(features & GNU_PROPERTY_X86_FEATURE_1_IBT)) {
17431744
warn(toString(f) + ": -z force-ibt: file does not have "
17441745
"GNU_PROPERTY_X86_FEATURE_1_IBT property");
17451746
features |= GNU_PROPERTY_X86_FEATURE_1_IBT;
17461747
}
1748+
if (config->zPacPlt && !(features & GNU_PROPERTY_AARCH64_FEATURE_1_PAC)) {
1749+
warn(toString(f) + ": -z pac-plt: file does not have "
1750+
"GNU_PROPERTY_AARCH64_FEATURE_1_PAC property");
1751+
features |= GNU_PROPERTY_AARCH64_FEATURE_1_PAC;
1752+
}
17471753
ret &= features;
17481754
}
17491755

1750-
// Force enable pointer authentication Plt, we don't warn in this case as
1751-
// this does not require support in the object for correctness.
1752-
if (config->zPacPlt)
1753-
ret |= GNU_PROPERTY_AARCH64_FEATURE_1_PAC;
17541756
// Force enable Shadow Stack.
17551757
if (config->zShstk)
17561758
ret |= GNU_PROPERTY_X86_FEATURE_1_SHSTK;

lld/ELF/SyntheticSections.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1401,7 +1401,7 @@ template <class ELFT> void DynamicSection<ELFT>::finalizeContents() {
14011401
if (config->emachine == EM_AARCH64) {
14021402
if (config->andFeatures & GNU_PROPERTY_AARCH64_FEATURE_1_BTI)
14031403
addInt(DT_AARCH64_BTI_PLT, 0);
1404-
if (config->andFeatures & GNU_PROPERTY_AARCH64_FEATURE_1_PAC)
1404+
if (config->zPacPlt)
14051405
addInt(DT_AARCH64_PAC_PLT, 0);
14061406
}
14071407

lld/test/ELF/aarch64-feature-bti.s

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@
174174

175175
# RUN: ld.lld %t.o %t2.o -z force-bti %t.so -o %tforcebti.exe 2>&1 | FileCheck --check-prefix=FORCE-WARN %s
176176

177-
# FORCE-WARN: aarch64-feature-bti.s.tmp2.o: -z force-bti: file does not have BTI property
177+
# FORCE-WARN: aarch64-feature-bti.s.tmp2.o: -z force-bti: file does not have GNU_PROPERTY_AARCH64_FEATURE_1_BTI property
178178

179179

180180
# RUN: llvm-readelf -n %tforcebti.exe | FileCheck --check-prefix=BTIPROP %s

lld/test/ELF/aarch64-feature-btipac.s

Lines changed: 48 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -25,32 +25,30 @@
2525
# BTIPACSO-NEXT: 10360: bti c
2626
# BTIPACSO-NEXT: stp x16, x30, [sp, #-16]!
2727
# BTIPACSO-NEXT: adrp x16, #131072
28-
# BTIPACSO-NEXT: ldr x17, [x16, #1160]
29-
# BTIPACSO-NEXT: add x16, x16, #1160
28+
# BTIPACSO-NEXT: ldr x17, [x16, #1136]
29+
# BTIPACSO-NEXT: add x16, x16, #1136
3030
# BTIPACSO-NEXT: br x17
3131
# BTIPACSO-NEXT: nop
3232
# BTIPACSO-NEXT: nop
3333
# BTIPACSO: 0000000000010380 func3@plt:
3434
# BTIPACSO-NEXT: 10380: adrp x16, #131072
35-
# BTIPACSO-NEXT: ldr x17, [x16, #1168]
36-
# BTIPACSO-NEXT: add x16, x16, #1168
37-
# BTIPACSO-NEXT: autia1716
35+
# BTIPACSO-NEXT: ldr x17, [x16, #1144]
36+
# BTIPACSO-NEXT: add x16, x16, #1144
3837
# BTIPACSO-NEXT: br x17
39-
# BTIPACSO-NEXT: nop
4038

4139
# BTIPACPROP: Properties: aarch64 feature: BTI, PAC
4240

4341
# BTIPACDYN: 0x0000000070000001 (AARCH64_BTI_PLT)
44-
# BTIPACDYN: 0x0000000070000003 (AARCH64_PAC_PLT)
42+
# BTIPACDYN-NOT: 0x0000000070000003 (AARCH64_PAC_PLT)
4543

4644
## Make an executable with both BTI and PAC properties. Expect:
4745
## PLT[0] bti c as first instruction
48-
## PLT[n] bti n as first instruction, autia1716 before br x17
46+
## PLT[n] bti n as first instruction
4947

5048
# RUN: ld.lld %t.o %t3btipac.o %t.so -o %t.exe
5149
# RUN: llvm-readelf -n %t.exe | FileCheck --check-prefix=BTIPACPROP %s
5250
# RUN: llvm-objdump -d -mattr=+v8.5a --no-show-raw-insn %t.exe | FileCheck --check-prefix BTIPACEX %s
53-
# RUN: llvm-readelf --dynamic-table %t.exe | FileCheck --check-prefix BTIPACDYN %s
51+
# RUN: llvm-readelf --dynamic-table %t.exe | FileCheck --check-prefix BTIPACDYNEX %s
5452

5553
# BTIPACEX: Disassembly of section .text:
5654
# BTIPACEX: 0000000000210370 func1:
@@ -64,19 +62,21 @@
6462
# BTIPACEX-NEXT: 210380: bti c
6563
# BTIPACEX-NEXT: stp x16, x30, [sp, #-16]!
6664
# BTIPACEX-NEXT: adrp x16, #131072
67-
# BTIPACEX-NEXT: ldr x17, [x16, #1208]
68-
# BTIPACEX-NEXT: add x16, x16, #1208
65+
# BTIPACEX-NEXT: ldr x17, [x16, #1192]
66+
# BTIPACEX-NEXT: add x16, x16, #1192
6967
# BTIPACEX-NEXT: br x17
7068
# BTIPACEX-NEXT: nop
7169
# BTIPACEX-NEXT: nop
7270
# BTIPACEX: 00000000002103a0 func2@plt:
7371
# BTIPACEX-NEXT: 2103a0: bti c
7472
# BTIPACEX-NEXT: adrp x16, #131072
75-
# BTIPACEX-NEXT: ldr x17, [x16, #1216]
76-
# BTIPACEX-NEXT: add x16, x16, #1216
77-
# BTIPACEX-NEXT: autia1716
73+
# BTIPACEX-NEXT: ldr x17, [x16, #1200]
74+
# BTIPACEX-NEXT: add x16, x16, #1200
7875
# BTIPACEX-NEXT: br x17
7976

77+
# BTIPACDYNEX: 0x0000000070000001 (AARCH64_BTI_PLT)
78+
# BTIPACDYNEX-NOT: 0x0000000070000003 (AARCH64_PAC_PLT)
79+
8080
## Check that combinations of BTI+PAC with 0 properties results in standard PLT
8181

8282
# RUN: ld.lld %t.o %t3.o %t.so -o %t.exe
@@ -112,14 +112,17 @@
112112
## Check that combination of -z pac-plt and -z force-bti warns for the file that
113113
## doesn't contain the BTI property, but generates PAC and BTI PLT sequences.
114114
## The -z pac-plt doesn't warn as it is not required for correctness.
115+
## Expect:
116+
## PLT[0] bti c as first instruction
117+
## PLT[n] bti n as first instruction, autia1716 before br x17
115118

116119
# RUN: ld.lld %t.o %t3.o %t.so -z pac-plt -z force-bti -o %t.exe 2>&1 | FileCheck --check-prefix=FORCE-WARN %s
117120

118-
# FORCE-WARN: aarch64-feature-btipac.s.tmp3.o: -z force-bti: file does not have BTI property
121+
# FORCE-WARN: aarch64-feature-btipac.s.tmp3.o: -z force-bti: file does not have GNU_PROPERTY_AARCH64_FEATURE_1_BTI property
119122

120123
# RUN: llvm-readelf -n %t.exe | FileCheck --check-prefix=BTIPACPROP %s
121-
# RUN: llvm-objdump -d -mattr=+v8.5a --no-show-raw-insn %t.exe | FileCheck --check-prefix BTIPACEX %s
122-
# RUN: llvm-readelf --dynamic-table %t.exe | FileCheck --check-prefix BTIPACDYN %s
124+
# RUN: llvm-objdump -d -mattr=+v8.5a --no-show-raw-insn %t.exe | FileCheck --check-prefix BTIPACEX2 %s
125+
# RUN: llvm-readelf --dynamic-table %t.exe | FileCheck --check-prefix BTIPACDYN2 %s
123126
.section ".note.gnu.property", "a"
124127
.long 4
125128
.long 0x10
@@ -140,3 +143,31 @@ func1:
140143
.globl func3
141144
.type func3,%function
142145
ret
146+
147+
# BTIPACEX2: Disassembly of section .text:
148+
# BTIPACEX2: 0000000000210370 func1:
149+
# BTIPACEX2-NEXT: 210370: bl #48 <func2@plt>
150+
# BTIPACEX2-NEXT: ret
151+
# BTIPACEX2-NEXT: ret
152+
# BTIPACEX2: 000000000021037c func3:
153+
# BTIPACEX2-NEXT: 21037c: ret
154+
# BTIPACEX2: Disassembly of section .plt:
155+
# BTIPACEX2: 0000000000210380 .plt:
156+
# BTIPACEX2-NEXT: 210380: bti c
157+
# BTIPACEX2-NEXT: stp x16, x30, [sp, #-16]!
158+
# BTIPACEX2-NEXT: adrp x16, #131072
159+
# BTIPACEX2-NEXT: ldr x17, [x16, #1208]
160+
# BTIPACEX2-NEXT: add x16, x16, #1208
161+
# BTIPACEX2-NEXT: br x17
162+
# BTIPACEX2-NEXT: nop
163+
# BTIPACEX2-NEXT: nop
164+
# BTIPACEX2: 00000000002103a0 func2@plt:
165+
# BTIPACEX2-NEXT: 2103a0: bti c
166+
# BTIPACEX2-NEXT: adrp x16, #131072
167+
# BTIPACEX2-NEXT: ldr x17, [x16, #1216]
168+
# BTIPACEX2-NEXT: add x16, x16, #1216
169+
# BTIPACEX2-NEXT: autia1716
170+
# BTIPACEX2-NEXT: br x17
171+
172+
# BTIPACDYN2: 0x0000000070000001 (AARCH64_BTI_PLT)
173+
# BTIPACDYN2-NEXT: 0x0000000070000003 (AARCH64_PAC_PLT)

lld/test/ELF/aarch64-feature-pac.s

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@
3232
# NOPAC-NEXT: add x16, x16, #968
3333
# NOPAC-NEXT: br x17
3434

35+
# SOGOTPLT: Hex dump of section '.got.plt':
36+
# SOGOTPLT-NEXT: 0x000303b0 00000000 00000000 00000000 00000000
37+
# SOGOTPLT-NEXT: 0x000303c0 00000000 00000000 d0020100 00000000
38+
3539
# NOPACDYN-NOT: 0x0000000070000001 (AARCH64_BTI_PLT)
3640
# NOPACDYN-NOT: 0x0000000070000003 (AARCH64_PAC_PLT)
3741

@@ -41,9 +45,7 @@
4145
# RUN: llvm-readelf -x .got.plt %t.so | FileCheck --check-prefix SOGOTPLT2 %s
4246
# RUN: llvm-readelf --dynamic-table %t.so | FileCheck --check-prefix PACDYN %s
4347

44-
## PAC has no effect on PLT[0], for PLT[N] autia1716 is used to authenticate
45-
## the address in x17 (context in x16) before branching to it. The dynamic
46-
## loader is responsible for calling pacia1716 on the entry.
48+
## PAC has no effect on PLT[0], for PLT[N].
4749
# PACSO: 0000000000010348 func2:
4850
# PACSO-NEXT: 10348: bl #56 <func3@plt>
4951
# PACSO-NEXT: ret
@@ -53,32 +55,26 @@
5355
# PACSO: 0000000000010360 .plt:
5456
# PACSO-NEXT: 10360: stp x16, x30, [sp, #-16]!
5557
# PACSO-NEXT: adrp x16, #131072
56-
# PACSO-NEXT: ldr x17, [x16, #1144]
57-
# PACSO-NEXT: add x16, x16, #1144
58+
# PACSO-NEXT: ldr x17, [x16, #1120]
59+
# PACSO-NEXT: add x16, x16, #1120
5860
# PACSO-NEXT: br x17
5961
# PACSO-NEXT: nop
6062
# PACSO-NEXT: nop
6163
# PACSO-NEXT: nop
6264
# PACSO: 0000000000010380 func3@plt:
6365
# PACSO-NEXT: 10380: adrp x16, #131072
64-
# PACSO-NEXT: ldr x17, [x16, #1152]
65-
# PACSO-NEXT: add x16, x16, #1152
66-
# PACSO-NEXT: autia1716
66+
# PACSO-NEXT: ldr x17, [x16, #1128]
67+
# PACSO-NEXT: add x16, x16, #1128
6768
# PACSO-NEXT: br x17
68-
# PACSO-NEXT: nop
69-
70-
# SOGOTPLT: Hex dump of section '.got.plt':
71-
# SOGOTPLT-NEXT: 0x000303b0 00000000 00000000 00000000 00000000
72-
# SOGOTPLT-NEXT: 0x000303c0 00000000 00000000 d0020100 00000000
7369

7470
# SOGOTPLT2: Hex dump of section '.got.plt':
75-
# SOGOTPLT2-NEXT: 0x00030468 00000000 00000000 00000000 00000000
76-
# SOGOTPLT2-NEXT: 0x00030478 00000000 00000000 60030100 00000000
71+
# SOGOTPLT2-NEXT: 0x00030450 00000000 00000000 00000000 00000000
72+
# SOGOTPLT2-NEXT: 0x00030460 00000000 00000000 60030100 00000000
7773

7874
# PACPROP: Properties: aarch64 feature: PAC
7975

8076
# PACDYN-NOT: 0x0000000070000001 (AARCH64_BTI_PLT)
81-
# PACDYN: 0x0000000070000003 (AARCH64_PAC_PLT)
77+
# PACDYN-NOT: 0x0000000070000003 (AARCH64_PAC_PLT)
8278

8379
## Turn on PAC entries with the -z pac-plt command line option. There are no
8480
## warnings in this case as the choice to use PAC in PLT entries is orthogonal
@@ -87,7 +83,7 @@
8783

8884
# RUN: ld.lld %t.o %t2.o -z pac-plt %t.so -o %tpacplt.exe
8985
# RUN: llvm-readelf -n %tpacplt.exe | FileCheck --check-prefix=PACPROP %s
90-
# RUN: llvm-readelf --dynamic-table %tpacplt.exe | FileCheck --check-prefix PACDYN %s
86+
# RUN: llvm-readelf --dynamic-table %tpacplt.exe | FileCheck --check-prefix PACDYN2 %s
9187
# RUN: llvm-objdump -d -mattr=+v8.3a --no-show-raw-insn %tpacplt.exe | FileCheck --check-prefix PACPLT %s
9288

9389
# PACPLT: Disassembly of section .text:
@@ -114,6 +110,9 @@
114110
# PACPLT-NEXT: br x17
115111
# PACPLT-NEXT: nop
116112

113+
# PACDYN2-NOT: 0x0000000070000001 (AARCH64_BTI_PLT)
114+
# PACDYN2: 0x0000000070000003 (AARCH64_PAC_PLT)
115+
117116
.section ".note.gnu.property", "a"
118117
.long 4
119118
.long 0x10

0 commit comments

Comments
 (0)