================
@@ -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 {
----------------
kovdan01 wrote:
Nit: alternatively, you can change the previous `else if` to just `else` and
put `Method == AuthCheckMethod::HighBitsNoTBI` condition as an assert in its
beginning. Feel free to ignore.
https://github.com/llvm/llvm-project/pull/110705
_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits