-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[PAC][lld] Use braa instr in PAC PLT sequence with valid PAuth core info #113945
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-lld Author: Daniil Kovalev (kovdan01) ChangesAssume PAC instructions being supported with PAuth core info different Full diff: https://github.com/llvm/llvm-project/pull/113945.diff 2 Files Affected:
diff --git a/lld/ELF/Arch/AArch64.cpp b/lld/ELF/Arch/AArch64.cpp
index 260307ac4c3dcb..c76f226bc5511c 100644
--- a/lld/ELF/Arch/AArch64.cpp
+++ b/lld/ELF/Arch/AArch64.cpp
@@ -999,7 +999,9 @@ class AArch64BtiPac final : public AArch64 {
private:
bool btiHeader; // bti instruction needed in PLT Header and Entry
- bool pacEntry; // autia1716 instruction needed in PLT Entry
+ bool pacEntry; // Authenticated branch needed in PLT Entry
+ bool pacUseHint =
+ true; // Use hint space instructions for authenticated branch in PLT entry
};
} // namespace
@@ -1016,6 +1018,10 @@ AArch64BtiPac::AArch64BtiPac(Ctx &ctx) : AArch64(ctx) {
// from properties in the objects, so we use the command line flag.
pacEntry = ctx.arg.zPacPlt;
+ if (llvm::any_of(ctx.aarch64PauthAbiCoreInfo,
+ [](uint8_t c) { return c != 0; }))
+ pacUseHint = false;
+
if (btiHeader || pacEntry) {
pltEntrySize = 24;
ipltEntrySize = 24;
@@ -1066,9 +1072,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
@@ -1097,7 +1107,8 @@ void AArch64BtiPac::writePlt(uint8_t *buf, const Symbol &sym,
relocateNoSym(buf + 8, R_AARCH64_ADD_ABS_LO12_NC, gotPltEntryAddr);
if (pacEntry)
- memcpy(buf + sizeof(addrInst), pacBr, sizeof(pacBr));
+ memcpy(buf + sizeof(addrInst), (pacUseHint ? pacHintBr : pacBr),
+ sizeof(pacUseHint ? 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 c11073dba86f24..34f2f2698a26b8 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
|
@llvm/pr-subscribers-lld-elf Author: Daniil Kovalev (kovdan01) ChangesAssume PAC instructions being supported with PAuth core info different Full diff: https://github.com/llvm/llvm-project/pull/113945.diff 2 Files Affected:
diff --git a/lld/ELF/Arch/AArch64.cpp b/lld/ELF/Arch/AArch64.cpp
index 260307ac4c3dcb..c76f226bc5511c 100644
--- a/lld/ELF/Arch/AArch64.cpp
+++ b/lld/ELF/Arch/AArch64.cpp
@@ -999,7 +999,9 @@ class AArch64BtiPac final : public AArch64 {
private:
bool btiHeader; // bti instruction needed in PLT Header and Entry
- bool pacEntry; // autia1716 instruction needed in PLT Entry
+ bool pacEntry; // Authenticated branch needed in PLT Entry
+ bool pacUseHint =
+ true; // Use hint space instructions for authenticated branch in PLT entry
};
} // namespace
@@ -1016,6 +1018,10 @@ AArch64BtiPac::AArch64BtiPac(Ctx &ctx) : AArch64(ctx) {
// from properties in the objects, so we use the command line flag.
pacEntry = ctx.arg.zPacPlt;
+ if (llvm::any_of(ctx.aarch64PauthAbiCoreInfo,
+ [](uint8_t c) { return c != 0; }))
+ pacUseHint = false;
+
if (btiHeader || pacEntry) {
pltEntrySize = 24;
ipltEntrySize = 24;
@@ -1066,9 +1072,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
@@ -1097,7 +1107,8 @@ void AArch64BtiPac::writePlt(uint8_t *buf, const Symbol &sym,
relocateNoSym(buf + 8, R_AARCH64_ADD_ABS_LO12_NC, gotPltEntryAddr);
if (pacEntry)
- memcpy(buf + sizeof(addrInst), pacBr, sizeof(pacBr));
+ memcpy(buf + sizeof(addrInst), (pacUseHint ? pacHintBr : pacBr),
+ sizeof(pacUseHint ? 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 c11073dba86f24..34f2f2698a26b8 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
|
lld/ELF/Arch/AArch64.cpp
Outdated
@@ -999,7 +999,9 @@ class AArch64BtiPac final : public AArch64 { | |||
|
|||
private: | |||
bool btiHeader; // bti instruction needed in PLT Header and Entry | |||
bool pacEntry; // autia1716 instruction needed in PLT Entry | |||
bool pacEntry; // Authenticated branch needed in PLT Entry |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe we can just have enum here instead of pair of bools? E.g.
enum {
Unsigned,
SignedHint, // use autia1716 instruction in PLT entry
Signed // can use non-hint braa instruction
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed to an enum, thanks! It might be worth using a switch statement instead of if's and ternary operators at the end of AArch64BtiPac::writePlt
, but it looks like that it's readable enough right now, so I left that "as is" unless there is a request for changing that as well.
0x9f, 0x21, 0x03, 0xd5, // autia1716 | ||
0x20, 0x02, 0x1f, 0xd6 // br x17 | ||
0x30, 0x0a, 0x1f, 0xd7, // braa x17, x16 | ||
0x1f, 0x20, 0x03, 0xd5 // nop |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe UDF instruction is a safer choice instead of NOP. also may not have any significance.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's a nice suggestion, but I'll apply it in a separate PR not to mix different changes - nop
is present both in pacBr
and stdBr
, while the current PR is intended to change only pacBr
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No objections from me. A small suggestion for the comment and a possible simplification.
@@ -1014,9 +1018,18 @@ 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; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It could be worth adding to the comment here. Something like:
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added, thanks, see b189f51
memcpy(buf + sizeof(addrInst), pacBr, sizeof(pacBr)); | ||
if (pacEntryKind != PEK_NoAuth) | ||
memcpy(buf + sizeof(addrInst), | ||
pacEntryKind == PEK_AuthHint ? pacHintBr : pacBr, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could be a possibility to make pacHintBr and pacBr into an array indexed by pacEntryKind.
memcpy(buf + sizeof(addrInst),
pacBrInstrs[pacEntryKind],
sizeof(pacBrInstrs[pacEntryKind]));
Not sure if it is worth the trouble though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for suggestion. I think I'll leave this "as is" w/o changes - it looks like that a pretty small decrease in code length here will require increase in complexity by introducing invariants on enum values and increase in code length somewhere else.
35d5c86
to
7f1e0fc
Compare
026d7ca
to
963794c
Compare
7f1e0fc
to
58b0ffa
Compare
963794c
to
6b35745
Compare
38b9ffd
to
b189f51
Compare
@MaskRay Please let me know if there are any objections on merging this |
Assume PAC instructions being supported with PAuth core info different from (0,0). Given that, `autia1716; br x17` can be replaced with `braa x17, x16; nop`.
b189f51
to
3d1670d
Compare
It is worth explaining what braa is. "Assume PAC instructions being supported with PAuth core info different from (0,0)" seems difficult to follow for AArch64 PAuth outsiders |
Thanks for suggestion! I changed the PR description to the following:
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/73/builds/8730 Here is the relevant piece of the build log for the reference
|
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 withbraa x17, x16; nop
, wherebraa
is an authenticated branch instruction using IA key, discriminator from x16 and signed target address from x17.