LLVM 19.0.0git
AArch64PointerAuth.cpp
Go to the documentation of this file.
1//===-- AArch64PointerAuth.cpp -- Harden code using PAuth ------------------==//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
10
11#include "AArch64.h"
12#include "AArch64InstrInfo.h"
14#include "AArch64Subtarget.h"
19
20using namespace llvm;
21using namespace llvm::AArch64PAuth;
22
23#define AARCH64_POINTER_AUTH_NAME "AArch64 Pointer Authentication"
24
25namespace {
26
27class AArch64PointerAuth : public MachineFunctionPass {
28public:
29 static char ID;
30
31 AArch64PointerAuth() : MachineFunctionPass(ID) {}
32
33 bool runOnMachineFunction(MachineFunction &MF) override;
34
35 StringRef getPassName() const override { return AARCH64_POINTER_AUTH_NAME; }
36
37private:
38 /// An immediate operand passed to BRK instruction, if it is ever emitted.
39 static unsigned BrkOperandForKey(AArch64PACKey::ID KeyId) {
40 const unsigned BrkOperandBase = 0xc470;
41 return BrkOperandBase + KeyId;
42 }
43
44 const AArch64Subtarget *Subtarget = nullptr;
45 const AArch64InstrInfo *TII = nullptr;
46 const AArch64RegisterInfo *TRI = nullptr;
47
48 void signLR(MachineFunction &MF, MachineBasicBlock::iterator MBBI) const;
49
50 void authenticateLR(MachineFunction &MF,
52
53 /// Stores blend(AddrDisc, IntDisc) to the Result register.
54 void emitBlend(MachineBasicBlock::iterator MBBI, Register Result,
55 Register AddrDisc, unsigned IntDisc) const;
56
57 /// Expands PAUTH_BLEND pseudo instruction.
58 void expandPAuthBlend(MachineBasicBlock::iterator MBBI) const;
59
60 bool checkAuthenticatedLR(MachineBasicBlock::iterator TI) const;
61};
62
63} // end anonymous namespace
64
65INITIALIZE_PASS(AArch64PointerAuth, "aarch64-ptrauth",
66 AARCH64_POINTER_AUTH_NAME, false, false)
67
69 return new AArch64PointerAuth();
70}
71
72char AArch64PointerAuth::ID = 0;
73
74// Where PAuthLR support is not known at compile time, it is supported using
75// PACM. PACM is in the hint space so has no effect when PAuthLR is not
76// supported by the hardware, but will alter the behaviour of PACI*SP, AUTI*SP
77// and RETAA/RETAB if the hardware supports PAuthLR.
78static void BuildPACM(const AArch64Subtarget &Subtarget, MachineBasicBlock &MBB,
80 MachineInstr::MIFlag Flags, MCSymbol *PACSym = nullptr) {
81 const TargetInstrInfo *TII = Subtarget.getInstrInfo();
82 auto &MFnI = *MBB.getParent()->getInfo<AArch64FunctionInfo>();
83
84 // ADR X16,<address_of_PACIASP>
85 if (PACSym) {
87 BuildMI(MBB, MBBI, DL, TII->get(AArch64::ADR))
88 .addReg(AArch64::X16, RegState::Define)
89 .addSym(PACSym);
90 }
91
92 // Only emit PACM if -mbranch-protection has +pc and the target does not
93 // have feature +pauth-lr.
94 if (MFnI.branchProtectionPAuthLR() && !Subtarget.hasPAuthLR())
95 BuildMI(MBB, MBBI, DL, TII->get(AArch64::PACM)).setMIFlag(Flags);
96}
97
98void AArch64PointerAuth::signLR(MachineFunction &MF,
100 auto &MFnI = *MF.getInfo<AArch64FunctionInfo>();
101 bool UseBKey = MFnI.shouldSignWithBKey();
102 bool EmitCFI = MFnI.needsDwarfUnwindInfo(MF);
103 bool NeedsWinCFI = MF.hasWinCFI();
104
106
107 // Debug location must be unknown, see AArch64FrameLowering::emitPrologue.
108 DebugLoc DL;
109
110 if (UseBKey) {
111 BuildMI(MBB, MBBI, DL, TII->get(AArch64::EMITBKEY))
113 }
114
115 // PAuthLR authentication instructions need to know the value of PC at the
116 // point of signing (PACI*).
117 if (MFnI.branchProtectionPAuthLR()) {
118 MCSymbol *PACSym = MF.getMMI().getContext().createTempSymbol();
119 MFnI.setSigningInstrLabel(PACSym);
120 }
121
122 // No SEH opcode for this one; it doesn't materialize into an
123 // instruction on Windows.
124 if (MFnI.branchProtectionPAuthLR() && Subtarget->hasPAuthLR()) {
125 BuildMI(MBB, MBBI, DL,
126 TII->get(MFnI.shouldSignWithBKey() ? AArch64::PACIBSPPC
127 : AArch64::PACIASPPC))
129 ->setPreInstrSymbol(MF, MFnI.getSigningInstrLabel());
130 } else {
132 BuildMI(MBB, MBBI, DL,
133 TII->get(MFnI.shouldSignWithBKey() ? AArch64::PACIBSP
134 : AArch64::PACIASP))
136 ->setPreInstrSymbol(MF, MFnI.getSigningInstrLabel());
137 }
138
139 if (EmitCFI) {
140 unsigned CFIIndex =
142 BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
143 .addCFIIndex(CFIIndex)
145 } else if (NeedsWinCFI) {
146 BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_PACSignLR))
148 }
149}
150
151void AArch64PointerAuth::authenticateLR(
154 bool UseBKey = MFnI->shouldSignWithBKey();
155 bool EmitAsyncCFI = MFnI->needsAsyncDwarfUnwindInfo(MF);
156 bool NeedsWinCFI = MF.hasWinCFI();
157
159 DebugLoc DL = MBBI->getDebugLoc();
160 // MBBI points to a PAUTH_EPILOGUE instruction to be replaced and
161 // TI points to a terminator instruction that may or may not be combined.
162 // Note that inserting new instructions "before MBBI" and "before TI" is
163 // not the same because if ShadowCallStack is enabled, its instructions
164 // are placed between MBBI and TI.
166
167 // The AUTIASP instruction assembles to a hint instruction before v8.3a so
168 // this instruction can safely used for any v8a architecture.
169 // From v8.3a onwards there are optimised authenticate LR and return
170 // instructions, namely RETA{A,B}, that can be used instead. In this case the
171 // DW_CFA_AARCH64_negate_ra_state can't be emitted.
172 bool TerminatorIsCombinable =
173 TI != MBB.end() && TI->getOpcode() == AArch64::RET;
174 MCSymbol *PACSym = MFnI->getSigningInstrLabel();
175
176 if (Subtarget->hasPAuth() && TerminatorIsCombinable && !NeedsWinCFI &&
177 !MF.getFunction().hasFnAttribute(Attribute::ShadowCallStack)) {
178 if (MFnI->branchProtectionPAuthLR() && Subtarget->hasPAuthLR()) {
179 assert(PACSym && "No PAC instruction to refer to");
180 BuildMI(MBB, TI, DL,
181 TII->get(UseBKey ? AArch64::RETABSPPCi : AArch64::RETAASPPCi))
182 .addSym(PACSym)
185 } else {
186 BuildPACM(*Subtarget, MBB, TI, DL, MachineInstr::FrameDestroy, PACSym);
187 BuildMI(MBB, TI, DL, TII->get(UseBKey ? AArch64::RETAB : AArch64::RETAA))
190 }
191 MBB.erase(TI);
192 } else {
193 if (MFnI->branchProtectionPAuthLR() && Subtarget->hasPAuthLR()) {
194 assert(PACSym && "No PAC instruction to refer to");
195 BuildMI(MBB, MBBI, DL,
196 TII->get(UseBKey ? AArch64::AUTIBSPPCi : AArch64::AUTIASPPCi))
197 .addSym(PACSym)
199 } else {
200 BuildPACM(*Subtarget, MBB, MBBI, DL, MachineInstr::FrameDestroy, PACSym);
201 BuildMI(MBB, MBBI, DL,
202 TII->get(UseBKey ? AArch64::AUTIBSP : AArch64::AUTIASP))
204 }
205
206 if (EmitAsyncCFI) {
207 unsigned CFIIndex =
209 BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
210 .addCFIIndex(CFIIndex)
212 }
213 if (NeedsWinCFI) {
214 BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_PACSignLR))
216 }
217 }
218}
219
220namespace {
221
222// Mark dummy LDR instruction as volatile to prevent removing it as dead code.
223MachineMemOperand *createCheckMemOperand(MachineFunction &MF,
224 const AArch64Subtarget &Subtarget) {
225 MachinePointerInfo PointerInfo(Subtarget.getAddressCheckPSV());
226 auto MOVolatileLoad =
228
229 return MF.getMachineMemOperand(PointerInfo, MOVolatileLoad, 4, Align(4));
230}
231
232} // namespace
233
236 Register AuthenticatedReg, Register TmpReg, bool UseIKey, unsigned BrkImm) {
237
240 const AArch64Subtarget &Subtarget = MF.getSubtarget<AArch64Subtarget>();
241 const AArch64InstrInfo *TII = Subtarget.getInstrInfo();
242 DebugLoc DL = MBBI->getDebugLoc();
243
244 // First, handle the methods not requiring creating extra MBBs.
245 switch (Method) {
246 default:
247 break;
248 case AuthCheckMethod::None:
249 return MBB;
250 case AuthCheckMethod::DummyLoad:
251 BuildMI(MBB, MBBI, DL, TII->get(AArch64::LDRWui), getWRegFromXReg(TmpReg))
252 .addReg(AuthenticatedReg)
253 .addImm(0)
254 .addMemOperand(createCheckMemOperand(MF, Subtarget));
255 return MBB;
256 }
257
258 // Control flow has to be changed, so arrange new MBBs.
259
260 // At now, at least an AUT* instruction is expected before MBBI
261 assert(MBBI != MBB.begin() &&
262 "Cannot insert the check at the very beginning of MBB");
263 // The block to insert check into.
264 MachineBasicBlock *CheckBlock = &MBB;
265 // The remaining part of the original MBB that is executed on success.
266 MachineBasicBlock *SuccessBlock = MBB.splitAt(*std::prev(MBBI));
267
268 // The block that explicitly generates a break-point exception on failure.
269 MachineBasicBlock *BreakBlock =
271 MF.push_back(BreakBlock);
272 MBB.splitSuccessor(SuccessBlock, BreakBlock);
273
274 assert(CheckBlock->getFallThrough() == SuccessBlock);
275 BuildMI(BreakBlock, DL, TII->get(AArch64::BRK)).addImm(BrkImm);
276
277 switch (Method) {
278 case AuthCheckMethod::None:
279 case AuthCheckMethod::DummyLoad:
280 llvm_unreachable("Should be handled above");
281 case AuthCheckMethod::HighBitsNoTBI:
282 BuildMI(CheckBlock, DL, TII->get(AArch64::EORXrs), TmpReg)
283 .addReg(AuthenticatedReg)
284 .addReg(AuthenticatedReg)
285 .addImm(1);
286 BuildMI(CheckBlock, DL, TII->get(AArch64::TBNZX))
287 .addReg(TmpReg)
288 .addImm(62)
289 .addMBB(BreakBlock);
290 return *SuccessBlock;
291 case AuthCheckMethod::XPACHint:
292 assert(AuthenticatedReg == AArch64::LR &&
293 "XPACHint mode is only compatible with checking the LR register");
294 assert(UseIKey && "XPACHint mode is only compatible with I-keys");
295 BuildMI(CheckBlock, DL, TII->get(AArch64::ORRXrs), TmpReg)
296 .addReg(AArch64::XZR)
297 .addReg(AArch64::LR)
298 .addImm(0);
299 BuildMI(CheckBlock, DL, TII->get(AArch64::XPACLRI));
300 BuildMI(CheckBlock, DL, TII->get(AArch64::SUBSXrs), AArch64::XZR)
301 .addReg(TmpReg)
302 .addReg(AArch64::LR)
303 .addImm(0);
304 BuildMI(CheckBlock, DL, TII->get(AArch64::Bcc))
306 .addMBB(BreakBlock);
307 return *SuccessBlock;
308 }
309 llvm_unreachable("Unknown AuthCheckMethod enum");
310}
311
313 switch (Method) {
314 case AuthCheckMethod::None:
315 return 0;
316 case AuthCheckMethod::DummyLoad:
317 return 4;
318 case AuthCheckMethod::HighBitsNoTBI:
319 return 12;
320 case AuthCheckMethod::XPACHint:
321 return 20;
322 }
323 llvm_unreachable("Unknown AuthCheckMethod enum");
324}
325
326bool AArch64PointerAuth::checkAuthenticatedLR(
328 const AArch64FunctionInfo *MFnI = TI->getMF()->getInfo<AArch64FunctionInfo>();
329 AArch64PACKey::ID KeyId =
331
333
334 if (Method == AuthCheckMethod::None)
335 return false;
336
337 // FIXME If FEAT_FPAC is implemented by the CPU, this check can be skipped.
338
339 assert(!TI->getMF()->hasWinCFI() && "WinCFI is not yet supported");
340
341 // The following code may create a signing oracle:
342 //
343 // <authenticate LR>
344 // TCRETURN ; the callee may sign and spill the LR in its prologue
345 //
346 // To avoid generating a signing oracle, check the authenticated value
347 // before possibly re-signing it in the callee, as follows:
348 //
349 // <authenticate LR>
350 // <check if LR contains a valid address>
351 // b.<cond> break_block
352 // ret_block:
353 // TCRETURN
354 // break_block:
355 // brk <BrkOperand>
356 //
357 // or just
358 //
359 // <authenticate LR>
360 // ldr tmp, [lr]
361 // TCRETURN
362
363 // TmpReg is chosen assuming X16 and X17 are dead after TI.
365 "Tail call is expected");
366 Register TmpReg =
367 TI->readsRegister(AArch64::X16, TRI) ? AArch64::X17 : AArch64::X16;
368 assert(!TI->readsRegister(TmpReg, TRI) &&
369 "More than a single register is used by TCRETURN");
370
371 checkAuthenticatedRegister(TI, Method, AArch64::LR, TmpReg, /*UseIKey=*/true,
372 BrkOperandForKey(KeyId));
373
374 return true;
375}
376
377void AArch64PointerAuth::emitBlend(MachineBasicBlock::iterator MBBI,
378 Register Result, Register AddrDisc,
379 unsigned IntDisc) const {
381 DebugLoc DL = MBBI->getDebugLoc();
382
383 if (Result != AddrDisc)
384 BuildMI(MBB, MBBI, DL, TII->get(AArch64::ORRXrs), Result)
385 .addReg(AArch64::XZR)
386 .addReg(AddrDisc)
387 .addImm(0);
388
389 BuildMI(MBB, MBBI, DL, TII->get(AArch64::MOVKXi), Result)
390 .addReg(Result)
391 .addImm(IntDisc)
392 .addImm(48);
393}
394
395void AArch64PointerAuth::expandPAuthBlend(
397 Register ResultReg = MBBI->getOperand(0).getReg();
398 Register AddrDisc = MBBI->getOperand(1).getReg();
399 unsigned IntDisc = MBBI->getOperand(2).getImm();
400 emitBlend(MBBI, ResultReg, AddrDisc, IntDisc);
401}
402
403bool AArch64PointerAuth::runOnMachineFunction(MachineFunction &MF) {
404 const auto *MFnI = MF.getInfo<AArch64FunctionInfo>();
405
406 Subtarget = &MF.getSubtarget<AArch64Subtarget>();
407 TII = Subtarget->getInstrInfo();
408 TRI = Subtarget->getRegisterInfo();
409
412
413 bool Modified = false;
414 bool HasAuthenticationInstrs = false;
415
416 for (auto &MBB : MF) {
417 // Using instr_iterator to catch unsupported bundled TCRETURN* instructions
418 // instead of just skipping them.
419 for (auto &MI : MBB.instrs()) {
420 switch (MI.getOpcode()) {
421 default:
422 // Bundled TCRETURN* instructions (such as created by KCFI)
423 // are not supported yet, but no support is required if no
424 // PAUTH_EPILOGUE instructions exist in the same function.
425 // Skip the BUNDLE instruction itself (actual bundled instructions
426 // follow it in the instruction list).
427 if (MI.isBundle())
428 continue;
430 TailCallInstrs.push_back(MI.getIterator());
431 break;
432 case AArch64::PAUTH_PROLOGUE:
433 case AArch64::PAUTH_EPILOGUE:
434 case AArch64::PAUTH_BLEND:
435 assert(!MI.isBundled());
436 PAuthPseudoInstrs.push_back(MI.getIterator());
437 break;
438 }
439 }
440 }
441
442 for (auto It : PAuthPseudoInstrs) {
443 switch (It->getOpcode()) {
444 case AArch64::PAUTH_PROLOGUE:
445 signLR(MF, It);
446 break;
447 case AArch64::PAUTH_EPILOGUE:
448 authenticateLR(MF, It);
449 HasAuthenticationInstrs = true;
450 break;
451 case AArch64::PAUTH_BLEND:
452 expandPAuthBlend(It);
453 break;
454 default:
455 llvm_unreachable("Unhandled opcode");
456 }
457 It->eraseFromParent();
458 Modified = true;
459 }
460
461 // FIXME Do we need to emit any PAuth-related epilogue code at all
462 // when SCS is enabled?
463 if (HasAuthenticationInstrs &&
465 for (auto TailCall : TailCallInstrs) {
466 assert(!TailCall->isBundled() && "Not yet supported");
467 Modified |= checkAuthenticatedLR(TailCall);
468 }
469 }
470
471 return Modified;
472}
#define AARCH64_POINTER_AUTH_NAME
static void BuildPACM(const AArch64Subtarget &Subtarget, MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, DebugLoc DL, MachineInstr::MIFlag Flags, MCSymbol *PACSym=nullptr)
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
unsigned const TargetRegisterInfo * TRI
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:38
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 needsAsyncDwarfUnwindInfo(const MachineFunction &MF) 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.
A debug info location.
Definition: DebugLoc.h:33
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:311
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition: Function.cpp:675
static MCCFIInstruction createNegateRAState(MCSymbol *L, SMLoc Loc={})
.cfi_negate_ra_state AArch64 negate RA state.
Definition: MCDwarf.h:609
MCSymbol * createTempSymbol()
Create a temporary symbol with a unique name.
Definition: MCContext.cpp:322
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:40
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...
unsigned addFrameInst(const MCCFIInstruction &Inst)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, 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.
void push_back(MachineBasicBlock *MBB)
Function & getFunction()
Return the LLVM function that this machine code represents.
MachineModuleInfo & getMMI() const
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 & addSym(MCSymbol *Sym, unsigned char TargetFlags=0) const
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
void setPreInstrSymbol(MachineFunction &MF, MCSymbol *Symbol)
Set a symbol that will be emitted just prior to the instruction itself.
A description of a memory reference used in the backend.
@ MOVolatile
The memory access is volatile.
@ MOLoad
The memory access reads data.
const MCContext & getContext() const
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
Definition: Pass.cpp:81
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
void push_back(const T &Elt)
Definition: SmallVector.h:426
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1209
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
TargetInstrInfo - Interface to description of machine instruction set.
#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.
Definition: CallingConv.h:24
@ Define
Register definition.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
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.
Definition: Alignment.h:39
This class contains a discriminated union of information about pointers in memory operands,...