summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/AsmPrinter/Win64Exception.cpp
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2015-03-31 22:35:44 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2015-03-31 22:35:44 +0000
commita225a19dd0739024f6a232d601c381d217483ca8 (patch)
treee6a8e66c4c9342738f47595835c157a9101bcce5 /llvm/lib/CodeGen/AsmPrinter/Win64Exception.cpp
parent6a9c46bc3f02573c51eb7eaf48872423f18f4745 (diff)
downloadbcm5719-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.cpp34
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
}
}
}
OpenPOWER on IntegriCloud