diff --git a/llvm/include/llvm/MC/MCDwarf.h b/llvm/include/llvm/MC/MCDwarf.h --- a/llvm/include/llvm/MC/MCDwarf.h +++ b/llvm/include/llvm/MC/MCDwarf.h @@ -300,6 +300,12 @@ DwarfVersion)); } + MCSymbol *getLabel() const { return Header.Label; } + + void setLabel(MCSymbol *Label) { Header.Label = Label; } + + void enableSplitLineTable() { HasSplitLineTable = true; } + void Emit(MCStreamer &MCOS, MCDwarfLineTableParams Params, MCSection *Section) const; }; diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -397,13 +397,16 @@ /// Holder for the skeleton information. DwarfFile SkeletonHolder; - /// Store file names for type units under fission in a line table + /// Store file names for split units under fission in a line table /// header that will be emitted into debug_line.dwo. // FIXME: replace this with a map from comp_dir to table so that we // can emit multiple tables during LTO each of which uses directory - // 0, referencing the comp_dir of all the type units that use it. - MCDwarfDwoLineTable SplitTypeUnitFileTable; + // 0, referencing the comp_dir of all the split units that use it. + MCDwarfDwoLineTable SplitUnitFileTable; /// @} + /// Start symbol for SplitUnitFileTable, this will be referenced by + /// debug_macro.dwo for setting up `debug_line_offset`. + MCSymbol *SplitUnitFileTableStartSym; /// True iff there are multiple CUs in this module. bool SingleCU; @@ -777,6 +780,7 @@ void addSectionLabel(const MCSymbol *Sym); const MCSymbol *getSectionLabel(const MCSection *S); + MCSymbol *getSplitFileTableStartSym() { return SplitUnitFileTableStartSym; } void insertSectionLabel(const MCSymbol *S); static void emitDebugLocValue(const AsmPrinter &AP, const DIBasicType *BT, diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -1015,6 +1015,14 @@ if (!CompilationDir.empty()) NewCU.addString(Die, dwarf::DW_AT_comp_dir, CompilationDir); addGnuPubAttributes(NewCU, Die); + } else if (!DIUnit->getMacros().empty()) { + // .debug_macro.dwo needs to reference .debug_line.dwo for + // setting up `debug_line_offset`. Initialize the split unit line table + // to be emitted later in .debug_line.dwo section. + MCDwarfDwoLineTable *SplitLineTable = getDwoLineTable(NewCU); + SplitLineTable->enableSplitLineTable(); + NewCU.initSplitLineTable(SplitLineTable); + NewCU.addSectionOffset(Die, dwarf::DW_AT_stmt_list, 0); } if (useAppleExtensionAttributes()) { @@ -3140,9 +3148,10 @@ void DwarfDebug::emitDebugLineDWO() { assert(useSplitDwarf() && "No split dwarf?"); - SplitTypeUnitFileTable.Emit( - *Asm->OutStreamer, MCDwarfLineTableParams(), - Asm->getObjFileLowering().getDwarfLineDWOSection()); + SplitUnitFileTableStartSym = Asm->createTempSymbol("split_unit_line_table"); + SplitUnitFileTable.setLabel(SplitUnitFileTableStartSym); + SplitUnitFileTable.Emit(*Asm->OutStreamer, MCDwarfLineTableParams(), + Asm->getObjFileLowering().getDwarfLineDWOSection()); } void DwarfDebug::emitStringOffsetsTableHeaderDWO() { @@ -3173,10 +3182,10 @@ if (!useSplitDwarf()) return nullptr; const DICompileUnit *DIUnit = CU.getCUNode(); - SplitTypeUnitFileTable.maybeSetRootFile( + SplitUnitFileTable.maybeSetRootFile( DIUnit->getDirectory(), DIUnit->getFilename(), CU.getMD5AsBytes(DIUnit->getFile()), DIUnit->getSource()); - return &SplitTypeUnitFileTable; + return &SplitUnitFileTable; } uint64_t DwarfDebug::makeTypeSignature(StringRef Identifier) { diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h --- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h @@ -72,14 +72,17 @@ /// corresponds to the MDNode mapped with the subprogram DIE. DenseMap ContainingTypeMap; - DwarfUnit(dwarf::Tag, const DICompileUnit *Node, AsmPrinter *A, DwarfDebug *DW, - DwarfFile *DWU); + DwarfUnit(dwarf::Tag, const DICompileUnit *Node, AsmPrinter *A, + DwarfDebug *DW, DwarfFile *DWU, + MCDwarfDwoLineTable *SplitLineTable = nullptr); bool applySubprogramDefinitionAttributes(const DISubprogram *SP, DIE &SPDie); bool shareAcrossDWOCUs() const; bool isShareableAcrossCUs(const DINode *D) const; + MCDwarfDwoLineTable *SplitLineTable; + public: // Accessors. AsmPrinter* getAsmPrinter() const { return Asm; } @@ -291,6 +294,10 @@ /// Get context owner's DIE. DIE *createTypeDIE(const DICompositeType *Ty); + void initSplitLineTable(MCDwarfDwoLineTable *SplitLineTable) { + this->SplitLineTable = SplitLineTable; + } + protected: ~DwarfUnit(); @@ -343,7 +350,6 @@ uint64_t TypeSignature; const DIE *Ty; DwarfCompileUnit &CU; - MCDwarfDwoLineTable *SplitLineTable; bool UsedLineTable = false; unsigned getOrCreateSourceID(const DIFile *File) override; diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp --- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -89,17 +89,18 @@ } DwarfUnit::DwarfUnit(dwarf::Tag UnitTag, const DICompileUnit *Node, - AsmPrinter *A, DwarfDebug *DW, DwarfFile *DWU) + AsmPrinter *A, DwarfDebug *DW, DwarfFile *DWU, + MCDwarfDwoLineTable *SplitLineTable) : DIEUnit(A->getDwarfVersion(), A->MAI->getCodePointerSize(), UnitTag), - CUNode(Node), Asm(A), DD(DW), DU(DWU), IndexTyDie(nullptr) { -} + CUNode(Node), Asm(A), DD(DW), DU(DWU), IndexTyDie(nullptr), + SplitLineTable(SplitLineTable) {} DwarfTypeUnit::DwarfTypeUnit(DwarfCompileUnit &CU, AsmPrinter *A, DwarfDebug *DW, DwarfFile *DWU, MCDwarfDwoLineTable *SplitLineTable) - : DwarfUnit(dwarf::DW_TAG_type_unit, CU.getCUNode(), A, DW, DWU), CU(CU), - SplitLineTable(SplitLineTable) { -} + : DwarfUnit(dwarf::DW_TAG_type_unit, CU.getCUNode(), A, DW, DWU, + SplitLineTable), + CU(CU) {} DwarfUnit::~DwarfUnit() { for (unsigned j = 0, M = DIEBlocks.size(); j < M; ++j) diff --git a/llvm/test/DebugInfo/X86/debug-line-macro-dwo.ll b/llvm/test/DebugInfo/X86/debug-line-macro-dwo.ll new file mode 100644 --- /dev/null +++ b/llvm/test/DebugInfo/X86/debug-line-macro-dwo.ll @@ -0,0 +1,36 @@ +; This test checks emission of .debug_line.dwo section when +; -gdwarf-5 -gsplit-dwarf -fdebug-macro is specified. + +; RUN: %llc_dwarf -dwarf-version=5 -O0 -filetype=asm \ +; RUN: -split-dwarf-file=test.dwo < %s | FileCheck %s + +; CHECK-LABEL: .debug_line.dwo +; CHECK-NEXT: .Lsplit_unit_line_table0: + +; ModuleID = 'test.c' +source_filename = "test.c" +target datalayout = "e-m:e-p200:32:32-p201:32:32-p202:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!14, !15, !16} +!llvm.ident = !{!17} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 11.0.0", isOptimized: false, runtimeVersion: 0, splitDebugFilename: "test.dwo", emissionKind: FullDebug, enums: !2, macros: !3, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/home/", checksumkind: CSK_MD5, checksum: "ef6a7032e0c7ceeef614583f2c00dc80") +!2 = !{} +!3 = !{!4} +!4 = !DIMacroFile(file: !1, nodes: !5) +!5 = !{!6, !10, !13} +!6 = !DIMacroFile(line: 1, file: !7, nodes: !8) +!7 = !DIFile(filename: "./foo.h", directory: "/home/", checksumkind: CSK_MD5, checksum: "0f0cd0e15b44f49d3944992c8dc28661") +!8 = !{!9} +!9 = !DIMacro(type: DW_MACINFO_define, line: 1, name: "FOO", value: "5") +!10 = !DIMacroFile(line: 2, file: !11, nodes: !12) +!11 = !DIFile(filename: "./bar.h", directory: "/home/", checksumkind: CSK_MD5, checksum: "bf4b34c263eaaa1d7085c18243b8d100") +!12 = !{!13} +!13 = !DIMacro(type: DW_MACINFO_undef, line: 14, name: "YEA") +!14 = !{i32 7, !"Dwarf Version", i32 5} +!15 = !{i32 2, !"Debug Info Version", i32 3} +!16 = !{i32 1, !"wchar_size", i32 4} +!17 = !{!"clang version 11.0.0"}