mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-03 17:32:59 +00:00
[WinEH] Add comments explaining the EH tables
This is aids in debugging WinEH, similar functionality is present for DWARF EH. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@256455 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
39227c5849
commit
7de4c3d125
@ -508,6 +508,12 @@ void WinException::emitCSpecificHandlerTable(const MachineFunction *MF) {
|
||||
MCContext &Ctx = Asm->OutContext;
|
||||
const WinEHFuncInfo &FuncInfo = *MF->getWinEHFuncInfo();
|
||||
|
||||
bool VerboseAsm = OS.isVerboseAsm();
|
||||
auto AddComment = [&](const Twine &Comment) {
|
||||
if (VerboseAsm)
|
||||
OS.AddComment(Comment);
|
||||
};
|
||||
|
||||
// Emit a label assignment with the SEH frame offset so we can use it for
|
||||
// llvm.x86.seh.recoverfp.
|
||||
StringRef FLinkageName =
|
||||
@ -527,6 +533,7 @@ void WinException::emitCSpecificHandlerTable(const MachineFunction *MF) {
|
||||
const MCExpr *LabelDiff = getOffset(TableEnd, TableBegin);
|
||||
const MCExpr *EntrySize = MCConstantExpr::create(16, Ctx);
|
||||
const MCExpr *EntryCount = MCBinaryExpr::createDiv(LabelDiff, EntrySize, Ctx);
|
||||
AddComment("Number of call sites");
|
||||
OS.EmitValue(EntryCount, 4);
|
||||
|
||||
OS.EmitLabel(TableBegin);
|
||||
@ -566,6 +573,12 @@ void WinException::emitSEHActionsForRange(const WinEHFuncInfo &FuncInfo,
|
||||
auto &OS = *Asm->OutStreamer;
|
||||
MCContext &Ctx = Asm->OutContext;
|
||||
|
||||
bool VerboseAsm = OS.isVerboseAsm();
|
||||
auto AddComment = [&](const Twine &Comment) {
|
||||
if (VerboseAsm)
|
||||
OS.AddComment(Comment);
|
||||
};
|
||||
|
||||
assert(BeginLabel && EndLabel);
|
||||
while (State != -1) {
|
||||
const SEHUnwindMapEntry &UME = FuncInfo.SEHUnwindMap[State];
|
||||
@ -583,9 +596,14 @@ void WinException::emitSEHActionsForRange(const WinEHFuncInfo &FuncInfo,
|
||||
ExceptOrNull = create32bitRef(Handler->getSymbol());
|
||||
}
|
||||
|
||||
AddComment("LabelStart");
|
||||
OS.EmitValue(getLabelPlusOne(BeginLabel), 4);
|
||||
AddComment("LabelEnd");
|
||||
OS.EmitValue(getLabelPlusOne(EndLabel), 4);
|
||||
AddComment(UME.IsFinally ? "FinallyFunclet" : UME.Filter ? "FilterFunction"
|
||||
: "CatchAll");
|
||||
OS.EmitValue(FilterOrFinally, 4);
|
||||
AddComment(UME.IsFinally ? "Null" : "ExceptionHandler");
|
||||
OS.EmitValue(ExceptOrNull, 4);
|
||||
|
||||
assert(UME.ToState < State && "states should decrease");
|
||||
@ -630,6 +648,12 @@ void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) {
|
||||
IPToStateXData =
|
||||
Asm->OutContext.getOrCreateSymbol(Twine("$ip2state$", FuncLinkageName));
|
||||
|
||||
bool VerboseAsm = OS.isVerboseAsm();
|
||||
auto AddComment = [&](const Twine &Comment) {
|
||||
if (VerboseAsm)
|
||||
OS.AddComment(Comment);
|
||||
};
|
||||
|
||||
// FuncInfo {
|
||||
// uint32_t MagicNumber
|
||||
// int32_t MaxState;
|
||||
@ -647,17 +671,38 @@ void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) {
|
||||
// EHFlags & 4 -> The function is noexcept(true), unwinding can't continue.
|
||||
OS.EmitValueToAlignment(4);
|
||||
OS.EmitLabel(FuncInfoXData);
|
||||
OS.EmitIntValue(0x19930522, 4); // MagicNumber
|
||||
OS.EmitIntValue(FuncInfo.CxxUnwindMap.size(), 4); // MaxState
|
||||
OS.EmitValue(create32bitRef(UnwindMapXData), 4); // UnwindMap
|
||||
OS.EmitIntValue(FuncInfo.TryBlockMap.size(), 4); // NumTryBlocks
|
||||
OS.EmitValue(create32bitRef(TryBlockMapXData), 4); // TryBlockMap
|
||||
OS.EmitIntValue(IPToStateTable.size(), 4); // IPMapEntries
|
||||
OS.EmitValue(create32bitRef(IPToStateXData), 4); // IPToStateMap
|
||||
if (Asm->MAI->usesWindowsCFI())
|
||||
OS.EmitIntValue(UnwindHelpOffset, 4); // UnwindHelp
|
||||
OS.EmitIntValue(0, 4); // ESTypeList
|
||||
OS.EmitIntValue(1, 4); // EHFlags
|
||||
|
||||
AddComment("MagicNumber");
|
||||
OS.EmitIntValue(0x19930522, 4);
|
||||
|
||||
AddComment("MaxState");
|
||||
OS.EmitIntValue(FuncInfo.CxxUnwindMap.size(), 4);
|
||||
|
||||
AddComment("UnwindMap");
|
||||
OS.EmitValue(create32bitRef(UnwindMapXData), 4);
|
||||
|
||||
AddComment("NumTryBlocks");
|
||||
OS.EmitIntValue(FuncInfo.TryBlockMap.size(), 4);
|
||||
|
||||
AddComment("TryBlockMap");
|
||||
OS.EmitValue(create32bitRef(TryBlockMapXData), 4);
|
||||
|
||||
AddComment("IPMapEntries");
|
||||
OS.EmitIntValue(IPToStateTable.size(), 4);
|
||||
|
||||
AddComment("IPToStateXData");
|
||||
OS.EmitValue(create32bitRef(IPToStateXData), 4);
|
||||
|
||||
if (Asm->MAI->usesWindowsCFI()) {
|
||||
AddComment("UnwindHelp");
|
||||
OS.EmitIntValue(UnwindHelpOffset, 4);
|
||||
}
|
||||
|
||||
AddComment("ESTypeList");
|
||||
OS.EmitIntValue(0, 4);
|
||||
|
||||
AddComment("EHFlags");
|
||||
OS.EmitIntValue(1, 4);
|
||||
|
||||
// UnwindMapEntry {
|
||||
// int32_t ToState;
|
||||
@ -668,8 +713,11 @@ void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) {
|
||||
for (const CxxUnwindMapEntry &UME : FuncInfo.CxxUnwindMap) {
|
||||
MCSymbol *CleanupSym =
|
||||
getMCSymbolForMBB(Asm, UME.Cleanup.dyn_cast<MachineBasicBlock *>());
|
||||
OS.EmitIntValue(UME.ToState, 4); // ToState
|
||||
OS.EmitValue(create32bitRef(CleanupSym), 4); // Action
|
||||
AddComment("ToState");
|
||||
OS.EmitIntValue(UME.ToState, 4);
|
||||
|
||||
AddComment("Action");
|
||||
OS.EmitValue(create32bitRef(CleanupSym), 4);
|
||||
}
|
||||
}
|
||||
|
||||
@ -702,11 +750,20 @@ void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) {
|
||||
assert(TBME.CatchHigh < int(FuncInfo.CxxUnwindMap.size()) &&
|
||||
"bad trymap interval");
|
||||
|
||||
OS.EmitIntValue(TBME.TryLow, 4); // TryLow
|
||||
OS.EmitIntValue(TBME.TryHigh, 4); // TryHigh
|
||||
OS.EmitIntValue(TBME.CatchHigh, 4); // CatchHigh
|
||||
OS.EmitIntValue(TBME.HandlerArray.size(), 4); // NumCatches
|
||||
OS.EmitValue(create32bitRef(HandlerMapXData), 4); // HandlerArray
|
||||
AddComment("TryLow");
|
||||
OS.EmitIntValue(TBME.TryLow, 4);
|
||||
|
||||
AddComment("TryHigh");
|
||||
OS.EmitIntValue(TBME.TryHigh, 4);
|
||||
|
||||
AddComment("CatchHigh");
|
||||
OS.EmitIntValue(TBME.CatchHigh, 4);
|
||||
|
||||
AddComment("NumCatches");
|
||||
OS.EmitIntValue(TBME.HandlerArray.size(), 4);
|
||||
|
||||
AddComment("HandlerArray");
|
||||
OS.EmitValue(create32bitRef(HandlerMapXData), 4);
|
||||
}
|
||||
|
||||
// All funclets use the same parent frame offset currently.
|
||||
@ -744,12 +801,22 @@ void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) {
|
||||
MCSymbol *HandlerSym =
|
||||
getMCSymbolForMBB(Asm, HT.Handler.dyn_cast<MachineBasicBlock *>());
|
||||
|
||||
OS.EmitIntValue(HT.Adjectives, 4); // Adjectives
|
||||
OS.EmitValue(create32bitRef(HT.TypeDescriptor), 4); // Type
|
||||
OS.EmitValue(FrameAllocOffsetRef, 4); // CatchObjOffset
|
||||
OS.EmitValue(create32bitRef(HandlerSym), 4); // Handler
|
||||
if (shouldEmitPersonality)
|
||||
OS.EmitIntValue(ParentFrameOffset, 4); // ParentFrameOffset
|
||||
AddComment("Adjectives");
|
||||
OS.EmitIntValue(HT.Adjectives, 4);
|
||||
|
||||
AddComment("Type");
|
||||
OS.EmitValue(create32bitRef(HT.TypeDescriptor), 4);
|
||||
|
||||
AddComment("CatchObjOffset");
|
||||
OS.EmitValue(FrameAllocOffsetRef, 4);
|
||||
|
||||
AddComment("Handler");
|
||||
OS.EmitValue(create32bitRef(HandlerSym), 4);
|
||||
|
||||
if (shouldEmitPersonality) {
|
||||
AddComment("ParentFrameOffset");
|
||||
OS.EmitIntValue(ParentFrameOffset, 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -761,8 +828,10 @@ void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) {
|
||||
if (IPToStateXData) {
|
||||
OS.EmitLabel(IPToStateXData);
|
||||
for (auto &IPStatePair : IPToStateTable) {
|
||||
OS.EmitValue(IPStatePair.first, 4); // IP
|
||||
OS.EmitIntValue(IPStatePair.second, 4); // State
|
||||
AddComment("IP");
|
||||
OS.EmitValue(IPStatePair.first, 4);
|
||||
AddComment("ToState");
|
||||
OS.EmitIntValue(IPStatePair.second, 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -846,6 +915,12 @@ void WinException::emitExceptHandlerTable(const MachineFunction *MF) {
|
||||
const Function *F = MF->getFunction();
|
||||
StringRef FLinkageName = GlobalValue::getRealLinkageName(F->getName());
|
||||
|
||||
bool VerboseAsm = OS.isVerboseAsm();
|
||||
auto AddComment = [&](const Twine &Comment) {
|
||||
if (VerboseAsm)
|
||||
OS.AddComment(Comment);
|
||||
};
|
||||
|
||||
const WinEHFuncInfo &FuncInfo = *MF->getWinEHFuncInfo();
|
||||
emitEHRegistrationOffsetLabel(FuncInfo, FLinkageName);
|
||||
|
||||
@ -872,24 +947,32 @@ void WinException::emitExceptHandlerTable(const MachineFunction *MF) {
|
||||
//
|
||||
// Only the EHCookieOffset field appears to vary, and it appears to be the
|
||||
// offset from the final saved SP value to the retaddr.
|
||||
AddComment("GSCookieOffset");
|
||||
OS.EmitIntValue(-2, 4);
|
||||
AddComment("GSCookieXOROffset");
|
||||
OS.EmitIntValue(0, 4);
|
||||
// FIXME: Calculate.
|
||||
AddComment("EHCookieOffset");
|
||||
OS.EmitIntValue(9999, 4);
|
||||
AddComment("EHCookieXOROffset");
|
||||
OS.EmitIntValue(0, 4);
|
||||
BaseState = -2;
|
||||
}
|
||||
|
||||
assert(!FuncInfo.SEHUnwindMap.empty());
|
||||
for (const SEHUnwindMapEntry &UME : FuncInfo.SEHUnwindMap) {
|
||||
MCSymbol *ExceptOrFinally =
|
||||
UME.Handler.get<MachineBasicBlock *>()->getSymbol();
|
||||
auto *Handler = UME.Handler.get<MachineBasicBlock *>();
|
||||
const MCSymbol *ExceptOrFinally =
|
||||
UME.IsFinally ? getMCSymbolForMBB(Asm, Handler) : Handler->getSymbol();
|
||||
// -1 is usually the base state for "unwind to caller", but for
|
||||
// _except_handler4 it's -2. Do that replacement here if necessary.
|
||||
int ToState = UME.ToState == -1 ? BaseState : UME.ToState;
|
||||
OS.EmitIntValue(ToState, 4); // ToState
|
||||
OS.EmitValue(create32bitRef(UME.Filter), 4); // Filter
|
||||
OS.EmitValue(create32bitRef(ExceptOrFinally), 4); // Except/Finally
|
||||
AddComment("ToState");
|
||||
OS.EmitIntValue(ToState, 4);
|
||||
AddComment(UME.IsFinally ? "Null" : "FilterFunction");
|
||||
OS.EmitValue(create32bitRef(UME.Filter), 4);
|
||||
AddComment(UME.IsFinally ? "FinallyFunclet" : "ExceptionHandler");
|
||||
OS.EmitValue(create32bitRef(ExceptOrFinally), 4);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -27,12 +27,12 @@ lpad: ; preds = %entry
|
||||
|
||||
; X64: .seh_handlerdata
|
||||
; X64-NEXT: .Lmain$parent_frame_offset = 32
|
||||
; X64-NEXT: .long (.Llsda_end0-.Llsda_begin0)/16
|
||||
; X64-NEXT: .long (.Llsda_end0-.Llsda_begin0)/16 # Number of call sites
|
||||
; X64-NEXT: .Llsda_begin0:
|
||||
; X64-NEXT: .long .Ltmp0@IMGREL+1
|
||||
; X64-NEXT: .long .Ltmp1@IMGREL+1
|
||||
; X64-NEXT: .long "?dtor$2@?0?main@4HA"@IMGREL
|
||||
; X64-NEXT: .long 0
|
||||
; X64-NEXT: .long .Ltmp0@IMGREL+1 # LabelStart
|
||||
; X64-NEXT: .long .Ltmp1@IMGREL+1 # LabelEnd
|
||||
; X64-NEXT: .long "?dtor$2@?0?main@4HA"@IMGREL # FinallyFunclet
|
||||
; X64-NEXT: .long 0 # Null
|
||||
; X64-NEXT: .Llsda_end0:
|
||||
|
||||
; X64-LABEL: "?dtor$2@?0?main@4HA":
|
||||
@ -49,9 +49,9 @@ lpad: ; preds = %entry
|
||||
|
||||
; X86: .section .xdata,"dr"
|
||||
; X86: L__ehtable$main:
|
||||
; X86-NEXT: .long -1
|
||||
; X86-NEXT: .long 0
|
||||
; X86-NEXT: .long LBB0_2
|
||||
; X86-NEXT: .long -1 # ToState
|
||||
; X86-NEXT: .long 0 # Null
|
||||
; X86-NEXT: .long "?dtor$2@?0?main@4HA" # FinallyFunclet
|
||||
|
||||
declare i32 @__C_specific_handler(...)
|
||||
|
||||
|
@ -46,8 +46,8 @@ invoke.cont: ; preds = %entry
|
||||
|
||||
; CHECK: .section .xdata,"dr"
|
||||
; CHECK: L__ehtable$try_except:
|
||||
; CHECK: .long -1
|
||||
; CHECK: .long _try_except_filter_catchall
|
||||
; CHECK: .long -1 # ToState
|
||||
; CHECK: .long _try_except_filter_catchall # Filter
|
||||
; CHECK: .long LBB0_1
|
||||
|
||||
define internal i32 @try_except_filter_catchall() #0 {
|
||||
|
@ -72,9 +72,9 @@ attributes #3 = { noinline }
|
||||
; CHECK: retl
|
||||
|
||||
; CHECK: L__ehtable$nested_finally:
|
||||
; CHECK: .long -1
|
||||
; CHECK: .long 0
|
||||
; CHECK: .long LBB0_[[outer]]
|
||||
; CHECK: .long 0
|
||||
; CHECK: .long 0
|
||||
; CHECK: .long LBB0_[[inner]]
|
||||
; CHECK: .long -1 # ToState
|
||||
; CHECK: .long 0 # Null
|
||||
; CHECK: .long "?dtor$[[outer]]@?0?nested_finally@4HA" # FinallyFunclet
|
||||
; CHECK: .long 0 # ToState
|
||||
; CHECK: .long 0 # Null
|
||||
; CHECK: .long "?dtor$[[inner]]@?0?nested_finally@4HA" # FinallyFunclet
|
||||
|
Loading…
Reference in New Issue
Block a user