[AArch64][PAC] Group arguments of emitPtrauthAuthResign (NFC) (#174002)

The caller of `AArch64AsmPrinter::emitPtrauthAuthResign` has to analyze
the operands of MachineInstr being emitted and pass them explicitly to
this method, which leads to large number of function arguments, some of
them being optional.

This commit introduces `struct PtrAuthSchema` to pass semantically-
related parameters as a single argument and to better express the idea
that the second schema can only be passed or omitted as a whole.

Furthermore, `AUTVal` argument is renamed to `Pointer`, as unlike other
arguments with the `AUT` prefix, it does not relate to the authentication
schema, but represents a tied in-out operand used throughout the entire
expanded instruction sequence.
This commit is contained in:
Anatoly Trosinenko 2026-01-21 14:28:52 +03:00 committed by GitHub
parent 527b78bf6b
commit be50b78afe
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -189,13 +189,21 @@ public:
// Check authenticated LR before tail calling.
void emitPtrauthTailCallHardening(const MachineInstr *TC);
struct PtrAuthSchema {
PtrAuthSchema(AArch64PACKey::ID Key, uint64_t IntDisc,
const MachineOperand &AddrDiscOp);
AArch64PACKey::ID Key;
uint64_t IntDisc;
Register AddrDisc;
bool AddrDiscIsKilled;
};
// Emit the sequence for AUT or AUTPAC.
void emitPtrauthAuthResign(Register AUTVal, AArch64PACKey::ID AUTKey,
uint64_t AUTDisc,
const MachineOperand *AUTAddrDisc,
Register Scratch,
std::optional<AArch64PACKey::ID> PACKey,
uint64_t PACDisc, Register PACAddrDisc, Value *DS);
void emitPtrauthAuthResign(Register Pointer, Register Scratch,
PtrAuthSchema AuthSchema,
std::optional<PtrAuthSchema> SignSchema,
Value *DS);
// Emit R_AARCH64_PATCHINST, the deactivation symbol relocation. Returns true
// if no instruction should be emitted because the deactivation symbol is
@ -2222,12 +2230,15 @@ bool AArch64AsmPrinter::emitDeactivationSymbolRelocation(Value *DS) {
return false;
}
AArch64AsmPrinter::PtrAuthSchema::PtrAuthSchema(
AArch64PACKey::ID Key, uint64_t IntDisc, const MachineOperand &AddrDiscOp)
: Key(Key), IntDisc(IntDisc), AddrDisc(AddrDiscOp.getReg()),
AddrDiscIsKilled(AddrDiscOp.isKill()) {}
void AArch64AsmPrinter::emitPtrauthAuthResign(
Register AUTVal, AArch64PACKey::ID AUTKey, uint64_t AUTDisc,
const MachineOperand *AUTAddrDisc, Register Scratch,
std::optional<AArch64PACKey::ID> PACKey, uint64_t PACDisc,
Register PACAddrDisc, Value *DS) {
const bool IsAUTPAC = PACKey.has_value();
Register Pointer, Register Scratch, PtrAuthSchema AuthSchema,
std::optional<PtrAuthSchema> SignSchema, Value *DS) {
const bool IsResign = SignSchema.has_value();
// We expand AUT/AUTPAC into a sequence of the form
//
@ -2267,35 +2278,38 @@ void AArch64AsmPrinter::emitPtrauthAuthResign(
}
// Compute aut discriminator
Register AUTDiscReg = emitPtrauthDiscriminator(
AUTDisc, AUTAddrDisc->getReg(), Scratch, AUTAddrDisc->isKill());
Register AUTDiscReg =
emitPtrauthDiscriminator(AuthSchema.IntDisc, AuthSchema.AddrDisc, Scratch,
AuthSchema.AddrDiscIsKilled);
if (!emitDeactivationSymbolRelocation(DS))
emitAUT(AUTKey, AUTVal, AUTDiscReg);
emitAUT(AuthSchema.Key, Pointer, AUTDiscReg);
// Unchecked or checked-but-non-trapping AUT is just an "AUT": we're done.
if (!IsAUTPAC && (!ShouldCheck || !ShouldTrap))
if (!IsResign && (!ShouldCheck || !ShouldTrap))
return;
MCSymbol *EndSym = nullptr;
if (ShouldCheck) {
if (IsAUTPAC && !ShouldTrap)
if (IsResign && !ShouldTrap)
EndSym = createTempSymbol("resign_end_");
emitPtrauthCheckAuthenticatedValue(
AUTVal, Scratch, AUTKey, AArch64PAuth::AuthCheckMethod::XPAC, EndSym);
emitPtrauthCheckAuthenticatedValue(Pointer, Scratch, AuthSchema.Key,
AArch64PAuth::AuthCheckMethod::XPAC,
EndSym);
}
// We already emitted unchecked and checked-but-non-trapping AUTs.
// That left us with trapping AUTs, and AUTPACs.
// Trapping AUTs don't need PAC: we're done.
if (!IsAUTPAC)
if (!IsResign)
return;
// Compute pac discriminator
Register PACDiscReg = emitPtrauthDiscriminator(PACDisc, PACAddrDisc, Scratch);
emitPAC(*PACKey, AUTVal, PACDiscReg);
Register PACDiscReg = emitPtrauthDiscriminator(SignSchema->IntDisc,
SignSchema->AddrDisc, Scratch);
emitPAC(SignSchema->Key, Pointer, PACDiscReg);
// Lend:
if (EndSym)
@ -3199,29 +3213,44 @@ void AArch64AsmPrinter::emitInstruction(const MachineInstr *MI) {
return;
}
case AArch64::AUTx16x17:
emitPtrauthAuthResign(
AArch64::X16, (AArch64PACKey::ID)MI->getOperand(0).getImm(),
MI->getOperand(1).getImm(), &MI->getOperand(2), AArch64::X17,
std::nullopt, 0, 0, MI->getDeactivationSymbol());
return;
case AArch64::AUTx16x17: {
const Register Pointer = AArch64::X16;
const Register Scratch = AArch64::X17;
case AArch64::AUTxMxN:
emitPtrauthAuthResign(MI->getOperand(0).getReg(),
(AArch64PACKey::ID)MI->getOperand(3).getImm(),
MI->getOperand(4).getImm(), &MI->getOperand(5),
MI->getOperand(1).getReg(), std::nullopt, 0, 0,
PtrAuthSchema AuthSchema((AArch64PACKey::ID)MI->getOperand(0).getImm(),
MI->getOperand(1).getImm(), MI->getOperand(2));
emitPtrauthAuthResign(Pointer, Scratch, AuthSchema, std::nullopt,
MI->getDeactivationSymbol());
return;
}
case AArch64::AUTPAC:
emitPtrauthAuthResign(
AArch64::X16, (AArch64PACKey::ID)MI->getOperand(0).getImm(),
MI->getOperand(1).getImm(), &MI->getOperand(2), AArch64::X17,
(AArch64PACKey::ID)MI->getOperand(3).getImm(),
MI->getOperand(4).getImm(), MI->getOperand(5).getReg(),
MI->getDeactivationSymbol());
case AArch64::AUTxMxN: {
const Register Pointer = MI->getOperand(0).getReg();
const Register Scratch = MI->getOperand(1).getReg();
PtrAuthSchema AuthSchema((AArch64PACKey::ID)MI->getOperand(3).getImm(),
MI->getOperand(4).getImm(), MI->getOperand(5));
emitPtrauthAuthResign(Pointer, Scratch, AuthSchema, std::nullopt,
MI->getDeactivationSymbol());
return;
}
case AArch64::AUTPAC: {
const Register Pointer = AArch64::X16;
const Register Scratch = AArch64::X17;
PtrAuthSchema AuthSchema((AArch64PACKey::ID)MI->getOperand(0).getImm(),
MI->getOperand(1).getImm(), MI->getOperand(2));
PtrAuthSchema SignSchema((AArch64PACKey::ID)MI->getOperand(3).getImm(),
MI->getOperand(4).getImm(), MI->getOperand(5));
emitPtrauthAuthResign(Pointer, Scratch, AuthSchema, SignSchema,
MI->getDeactivationSymbol());
return;
}
case AArch64::PAC:
emitPtrauthSign(MI);