diff options
Diffstat (limited to 'llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp')
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp | 105 |
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); -} |