diff --git a/llvm/lib/Target/AArch64/AArch64BranchTargets.cpp b/llvm/lib/Target/AArch64/AArch64BranchTargets.cpp --- a/llvm/lib/Target/AArch64/AArch64BranchTargets.cpp +++ b/llvm/lib/Target/AArch64/AArch64BranchTargets.cpp @@ -39,7 +39,8 @@ StringRef getPassName() const override { return AARCH64_BRANCH_TARGETS_NAME; } private: - void addBTI(MachineBasicBlock &MBB, bool CouldCall, bool CouldJump); + void addBTI(MachineBasicBlock &MBB, bool CouldCall, bool CouldJump, + bool NeedsWinCFI); }; } // end anonymous namespace @@ -75,6 +76,7 @@ JumpTableTargets.insert(MBB); bool MadeChange = false; + bool HasWinCFI = MF.hasWinCFI(); for (MachineBasicBlock &MBB : MF) { bool CouldCall = false, CouldJump = false; // Even in cases where a function has internal linkage and is only called @@ -95,7 +97,7 @@ CouldJump = true; if (CouldCall || CouldJump) { - addBTI(MBB, CouldCall, CouldJump); + addBTI(MBB, CouldCall, CouldJump, HasWinCFI); MadeChange = true; } } @@ -104,7 +106,7 @@ } void AArch64BranchTargets::addBTI(MachineBasicBlock &MBB, bool CouldCall, - bool CouldJump) { + bool CouldJump, bool HasWinCFI) { LLVM_DEBUG(dbgs() << "Adding BTI " << (CouldJump ? "j" : "") << (CouldCall ? "c" : "") << " to " << MBB.getName() << "\n"); @@ -134,6 +136,10 @@ MBBI->getOpcode() == AArch64::PACIBSP)) return; + if (HasWinCFI && MBBI->getFlag(MachineInstr::FrameSetup)) { + BuildMI(MBB, MBB.begin(), MBB.findDebugLoc(MBB.begin()), + TII->get(AArch64::SEH_Nop)); + } BuildMI(MBB, MBB.begin(), MBB.findDebugLoc(MBB.begin()), TII->get(AArch64::HINT)) .addImm(HintNum); diff --git a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp --- a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp @@ -1409,6 +1409,7 @@ if (MFnI.shouldSignWithBKey()) { BuildMI(MBB, MBBI, DL, TII->get(AArch64::EMITBKEY)) .setMIFlag(MachineInstr::FrameSetup); + // No SEH_Nop for this one PACI = Subtarget.hasPAuth() ? AArch64::PACIB : AArch64::PACIBSP; } else { PACI = Subtarget.hasPAuth() ? AArch64::PACIA : AArch64::PACIASP; @@ -1426,11 +1427,20 @@ BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION)) .addCFIIndex(CFIIndex) .setMIFlags(MachineInstr::FrameSetup); + } else if (NeedsWinCFI) { + HasWinCFI = true; + BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_Nop)) + .setMIFlag(MachineInstr::FrameSetup); } } if (EmitCFI && MFnI.isMTETagged()) { BuildMI(MBB, MBBI, DL, TII->get(AArch64::EMITMTETAGGED)) .setMIFlag(MachineInstr::FrameSetup); + if (NeedsWinCFI) { + HasWinCFI = true; + BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_Nop)) + .setMIFlag(MachineInstr::FrameSetup); + } } // We signal the presence of a Swift extended frame to external tools by @@ -1847,7 +1857,8 @@ } static void InsertReturnAddressAuth(MachineFunction &MF, - MachineBasicBlock &MBB) { + MachineBasicBlock &MBB, bool NeedsWinCFI, + bool *HasWinCFI) { const auto &MFI = *MF.getInfo(); if (!MFI.shouldSignReturnAddress()) return; @@ -1870,6 +1881,11 @@ BuildMI(MBB, MBBI, DL, TII->get(MFI.shouldSignWithBKey() ? AArch64::RETAB : AArch64::RETAA)) .copyImplicitOps(*MBBI); + if (NeedsWinCFI) { + *HasWinCFI = true; + BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_Nop)) + .setMIFlag(MachineInstr::FrameSetup); + } MBB.erase(MBBI); } else { BuildMI( @@ -1882,6 +1898,11 @@ BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION)) .addCFIIndex(CFIIndex) .setMIFlags(MachineInstr::FrameDestroy); + if (NeedsWinCFI) { + *HasWinCFI = true; + BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_Nop)) + .setMIFlag(MachineInstr::FrameSetup); + } } } @@ -1914,11 +1935,14 @@ } auto FinishingTouches = make_scope_exit([&]() { - InsertReturnAddressAuth(MF, MBB); + InsertReturnAddressAuth(MF, MBB, NeedsWinCFI, &HasWinCFI); if (needsShadowCallStackPrologueEpilogue(MF)) emitShadowCallStackEpilogue(*TII, MF, MBB, MBB.getFirstTerminator(), DL); if (EmitCFI) emitCalleeSavedGPRRestores(MBB, MBB.getFirstTerminator()); + if (HasWinCFI) + BuildMI(MBB, MBB.getFirstTerminator(), DL, TII->get(AArch64::SEH_EpilogEnd)) + .setMIFlag(MachineInstr::FrameDestroy); }); int64_t NumBytes = IsFunclet ? getWinEHFuncletFrameSize(MF) @@ -2066,10 +2090,6 @@ StackOffset::getFixed(NumBytes + (int64_t)AfterCSRPopSize), TII, MachineInstr::FrameDestroy, false, NeedsWinCFI, &HasWinCFI, EmitCFI, StackOffset::getFixed(NumBytes)); - if (HasWinCFI) - BuildMI(MBB, MBB.getFirstTerminator(), DL, - TII->get(AArch64::SEH_EpilogEnd)) - .setMIFlag(MachineInstr::FrameDestroy); return; } @@ -2162,11 +2182,6 @@ // If we were able to combine the local stack pop with the argument pop, // then we're done. if (NoCalleeSaveRestore || AfterCSRPopSize == 0) { - if (HasWinCFI) { - BuildMI(MBB, MBB.getFirstTerminator(), DL, - TII->get(AArch64::SEH_EpilogEnd)) - .setMIFlag(MachineInstr::FrameDestroy); - } return; } @@ -2211,9 +2226,6 @@ false, NeedsWinCFI, &HasWinCFI, EmitCFI, StackOffset::getFixed(CombineAfterCSRBump ? PrologueSaveSize : 0)); } - if (HasWinCFI) - BuildMI(MBB, MBB.getFirstTerminator(), DL, TII->get(AArch64::SEH_EpilogEnd)) - .setMIFlag(MachineInstr::FrameDestroy); } /// getFrameIndexReference - Provide a base+offset reference to an FI slot for