Skip to content

Commit f3584a0

Browse files
committed
[PAC][lld] Use PAC instructions in PLT header with -z pac-plt
1. Sign return address before storing into stack. 2. Treat lazy resolver address as signed.
1 parent 3d1670d commit f3584a0

File tree

4 files changed

+38
-11
lines changed

4 files changed

+38
-11
lines changed

lld/ELF/Arch/AArch64.cpp

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1040,13 +1040,23 @@ AArch64BtiPac::AArch64BtiPac(Ctx &ctx) : AArch64(ctx) {
10401040

10411041
void AArch64BtiPac::writePltHeader(uint8_t *buf) const {
10421042
const uint8_t btiData[] = { 0x5f, 0x24, 0x03, 0xd5 }; // bti c
1043+
const uint8_t signLR[] = {0x7f, 0x23, 0x03, 0xd5}; // pacibsp
10431044
const uint8_t pltData[] = {
10441045
0xf0, 0x7b, 0xbf, 0xa9, // stp x16, x30, [sp,#-16]!
10451046
0x10, 0x00, 0x00, 0x90, // adrp x16, Page(&(.got.plt[2]))
10461047
0x11, 0x02, 0x40, 0xf9, // ldr x17, [x16, Offset(&(.got.plt[2]))]
10471048
0x10, 0x02, 0x00, 0x91, // add x16, x16, Offset(&(.got.plt[2]))
1048-
0x20, 0x02, 0x1f, 0xd6, // br x17
1049-
0x1f, 0x20, 0x03, 0xd5, // nop
1049+
};
1050+
const uint8_t pacHintBr[] = {
1051+
0x9f, 0x21, 0x03, 0xd5, // autia1716
1052+
0x20, 0x02, 0x1f, 0xd6 // br x17
1053+
};
1054+
const uint8_t pacBr[] = {
1055+
0x30, 0x0a, 0x1f, 0xd7, // braa x17, x16
1056+
0x1f, 0x20, 0x03, 0xd5 // nop
1057+
};
1058+
const uint8_t stdBr[] = {
1059+
0x20, 0x02, 0x1f, 0xd6, // br x17
10501060
0x1f, 0x20, 0x03, 0xd5 // nop
10511061
};
10521062
const uint8_t nopData[] = { 0x1f, 0x20, 0x03, 0xd5 }; // nop
@@ -1061,15 +1071,30 @@ void AArch64BtiPac::writePltHeader(uint8_t *buf) const {
10611071
buf += sizeof(btiData);
10621072
plt += sizeof(btiData);
10631073
}
1074+
if (pacEntryKind != PEK_NoAuth) {
1075+
memcpy(buf, signLR, sizeof(signLR));
1076+
buf += sizeof(signLR);
1077+
plt += sizeof(signLR);
1078+
}
10641079
memcpy(buf, pltData, sizeof(pltData));
10651080

10661081
relocateNoSym(buf + 4, R_AARCH64_ADR_PREL_PG_HI21,
10671082
getAArch64Page(got + 16) - getAArch64Page(plt + 4));
10681083
relocateNoSym(buf + 8, R_AARCH64_LDST64_ABS_LO12_NC, got + 16);
10691084
relocateNoSym(buf + 12, R_AARCH64_ADD_ABS_LO12_NC, got + 16);
1085+
1086+
if (pacEntryKind != PEK_NoAuth)
1087+
memcpy(buf + sizeof(pltData),
1088+
(pacEntryKind == PEK_AuthHint ? pacHintBr : pacBr),
1089+
sizeof(pacEntryKind == PEK_AuthHint ? pacHintBr : pacBr));
1090+
else
1091+
memcpy(buf + sizeof(pltData), stdBr, sizeof(stdBr));
10701092
if (!btiHeader)
10711093
// We didn't add the BTI c instruction so round out size with NOP.
1072-
memcpy(buf + sizeof(pltData), nopData, sizeof(nopData));
1094+
memcpy(buf + sizeof(pltData) + sizeof(stdBr), nopData, sizeof(nopData));
1095+
if (pacEntryKind == PEK_NoAuth)
1096+
// We didn't add the PACIBSP instruction so round out size with NOP.
1097+
memcpy(buf + sizeof(pltData) + sizeof(stdBr), nopData, sizeof(nopData));
10731098
}
10741099

10751100
void AArch64BtiPac::writePlt(uint8_t *buf, const Symbol &sym,

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,13 +155,13 @@ func1:
155155
# BTIPACEX2: Disassembly of section .plt:
156156
# BTIPACEX2: 0000000000210380 <.plt>:
157157
# BTIPACEX2-NEXT: 210380: bti c
158+
# BTIPACEX2-NEXT: pacibsp
158159
# BTIPACEX2-NEXT: stp x16, x30, [sp, #-16]!
159160
# BTIPACEX2-NEXT: adrp x16, 0x230000
160161
# BTIPACEX2-NEXT: ldr x17, [x16, #1208]
161162
# BTIPACEX2-NEXT: add x16, x16, #1208
163+
# BTIPACEX2-NEXT: autia1716
162164
# BTIPACEX2-NEXT: br x17
163-
# BTIPACEX2-NEXT: nop
164-
# BTIPACEX2-NEXT: nop
165165
# BTIPACEX2: 00000000002103a0 <func2@plt>:
166166
# BTIPACEX2-NEXT: 2103a0: adrp x16, 0x230000
167167
# BTIPACEX2-NEXT: ldr x17, [x16, #1216]

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,14 +96,14 @@
9696
# PACPLT-NEXT: 210378: ret
9797
# PACPLT: Disassembly of section .plt:
9898
# PACPLT: 0000000000210380 <.plt>:
99-
# PACPLT-NEXT: 210380: stp x16, x30, [sp, #-16]!
99+
# PACPLT-NEXT: 210380: pacibsp
100+
# PACPLT-NEXT: stp x16, x30, [sp, #-16]!
100101
# PACPLT-NEXT: adrp x16, 0x230000
101102
# PACPLT-NEXT: ldr x17, [x16, #1192]
102103
# PACPLT-NEXT: add x16, x16, #1192
104+
# PACPLT-NEXT: autia1716
103105
# PACPLT-NEXT: br x17
104106
# PACPLT-NEXT: nop
105-
# PACPLT-NEXT: nop
106-
# PACPLT-NEXT: nop
107107
# PACPLT: 00000000002103a0 <func2@plt>:
108108
# PACPLT-NEXT: 2103a0: adrp x16, 0x230000
109109
# PACPLT-NEXT: ldr x17, [x16, #1200]

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

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,15 @@
6565
# PACPLT-NEXT: ret
6666
# PACPLT: Disassembly of section .plt:
6767
# PACPLT: <.plt>:
68+
# PACPLT-NEXT: pacibsp
6869
# PACPLT-NEXT: stp x16, x30, [sp, #-0x10]!
6970
# PACPLT-NEXT: adrp x16, 0x30000 <func3+0x30000>
7071
# PACPLT-NEXT: ldr x17, [x16, #0x[[B]]]
7172
# PACPLT-NEXT: add x16, x16, #0x[[B]]
72-
# PACPLT-NEXT: br x17
73-
# PACPLT-NEXT: nop
74-
# PACPLT-NEXT: nop
73+
# NOHINT-NEXT: braa x17, x16
74+
# NOHINT-NEXT: nop
75+
# HINT-NEXT: autia1716
76+
# HINT-NEXT: br x17
7577
# PACPLT-NEXT: nop
7678
# PACPLT: <func3@plt>:
7779
# PACPLT-NEXT: adrp x16, 0x30000 <func3+0x30000>

0 commit comments

Comments
 (0)