diff options
| author | Reid Kleckner <reid@kleckner.net> | 2015-06-30 22:46:59 +0000 |
|---|---|---|
| committer | Reid Kleckner <reid@kleckner.net> | 2015-06-30 22:46:59 +0000 |
| commit | 399a2fe400912313eafdb7ff3b6e17b439887e9d (patch) | |
| tree | 556f40456637c0e60c51ae07819490a2bf7d4b7d /llvm/lib/CodeGen/AsmPrinter/WinException.cpp | |
| parent | a5812a215bd90c320221b4d33bdf2767f4ec7077 (diff) | |
| download | bcm5719-llvm-399a2fe400912313eafdb7ff3b6e17b439887e9d.tar.gz bcm5719-llvm-399a2fe400912313eafdb7ff3b6e17b439887e9d.zip | |
[SEH] Add new intrinsics for recovering and restoring parent frames
The incoming EBP value established by the runtime is actually a pointer
to the end of the EH registration object, and not the true parent
function frame pointer. Clang doesn't need llvm.x86.seh.exceptioninfo
anymore because we know that the exception info pointer is at a fixed
offset from this incoming EBP.
The llvm.x86.seh.recoverfp intrinsic takes an EBP value provided by the
EH runtime and returns a pointer that is usable with llvm.framerecover.
The llvm.x86.seh.restoreframe intrinsic is inserted by the 32-bit
specific preparation pass in blocks targetted by the EH runtime. It
re-establishes any physical registers used by the parent function to
address the stack, such as the frame, base, and stack pointers.
Neither of these intrinsics correctly handle stack realignment prologues
yet, but it's possible to add that later.
Reviewers: majnemer
Differential Revision: http://reviews.llvm.org/D10848
llvm-svn: 241125
Diffstat (limited to 'llvm/lib/CodeGen/AsmPrinter/WinException.cpp')
| -rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/WinException.cpp | 36 |
1 files changed, 21 insertions, 15 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/WinException.cpp b/llvm/lib/CodeGen/AsmPrinter/WinException.cpp index 1ba6060a89f..79830bc3443 100644 --- a/llvm/lib/CodeGen/AsmPrinter/WinException.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/WinException.cpp @@ -319,6 +319,7 @@ void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) { return; } else { FuncInfoXData = Asm->OutContext.getOrCreateLSDASymbol(ParentLinkageName); + emitEHRegistrationOffsetLabel(FuncInfo, ParentLinkageName); } MCSymbol *UnwindMapXData = nullptr; @@ -547,28 +548,33 @@ void WinException::extendIP2StateTable(const MachineFunction *MF, } } +void WinException::emitEHRegistrationOffsetLabel(const WinEHFuncInfo &FuncInfo, + StringRef FLinkageName) { + // Outlined helpers called by the EH runtime need to know the offset of the EH + // registration in order to recover the parent frame pointer. Now that we know + // we've code generated the parent, we can emit the label assignment that + // those helpers use to get the offset of the registration node. + assert(FuncInfo.EHRegNodeEscapeIndex != INT_MAX && + "no EH reg node frameescape index"); + MCSymbol *ParentFrameOffset = + Asm->OutContext.getOrCreateParentFrameOffsetSymbol(FLinkageName); + MCSymbol *RegistrationOffsetSym = Asm->OutContext.getOrCreateFrameAllocSymbol( + FLinkageName, FuncInfo.EHRegNodeEscapeIndex); + const MCExpr *RegistrationOffsetSymRef = + MCSymbolRefExpr::create(RegistrationOffsetSym, Asm->OutContext); + Asm->OutStreamer->EmitAssignment(ParentFrameOffset, RegistrationOffsetSymRef); +} + /// Emit the language-specific data that _except_handler3 and 4 expect. This is /// functionally equivalent to the __C_specific_handler table, except it is /// indexed by state number instead of IP. void WinException::emitExceptHandlerTable(const MachineFunction *MF) { MCStreamer &OS = *Asm->OutStreamer; - - // Define the EH registration node offset label in terms of its frameescape - // label. The WinEHStatePass ensures that the registration node is passed to - // frameescape. This allows SEH filter functions to access the - // EXCEPTION_POINTERS field, which is filled in by the _except_handlerN. const Function *F = MF->getFunction(); - WinEHFuncInfo &FuncInfo = MMI->getWinEHFuncInfo(F); - assert(FuncInfo.EHRegNodeEscapeIndex != INT_MAX && - "no EH reg node frameescape index"); StringRef FLinkageName = GlobalValue::getRealLinkageName(F->getName()); - MCSymbol *ParentFrameOffset = - Asm->OutContext.getOrCreateParentFrameOffsetSymbol(FLinkageName); - MCSymbol *FrameAllocSym = Asm->OutContext.getOrCreateFrameAllocSymbol( - FLinkageName, FuncInfo.EHRegNodeEscapeIndex); - const MCSymbolRefExpr *FrameAllocSymRef = - MCSymbolRefExpr::create(FrameAllocSym, Asm->OutContext); - OS.EmitAssignment(ParentFrameOffset, FrameAllocSymRef); + + WinEHFuncInfo &FuncInfo = MMI->getWinEHFuncInfo(F); + emitEHRegistrationOffsetLabel(FuncInfo, FLinkageName); // Emit the __ehtable label that we use for llvm.x86.seh.lsda. MCSymbol *LSDALabel = Asm->OutContext.getOrCreateLSDASymbol(FLinkageName); |

