diff options
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/WinException.cpp | 76 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/WinException.h | 3 |
2 files changed, 51 insertions, 28 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/WinException.cpp b/llvm/lib/CodeGen/AsmPrinter/WinException.cpp index 5661a378c30..56a8b844ca5 100644 --- a/llvm/lib/CodeGen/AsmPrinter/WinException.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/WinException.cpp @@ -418,7 +418,7 @@ invoke_ranges(WinEHFuncInfo &EHInfo, const MachineBasicBlock &MBB) { /// imagerel32 LabelStart; /// imagerel32 LabelEnd; /// imagerel32 FilterOrFinally; // One means catch-all. -/// imagerel32 LabelLPad; // Zero means __finally. +/// imagerel32 ExceptOrNull; // Zero means __finally. /// } Entries[NumEntries]; /// }; void WinException::emitCSpecificHandlerTable(const MachineFunction *MF) { @@ -469,39 +469,20 @@ void WinException::emitCSpecificHandlerTable(const MachineFunction *MF) { // If this invoke ends a previous one, emit all the actions for this // state. - if (LastEHState != -1) { - assert(LastBeginLabel && LastEndLabel); - for (int State = LastEHState; State != -1;) { - SEHUnwindMapEntry &UME = FuncInfo.SEHUnwindMap[State]; - const MCExpr *FilterOrFinally; - const MCExpr *ExceptOrNull; - auto *Handler = UME.Handler.get<MachineBasicBlock *>(); - if (UME.IsFinally) { - FilterOrFinally = - create32bitRef(getMCSymbolForMBBOrGV(Asm, Handler)); - ExceptOrNull = MCConstantExpr::create(0, Ctx); - } else { - // For an except, the filter can be 1 (catch-all) or a function - // label. - FilterOrFinally = UME.Filter ? create32bitRef(UME.Filter) - : MCConstantExpr::create(1, Ctx); - ExceptOrNull = create32bitRef(Handler->getSymbol()); - } - - OS.EmitValue(getLabelPlusOne(LastBeginLabel), 4); - OS.EmitValue(getLabelPlusOne(LastEndLabel), 4); - OS.EmitValue(FilterOrFinally, 4); - OS.EmitValue(ExceptOrNull, 4); - - State = UME.ToState; - } - } + if (LastEHState != -1) + emitSEHActionsForRange(FuncInfo, LastBeginLabel, LastEndLabel, + LastEHState); LastBeginLabel = I.BeginLabel; LastEndLabel = I.EndLabel; LastEHState = I.State; } } + + if (LastEndLabel) + emitSEHActionsForRange(FuncInfo, LastBeginLabel, LastEndLabel, + LastEHState); + OS.EmitLabel(TableEnd); return; } @@ -589,6 +570,45 @@ void WinException::emitCSpecificHandlerTable(const MachineFunction *MF) { } } +void WinException::emitSEHActionsForRange(WinEHFuncInfo &FuncInfo, + MCSymbol *BeginLabel, + MCSymbol *EndLabel, int State) { + auto &OS = *Asm->OutStreamer; + MCContext &Ctx = Asm->OutContext; + + assert(BeginLabel && EndLabel); + while (State != -1) { + // struct Entry { + // imagerel32 LabelStart; + // imagerel32 LabelEnd; + // imagerel32 FilterOrFinally; // One means catch-all. + // imagerel32 ExceptOrNull; // Zero means __finally. + // }; + SEHUnwindMapEntry &UME = FuncInfo.SEHUnwindMap[State]; + const MCExpr *FilterOrFinally; + const MCExpr *ExceptOrNull; + auto *Handler = UME.Handler.get<MachineBasicBlock *>(); + if (UME.IsFinally) { + FilterOrFinally = create32bitRef(getMCSymbolForMBBOrGV(Asm, Handler)); + ExceptOrNull = MCConstantExpr::create(0, Ctx); + } else { + // For an except, the filter can be 1 (catch-all) or a function + // label. + FilterOrFinally = UME.Filter ? create32bitRef(UME.Filter) + : MCConstantExpr::create(1, Ctx); + ExceptOrNull = create32bitRef(Handler->getSymbol()); + } + + OS.EmitValue(getLabelPlusOne(BeginLabel), 4); + OS.EmitValue(getLabelPlusOne(EndLabel), 4); + OS.EmitValue(FilterOrFinally, 4); + OS.EmitValue(ExceptOrNull, 4); + + assert(UME.ToState < State && "states should decrease"); + State = UME.ToState; + } +} + void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) { const Function *F = MF->getFunction(); auto &OS = *Asm->OutStreamer; diff --git a/llvm/lib/CodeGen/AsmPrinter/WinException.h b/llvm/lib/CodeGen/AsmPrinter/WinException.h index 5c853349d2e..ded00d5cf39 100644 --- a/llvm/lib/CodeGen/AsmPrinter/WinException.h +++ b/llvm/lib/CodeGen/AsmPrinter/WinException.h @@ -41,6 +41,9 @@ class LLVM_LIBRARY_VISIBILITY WinException : public EHStreamer { void emitCSpecificHandlerTable(const MachineFunction *MF); + void emitSEHActionsForRange(WinEHFuncInfo &FuncInfo, MCSymbol *BeginLabel, + MCSymbol *EndLabel, int State); + /// Emit the EH table data for 32-bit and 64-bit functions using /// the __CxxFrameHandler3 personality. void emitCXXFrameHandler3Table(const MachineFunction *MF); |