diff options
Diffstat (limited to 'llvm/lib/CodeGen/AsmPrinter/WinException.cpp')
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/WinException.cpp | 52 |
1 files changed, 39 insertions, 13 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/WinException.cpp b/llvm/lib/CodeGen/AsmPrinter/WinException.cpp index aedac5467c6..e706d73dee2 100644 --- a/llvm/lib/CodeGen/AsmPrinter/WinException.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/WinException.cpp @@ -161,7 +161,7 @@ void WinException::endFunction(const MachineFunction *MF) { // Emit the tables appropriate to the personality function in use. If we // don't recognize the personality, assume it uses an Itanium-style LSDA. if (Per == EHPersonality::MSVC_Win64SEH) - emitCSpecificHandlerTable(); + emitCSpecificHandlerTable(MF); else if (Per == EHPersonality::MSVC_X86SEH) emitExceptHandlerTable(MF); else if (Per == EHPersonality::MSVC_CXX) @@ -222,9 +222,13 @@ const MCExpr *WinException::create32bitRef(const Value *V) { /// imagerel32 LabelLPad; // Zero means __finally. /// } Entries[NumEntries]; /// }; -void WinException::emitCSpecificHandlerTable() { +void WinException::emitCSpecificHandlerTable(const MachineFunction *MF) { const std::vector<LandingPadInfo> &PadInfos = MMI->getLandingPads(); + WinEHFuncInfo &FuncInfo = MMI->getWinEHFuncInfo(MF->getFunction()); + if (!FuncInfo.SEHUnwindMap.empty()) + report_fatal_error("x64 SEH tables not yet implemented"); + // Simplifying assumptions for first implementation: // - Cleanups are not implemented. // - Filters are not implemented. @@ -309,6 +313,15 @@ void WinException::emitCSpecificHandlerTable() { } } +/// Retreive the MCSymbol for a GlobalValue or MachineBasicBlock. GlobalValues +/// are used in the old WinEH scheme, and they will be removed eventually. +static MCSymbol *getMCSymbolForMBBOrGV(AsmPrinter *Asm, ValueOrMBB Handler) { + if (Handler.is<MachineBasicBlock *>()) + return Handler.get<MachineBasicBlock *>()->getSymbol(); + else + return Asm->getSymbol(cast<GlobalValue>(Handler.get<const Value *>())); +} + void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) { const Function *F = MF->getFunction(); const Function *ParentF = MMI->getWinEHParent(F); @@ -422,9 +435,9 @@ void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) { int CatchHigh = TBME.CatchHigh; if (CatchHigh == -1) { for (WinEHHandlerType &HT : TBME.HandlerArray) - CatchHigh = std::max( - CatchHigh, - FuncInfo.CatchHandlerMaxState[cast<Function>(HT.Handler)]); + CatchHigh = + std::max(CatchHigh, FuncInfo.CatchHandlerMaxState[cast<Function>( + HT.Handler.get<const Value *>())]); } assert(TBME.TryLow <= TBME.TryHigh); @@ -464,13 +477,12 @@ void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) { FrameAllocOffsetRef = MCConstantExpr::create(0, Asm->OutContext); } - OS.EmitIntValue(HT.Adjectives, 4); // Adjectives - OS.EmitValue(create32bitRef(HT.TypeDescriptor), 4); // Type - OS.EmitValue(FrameAllocOffsetRef, 4); // CatchObjOffset - if (HT.HandlerMBB) // Handler - OS.EmitValue(create32bitRef(HT.HandlerMBB->getSymbol()), 4); - else - OS.EmitValue(create32bitRef(HT.Handler), 4); + MCSymbol *HandlerSym = getMCSymbolForMBBOrGV(Asm, HT.Handler); + + OS.EmitIntValue(HT.Adjectives, 4); // Adjectives + OS.EmitValue(create32bitRef(HT.TypeDescriptor), 4); // Type + OS.EmitValue(FrameAllocOffsetRef, 4); // CatchObjOffset + OS.EmitValue(create32bitRef(HandlerSym), 4); // Handler if (shouldEmitPersonality) { if (FuncInfo.CatchHandlerParentFrameObjOffset.empty()) { @@ -482,7 +494,8 @@ void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) { } else { MCSymbol *ParentFrameOffset = Asm->OutContext.getOrCreateParentFrameOffsetSymbol( - GlobalValue::getRealLinkageName(HT.Handler->getName())); + GlobalValue::getRealLinkageName( + HT.Handler.get<const Value *>()->getName())); const MCSymbolRefExpr *ParentFrameOffsetRef = MCSymbolRefExpr::create(ParentFrameOffset, Asm->OutContext); OS.EmitValue(ParentFrameOffsetRef, 4); // ParentFrameOffset @@ -642,6 +655,19 @@ void WinException::emitExceptHandlerTable(const MachineFunction *MF) { BaseState = -2; } + if (!FuncInfo.SEHUnwindMap.empty()) { + for (SEHUnwindMapEntry &UME : FuncInfo.SEHUnwindMap) { + MCSymbol *ExceptOrFinally = + UME.Handler.get<MachineBasicBlock *>()->getSymbol(); + OS.EmitIntValue(UME.ToState, 4); // ToState + OS.EmitValue(create32bitRef(UME.Filter), 4); // Filter + OS.EmitValue(create32bitRef(ExceptOrFinally), 4); // Except/Finally + } + return; + } + // FIXME: The following code is for the old landingpad-based SEH + // implementation. Remove it when possible. + // Build a list of pointers to LandingPadInfos and then sort by WinEHState. const std::vector<LandingPadInfo> &PadInfos = MMI->getLandingPads(); SmallVector<const LandingPadInfo *, 4> LPads; |