Skip to content

Commit b717568

Browse files
authored
[AArch64] Fix the emission of WinCFI for pac-ret+leaf and SCS (#147518)
This commit fixes WinCFI opcodes being incorrectly emitted for test cases in sign-return-address.ll. Emit SEH_Nop opcode in emitShadowCallStackEpilogue the same way it is done in emitShadowCallStackPrologue function - this fixes 12 bytes of instructions in range, but .seh directives corresponding to 8 bytes error being reported for the epilogue of non_leaf_scs function. Emit SEH_PrologEnd on the code path in emitPrologue function that may be taken when pac-ret protection is emitted for a leaf function - this fixes errors like the following: starting epilogue (.seh_startepilogue) before prologue has ended (.seh_endprologue) in leaf_sign_all_v83 Stray .seh_endepilogue in leaf_sign_all_v83
1 parent 007fc77 commit b717568

File tree

2 files changed

+773
-285
lines changed

2 files changed

+773
-285
lines changed

llvm/lib/Target/AArch64/AArch64FrameLowering.cpp

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1746,7 +1746,7 @@ static void emitShadowCallStackEpilogue(const TargetInstrInfo &TII,
17461746
MachineFunction &MF,
17471747
MachineBasicBlock &MBB,
17481748
MachineBasicBlock::iterator MBBI,
1749-
const DebugLoc &DL) {
1749+
const DebugLoc &DL, bool NeedsWinCFI) {
17501750
// Shadow call stack epilog: ldr x30, [x18, #-8]!
17511751
BuildMI(MBB, MBBI, DL, TII.get(AArch64::LDRXpre))
17521752
.addReg(AArch64::X18, RegState::Define)
@@ -1755,6 +1755,10 @@ static void emitShadowCallStackEpilogue(const TargetInstrInfo &TII,
17551755
.addImm(-8)
17561756
.setMIFlag(MachineInstr::FrameDestroy);
17571757

1758+
if (NeedsWinCFI)
1759+
BuildMI(MBB, MBBI, DL, TII.get(AArch64::SEH_Nop))
1760+
.setMIFlag(MachineInstr::FrameDestroy);
1761+
17581762
if (MF.getInfo<AArch64FunctionInfo>()->needsAsyncDwarfUnwindInfo(MF))
17591763
CFIInstBuilder(MBB, MBBI, MachineInstr::FrameDestroy)
17601764
.buildRestore(AArch64::X18);
@@ -1899,13 +1903,15 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
18991903
BuildMI(MBB, MBBI, DL, TII->get(AArch64::PAUTH_PROLOGUE))
19001904
.setMIFlag(MachineInstr::FrameSetup);
19011905
}
1902-
if (NeedsWinCFI)
1903-
HasWinCFI = true; // AArch64PointerAuth pass will insert SEH_PACSignLR
1906+
// AArch64PointerAuth pass will insert SEH_PACSignLR
1907+
HasWinCFI |= NeedsWinCFI;
19041908
}
19051909

1906-
if (MFnI.needsShadowCallStackPrologueEpilogue(MF))
1910+
if (MFnI.needsShadowCallStackPrologueEpilogue(MF)) {
19071911
emitShadowCallStackPrologue(*TII, MF, MBB, MBBI, DL, NeedsWinCFI,
19081912
MFnI.needsDwarfUnwindInfo(MF));
1913+
HasWinCFI |= NeedsWinCFI;
1914+
}
19091915

19101916
if (EmitCFI && MFnI.isMTETagged()) {
19111917
BuildMI(MBB, MBBI, DL, TII->get(AArch64::EMITMTETAGGED))
@@ -1990,8 +1996,13 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
19901996
"unexpected function without stack frame but with SVE objects");
19911997
// All of the stack allocation is for locals.
19921998
AFI->setLocalStackSize(NumBytes);
1993-
if (!NumBytes)
1999+
if (!NumBytes) {
2000+
if (NeedsWinCFI && HasWinCFI) {
2001+
BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_PrologEnd))
2002+
.setMIFlag(MachineInstr::FrameSetup);
2003+
}
19942004
return;
2005+
}
19952006
// REDZONE: If the stack size is less than 128 bytes, we don't need
19962007
// to actually allocate.
19972008
if (canUseRedZone(MF)) {
@@ -2460,8 +2471,11 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
24602471
MachineBasicBlock::iterator EpilogStartI = MBB.end();
24612472

24622473
auto FinishingTouches = make_scope_exit([&]() {
2463-
if (AFI->needsShadowCallStackPrologueEpilogue(MF))
2464-
emitShadowCallStackEpilogue(*TII, MF, MBB, MBB.getFirstTerminator(), DL);
2474+
if (AFI->needsShadowCallStackPrologueEpilogue(MF)) {
2475+
emitShadowCallStackEpilogue(*TII, MF, MBB, MBB.getFirstTerminator(), DL,
2476+
NeedsWinCFI);
2477+
HasWinCFI |= NeedsWinCFI;
2478+
}
24652479
if (EmitCFI)
24662480
emitCalleeSavedGPRRestores(MBB, MBB.getFirstTerminator());
24672481
if (AFI->shouldSignReturnAddress(MF)) {
@@ -2472,8 +2486,8 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
24722486
TII->get(AArch64::PAUTH_EPILOGUE))
24732487
.setMIFlag(MachineInstr::FrameDestroy);
24742488
}
2475-
if (NeedsWinCFI)
2476-
HasWinCFI = true; // AArch64PointerAuth pass will insert SEH_PACSignLR
2489+
// AArch64PointerAuth pass will insert SEH_PACSignLR
2490+
HasWinCFI |= NeedsWinCFI;
24772491
}
24782492
if (HasWinCFI) {
24792493
BuildMI(MBB, MBB.getFirstTerminator(), DL,

0 commit comments

Comments
 (0)