Skip to content

Commit e92bb83

Browse files
authored
[AArch64][PAC] Simplify emission of authenticated pointer check (NFC) (#160899)
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 when `ShouldTrap` is true, `OnFailure` must be null. But the opposite holds as well: 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 In other words, the value of `ShouldTrap` argument can be computed as `OnFailure == nullptr` at all existing call sites. In fact, at three of four call sites, constant `true` and `nullptr` are passed as the values of these function arguments. `emitPtrauthAuthResign` is the only caller that potentially makes use of checking-but-not-trapping mode of `emitPtrauthCheckAuthenticatedValue`, 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 0549aa1 commit e92bb83

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);
@@ -1937,14 +1936,19 @@ Register AArch64AsmPrinter::emitPtrauthDiscriminator(uint16_t Disc,
19371936
return ScratchReg;
19381937
}
19391938

1940-
/// Emits a code sequence to check an authenticated pointer value.
1939+
/// Emit a code sequence to check an authenticated pointer value.
19411940
///
1942-
/// If OnFailure argument is passed, jump there on check failure instead
1943-
/// of proceeding to the next instruction (only if ShouldTrap is false).
1941+
/// This function emits a sequence of instructions that checks if TestedReg was
1942+
/// authenticated successfully. On success, execution continues at the next
1943+
/// instruction after the sequence.
1944+
///
1945+
/// The action performed on failure depends on the OnFailure argument:
1946+
/// * if OnFailure is not nullptr, control is transferred to that label after
1947+
/// clearing the PAC field
1948+
/// * otherwise, BRK instruction is emitted to generate an error
19441949
void AArch64AsmPrinter::emitPtrauthCheckAuthenticatedValue(
19451950
Register TestedReg, Register ScratchReg, AArch64PACKey::ID Key,
1946-
AArch64PAuth::AuthCheckMethod Method, bool ShouldTrap,
1947-
const MCSymbol *OnFailure) {
1951+
AArch64PAuth::AuthCheckMethod Method, const MCSymbol *OnFailure) {
19481952
// Insert a sequence to check if authentication of TestedReg succeeded,
19491953
// such as:
19501954
//
@@ -1981,7 +1985,7 @@ void AArch64AsmPrinter::emitPtrauthCheckAuthenticatedValue(
19811985
.addReg(getWRegFromXReg(ScratchReg))
19821986
.addReg(TestedReg)
19831987
.addImm(0));
1984-
assert(ShouldTrap && !OnFailure && "DummyLoad always traps on error");
1988+
assert(!OnFailure && "DummyLoad always traps on error");
19851989
return;
19861990
}
19871991

@@ -2035,15 +2039,14 @@ void AArch64AsmPrinter::emitPtrauthCheckAuthenticatedValue(
20352039
llvm_unreachable("Unsupported check method");
20362040
}
20372041

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

@@ -2068,12 +2071,9 @@ void AArch64AsmPrinter::emitPtrauthCheckAuthenticatedValue(
20682071
MCInstBuilder(XPACOpc).addReg(TestedReg).addReg(TestedReg));
20692072
}
20702073

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

20792079
// If the auth check succeeds, we can continue.
@@ -2100,9 +2100,8 @@ void AArch64AsmPrinter::emitPtrauthTailCallHardening(const MachineInstr *TC) {
21002100
"Neither x16 nor x17 is available as a scratch register");
21012101
AArch64PACKey::ID Key =
21022102
AArch64FI->shouldSignWithBKey() ? AArch64PACKey::IB : AArch64PACKey::IA;
2103-
emitPtrauthCheckAuthenticatedValue(
2104-
AArch64::LR, ScratchReg, Key, LRCheckMethod,
2105-
/*ShouldTrap=*/true, /*OnFailure=*/nullptr);
2103+
emitPtrauthCheckAuthenticatedValue(AArch64::LR, ScratchReg, Key,
2104+
LRCheckMethod);
21062105
}
21072106

21082107
void AArch64AsmPrinter::emitPtrauthAuthResign(
@@ -2176,9 +2175,8 @@ void AArch64AsmPrinter::emitPtrauthAuthResign(
21762175
if (IsAUTPAC && !ShouldTrap)
21772176
EndSym = createTempSymbol("resign_end_");
21782177

2179-
emitPtrauthCheckAuthenticatedValue(AUTVal, Scratch, AUTKey,
2180-
AArch64PAuth::AuthCheckMethod::XPAC,
2181-
ShouldTrap, EndSym);
2178+
emitPtrauthCheckAuthenticatedValue(
2179+
AUTVal, Scratch, AUTKey, AArch64PAuth::AuthCheckMethod::XPAC, EndSym);
21822180
}
21832181

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

25192517
emitPtrauthCheckAuthenticatedValue(AArch64::X16, AArch64::X17, AuthKey,
2520-
AArch64PAuth::AuthCheckMethod::XPAC,
2521-
/*ShouldTrap=*/true,
2522-
/*OnFailure=*/nullptr);
2518+
AArch64PAuth::AuthCheckMethod::XPAC);
25232519
}
25242520
} else {
25252521
EmitToStreamer(MCInstBuilder(AArch64::LDRXui)
@@ -2652,9 +2648,7 @@ void AArch64AsmPrinter::LowerLOADgotAUTH(const MachineInstr &MI) {
26522648
(AuthOpcode == AArch64::AUTIA ? AArch64PACKey::IA : AArch64PACKey::DA);
26532649

26542650
emitPtrauthCheckAuthenticatedValue(AuthResultReg, AArch64::X17, AuthKey,
2655-
AArch64PAuth::AuthCheckMethod::XPAC,
2656-
/*ShouldTrap=*/true,
2657-
/*OnFailure=*/nullptr);
2651+
AArch64PAuth::AuthCheckMethod::XPAC);
26582652

26592653
emitMovXReg(DstReg, AuthResultReg);
26602654
}

0 commit comments

Comments
 (0)