Skip to content

Commit 10caccb

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 1c4f335 commit 10caccb

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
@@ -1039,13 +1039,23 @@ AArch64BtiPac::AArch64BtiPac(Ctx &ctx) : AArch64(ctx) {
10391039

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

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

10741099
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)