From 03d0b1421e4435d4b3183fefff0374452fc16b87 Mon Sep 17 00:00:00 2001 From: Reid Kleckner <rnk@google.com> Date: Wed, 7 Oct 2015 21:13:15 +0000 Subject: [PATCH] [WinEH] Undo the effect of r249578 for 32-bit The __CxxFrameHandler3 tables for 32-bit are supposed to hold stack offsets relative to EBP, not ESP. I blindly updated the win-catchpad.ll test case, and immediately noticed that 32-bit catching stopped working. While I'm at it, move the frame index to frame offset WinEH table logic out of PEI. PEI shouldn't have to know about WinEHFuncInfo. I realized we can calculate frame index offsets just fine from the table printer. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@249618 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/WinEHFuncInfo.h | 2 -- lib/CodeGen/AsmPrinter/WinException.cpp | 19 ++++++++++++++++--- lib/CodeGen/AsmPrinter/WinException.h | 6 ++++++ lib/CodeGen/PrologEpilogInserter.cpp | 22 ---------------------- test/CodeGen/X86/win-catchpad.ll | 2 +- 5 files changed, 23 insertions(+), 28 deletions(-) diff --git a/include/llvm/CodeGen/WinEHFuncInfo.h b/include/llvm/CodeGen/WinEHFuncInfo.h index 11591a85d28..773931ff7cd 100644 --- a/include/llvm/CodeGen/WinEHFuncInfo.h +++ b/include/llvm/CodeGen/WinEHFuncInfo.h @@ -147,7 +147,6 @@ struct WinEHHandlerType { /// index, and after PEI, becomes a raw offset. union { const AllocaInst *Alloca; - int FrameOffset; int FrameIndex; } CatchObj = {}; GlobalVariable *TypeDescriptor; @@ -180,7 +179,6 @@ struct WinEHFuncInfo { SmallVector<SEHUnwindMapEntry, 4> SEHUnwindMap; SmallVector<ClrEHUnwindMapEntry, 4> ClrEHUnwindMap; int UnwindHelpFrameIdx = INT_MAX; - int UnwindHelpFrameOffset = -1; int getLastStateNumber() const { return UnwindMap.size() - 1; } diff --git a/lib/CodeGen/AsmPrinter/WinException.cpp b/lib/CodeGen/AsmPrinter/WinException.cpp index bc2c9ee635c..f672f93a3ee 100644 --- a/lib/CodeGen/AsmPrinter/WinException.cpp +++ b/lib/CodeGen/AsmPrinter/WinException.cpp @@ -38,6 +38,7 @@ #include "llvm/Target/TargetLoweringObjectFile.h" #include "llvm/Target/TargetOptions.h" #include "llvm/Target/TargetRegisterInfo.h" +#include "llvm/Target/TargetSubtargetInfo.h" using namespace llvm; WinException::WinException(AsmPrinter *A) : EHStreamer(A) { @@ -292,6 +293,14 @@ const MCExpr *WinException::getLabelPlusOne(MCSymbol *Label) { Asm->OutContext); } +int WinException::getFrameIndexOffset(int FrameIndex) { + const TargetFrameLowering &TFI = *Asm->MF->getSubtarget().getFrameLowering(); + unsigned UnusedReg; + if (Asm->MAI->usesWindowsCFI()) + return TFI.getFrameIndexReferenceFromSP(*Asm->MF, FrameIndex, UnusedReg); + return TFI.getFrameIndexReference(*Asm->MF, FrameIndex, UnusedReg); +} + namespace { /// Information describing an invoke range. struct InvokeRange { @@ -599,6 +608,10 @@ void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) { emitEHRegistrationOffsetLabel(FuncInfo, FuncLinkageName); } + int UnwindHelpOffset = 0; + if (Asm->MAI->usesWindowsCFI()) + UnwindHelpOffset = getFrameIndexOffset(FuncInfo.UnwindHelpFrameIdx); + MCSymbol *UnwindMapXData = nullptr; MCSymbol *TryBlockMapXData = nullptr; MCSymbol *IPToStateXData = nullptr; @@ -637,7 +650,7 @@ void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) { OS.EmitIntValue(IPToStateTable.size(), 4); // IPMapEntries OS.EmitValue(create32bitRef(IPToStateXData), 4); // IPToStateMap if (Asm->MAI->usesWindowsCFI()) - OS.EmitIntValue(FuncInfo.UnwindHelpFrameOffset, 4); // UnwindHelp + OS.EmitIntValue(UnwindHelpOffset, 4); // UnwindHelp OS.EmitIntValue(0, 4); // ESTypeList OS.EmitIntValue(1, 4); // EHFlags @@ -714,8 +727,8 @@ void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) { FuncLinkageName, HT.CatchObjRecoverIdx); FrameAllocOffsetRef = MCSymbolRefExpr::create( FrameAllocOffset, MCSymbolRefExpr::VK_None, Asm->OutContext); - } else if (HT.CatchObj.FrameOffset != INT_MAX) { - int Offset = HT.CatchObj.FrameOffset; + } else if (HT.CatchObj.FrameIndex != INT_MAX) { + int Offset = getFrameIndexOffset(HT.CatchObj.FrameIndex); // For 32-bit, the catch object offset is relative to the end of the // EH registration node. For 64-bit, it's relative to SP at the end of // the prologue. diff --git a/lib/CodeGen/AsmPrinter/WinException.h b/lib/CodeGen/AsmPrinter/WinException.h index bf1724f60f7..5c853349d2e 100644 --- a/lib/CodeGen/AsmPrinter/WinException.h +++ b/lib/CodeGen/AsmPrinter/WinException.h @@ -63,6 +63,12 @@ class LLVM_LIBRARY_VISIBILITY WinException : public EHStreamer { const MCExpr *create32bitRef(const Value *V); const MCExpr *getLabelPlusOne(MCSymbol *Label); + /// Gets the offset that we should use in a table for a stack object with the + /// given index. For targets using CFI (Win64, etc), this is relative to the + /// established SP at the end of the prologue. For targets without CFI (Win32 + /// only), it is relative to the frame pointer. + int getFrameIndexOffset(int FrameIndex); + public: //===--------------------------------------------------------------------===// // Main entry points. diff --git a/lib/CodeGen/PrologEpilogInserter.cpp b/lib/CodeGen/PrologEpilogInserter.cpp index 495da5c07d1..fab56bcfe85 100644 --- a/lib/CodeGen/PrologEpilogInserter.cpp +++ b/lib/CodeGen/PrologEpilogInserter.cpp @@ -807,28 +807,6 @@ void PEI::replaceFrameIndices(MachineFunction &Fn) { const TargetFrameLowering &TFI = *Fn.getSubtarget().getFrameLowering(); if (!TFI.needsFrameIndexResolution(Fn)) return; - MachineModuleInfo &MMI = Fn.getMMI(); - const Function *F = Fn.getFunction(); - const Function *ParentF = MMI.getWinEHParent(F); - unsigned FrameReg; - if (F == ParentF) { - WinEHFuncInfo &FuncInfo = MMI.getWinEHFuncInfo(Fn.getFunction()); - // FIXME: This should be unconditional but we have bugs in the preparation - // pass. - if (FuncInfo.UnwindHelpFrameIdx != INT_MAX) - FuncInfo.UnwindHelpFrameOffset = TFI.getFrameIndexReferenceFromSP( - Fn, FuncInfo.UnwindHelpFrameIdx, FrameReg); - for (WinEHTryBlockMapEntry &TBME : FuncInfo.TryBlockMap) { - for (WinEHHandlerType &H : TBME.HandlerArray) { - if (H.CatchObj.FrameIndex == INT_MAX) - H.CatchObj.FrameOffset = INT_MAX; - else - H.CatchObj.FrameOffset = TFI.getFrameIndexReferenceFromSP( - Fn, H.CatchObj.FrameIndex, FrameReg); - } - } - } - // Store SPAdj at exit of a basic block. SmallVector<int, 8> SPState; SPState.resize(Fn.getNumBlockIDs()); diff --git a/test/CodeGen/X86/win-catchpad.ll b/test/CodeGen/X86/win-catchpad.ll index 67875f23060..78a8fcfc8f4 100644 --- a/test/CodeGen/X86/win-catchpad.ll +++ b/test/CodeGen/X86/win-catchpad.ll @@ -120,7 +120,7 @@ catchendblock: ; preds = %catch, %catch.2, %c ; X86: $handlerMap$0$try_catch_catch: ; X86-NEXT: .long 0 ; X86-NEXT: .long "??_R0H@8" -; X86-NEXT: .long 24 +; X86-NEXT: .long -20 ; X86-NEXT: .long "?catch$[[catch1bb]]@?0?try_catch_catch@4HA" ; X86-NEXT: .long 64 ; X86-NEXT: .long 0 -- 2.34.1