Skip to content

Commit a4d3c0c

Browse files
committed
[AArch64][PAC] Simplify emission of authenticated pointer check (NFC)
The AArch64AsmPrinter::emitPtrauthCheckAuthenticatedValue method accepts two arguments, `bool ShouldTrap` and `const MCSymbol *OnFailure`, that control the behavior of the emitted instruction sequence when the check fails: * `ShouldTrap` requests an error to be generated * `OnFailure` requests branching to the given label after clearing the PAC field An assertion in `emitPtrauthCheckAuthenticatedValue` ensures that `OnFailure` must be null when `ShouldTrap` is set. But the opposite is also true: when `ShouldTrap` is false, `OnFailure` is always non-null, as otherwise the entire sequence following `AUT[ID][AB]` instruction would turn into a very expensive equivalent of XPAC (unless the CPU implements FEAT_FPAC): authenticate Xn inspect PAC field of Xn if PAC field was not cleared: clear PAC field The only caller that makes use of checking-but-not-trapping mode of emitPtrauthCheckAuthenticatedValue is emitPtrauthAuthResign, and it passes a non-null pointer as OnFailure when ShouldTrap is false. This commit makes the invariant explicit by omitting the ShouldTrap argument and inferring its value from the OnFailure argument instead.
1 parent c10befb commit a4d3c0c

File tree

1 file changed

+24
-30
lines changed

1 file changed

+24
-30
lines changed

llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp

Lines changed: 24 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,7 @@ class AArch64AsmPrinter : public AsmPrinter {
162162
Register ScratchReg,
163163
AArch64PACKey::ID Key,
164164
AArch64PAuth::AuthCheckMethod Method,
165-
bool ShouldTrap,
166-
const MCSymbol *OnFailure);
165+
const MCSymbol *OnFailure = nullptr);
167166

168167
// Check authenticated LR before tail calling.
169168
void emitPtrauthTailCallHardening(const MachineInstr *TC);
@@ -1939,14 +1938,19 @@ Register AArch64AsmPrinter::emitPtrauthDiscriminator(uint16_t Disc,
19391938
return ScratchReg;
19401939
}
19411940

1942-
/// Emits a code sequence to check an authenticated pointer value.
1941+
/// Emit a code sequence to check an authenticated pointer value.
19431942
///
1944-
/// If OnFailure argument is passed, jump there on check failure instead
1945-
/// of proceeding to the next instruction (only if ShouldTrap is false).
1943+
/// This function emits a sequence of instructions that checks if TestedReg was
1944+
/// authenticated successfully. On success, execution continues at the next
1945+
/// instruction after the sequence.
1946+
///
1947+
/// The action performed on failure depends on the OnFailure argument:
1948+
/// * if OnFailure is not nullptr, control is transferred to that label after
1949+
/// clearing the PAC field
1950+
/// * otherwise, BRK instruction is emitted to generate an error
19461951
void AArch64AsmPrinter::emitPtrauthCheckAuthenticatedValue(
19471952
Register TestedReg, Register ScratchReg, AArch64PACKey::ID Key,
1948-
AArch64PAuth::AuthCheckMethod Method, bool ShouldTrap,
1949-
const MCSymbol *OnFailure) {
1953+
AArch64PAuth::AuthCheckMethod Method, const MCSymbol *OnFailure) {
19501954
// Insert a sequence to check if authentication of TestedReg succeeded,
19511955
// such as:
19521956
//
@@ -1983,7 +1987,7 @@ void AArch64AsmPrinter::emitPtrauthCheckAuthenticatedValue(
19831987
.addReg(getWRegFromXReg(ScratchReg))
19841988
.addReg(TestedReg)
19851989
.addImm(0));
1986-
assert(ShouldTrap && !OnFailure && "DummyLoad always traps on error");
1990+
assert(!OnFailure && "DummyLoad always traps on error");
19871991
return;
19881992
}
19891993

@@ -2037,15 +2041,14 @@ void AArch64AsmPrinter::emitPtrauthCheckAuthenticatedValue(
20372041
llvm_unreachable("Unsupported check method");
20382042
}
20392043

