summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp')
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp105
1 files changed, 21 insertions, 84 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
index 1037fd09400..57fa54a5e9b 100644
--- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
@@ -232,7 +232,7 @@ void CodeViewDebug::emitCodeViewMagicVersion() {
}
void CodeViewDebug::endModule() {
- if (!Asm || !MMI->hasDebugInfo())
+ if (FnDebugInfo.empty())
return;
assert(Asm != nullptr);
@@ -242,18 +242,13 @@ void CodeViewDebug::endModule() {
// of the payload followed by the payload itself. The subsections are 4-byte
// aligned.
- // Use the generic .debug$S section, and make a subsection for all the inlined
- // subprograms.
- switchToDebugSectionForSymbol(nullptr);
+ // Make a subsection for all the inlined subprograms.
emitInlineeLinesSubsection();
// Emit per-function debug information.
for (auto &P : FnDebugInfo)
emitDebugInfoForFunction(P.first, P.second);
- // Emit global variable debug information.
- emitDebugInfoForGlobals();
-
// Switch back to the generic .debug$S section after potentially processing
// comdat symbol sections.
switchToDebugSectionForSymbol(nullptr);
@@ -331,9 +326,17 @@ void CodeViewDebug::emitInlineeLinesSubsection() {
if (InlinedSubprograms.empty())
return;
+ // Use the generic .debug$S section.
+ switchToDebugSectionForSymbol(nullptr);
+
+ MCSymbol *InlineBegin = MMI->getContext().createTempSymbol(),
+ *InlineEnd = MMI->getContext().createTempSymbol();
OS.AddComment("Inlinee lines subsection");
- MCSymbol *InlineEnd = beginCVSubsection(ModuleSubstreamKind::InlineeLines);
+ OS.EmitIntValue(unsigned(ModuleSubstreamKind::InlineeLines), 4);
+ OS.AddComment("Subsection size");
+ OS.emitAbsoluteSymbolDiff(InlineEnd, InlineBegin, 4);
+ OS.EmitLabel(InlineBegin);
// We don't provide any extra file info.
// FIXME: Find out if debuggers use this info.
@@ -360,7 +363,7 @@ void CodeViewDebug::emitInlineeLinesSubsection() {
OS.EmitIntValue(SP->getLine(), 4);
}
- endCVSubsection(InlineEnd);
+ OS.EmitLabel(InlineEnd);
}
void CodeViewDebug::collectInlineSiteChildren(
@@ -464,8 +467,13 @@ void CodeViewDebug::emitDebugInfoForFunction(const Function *GV,
FuncName = GlobalValue::getRealLinkageName(GV->getName());
// Emit a symbol subsection, required by VS2012+ to find function boundaries.
+ MCSymbol *SymbolsBegin = MMI->getContext().createTempSymbol(),
+ *SymbolsEnd = MMI->getContext().createTempSymbol();
OS.AddComment("Symbol subsection for " + Twine(FuncName));
- MCSymbol *SymbolsEnd = beginCVSubsection(ModuleSubstreamKind::Symbols);
+ OS.EmitIntValue(unsigned(ModuleSubstreamKind::Symbols), 4);
+ OS.AddComment("Subsection size");
+ OS.emitAbsoluteSymbolDiff(SymbolsEnd, SymbolsBegin, 4);
+ OS.EmitLabel(SymbolsBegin);
{
MCSymbol *ProcRecordBegin = MMI->getContext().createTempSymbol(),
*ProcRecordEnd = MMI->getContext().createTempSymbol();
@@ -524,7 +532,9 @@ void CodeViewDebug::emitDebugInfoForFunction(const Function *GV,
OS.AddComment("Record kind: S_PROC_ID_END");
OS.EmitIntValue(unsigned(SymbolKind::S_PROC_ID_END), 2);
}
- endCVSubsection(SymbolsEnd);
+ OS.EmitLabel(SymbolsEnd);
+ // Every subsection must be aligned to a 4-byte boundary.
+ OS.EmitValueToAlignment(4);
// We have an assembler directive that takes care of the whole line table.
OS.EmitCVLinetableDirective(FI.FuncId, Fn, FI.End);
@@ -1262,76 +1272,3 @@ void CodeViewDebug::beginInstruction(const MachineInstr *MI) {
return;
maybeRecordLocation(DL, Asm->MF);
}
-
-MCSymbol *CodeViewDebug::beginCVSubsection(ModuleSubstreamKind Kind) {
- MCSymbol *BeginLabel = MMI->getContext().createTempSymbol(),
- *EndLabel = MMI->getContext().createTempSymbol();
- OS.EmitIntValue(unsigned(Kind), 4);
- OS.AddComment("Subsection size");
- OS.emitAbsoluteSymbolDiff(EndLabel, BeginLabel, 4);
- OS.EmitLabel(BeginLabel);
- return EndLabel;
-}
-
-void CodeViewDebug::endCVSubsection(MCSymbol *EndLabel) {
- OS.EmitLabel(EndLabel);
- // Every subsection must be aligned to a 4-byte boundary.
- OS.EmitValueToAlignment(4);
-}
-
-void CodeViewDebug::emitDebugInfoForGlobals() {
- NamedMDNode *CUs = MMI->getModule()->getNamedMetadata("llvm.dbg.cu");
- for (const MDNode *Node : CUs->operands()) {
- const auto *CU = cast<DICompileUnit>(Node);
-
- // First, emit all globals that are not in a comdat in a single symbol
- // substream.
- switchToDebugSectionForSymbol(nullptr);
- OS.AddComment("Symbol subsection for globals");
- MCSymbol *EndLabel = beginCVSubsection(ModuleSubstreamKind::Symbols);
- for (const DIGlobalVariable *G : CU->getGlobalVariables()) {
- if (const auto *GV = dyn_cast<GlobalVariable>(G->getVariable()))
- if (!GV->hasComdat())
- emitDebugInfoForGlobal(G, Asm->getSymbol(GV));
- }
- endCVSubsection(EndLabel);
-
- // Second, emit each global that is in a comdat into its own .debug$S
- // section along with its own symbol substream.
- for (const DIGlobalVariable *G : CU->getGlobalVariables()) {
- if (const auto *GV = dyn_cast<GlobalVariable>(G->getVariable())) {
- if (GV->hasComdat()) {
- MCSymbol *GVSym = Asm->getSymbol(GV);
- OS.AddComment("Symbol subsection for " +
- Twine(GlobalValue::getRealLinkageName(GV->getName())));
- switchToDebugSectionForSymbol(GVSym);
- EndLabel = beginCVSubsection(ModuleSubstreamKind::Symbols);
- emitDebugInfoForGlobal(G, GVSym);
- endCVSubsection(EndLabel);
- }
- }
- }
- }
-}
-
-void CodeViewDebug::emitDebugInfoForGlobal(const DIGlobalVariable *DIGV,
- MCSymbol *GVSym) {
- // DataSym record, see SymbolRecord.h for more info.
- // FIXME: Thread local data, etc
- MCSymbol *DataBegin = MMI->getContext().createTempSymbol(),
- *DataEnd = MMI->getContext().createTempSymbol();
- OS.AddComment("Record length");
- OS.emitAbsoluteSymbolDiff(DataEnd, DataBegin, 2);
- OS.EmitLabel(DataBegin);
- OS.AddComment("Record kind: S_GDATA32");
- OS.EmitIntValue(unsigned(SymbolKind::S_GDATA32), 2);
- OS.AddComment("Type");
- OS.EmitIntValue(getCompleteTypeIndex(DIGV->getType()).getIndex(), 4);
- OS.AddComment("DataOffset");
- OS.EmitCOFFSecRel32(GVSym);
- OS.AddComment("Segment");
- OS.EmitCOFFSectionIndex(GVSym);
- OS.AddComment("Name");
- emitNullTerminatedSymbolName(OS, DIGV->getName());
- OS.EmitLabel(DataEnd);
-}
OpenPOWER on IntegriCloud