From 63ac50a2b64846841848005c699bf1e4a6129311 Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Fri, 9 Oct 2015 20:39:39 +0000 Subject: [PATCH] [SEH] Remember to emit the last invoke range for SEH This wasn't very observable in execution tests, because usually there is an invoke in the catchpad that unwinds the the catchendpad but never actually throws. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@249898 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/AsmPrinter/WinException.cpp | 76 ++++++++++++++++--------- lib/CodeGen/AsmPrinter/WinException.h | 3 + test/CodeGen/X86/seh-catch-all.ll | 36 ++++++------ test/CodeGen/X86/seh-catchpad.ll | 12 ++-- 4 files changed, 77 insertions(+), 50 deletions(-) diff --git a/lib/CodeGen/AsmPrinter/WinException.cpp b/lib/CodeGen/AsmPrinter/WinException.cpp index 5661a378c30..56a8b844ca5 100644 --- a/lib/CodeGen/AsmPrinter/WinException.cpp +++ b/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(); - 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(); + 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/lib/CodeGen/AsmPrinter/WinException.h b/lib/CodeGen/AsmPrinter/WinException.h index 5c853349d2e..ded00d5cf39 100644 --- a/lib/CodeGen/AsmPrinter/WinException.h +++ b/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); diff --git a/test/CodeGen/X86/seh-catch-all.ll b/test/CodeGen/X86/seh-catch-all.ll index 00a2455655b..0c4f33f6300 100644 --- a/test/CodeGen/X86/seh-catch-all.ll +++ b/test/CodeGen/X86/seh-catch-all.ll @@ -2,6 +2,7 @@ @str = linkonce_odr unnamed_addr constant [27 x i8] c"GetExceptionCode(): 0x%lx\0A\00", align 1 +declare i32 @llvm.eh.exceptioncode(token) declare i32 @__C_specific_handler(...) declare void @crash() declare i32 @printf(i8* nocapture readonly, ...) nounwind @@ -11,20 +12,20 @@ entry: invoke void @crash() to label %__try.cont unwind label %lpad -lpad: - %0 = landingpad { i8*, i32 } - catch i8* null - %1 = extractvalue { i8*, i32 } %0, 0 - %2 = ptrtoint i8* %1 to i64 - %3 = trunc i64 %2 to i32 - call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([27 x i8], [27 x i8]* @str, i64 0, i64 0), i32 %3) - br label %__try.cont - __try.cont: ret i32 0 -eh.resume: - resume { i8*, i32 } %0 +lpad: + %p = catchpad [i8* null, i32 64, i8* null] + to label %catchall unwind label %endpad + +catchall: + %code = call i32 @llvm.eh.exceptioncode(token %p) + call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([27 x i8], [27 x i8]* @str, i64 0, i64 0), i32 %code) + catchret %p to label %__try.cont + +endpad: + catchendpad unwind to caller } ; Check that we can get the exception code from eax to the printf. @@ -32,18 +33,17 @@ eh.resume: ; CHECK-LABEL: main: ; CHECK: callq crash ; CHECK: retq -; CHECK: # Block address taken +; CHECK: .LBB0_2: # %lpad +; CHECK: # %catchall ; CHECK: leaq str(%rip), %rcx ; CHECK: movl %eax, %edx ; CHECK: callq printf ; CHECK: .seh_handlerdata -; CHECK-NEXT: .text -; CHECK-NEXT: .Ltmp{{[0-9]+}} -; CHECK-NEXT: .seh_endproc -; CHECK-NEXT: .section .xdata,"dr" -; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long (.Llsda_end0-.Llsda_begin0)/16 +; CHECK-NEXT: .Llsda_begin0: ; CHECK-NEXT: .long .Ltmp{{[0-9]+}}@IMGREL ; CHECK-NEXT: .long .Ltmp{{[0-9]+}}@IMGREL+1 ; CHECK-NEXT: .long 1 -; CHECK-NEXT: .long .Ltmp{{[0-9]+}}@IMGREL +; CHECK-NEXT: .long .LBB0_2@IMGREL +; CHECK-NEXT: .Llsda_end0: diff --git a/test/CodeGen/X86/seh-catchpad.ll b/test/CodeGen/X86/seh-catchpad.ll index 865596d206f..e981744db42 100644 --- a/test/CodeGen/X86/seh-catchpad.ll +++ b/test/CodeGen/X86/seh-catchpad.ll @@ -130,22 +130,26 @@ ehcleanup.end: ; preds = %ehcleanup ; CHECK: .seh_handlerdata ; CHECK-NEXT: .long (.Llsda_end0-.Llsda_begin0)/16 ; CHECK-NEXT: .Llsda_begin0: -; CHECK-NEXT: .long .Ltmp0@IMGREL +; CHECK-NEXT: .long .Ltmp0@IMGREL+1 ; CHECK-NEXT: .long .Ltmp1@IMGREL+1 ; CHECK-NEXT: .long 1 ; CHECK-NEXT: .long .LBB1_[[except1bb]]@IMGREL -; CHECK-NEXT: .long .Ltmp0@IMGREL +; CHECK-NEXT: .long .Ltmp0@IMGREL+1 ; CHECK-NEXT: .long .Ltmp1@IMGREL+1 ; CHECK-NEXT: .long "?filt$0@0@main@@"@IMGREL ; CHECK-NEXT: .long .LBB1_[[except2bb]]@IMGREL -; CHECK-NEXT: .long .Ltmp2@IMGREL +; CHECK-NEXT: .long .Ltmp2@IMGREL+1 ; CHECK-NEXT: .long .Ltmp3@IMGREL+1 ; CHECK-NEXT: .long "?dtor$[[finbb:[0-9]+]]@?0?main@4HA"@IMGREL ; CHECK-NEXT: .long 0 -; CHECK-NEXT: .long .Ltmp2@IMGREL +; CHECK-NEXT: .long .Ltmp2@IMGREL+1 ; CHECK-NEXT: .long .Ltmp3@IMGREL+1 ; CHECK-NEXT: .long "?filt$0@0@main@@"@IMGREL ; CHECK-NEXT: .long .LBB1_6@IMGREL +; CHECK-NEXT: .long .Ltmp6@IMGREL+1 +; CHECK-NEXT: .long .Ltmp5@IMGREL+1 +; CHECK-NEXT: .long "?filt$0@0@main@@"@IMGREL +; CHECK-NEXT: .long .LBB1_6@IMGREL ; CHECK-NEXT: .Llsda_end0: ; CHECK: .text -- 2.34.1