diff options
author | Reid Kleckner <reid@kleckner.net> | 2015-06-11 23:37:18 +0000 |
---|---|---|
committer | Reid Kleckner <reid@kleckner.net> | 2015-06-11 23:37:18 +0000 |
commit | 81d1cc00b7d6de7303deb31ab8569ff3fa4abf56 (patch) | |
tree | 22a47dcad0b233cdf40fea05a33a8f8bba27cde5 /llvm/lib/CodeGen/AsmPrinter/WinException.cpp | |
parent | b5aee61c3617b726245182b48df8ab573d75d1a9 (diff) | |
download | bcm5719-llvm-81d1cc00b7d6de7303deb31ab8569ff3fa4abf56.tar.gz bcm5719-llvm-81d1cc00b7d6de7303deb31ab8569ff3fa4abf56.zip |
[WinEH] Put finally pointers in the handler scope table field
We were putting them in the filter field, which is correct for 64-bit
but wrong for 32-bit.
Also switch the order of scope table entry emission so outermost entries
are emitted first, and fix an obvious state assignment bug.
llvm-svn: 239574
Diffstat (limited to 'llvm/lib/CodeGen/AsmPrinter/WinException.cpp')
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/WinException.cpp | 27 |
1 files changed, 13 insertions, 14 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/WinException.cpp b/llvm/lib/CodeGen/AsmPrinter/WinException.cpp index 75287fd9855..1ba6060a89f 100644 --- a/llvm/lib/CodeGen/AsmPrinter/WinException.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/WinException.cpp @@ -613,8 +613,8 @@ void WinException::emitExceptHandlerTable(const MachineFunction *MF) { // For each action in each lpad, emit one of these: // struct ScopeTableEntry { // int32_t EnclosingLevel; - // int32_t (__cdecl *FilterOrFinally)(); - // void *HandlerLabel; + // int32_t (__cdecl *Filter)(); + // void *HandlerOrFinally; // }; // // The "outermost" action will use BaseState as its enclosing level. Each @@ -625,21 +625,20 @@ void WinException::emitExceptHandlerTable(const MachineFunction *MF) { assert(CurState + int(LPInfo->SEHHandlers.size()) - 1 == LPInfo->WinEHState && "gaps in the SEH scope table"); - for (const SEHHandler &Handler : LPInfo->SEHHandlers) { - // Emit the filter or finally function pointer, if present. Otherwise, - // emit '0' to indicate a catch-all. - const Function *F = Handler.FilterOrFinally; - const MCExpr *FilterOrFinally = - create32bitRef(F ? Asm->getSymbol(F) : nullptr); - - // Compute the recovery address, which is a block address or null. + for (auto I = LPInfo->SEHHandlers.rbegin(), E = LPInfo->SEHHandlers.rend(); + I != E; ++I) { + const SEHHandler &Handler = *I; const BlockAddress *BA = Handler.RecoverBA; - const MCExpr *RecoverBBOrNull = - create32bitRef(BA ? Asm->GetBlockAddressSymbol(BA) : nullptr); + const Function *F = Handler.FilterOrFinally; + assert(F && "cannot catch all in 32-bit SEH without filter function"); + const MCExpr *FilterOrNull = + create32bitRef(BA ? Asm->getSymbol(F) : nullptr); + const MCExpr *ExceptOrFinally = create32bitRef( + BA ? Asm->GetBlockAddressSymbol(BA) : Asm->getSymbol(F)); OS.EmitIntValue(EnclosingLevel, 4); - OS.EmitValue(FilterOrFinally, 4); - OS.EmitValue(RecoverBBOrNull, 4); + OS.EmitValue(FilterOrNull, 4); + OS.EmitValue(ExceptOrFinally, 4); // The next state unwinds to this state. EnclosingLevel = CurState; |