[llvm] [AArch64] Codegen for AArch64 Return Address Signing Hardening (PR #176187)
Anatoly Trosinenko via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 9 09:50:23 PDT 2026
================
@@ -548,6 +563,99 @@ bool AArch64PointerAuthImpl::run(MachineFunction &MF) {
Modified = true;
}
+ Modified |= emitSignReturnAddressHardening(MF);
+
+ return Modified;
+}
+
+bool AArch64PointerAuthImpl::emitSignReturnAddressHardening(
+ MachineFunction &MF) {
+ const auto *FI = MF.getInfo<AArch64FunctionInfo>();
+ assert(FI && "FI can't be null");
+ if (!FI->shouldSignReturnAddress(MF) || !FI->shouldHardenSignReturnAddress())
+ return false;
+ assert(Subtarget && "Subtarget must be initialized");
+
+ RegScavenger RS;
+ bool Modified = false;
+ for (MachineBasicBlock &MBB : MF) {
+ MachineBasicBlock::iterator RetInstIter = MBB.getFirstTerminator();
+
+ if (RetInstIter == MBB.end() || RetInstIter->getOpcode() != AArch64::RET)
+ continue;
+
+ assert(RetInstIter->getOperand(0).getReg() == AArch64::LR &&
+ "Return instruction must be returning via LR");
+
+ MachineBasicBlock::iterator InsertionPoint = RetInstIter;
+ // In the case of Windows SEH, the hardening sequence does not immediately
+ // precede the return instruction. Instead, it precedes the SEH_EpilogEnd
+ // pseudo-instruction, which itself is expected to be the predecessor of
+ // the return. Plus, each instruction in the sequence needs one SEH_Nop.
+ const bool NeedsWinCFI = MF.hasWinCFI();
+ if (NeedsWinCFI) {
+ --InsertionPoint;
+ assert(InsertionPoint->getOpcode() == AArch64::SEH_EpilogEnd);
+ }
+ DebugLoc DL = InsertionPoint->getDebugLoc();
+ const auto emitSEHNopIfRequired = [&, NeedsWinCFI]() {
+ if (NeedsWinCFI)
+ BuildMI(MBB, InsertionPoint, DL, TII->get(AArch64::SEH_Nop))
+ .setMIFlag(MachineInstr::FrameDestroy);
+ };
+
+ RS.enterBasicBlockEnd(MBB);
+ Register XReg = RS.scavengeRegisterBackwards(
+ AArch64::GPR64RegClass, InsertionPoint,
+ /*RestoreAfter=*/false, /*SPAdj=*/0, /*AllowSpill=*/false);
+ if (XReg == AArch64::NoRegister)
+ // Couldn't find a free register to use for the hardening. Skip.
+ continue;
----------------
atrosinenko wrote:
It is probably reasonable to show a warning message to the user. Something along these lines seems to work in the backend:
```cpp
MF.getContext().reportWarning(SMLoc(), "harden-pac-ret failed for function " + MF.getName());
```
https://github.com/llvm/llvm-project/pull/176187
More information about the llvm-commits
mailing list