diff options
| author | Reid Kleckner <reid@kleckner.net> | 2015-06-11 22:32:23 +0000 |
|---|---|---|
| committer | Reid Kleckner <reid@kleckner.net> | 2015-06-11 22:32:23 +0000 |
| commit | a9d62535727e23588c86dd6ad1d339cb331799ac (patch) | |
| tree | 080dba998fbb1a75d1939d30c6428d450d08a5f2 /llvm/lib/CodeGen | |
| parent | 6bb26dafa4cda63c14da97e65eff1e982375fd16 (diff) | |
| download | bcm5719-llvm-a9d62535727e23588c86dd6ad1d339cb331799ac.tar.gz bcm5719-llvm-a9d62535727e23588c86dd6ad1d339cb331799ac.zip | |
[WinEH] Create an llvm.x86.seh.exceptioninfo intrinsic
This intrinsic is like framerecover plus a load. It recovers the EH
registration stack allocation from the parent frame and loads the
exception information field out of it, giving back a pointer to an
EXCEPTION_POINTERS struct. It's designed for clang to use in SEH filter
expressions instead of accessing the EXCEPTION_POINTERS parameter that
is available on x64.
This required a minor change to MC to allow defining a label variable to
another absolute framerecover label variable.
llvm-svn: 239567
Diffstat (limited to 'llvm/lib/CodeGen')
| -rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/WinException.cpp | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/WinException.cpp b/llvm/lib/CodeGen/AsmPrinter/WinException.cpp index 40d6bab8b6d..75287fd9855 100644 --- a/llvm/lib/CodeGen/AsmPrinter/WinException.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/WinException.cpp @@ -449,7 +449,7 @@ void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) { Asm->OutContext.getOrCreateParentFrameOffsetSymbol( GlobalValue::getRealLinkageName(HT.Handler->getName())); const MCSymbolRefExpr *ParentFrameOffsetRef = MCSymbolRefExpr::create( - ParentFrameOffset, MCSymbolRefExpr::VK_None, Asm->OutContext); + ParentFrameOffset, Asm->OutContext); OS.EmitValue(ParentFrameOffsetRef, 4); // ParentFrameOffset } } @@ -551,11 +551,26 @@ void WinException::extendIP2StateTable(const MachineFunction *MF, /// functionally equivalent to the __C_specific_handler table, except it is /// indexed by state number instead of IP. void WinException::emitExceptHandlerTable(const MachineFunction *MF) { - auto &OS = *Asm->OutStreamer; + MCStreamer &OS = *Asm->OutStreamer; - // Emit the __ehtable label that we use for llvm.x86.seh.lsda. + // 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); + + // Emit the __ehtable label that we use for llvm.x86.seh.lsda. MCSymbol *LSDALabel = Asm->OutContext.getOrCreateLSDASymbol(FLinkageName); OS.EmitLabel(LSDALabel); |

