22#define AARCH64_POINTER_AUTH_NAME "AArch64 Pointer Authentication"
38 const unsigned BrkOperand = 0xc471;
58 return new AArch64PointerAuth();
61char AArch64PointerAuth::ID = 0;
83 TII->get(UseBKey ? AArch64::PACIBSP : AArch64::PACIASP))
92 }
else if (NeedsWinCFI) {
98void AArch64PointerAuth::authenticateLR(
119 bool TerminatorIsCombinable =
120 TI !=
MBB.
end() && TI->getOpcode() == AArch64::RET;
121 if (Subtarget->hasPAuth() && TerminatorIsCombinable && !NeedsWinCFI &&
123 unsigned CombinedRetOpcode = UseBKey ? AArch64::RETAB : AArch64::RETAA;
127 unsigned AutOpcode = UseBKey ? AArch64::AUTIBSP : AArch64::AUTIASP;
151 auto MOVolatileLoad =
161 Register AuthenticatedReg,
Register TmpReg,
bool UseIKey,
unsigned BrkImm) {
173 case AuthCheckMethod::None:
175 case AuthCheckMethod::DummyLoad:
187 "Cannot insert the check at the very beginning of MBB");
203 case AuthCheckMethod::None:
204 case AuthCheckMethod::DummyLoad:
206 case AuthCheckMethod::HighBitsNoTBI:
207 BuildMI(CheckBlock,
DL,
TII->get(AArch64::EORXrs), TmpReg)
215 return *SuccessBlock;
216 case AuthCheckMethod::XPACHint:
217 assert(AuthenticatedReg == AArch64::LR &&
218 "XPACHint mode is only compatible with checking the LR register");
219 assert(UseIKey &&
"XPACHint mode is only compatible with I-keys");
220 BuildMI(CheckBlock,
DL,
TII->get(AArch64::ORRXrs), TmpReg)
225 BuildMI(CheckBlock,
DL,
TII->get(AArch64::SUBSXrs), AArch64::XZR)
232 return *SuccessBlock;
239 case AuthCheckMethod::None:
241 case AuthCheckMethod::DummyLoad:
243 case AuthCheckMethod::HighBitsNoTBI:
245 case AuthCheckMethod::XPACHint:
251bool AArch64PointerAuth::checkAuthenticatedLR(
255 if (Method == AuthCheckMethod::None)
260 assert(!TI->getMF()->hasWinCFI() &&
"WinCFI is not yet supported");
286 "Tail call is expected");
288 TI->readsRegister(AArch64::X16,
TRI) ? AArch64::X17 : AArch64::X16;
289 assert(!TI->readsRegister(TmpReg,
TRI) &&
290 "More than a single register is used by TCRETURN");
302 TII = Subtarget->getInstrInfo();
303 TRI = Subtarget->getRegisterInfo();
309 bool HasAuthenticationInstrs =
false;
311 for (
auto &
MBB : MF) {
315 switch (
MI.getOpcode()) {
327 case AArch64::PAUTH_PROLOGUE:
328 case AArch64::PAUTH_EPILOGUE:
336 for (
auto It : PAuthPseudoInstrs) {
337 switch (It->getOpcode()) {
338 case AArch64::PAUTH_PROLOGUE:
341 case AArch64::PAUTH_EPILOGUE:
342 authenticateLR(MF, It);
343 HasAuthenticationInstrs =
true;
348 It->eraseFromParent();
354 if (HasAuthenticationInstrs &&
356 for (
auto TailCall : TailCallInstrs) {
358 Modified |= checkAuthenticatedLR(TailCall);
#define AARCH64_POINTER_AUTH_NAME
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
const HexagonInstrInfo * TII
unsigned const TargetRegisterInfo * TRI
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
AArch64FunctionInfo - This class is derived from MachineFunctionInfo and contains private AArch64-spe...
bool needsShadowCallStackPrologueEpilogue(MachineFunction &MF) const
bool needsDwarfUnwindInfo(const MachineFunction &MF) const
bool needsAsyncDwarfUnwindInfo(const MachineFunction &MF) const
bool shouldSignWithBKey() const
static bool isTailCallReturnInst(const MachineInstr &MI)
Returns true if MI is one of the TCRETURN* instructions.
const AArch64InstrInfo * getInstrInfo() const override
const PseudoSourceValue * getAddressCheckPSV() const
AArch64PAuth::AuthCheckMethod getAuthenticatedLRCheckMethod() const
Choose a method of checking LR before performing a tail call.
FunctionPass class - This class is used to implement most global optimizations.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
static MCCFIInstruction createNegateRAState(MCSymbol *L, SMLoc Loc={})
.cfi_negate_ra_state AArch64 negate RA state.
MachineBasicBlock * getFallThrough(bool JumpToFallThrough=true)
Return the fallthrough block if the block can implicitly transfer control to the block after it by fa...
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
void splitSuccessor(MachineBasicBlock *Old, MachineBasicBlock *New, bool NormalizeSuccProbs=false)
Split the old successor into old plus new and updates the probability info.
MachineBasicBlock * splitAt(MachineInstr &SplitInst, bool UpdateLiveIns=true, LiveIntervals *LIS=nullptr)
Split a basic block into 2 pieces at SplitPoint.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
instr_iterator getFirstInstrTerminator()
Same getFirstTerminator but it ignores bundles and return an instr_iterator instead.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, uint64_t s, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
unsigned addFrameInst(const MCCFIInstruction &Inst)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
void push_back(MachineBasicBlock *MBB)
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineBasicBlock - Allocate a new MachineBasicBlock.
const MachineInstrBuilder & addCFIIndex(unsigned CFIIndex) const
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
const MachineInstrBuilder & copyImplicitOps(const MachineInstr &OtherMI) const
Copy all the implicit operands from OtherMI onto this one.
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
A description of a memory reference used in the backend.
@ MOVolatile
The memory access is volatile.
@ MOLoad
The memory access reads data.
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
Wrapper class representing virtual and physical registers.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned getCheckerSizeInBytes(AuthCheckMethod Method)
Returns the number of bytes added by checkAuthenticatedRegister.
AuthCheckMethod
Variants of check performed on an authenticated pointer.
MachineBasicBlock & checkAuthenticatedRegister(MachineBasicBlock::iterator MBBI, AuthCheckMethod Method, Register AuthenticatedReg, Register TmpReg, bool UseIKey, unsigned BrkImm)
Explicitly checks that pointer authentication succeeded.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
FunctionPass * createAArch64PointerAuthPass()
static unsigned getWRegFromXReg(unsigned Reg)
This struct is a compact representation of a valid (non-zero power of two) alignment.
This class contains a discriminated union of information about pointers in memory operands,...