summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen
diff options
context:
space:
mode:
authorReid Kleckner <reid@kleckner.net>2015-06-11 22:32:23 +0000
committerReid Kleckner <reid@kleckner.net>2015-06-11 22:32:23 +0000
commita9d62535727e23588c86dd6ad1d339cb331799ac (patch)
tree080dba998fbb1a75d1939d30c6428d450d08a5f2 /llvm/lib/CodeGen
parent6bb26dafa4cda63c14da97e65eff1e982375fd16 (diff)
downloadbcm5719-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.cpp21
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);
OpenPOWER on IntegriCloud