[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.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@239574 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Reid Kleckner
2015-06-11 23:37:18 +00:00
parent 341ba392d9
commit 2bd0221fa4
5 changed files with 70 additions and 37 deletions

View File

@ -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;