Skip to content

Commit ef5d3b9

Browse files
committed
[AArch64] Fix the emission of WinCFI for pac-ret+leaf and SCS
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 bedd7dd commit ef5d3b9

File tree

2 files changed

+28
-9
lines changed

2 files changed

+28
-9
lines changed

llvm/lib/Target/AArch64/AArch64FrameLowering.cpp

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1673,7 +1673,7 @@ static void emitShadowCallStackEpilogue(const TargetInstrInfo &TII,
16731673
MachineFunction &MF,
16741674
MachineBasicBlock &MBB,
16751675
MachineBasicBlock::iterator MBBI,
1676-
const DebugLoc &DL) {
1676+
const DebugLoc &DL, bool NeedsWinCFI) {
16771677
// Shadow call stack epilog: ldr x30, [x18, #-8]!
16781678
BuildMI(MBB, MBBI, DL, TII.get(AArch64::LDRXpre))
16791679
.addReg(AArch64::X18, RegState::Define)
@@ -1682,6 +1682,10 @@ static void emitShadowCallStackEpilogue(const TargetInstrInfo &TII,
16821682
.addImm(-8)
16831683
.setMIFlag(MachineInstr::FrameDestroy);
16841684

1685+
if (NeedsWinCFI)
1686+
BuildMI(MBB, MBBI, DL, TII.get(AArch64::SEH_Nop))
1687+
.setMIFlag(MachineInstr::FrameDestroy);
1688+
16851689
if (MF.getInfo<AArch64FunctionInfo>()->needsAsyncDwarfUnwindInfo(MF))
16861690
CFIInstBuilder(MBB, MBBI, MachineInstr::FrameDestroy)
16871691
.buildRestore(AArch64::X18);
@@ -1786,15 +1790,17 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
17861790
DebugLoc DL;
17871791

17881792
const auto &MFnI = *MF.getInfo<AArch64FunctionInfo>();
1789-
if (MFnI.needsShadowCallStackPrologueEpilogue(MF))
1793+
if (MFnI.needsShadowCallStackPrologueEpilogue(MF)) {
17901794
emitShadowCallStackPrologue(*TII, MF, MBB, MBBI, DL, NeedsWinCFI,
17911795
MFnI.needsDwarfUnwindInfo(MF));
1796+
HasWinCFI |= NeedsWinCFI;
1797+
}
17921798

17931799
if (MFnI.shouldSignReturnAddress(MF)) {
17941800
BuildMI(MBB, MBBI, DL, TII->get(AArch64::PAUTH_PROLOGUE))
17951801
.setMIFlag(MachineInstr::FrameSetup);
1796-
if (NeedsWinCFI)
1797-
HasWinCFI = true; // AArch64PointerAuth pass will insert SEH_PACSignLR
1802+
// AArch64PointerAuth pass will insert SEH_PACSignLR
1803+
HasWinCFI |= NeedsWinCFI;
17981804
}
17991805

18001806
if (EmitCFI && MFnI.isMTETagged()) {
@@ -1880,8 +1886,13 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
18801886
"unexpected function without stack frame but with SVE objects");
18811887
// All of the stack allocation is for locals.
18821888
AFI->setLocalStackSize(NumBytes);
1883-
if (!NumBytes)
1889+
if (!NumBytes) {
1890+
if (NeedsWinCFI && HasWinCFI) {
1891+
BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_PrologEnd))
1892+
.setMIFlag(MachineInstr::FrameSetup);
1893+
}
18841894
return;
1895+
}
18851896
// REDZONE: If the stack size is less than 128 bytes, we don't need
18861897
// to actually allocate.
18871898
if (canUseRedZone(MF)) {
@@ -2354,11 +2365,14 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
23542365
BuildMI(MBB, MBB.getFirstTerminator(), DL,
23552366
TII->get(AArch64::PAUTH_EPILOGUE))
23562367
.setMIFlag(MachineInstr::FrameDestroy);
2357-
if (NeedsWinCFI)
2358-
HasWinCFI = true; // AArch64PointerAuth pass will insert SEH_PACSignLR
2368+
// AArch64PointerAuth pass will insert SEH_PACSignLR
2369+
HasWinCFI |= NeedsWinCFI;
2370+
}
2371+
if (AFI->needsShadowCallStackPrologueEpilogue(MF)) {
2372+
emitShadowCallStackEpilogue(*TII, MF, MBB, MBB.getFirstTerminator(), DL,
2373+
NeedsWinCFI);
2374+
HasWinCFI |= NeedsWinCFI;
23592375
}
2360-
if (AFI->needsShadowCallStackPrologueEpilogue(MF))
2361-
emitShadowCallStackEpilogue(*TII, MF, MBB, MBB.getFirstTerminator(), DL);
23622376
if (EmitCFI)
23632377
emitCalleeSavedGPRRestores(MBB, MBB.getFirstTerminator());
23642378
if (HasWinCFI) {

llvm/test/CodeGen/AArch64/sign-return-address.ll

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@
55
; v9.5-A is not expected to change codegen without -mbranch-protection=+pc, so reuse V83A.
66
; RUN: llc -mtriple=aarch64 -mattr=v9.5a < %s | FileCheck --check-prefixes=CHECK,V83A %s
77

8+
; Make sure no errors are detected when emitting SEH opcodes.
9+
; Errors are only checked for when generating a binary, so emit a dummy object
10+
; file and make sure llc produces zero exit code.
11+
; RUN: llc -mtriple=aarch64-windows -o %t.dummy.o --filetype=obj < %s
12+
813
define i32 @leaf(i32 %x) {
914
; CHECK-LABEL: leaf:
1015
; CHECK: // %bb.0:

0 commit comments

Comments
 (0)