From a9d62535727e23588c86dd6ad1d339cb331799ac Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Thu, 11 Jun 2015 22:32:23 +0000 Subject: [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 --- llvm/lib/CodeGen/AsmPrinter/WinException.cpp | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) (limited to 'llvm/lib/CodeGen/AsmPrinter/WinException.cpp') 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); -- cgit v1.2.3