[llvm] [AArch64][PAC] Move emission of LR checks in tail calls to AsmPrinter (PR #110705)
Anatoly Trosinenko via llvm-commits
llvm-commits at lists.llvm.org
Tue Nov 5 10:28:44 PST 2024
================
@@ -1757,38 +1762,70 @@ void AArch64AsmPrinter::emitPtrauthCheckAuthenticatedValue(
// Lsuccess:
// ...
//
- // This sequence is expensive, but we need more information to be able to
- // do better.
- //
- // We can't TBZ the poison bit because EnhancedPAC2 XORs the PAC bits
- // on failure.
- // We can't TST the PAC bits because we don't always know how the address
- // space is setup for the target environment (and the bottom PAC bit is
- // based on that).
- // Either way, we also don't always know whether TBI is enabled or not for
- // the specific target environment.
+ // See the documentation on AuthCheckMethod enumeration constants for
+ // the specific code sequences that can be used to perform the check.
+ using AArch64PAuth::AuthCheckMethod;
- unsigned XPACOpc = getXPACOpcodeForKey(Key);
+ if (Method == AuthCheckMethod::None)
+ return;
+ if (Method == AuthCheckMethod::DummyLoad) {
+ EmitToStreamer(MCInstBuilder(AArch64::LDRWui)
+ .addReg(getWRegFromXReg(ScratchReg))
+ .addReg(TestedReg)
+ .addImm(0));
+ assert(ShouldTrap && !OnFailure && "DummyLoad always traps on error");
+ return;
+ }
MCSymbol *SuccessSym = createTempSymbol("auth_success_");
+ if (Method == AuthCheckMethod::XPAC || Method == AuthCheckMethod::XPACHint) {
+ // mov Xscratch, Xtested
+ emitMovXReg(ScratchReg, TestedReg);
- // mov Xscratch, Xtested
- emitMovXReg(ScratchReg, TestedReg);
-
- // xpac(i|d) Xscratch
- EmitToStreamer(MCInstBuilder(XPACOpc).addReg(ScratchReg).addReg(ScratchReg));
+ if (Method == AuthCheckMethod::XPAC) {
+ // xpac(i|d) Xscratch
+ unsigned XPACOpc = getXPACOpcodeForKey(Key);
+ EmitToStreamer(
+ MCInstBuilder(XPACOpc).addReg(ScratchReg).addReg(ScratchReg));
+ } else {
+ // xpaclri
+
+ // Note that this method applies XPAC to TestedReg instead of ScratchReg.
+ assert(TestedReg == AArch64::LR &&
+ "XPACHint mode is only compatible with checking the LR register");
+ assert((Key == AArch64PACKey::IA || Key == AArch64PACKey::IB) &&
+ "XPACHint mode is only compatible with I-keys");
+ EmitToStreamer(MCInstBuilder(AArch64::XPACLRI));
+ }
- // cmp Xtested, Xscratch
- EmitToStreamer(MCInstBuilder(AArch64::SUBSXrs)
- .addReg(AArch64::XZR)
- .addReg(TestedReg)
- .addReg(ScratchReg)
- .addImm(0));
+ // cmp Xtested, Xscratch
+ EmitToStreamer(MCInstBuilder(AArch64::SUBSXrs)
+ .addReg(AArch64::XZR)
+ .addReg(TestedReg)
+ .addReg(ScratchReg)
+ .addImm(0));
- // b.eq Lsuccess
- EmitToStreamer(MCInstBuilder(AArch64::Bcc)
- .addImm(AArch64CC::EQ)
- .addExpr(MCSymbolRefExpr::create(SuccessSym, OutContext)));
+ // b.eq Lsuccess
+ EmitToStreamer(
+ MCInstBuilder(AArch64::Bcc)
+ .addImm(AArch64CC::EQ)
+ .addExpr(MCSymbolRefExpr::create(SuccessSym, OutContext)));
+ } else if (Method == AuthCheckMethod::HighBitsNoTBI) {
+ // eor Xscratch, Xtested, Xtested, lsl #1
+ EmitToStreamer(MCInstBuilder(AArch64::EORXrs)
+ .addReg(ScratchReg)
+ .addReg(TestedReg)
+ .addReg(TestedReg)
+ .addImm(1));
+ // tbz Xscratch, #62, Lsuccess
+ EmitToStreamer(
+ MCInstBuilder(AArch64::TBZX)
+ .addReg(ScratchReg)
+ .addImm(62)
+ .addExpr(MCSymbolRefExpr::create(SuccessSym, OutContext)));
+ } else {
----------------
atrosinenko wrote:
On the one hand, a dangling
```cpp
} else {
llvm_unreachable("Unsupported check method");
}
```
block looks a bit clumsy, on the other hand, it looks natural from the standpoint of introducing completely new check methods (if any) by inserting one more `if else (... ) { ... }` block of text, so let's keep as-is for now...
https://github.com/llvm/llvm-project/pull/110705
More information about the llvm-commits
mailing list