[lld] 1c4f335 - [PAC][lld] Use braa instr in PAC PLT sequence with valid PAuth core info (#113945)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Nov 17 21:07:37 PST 2024
Author: Daniil Kovalev
Date: 2024-11-18T08:07:33+03:00
New Revision: 1c4f335ec29c6bb269d0f8b2d6149d439312c69a
URL: https://github.com/llvm/llvm-project/commit/1c4f335ec29c6bb269d0f8b2d6149d439312c69a
DIFF: https://github.com/llvm/llvm-project/commit/1c4f335ec29c6bb269d0f8b2d6149d439312c69a.diff
LOG: [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.
Added:
Modified:
lld/ELF/Arch/AArch64.cpp
lld/test/ELF/aarch64-feature-pauth.s
Removed:
################################################################################
diff --git a/lld/ELF/Arch/AArch64.cpp b/lld/ELF/Arch/AArch64.cpp
index bc7ac676165fec..5b5ad482ea1279 100644
--- a/lld/ELF/Arch/AArch64.cpp
+++ b/lld/ELF/Arch/AArch64.cpp
@@ -998,7 +998,11 @@ class AArch64BtiPac final : public AArch64 {
private:
bool btiHeader; // bti instruction needed in PLT Header and Entry
- bool pacEntry; // autia1716 instruction needed in PLT Entry
+ enum {
+ PEK_NoAuth,
+ PEK_AuthHint, // use autia1716 instr for authenticated branch in PLT entry
+ PEK_Auth, // use braa instr for authenticated branch in PLT entry
+ } pacEntryKind;
};
} // namespace
@@ -1013,9 +1017,21 @@ AArch64BtiPac::AArch64BtiPac(Ctx &ctx) : AArch64(ctx) {
// relocations.
// The PAC PLT entries require dynamic loader support and this isn't known
// from properties in the objects, so we use the command line flag.
- pacEntry = ctx.arg.zPacPlt;
+ // By default we only use hint-space instructions, but if we detect the
+ // PAuthABI, which requires v8.3-A, we can use the non-hint space
+ // instructions.
+
+ if (ctx.arg.zPacPlt) {
+ if (llvm::any_of(ctx.aarch64PauthAbiCoreInfo,
+ [](uint8_t c) { return c != 0; }))
+ pacEntryKind = PEK_Auth;
+ else
+ pacEntryKind = PEK_AuthHint;
+ } else {
+ pacEntryKind = PEK_NoAuth;
+ }
- if (btiHeader || pacEntry) {
+ if (btiHeader || (pacEntryKind != PEK_NoAuth)) {
pltEntrySize = 24;
ipltEntrySize = 24;
}
@@ -1065,9 +1081,13 @@ void AArch64BtiPac::writePlt(uint8_t *buf, const Symbol &sym,
0x11, 0x02, 0x40, 0xf9, // ldr x17, [x16, Offset(&(.got.plt[n]))]
0x10, 0x02, 0x00, 0x91 // add x16, x16, Offset(&(.got.plt[n]))
};
+ const uint8_t pacHintBr[] = {
+ 0x9f, 0x21, 0x03, 0xd5, // autia1716
+ 0x20, 0x02, 0x1f, 0xd6 // br x17
+ };
const uint8_t pacBr[] = {
- 0x9f, 0x21, 0x03, 0xd5, // autia1716
- 0x20, 0x02, 0x1f, 0xd6 // br x17
+ 0x30, 0x0a, 0x1f, 0xd7, // braa x17, x16
+ 0x1f, 0x20, 0x03, 0xd5 // nop
};
const uint8_t stdBr[] = {
0x20, 0x02, 0x1f, 0xd6, // br x17
@@ -1095,8 +1115,10 @@ void AArch64BtiPac::writePlt(uint8_t *buf, const Symbol &sym,
relocateNoSym(buf + 4, R_AARCH64_LDST64_ABS_LO12_NC, gotPltEntryAddr);
relocateNoSym(buf + 8, R_AARCH64_ADD_ABS_LO12_NC, gotPltEntryAddr);
- if (pacEntry)
- memcpy(buf + sizeof(addrInst), pacBr, sizeof(pacBr));
+ if (pacEntryKind != PEK_NoAuth)
+ memcpy(buf + sizeof(addrInst),
+ pacEntryKind == PEK_AuthHint ? pacHintBr : pacBr,
+ sizeof(pacEntryKind == PEK_AuthHint ? pacHintBr : pacBr));
else
memcpy(buf + sizeof(addrInst), stdBr, sizeof(stdBr));
if (!hasBti)
diff --git a/lld/test/ELF/aarch64-feature-pauth.s b/lld/test/ELF/aarch64-feature-pauth.s
index 3150c130d460f5..c50f38f4a7c975 100644
--- a/lld/test/ELF/aarch64-feature-pauth.s
+++ b/lld/test/ELF/aarch64-feature-pauth.s
@@ -56,8 +56,8 @@
# PACPLTTAG: 0x0000000070000003 (AARCH64_PAC_PLT)
-# RUN: llvm-objdump -d pacplt-nowarn | FileCheck --check-prefix PACPLT -DA=10380 -DB=478 -DC=480 %s
-# RUN: llvm-objdump -d pacplt-warn | FileCheck --check-prefix PACPLT -DA=10390 -DB=488 -DC=490 %s
+# RUN: llvm-objdump -d pacplt-nowarn | FileCheck --check-prefixes=PACPLT,NOHINT -DA=10380 -DB=478 -DC=480 %s
+# RUN: llvm-objdump -d pacplt-warn | FileCheck --check-prefixes=PACPLT,HINT -DA=10390 -DB=488 -DC=490 %s
# PACPLT: Disassembly of section .text:
# PACPLT: <func2>:
@@ -77,8 +77,10 @@
# PACPLT-NEXT: adrp x16, 0x30000 <func3+0x30000>
# PACPLT-NEXT: ldr x17, [x16, #0x[[C]]]
# PACPLT-NEXT: add x16, x16, #0x[[C]]
-# PACPLT-NEXT: autia1716
-# PACPLT-NEXT: br x17
+# NOHINT-NEXT: braa x17, x16
+# NOHINT-NEXT: nop
+# HINT-NEXT: autia1716
+# HINT-NEXT: br x17
# PACPLT-NEXT: nop
#--- abi-tag-short.s
More information about the llvm-commits
mailing list