Skip to content

Commit 1c4f335

Browse files
authored
[PAC][lld] Use braa instr in PAC PLT sequence with valid PAuth core info (#113945)
Assume PAC instructions being supported with PAuth core info different from (0,0). The (0,0) value means that an ELF file is incompatible with PAuth - see https://github.com/ARM-software/abi-aa/blob/2024Q3/pauthabielf64/pauthabielf64.rst#core-information. With PAC non-hint instructions supported, `autia1716; br x17` can be replaced with `braa x17, x16; nop`, where `braa` is an authenticated branch instruction using IA key, discriminator from x16 and signed target address from x17.
1 parent 686a291 commit 1c4f335

File tree

2 files changed

+35
-11
lines changed

2 files changed

+35
-11
lines changed

lld/ELF/Arch/AArch64.cpp

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -998,7 +998,11 @@ class AArch64BtiPac final : public AArch64 {
998998

999999
private:
10001000
bool btiHeader; // bti instruction needed in PLT Header and Entry
1001-
bool pacEntry; // autia1716 instruction needed in PLT Entry
1001+
enum {
1002+
PEK_NoAuth,
1003+
PEK_AuthHint, // use autia1716 instr for authenticated branch in PLT entry
1004+
PEK_Auth, // use braa instr for authenticated branch in PLT entry
1005+
} pacEntryKind;
10021006
};
10031007
} // namespace
10041008

@@ -1013,9 +1017,21 @@ AArch64BtiPac::AArch64BtiPac(Ctx &ctx) : AArch64(ctx) {
10131017
// relocations.
10141018
// The PAC PLT entries require dynamic loader support and this isn't known
10151019
// from properties in the objects, so we use the command line flag.
1016-
pacEntry = ctx.arg.zPacPlt;
1020+
// By default we only use hint-space instructions, but if we detect the
1021+
// PAuthABI, which requires v8.3-A, we can use the non-hint space
1022+
// instructions.
1023+
1024+
if (ctx.arg.zPacPlt) {
1025+
if (llvm::any_of(ctx.aarch64PauthAbiCoreInfo,
1026+
[](uint8_t c) { return c != 0; }))
1027+
pacEntryKind = PEK_Auth;
1028+
else
1029+
pacEntryKind = PEK_AuthHint;
1030+
} else {
1031+
pacEntryKind = PEK_NoAuth;
1032+
}
10171033

1018-
if (btiHeader || pacEntry) {
1034+
if (btiHeader || (pacEntryKind != PEK_NoAuth)) {
10191035
pltEntrySize = 24;
10201036
ipltEntrySize = 24;
10211037
}
@@ -1065,9 +1081,13 @@ void AArch64BtiPac::writePlt(uint8_t *buf, const Symbol &sym,
10651081
0x11, 0x02, 0x40, 0xf9, // ldr x17, [x16, Offset(&(.got.plt[n]))]
10661082
0x10, 0x02, 0x00, 0x91 // add x16, x16, Offset(&(.got.plt[n]))
10671083
};
1084+
const uint8_t pacHintBr[] = {
1085+
0x9f, 0x21, 0x03, 0xd5, // autia1716
1086+
0x20, 0x02, 0x1f, 0xd6 // br x17
1087+
};
10681088
const uint8_t pacBr[] = {
1069-
0x9f, 0x21, 0x03, 0xd5, // autia1716
1070-
0x20, 0x02, 0x1f, 0xd6 // br x17
1089+
0x30, 0x0a, 0x1f, 0xd7, // braa x17, x16
1090+
0x1f, 0x20, 0x03, 0xd5 // nop
10711091
};
10721092
const uint8_t stdBr[] = {
10731093
0x20, 0x02, 0x1f, 0xd6, // br x17
@@ -1095,8 +1115,10 @@ void AArch64BtiPac::writePlt(uint8_t *buf, const Symbol &sym,
10951115
relocateNoSym(buf + 4, R_AARCH64_LDST64_ABS_LO12_NC, gotPltEntryAddr);
10961116
relocateNoSym(buf + 8, R_AARCH64_ADD_ABS_LO12_NC, gotPltEntryAddr);
10971117

1098-
if (pacEntry)
1099-
memcpy(buf + sizeof(addrInst), pacBr, sizeof(pacBr));
1118+
if (pacEntryKind != PEK_NoAuth)
1119+
memcpy(buf + sizeof(addrInst),
1120+
pacEntryKind == PEK_AuthHint ? pacHintBr : pacBr,
1121+
sizeof(pacEntryKind == PEK_AuthHint ? pacHintBr : pacBr));
11001122
else
11011123
memcpy(buf + sizeof(addrInst), stdBr, sizeof(stdBr));
11021124
if (!hasBti)

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

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,8 @@
5656

5757
# PACPLTTAG: 0x0000000070000003 (AARCH64_PAC_PLT)
5858

59-
# RUN: llvm-objdump -d pacplt-nowarn | FileCheck --check-prefix PACPLT -DA=10380 -DB=478 -DC=480 %s
60-
# RUN: llvm-objdump -d pacplt-warn | FileCheck --check-prefix PACPLT -DA=10390 -DB=488 -DC=490 %s
59+
# RUN: llvm-objdump -d pacplt-nowarn | FileCheck --check-prefixes=PACPLT,NOHINT -DA=10380 -DB=478 -DC=480 %s
60+
# RUN: llvm-objdump -d pacplt-warn | FileCheck --check-prefixes=PACPLT,HINT -DA=10390 -DB=488 -DC=490 %s
6161

6262
# PACPLT: Disassembly of section .text:
6363
# PACPLT: <func2>:
@@ -77,8 +77,10 @@
7777
# PACPLT-NEXT: adrp x16, 0x30000 <func3+0x30000>
7878
# PACPLT-NEXT: ldr x17, [x16, #0x[[C]]]
7979
# PACPLT-NEXT: add x16, x16, #0x[[C]]
80-
# PACPLT-NEXT: autia1716
81-
# PACPLT-NEXT: br x17
80+
# NOHINT-NEXT: braa x17, x16
81+
# NOHINT-NEXT: nop
82+
# HINT-NEXT: autia1716
83+
# HINT-NEXT: br x17
8284
# PACPLT-NEXT: nop
8385

8486
#--- abi-tag-short.s

0 commit comments

Comments
 (0)