diff options
author | David Majnemer <david.majnemer@gmail.com> | 2015-03-31 22:35:44 +0000 |
---|---|---|
committer | David Majnemer <david.majnemer@gmail.com> | 2015-03-31 22:35:44 +0000 |
commit | a225a19dd0739024f6a232d601c381d217483ca8 (patch) | |
tree | e6a8e66c4c9342738f47595835c157a9101bcce5 /llvm/lib/CodeGen/AsmPrinter/Win64Exception.cpp | |
parent | 6a9c46bc3f02573c51eb7eaf48872423f18f4745 (diff) | |
download | bcm5719-llvm-a225a19dd0739024f6a232d601c381d217483ca8.tar.gz bcm5719-llvm-a225a19dd0739024f6a232d601c381d217483ca8.zip |
[WinEH] Generate .xdata for catch handlers
This lets us catch exceptions in simple cases.
N.B. Things that do not work include (but are not limited to):
- Throwing from within a catch handler.
- Catching an object with a named catch parameter.
- 'CatchHigh' is fictitious, we aren't sure of its purpose.
- We aren't entirely efficient with regards to the number of EH states
that we generate.
- IP-to-State tables are sensitive to the order of emission.
llvm-svn: 233767
Diffstat (limited to 'llvm/lib/CodeGen/AsmPrinter/Win64Exception.cpp')
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/Win64Exception.cpp | 34 |
1 files changed, 30 insertions, 4 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/Win64Exception.cpp b/llvm/lib/CodeGen/AsmPrinter/Win64Exception.cpp index 974e94dcb6a..7a82daa3337 100644 --- a/llvm/lib/CodeGen/AsmPrinter/Win64Exception.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/Win64Exception.cpp @@ -68,6 +68,27 @@ void Win64Exception::beginFunction(const MachineFunction *MF) { shouldEmitLSDA = shouldEmitPersonality && LSDAEncoding != dwarf::DW_EH_PE_omit; + + // If this was an outlined handler, we need to define the label corresponding + // to the offset of the parent frame relative to the stack pointer after the + // prologue. + const Function *F = MF->getFunction(); + const Function *ParentF = MMI->getWinEHParent(F); + if (F != ParentF) { + WinEHFuncInfo &FuncInfo = MMI->getWinEHFuncInfo(ParentF); + auto I = FuncInfo.CatchHandlerParentFrameObjOffset.find(F); + if (I != FuncInfo.CatchHandlerParentFrameObjOffset.end()) { + MCSymbol *HandlerTypeParentFrameOffset = + Asm->OutContext.getOrCreateParentFrameOffsetSymbol( + GlobalValue::getRealLinkageName(F->getName())); + + // Emit a symbol assignment. + Asm->OutStreamer.EmitAssignment( + HandlerTypeParentFrameOffset, + MCConstantExpr::Create(I->second, Asm->OutContext)); + } + } + if (!shouldEmitPersonality && !shouldEmitMoves) return; @@ -253,6 +274,7 @@ void Win64Exception::emitCXXFrameHandler3Table(const MachineFunction *MF) { const Function *F = MF->getFunction(); const Function *ParentF = MMI->getWinEHParent(F); auto &OS = Asm->OutStreamer; + WinEHFuncInfo &FuncInfo = MMI->getWinEHFuncInfo(ParentF); StringRef ParentLinkageName = GlobalValue::getRealLinkageName(ParentF->getName()); @@ -279,8 +301,6 @@ void Win64Exception::emitCXXFrameHandler3Table(const MachineFunction *MF) { // an ordinary call) between the end of the previous try-range and now. bool SawPotentiallyThrowing = false; - WinEHFuncInfo &FuncInfo = MMI->getWinEHFuncInfo(ParentF); - int LastEHState = -2; // The parent function and the catch handlers contribute to the 'ip2state' @@ -424,11 +444,17 @@ void Win64Exception::emitCXXFrameHandler3Table(const MachineFunction *MF) { // }; OS.EmitLabel(HandlerMapXData); for (const WinEHHandlerType &HT : TBME.HandlerArray) { + MCSymbol *ParentFrameOffset = + Asm->OutContext.getOrCreateParentFrameOffsetSymbol( + GlobalValue::getRealLinkageName(HT.Handler->getName())); + const MCSymbolRefExpr *ParentFrameOffsetRef = MCSymbolRefExpr::Create( + ParentFrameOffset, MCSymbolRefExpr::VK_None, Asm->OutContext); + OS.EmitIntValue(HT.Adjectives, 4); // Adjectives OS.EmitValue(createImageRel32(HT.TypeDescriptor), 4); // Type - OS.EmitIntValue(0, 4); // CatchObjOffset + OS.EmitIntValue(HT.CatchObjOffset, 4); // CatchObjOffset OS.EmitValue(createImageRel32(HT.Handler), 4); // Handler - OS.EmitIntValue(0, 4); // ParentFrameOffset + OS.EmitValue(ParentFrameOffsetRef, 4); // ParentFrameOffset } } } |