diff options
author | Brock Wyma <brock.wyma@intel.com> | 2018-04-16 16:53:57 +0000 |
---|---|---|
committer | Brock Wyma <brock.wyma@intel.com> | 2018-04-16 16:53:57 +0000 |
commit | 94ece8fbc961f2dedeee8d72c1950c1fa6937d04 (patch) | |
tree | 1a2b114cc1c15287704ade70e052a758642d252d /llvm/lib | |
parent | 596b8b4a2268c0e60c6eb9b7147b3e423dee8a93 (diff) | |
download | bcm5719-llvm-94ece8fbc961f2dedeee8d72c1950c1fa6937d04.tar.gz bcm5719-llvm-94ece8fbc961f2dedeee8d72c1950c1fa6937d04.zip |
[CodeView] Initial support for emitting S_THUNK32 symbols for compiler...
When emitting CodeView debug information, compiler-generated thunk routines
should be emitted using S_THUNK32 symbols instead of S_GPROC32_ID symbols so
Visual Studio can properly step into the user code. This initial support only
handles standard thunk ordinals.
Differential Revision: https://reviews.llvm.org/D43838
llvm-svn: 330132
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp | 59 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h | 4 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/CodeView/SymbolDumper.cpp | 1 |
3 files changed, 63 insertions, 1 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp index 6769ed4cff0..a7bc8a84818 100644 --- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp @@ -838,6 +838,57 @@ void CodeViewDebug::switchToDebugSectionForSymbol(const MCSymbol *GVSym) { emitCodeViewMagicVersion(); } +// Emit an S_THUNK32/S_END symbol pair for a thunk routine. +// The only supported thunk ordinal is currently the standard type. +void CodeViewDebug::emitDebugInfoForThunk(const Function *GV, + FunctionInfo &FI, + const MCSymbol *Fn) { + std::string FuncName = GlobalValue::dropLLVMManglingEscape(GV->getName()); + const ThunkOrdinal ordinal = ThunkOrdinal::Standard; // Only supported kind. + + OS.AddComment("Symbol subsection for " + Twine(FuncName)); + MCSymbol *SymbolsEnd = beginCVSubsection(DebugSubsectionKind::Symbols); + + // Emit S_THUNK32 + MCSymbol *ThunkRecordBegin = MMI->getContext().createTempSymbol(), + *ThunkRecordEnd = MMI->getContext().createTempSymbol(); + OS.AddComment("Record length"); + OS.emitAbsoluteSymbolDiff(ThunkRecordEnd, ThunkRecordBegin, 2); + OS.EmitLabel(ThunkRecordBegin); + OS.AddComment("Record kind: S_THUNK32"); + OS.EmitIntValue(unsigned(SymbolKind::S_THUNK32), 2); + OS.AddComment("PtrParent"); + OS.EmitIntValue(0, 4); + OS.AddComment("PtrEnd"); + OS.EmitIntValue(0, 4); + OS.AddComment("PtrNext"); + OS.EmitIntValue(0, 4); + OS.AddComment("Thunk section relative address"); + OS.EmitCOFFSecRel32(Fn, /*Offset=*/0); + OS.AddComment("Thunk section index"); + OS.EmitCOFFSectionIndex(Fn); + OS.AddComment("Code size"); + OS.emitAbsoluteSymbolDiff(FI.End, Fn, 2); + OS.AddComment("Ordinal"); + OS.EmitIntValue(unsigned(ordinal), 1); + OS.AddComment("Function name"); + emitNullTerminatedSymbolName(OS, FuncName); + // Additional fields specific to the thunk ordinal would go here. + OS.EmitLabel(ThunkRecordEnd); + + // Local variables/inlined routines are purposely omitted here. The point of + // marking this as a thunk is so Visual Studio will NOT stop in this routine. + + // Emit S_PROC_ID_END + const unsigned RecordLengthForSymbolEnd = 2; + OS.AddComment("Record length"); + OS.EmitIntValue(RecordLengthForSymbolEnd, 2); + OS.AddComment("Record kind: S_PROC_ID_END"); + OS.EmitIntValue(unsigned(SymbolKind::S_PROC_ID_END), 2); + + endCVSubsection(SymbolsEnd); +} + void CodeViewDebug::emitDebugInfoForFunction(const Function *GV, FunctionInfo &FI) { // For each function there is a separate subsection which holds the PC to @@ -853,6 +904,11 @@ void CodeViewDebug::emitDebugInfoForFunction(const Function *GV, assert(SP); setCurrentSubprogram(SP); + if (SP->isThunk()) { + emitDebugInfoForThunk(GV, FI, Fn); + return; + } + // If we have a display name, build the fully qualified name by walking the // chain of scopes. if (!SP->getName().empty()) @@ -2516,7 +2572,8 @@ void CodeViewDebug::endFunctionImpl(const MachineFunction *MF) { ScopeVariables.clear(); // Don't emit anything if we don't have any line tables. - if (!CurFn->HaveLineInfo) { + // Thunks are compiler-generated and probably won't have source correlation. + if (!CurFn->HaveLineInfo && !GV.getSubprogram()->isThunk()) { FnDebugInfo.erase(&GV); CurFn = nullptr; return; diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h index e58c4c666f2..e16c035cdfd 100644 --- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h +++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h @@ -251,6 +251,10 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase { void emitInlineeLinesSubsection(); + void emitDebugInfoForThunk(const Function *GV, + FunctionInfo &FI, + const MCSymbol *Fn); + void emitDebugInfoForFunction(const Function *GV, FunctionInfo &FI); void emitDebugInfoForGlobals(); diff --git a/llvm/lib/DebugInfo/CodeView/SymbolDumper.cpp b/llvm/lib/DebugInfo/CodeView/SymbolDumper.cpp index df75f52661e..af249adc977 100644 --- a/llvm/lib/DebugInfo/CodeView/SymbolDumper.cpp +++ b/llvm/lib/DebugInfo/CodeView/SymbolDumper.cpp @@ -129,6 +129,7 @@ Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, BlockSym &Block) { } Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, Thunk32Sym &Thunk) { + W.printString("Name", Thunk.Name); W.printNumber("Parent", Thunk.Parent); W.printNumber("End", Thunk.End); W.printNumber("Next", Thunk.Next); |