2040-
if (ShouldTrap) {
2041-
assert(!OnFailure && "Cannot specify OnFailure with ShouldTrap");
2044+
if (!OnFailure) {
20422045
// Trapping sequences do a 'brk'.
20432046
// brk #<0xc470 + aut key>
20442047
EmitToStreamer(MCInstBuilder(AArch64::BRK).addImm(0xc470 | Key));
20452048
} else {
20462049
// Non-trapping checked sequences return the stripped result in TestedReg,
2047-
// skipping over success-only code (such as re-signing the pointer) if
2048-
// there is one.
2050+
// skipping over success-only code (such as re-signing the pointer) by
2051+
// jumping to OnFailure label.
20492052
// Note that this can introduce an authentication oracle (such as based on
20502053
// the high bits of the re-signed value).
20512054

@@ -2070,12 +2073,9 @@ void AArch64AsmPrinter::emitPtrauthCheckAuthenticatedValue(
20702073
MCInstBuilder(XPACOpc).addReg(TestedReg).addReg(TestedReg));
20712074
}
20722075

2073-
if (OnFailure) {
2074-
// b Lend
2075-
EmitToStreamer(
2076-
MCInstBuilder(AArch64::B)
2077-
.addExpr(MCSymbolRefExpr::create(OnFailure, OutContext)));
2078-
}
2076+
// b Lend
2077+
const auto *OnFailureExpr = MCSymbolRefExpr::create(OnFailure, OutContext);
2078+
EmitToStreamer(MCInstBuilder(AArch64::B).addExpr(OnFailureExpr));
20792079
}
20802080

20812081
// If the auth check succeeds, we can continue.
@@ -2102,9 +2102,8 @@ void AArch64AsmPrinter::emitPtrauthTailCallHardening(const MachineInstr *TC) {
21022102
"Neither x16 nor x17 is available as a scratch register");
21032103
AArch64PACKey::ID Key =
21042104
AArch64FI->shouldSignWithBKey() ? AArch64PACKey::IB : AArch64PACKey::IA;
2105-
emitPtrauthCheckAuthenticatedValue(
2106-
AArch64::LR, ScratchReg, Key, LRCheckMethod,
2107-
/*ShouldTrap=*/true, /*OnFailure=*/nullptr);
2105+
emitPtrauthCheckAuthenticatedValue(AArch64::LR, ScratchReg, Key,
2106+
LRCheckMethod);
21082107
}
21092108

21102109
void AArch64AsmPrinter::emitPtrauthAuthResign(
@@ -2178,9 +2177,8 @@ void AArch64AsmPrinter::emitPtrauthAuthResign(
21782177
if (IsAUTPAC && !ShouldTrap)
21792178
EndSym = createTempSymbol("resign_end_");
21802179

2181-
emitPtrauthCheckAuthenticatedValue(AUTVal, Scratch, AUTKey,
2182-
AArch64PAuth::AuthCheckMethod::XPAC,
2183-
ShouldTrap, EndSym);
2180+
emitPtrauthCheckAuthenticatedValue(
2181+
AUTVal, Scratch, AUTKey, AArch64PAuth::AuthCheckMethod::XPAC, EndSym);
21842182
}
21852183

21862184
// We already emitted unchecked and checked-but-non-trapping AUTs.
@@ -2519,9 +2517,7 @@ void AArch64AsmPrinter::LowerMOVaddrPAC(const MachineInstr &MI) {
25192517
: AArch64PACKey::DA);
25202518

25212519
emitPtrauthCheckAuthenticatedValue(AArch64::X16, AArch64::X17, AuthKey,
2522-
AArch64PAuth::AuthCheckMethod::XPAC,
2523-
/*ShouldTrap=*/true,
2524-
/*OnFailure=*/nullptr);
2520+
AArch64PAuth::AuthCheckMethod::XPAC);
25252521
}
25262522
} else {
25272523
EmitToStreamer(MCInstBuilder(AArch64::LDRXui)
@@ -2654,9 +2650,7 @@ void AArch64AsmPrinter::LowerLOADgotAUTH(const MachineInstr &MI) {
26542650
(AuthOpcode == AArch64::AUTIA ? AArch64PACKey::IA : AArch64PACKey::DA);
26552651

26562652
emitPtrauthCheckAuthenticatedValue(AuthResultReg, AArch64::X17, AuthKey,
2657-
AArch64PAuth::AuthCheckMethod::XPAC,
2658-
/*ShouldTrap=*/true,
2659-
/*OnFailure=*/nullptr);
2653+
AArch64PAuth::AuthCheckMethod::XPAC);
26602654

26612655
emitMovXReg(DstReg, AuthResultReg);
26622656
}

0 commit comments

Comments
 (0)