diff options
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 65 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h | 2 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfFile.cpp | 11 | ||||
-rw-r--r-- | llvm/test/DebugInfo/X86/fission-cu.ll | 40 | ||||
-rw-r--r-- | llvm/test/DebugInfo/X86/fission-ranges.ll | 2 | ||||
-rw-r--r-- | llvm/test/DebugInfo/X86/string-offsets-table-order.ll | 8 | ||||
-rw-r--r-- | llvm/test/DebugInfo/X86/string-offsets-table.ll | 20 |
7 files changed, 80 insertions, 68 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 774f7d1df4e..5fc8d0622a4 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -568,25 +568,10 @@ void DwarfDebug::addGnuPubAttributes(DwarfCompileUnit &U, DIE &D) const { U.addFlag(D, dwarf::DW_AT_GNU_pubnames); } -// Create new DwarfCompileUnit for the given metadata node with tag -// DW_TAG_compile_unit. -DwarfCompileUnit & -DwarfDebug::getOrCreateDwarfCompileUnit(const DICompileUnit *DIUnit) { - if (auto *CU = CUMap.lookup(DIUnit)) - return *CU; - StringRef FN = DIUnit->getFilename(); - CompilationDir = DIUnit->getDirectory(); - - auto OwnedUnit = llvm::make_unique<DwarfCompileUnit>( - InfoHolder.getUnits().size(), DIUnit, Asm, this, &InfoHolder); - DwarfCompileUnit &NewCU = *OwnedUnit; +void DwarfDebug::finishUnitAttributes(const DICompileUnit *DIUnit, + DwarfCompileUnit &NewCU) { DIE &Die = NewCU.getUnitDie(); - InfoHolder.addUnit(std::move(OwnedUnit)); - if (useSplitDwarf()) { - NewCU.setSkeleton(constructSkeletonCU(NewCU)); - NewCU.addString(Die, dwarf::DW_AT_GNU_dwo_name, - Asm->TM.Options.MCOptions.SplitDwarfFile); - } + StringRef FN = DIUnit->getFilename(); for (auto *IE : DIUnit->getImportedEntities()) NewCU.addImportedEntity(IE); @@ -640,11 +625,6 @@ DwarfDebug::getOrCreateDwarfCompileUnit(const DICompileUnit *DIUnit) { dwarf::DW_FORM_data1, RVer); } - if (useSplitDwarf()) - NewCU.setSection(Asm->getObjFileLowering().getDwarfInfoDWOSection()); - else - NewCU.setSection(Asm->getObjFileLowering().getDwarfInfoSection()); - if (DIUnit->getDWOId()) { // This CU is either a clang module DWO or a skeleton CU. NewCU.addUInt(Die, dwarf::DW_AT_GNU_dwo_id, dwarf::DW_FORM_data8, @@ -654,9 +634,31 @@ DwarfDebug::getOrCreateDwarfCompileUnit(const DICompileUnit *DIUnit) { NewCU.addString(Die, dwarf::DW_AT_GNU_dwo_name, DIUnit->getSplitDebugFilename()); } +} +// Create new DwarfCompileUnit for the given metadata node with tag +// DW_TAG_compile_unit. +DwarfCompileUnit & +DwarfDebug::getOrCreateDwarfCompileUnit(const DICompileUnit *DIUnit) { + if (auto *CU = CUMap.lookup(DIUnit)) + return *CU; + + CompilationDir = DIUnit->getDirectory(); + + auto OwnedUnit = llvm::make_unique<DwarfCompileUnit>( + InfoHolder.getUnits().size(), DIUnit, Asm, this, &InfoHolder); + DwarfCompileUnit &NewCU = *OwnedUnit; + InfoHolder.addUnit(std::move(OwnedUnit)); + + if (useSplitDwarf()) { + NewCU.setSkeleton(constructSkeletonCU(NewCU)); + NewCU.setSection(Asm->getObjFileLowering().getDwarfInfoDWOSection()); + } else { + finishUnitAttributes(DIUnit, NewCU); + NewCU.setSection(Asm->getObjFileLowering().getDwarfInfoSection()); + } CUMap.insert({DIUnit, &NewCU}); - CUDieMap.insert({&Die, &NewCU}); + CUDieMap.insert({&NewCU.getUnitDie(), &NewCU}); return NewCU; } @@ -851,7 +853,12 @@ void DwarfDebug::finalizeModuleInfo() { // If we're splitting the dwarf out now that we've got the entire // CU then add the dwo id to it. auto *SkCU = TheCU.getSkeleton(); - if (useSplitDwarf()) { + if (useSplitDwarf() && !empty(TheCU.getUnitDie().children())) { + finishUnitAttributes(TheCU.getCUNode(), TheCU); + TheCU.addString(TheCU.getUnitDie(), dwarf::DW_AT_GNU_dwo_name, + Asm->TM.Options.MCOptions.SplitDwarfFile); + SkCU->addString(SkCU->getUnitDie(), dwarf::DW_AT_GNU_dwo_name, + Asm->TM.Options.MCOptions.SplitDwarfFile); // Emit a unique identifier for this CU. uint64_t ID = DIEHash(Asm).computeCUSignature(DWOName, TheCU.getUnitDie()); @@ -870,6 +877,8 @@ void DwarfDebug::finalizeModuleInfo() { SkCU->addSectionLabel(SkCU->getUnitDie(), dwarf::DW_AT_GNU_ranges_base, Sym, Sym); } + } else if (SkCU) { + finishUnitAttributes(SkCU->getCUNode(), *SkCU); } // If we have code split among multiple sections or non-contiguous @@ -882,7 +891,9 @@ void DwarfDebug::finalizeModuleInfo() { // We don't keep track of which addresses are used in which CU so this // is a bit pessimistic under LTO. - if (!AddrPool.isEmpty()) + if (!AddrPool.isEmpty() && + (getDwarfVersion() >= 5 || + (SkCU && !empty(TheCU.getUnitDie().children())))) U.addAddrTableBase(); if (unsigned NumRanges = TheCU.getRanges().size()) { @@ -2483,8 +2494,6 @@ void DwarfDebug::emitDebugMacinfo() { void DwarfDebug::initSkeletonUnit(const DwarfUnit &U, DIE &Die, std::unique_ptr<DwarfCompileUnit> NewU) { - NewU->addString(Die, dwarf::DW_AT_GNU_dwo_name, - Asm->TM.Options.MCOptions.SplitDwarfFile); if (!CompilationDir.empty()) NewU->addString(Die, dwarf::DW_AT_comp_dir, CompilationDir); diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h index c73d442af2f..56aac676ed5 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -540,6 +540,8 @@ class DwarfDebug : public DebugHandlerBase { /// Create new DwarfCompileUnit for the given metadata node with tag /// DW_TAG_compile_unit. DwarfCompileUnit &getOrCreateDwarfCompileUnit(const DICompileUnit *DIUnit); + void finishUnitAttributes(const DICompileUnit *DIUnit, + DwarfCompileUnit &NewCU); /// Construct imported_module or imported_declaration DIE. void constructAndAddImportedEntityDIE(DwarfCompileUnit &TheCU, diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfFile.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfFile.cpp index 4e410bb49be..0bfa1d46008 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfFile.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfFile.cpp @@ -39,13 +39,14 @@ void DwarfFile::emitUnit(DwarfUnit *TheU, bool UseOffsets) { if (TheU->getCUNode()->isDebugDirectivesOnly()) return; - DIE &Die = TheU->getUnitDie(); - MCSection *USection = TheU->getSection(); - Asm->OutStreamer->SwitchSection(USection); + MCSection *S = TheU->getSection(); - TheU->emitHeader(UseOffsets); + if (!S) + return; - Asm->emitDwarfDIE(Die); + Asm->OutStreamer->SwitchSection(S); + TheU->emitHeader(UseOffsets); + Asm->emitDwarfDIE(TheU->getUnitDie()); } // Compute the size and offset for each DIE. diff --git a/llvm/test/DebugInfo/X86/fission-cu.ll b/llvm/test/DebugInfo/X86/fission-cu.ll index 1551bedc981..95669b6dd59 100644 --- a/llvm/test/DebugInfo/X86/fission-cu.ll +++ b/llvm/test/DebugInfo/X86/fission-cu.ll @@ -25,18 +25,18 @@ source_filename = "test/DebugInfo/X86/fission-cu.ll" ; CHECK: Abbrev table for offset: 0x00000000 ; CHECK: [1] DW_TAG_compile_unit DW_CHILDREN_no ; CHECK: DW_AT_stmt_list DW_FORM_sec_offset -; CHECK: DW_AT_GNU_dwo_name DW_FORM_strp ; CHECK: DW_AT_comp_dir DW_FORM_strp +; CHECK: DW_AT_GNU_dwo_name DW_FORM_strp ; CHECK: DW_AT_GNU_dwo_id DW_FORM_data8 ; Check that we're using the right forms. ; CHECK: .debug_abbrev.dwo contents: ; CHECK: Abbrev table for offset: 0x00000000 ; CHECK: [1] DW_TAG_compile_unit DW_CHILDREN_yes -; CHECK: DW_AT_GNU_dwo_name DW_FORM_GNU_str_index ; CHECK: DW_AT_producer DW_FORM_GNU_str_index ; CHECK: DW_AT_language DW_FORM_data2 ; CHECK: DW_AT_name DW_FORM_GNU_str_index +; CHECK: DW_AT_GNU_dwo_name DW_FORM_GNU_str_index ; CHECK-NOT: DW_AT_low_pc ; CHECK-NOT: DW_AT_stmt_list ; CHECK-NOT: DW_AT_comp_dir @@ -58,48 +58,48 @@ source_filename = "test/DebugInfo/X86/fission-cu.ll" ; CHECK: .debug_info contents: ; CHECK: DW_TAG_compile_unit ; CHECK-NEXT: DW_AT_stmt_list [DW_FORM_sec_offset] (0x00000000) -; CHECK-NEXT: DW_AT_GNU_dwo_name [DW_FORM_strp] ( .debug_str[0x00000000] = "baz.dwo") -; CHECK-NEXT: DW_AT_comp_dir [DW_FORM_strp] ( .debug_str[0x00000008] = "/usr/local/google/home/echristo/tmp") +; CHECK-NEXT: DW_AT_comp_dir [DW_FORM_strp] ( .debug_str[0x00000000] = "/usr/local/google/home/echristo/tmp") +; CHECK-NEXT: DW_AT_GNU_dwo_name [DW_FORM_strp] ( .debug_str[0x00000024] = "baz.dwo") ; CHECK-NEXT: DW_AT_GNU_dwo_id [DW_FORM_data8] (0x1f1f859683d49324) ; Check that the rest of the compile units have information. ; CHECK: .debug_info.dwo contents: ; CHECK: DW_TAG_compile_unit -; CHECK: DW_AT_GNU_dwo_name [DW_FORM_GNU_str_index] ( indexed (00000000) string = "baz.dwo") -; CHECK: DW_AT_producer [DW_FORM_GNU_str_index] ( indexed (00000001) string = "clang version 3.3 (trunk 169021) (llvm/trunk 169020)") +; CHECK: DW_AT_producer [DW_FORM_GNU_str_index] ( indexed (00000002) string = "clang version 3.3 (trunk 169021) (llvm/trunk 169020)") ; CHECK: DW_AT_language [DW_FORM_data2] (DW_LANG_C99) -; CHECK: DW_AT_name [DW_FORM_GNU_str_index] ( indexed (00000002) string = "baz.c") +; CHECK: DW_AT_name [DW_FORM_GNU_str_index] ( indexed (00000003) string = "baz.c") +; CHECK: DW_AT_GNU_dwo_name [DW_FORM_GNU_str_index] ( indexed (00000004) string = "baz.dwo") ; CHECK-NOT: DW_AT_low_pc ; CHECK-NOT: DW_AT_stmt_list ; CHECK-NOT: DW_AT_comp_dir ; CHECK: DW_AT_GNU_dwo_id [DW_FORM_data8] (0x1f1f859683d49324) ; CHECK: DW_TAG_variable -; CHECK: DW_AT_name [DW_FORM_GNU_str_index] ( indexed (00000003) string = "a") +; CHECK: DW_AT_name [DW_FORM_GNU_str_index] ( indexed (00000000) string = "a") ; CHECK: DW_AT_type [DW_FORM_ref4] (cu + 0x{{[0-9a-f]*}} => {[[TYPE:0x[0-9a-f]*]]} ; CHECK: DW_AT_external [DW_FORM_flag_present] (true) ; CHECK: DW_AT_decl_file [DW_FORM_data1] (0x01) ; CHECK: DW_AT_decl_line [DW_FORM_data1] (1) ; CHECK: DW_AT_location [DW_FORM_exprloc] (DW_OP_GNU_addr_index 0x0) ; CHECK: [[TYPE]]: DW_TAG_base_type -; CHECK: DW_AT_name [DW_FORM_GNU_str_index] ( indexed (00000004) string = "int") +; CHECK: DW_AT_name [DW_FORM_GNU_str_index] ( indexed (00000001) string = "int") ; CHECK: .debug_str contents: -; CHECK: 0x00000000: "baz.dwo" -; CHECK: 0x00000008: "/usr/local/google/home/echristo/tmp" +; CHECK: 0x00000000: "/usr/local/google/home/echristo/tmp" +; CHECK: 0x00000024: "baz.dwo" ; CHECK: .debug_str.dwo contents: -; CHECK: 0x00000000: "baz.dwo" -; CHECK: 0x00000008: "clang version 3.3 (trunk 169021) (llvm/trunk 169020)" -; CHECK: 0x0000003d: "baz.c" -; CHECK: 0x00000043: "a" -; CHECK: 0x00000045: "int" +; CHECK: 0x00000000: "a" +; CHECK: 0x00000002: "int" +; CHECK: 0x00000006: "clang version 3.3 (trunk 169021) (llvm/trunk 169020)" +; CHECK: 0x0000003b: "baz.c" +; CHECK: 0x00000041: "baz.dwo" ; CHECK: .debug_str_offsets.dwo contents: ; CHECK: 0x00000000: 00000000 -; CHECK: 0x00000004: 00000008 -; CHECK: 0x00000008: 0000003d -; CHECK: 0x0000000c: 00000043 -; CHECK: 0x00000010: 00000045 +; CHECK: 0x00000004: 00000002 +; CHECK: 0x00000008: 00000006 +; CHECK: 0x0000000c: 0000003b +; CHECK: 0x00000010: 00000041 ; Object file checks ; For x86-64-linux we should have this set of relocations for the debug info section diff --git a/llvm/test/DebugInfo/X86/fission-ranges.ll b/llvm/test/DebugInfo/X86/fission-ranges.ll index 5883d2b0c40..1a1dc22870a 100644 --- a/llvm/test/DebugInfo/X86/fission-ranges.ll +++ b/llvm/test/DebugInfo/X86/fission-ranges.ll @@ -8,8 +8,8 @@ ; CHECK: .debug_info contents: ; CHECK: DW_TAG_compile_unit ; CHECK-NEXT: DW_AT_stmt_list -; CHECK-NEXT: DW_AT_GNU_dwo_name ; CHECK-NEXT: DW_AT_comp_dir +; CHECK-NEXT: DW_AT_GNU_dwo_name ; CHECK-NEXT: DW_AT_GNU_dwo_id ; CHECK-NEXT: DW_AT_GNU_ranges_base ; CHECK-NEXT: DW_AT_GNU_addr_base [DW_FORM_sec_offset] (0x00000000) diff --git a/llvm/test/DebugInfo/X86/string-offsets-table-order.ll b/llvm/test/DebugInfo/X86/string-offsets-table-order.ll index 79c0ffcaa3e..1378b134659 100644 --- a/llvm/test/DebugInfo/X86/string-offsets-table-order.ll +++ b/llvm/test/DebugInfo/X86/string-offsets-table-order.ll @@ -13,11 +13,11 @@ ; CHECK: .debug_info contents: ; CHECK: DW_TAG_compile_unit -; CHECK: DW_AT_comp_dir [DW_FORM_strx1] ( indexed (00000001) string = "X3") +; CHECK: DW_AT_comp_dir [DW_FORM_strx1] ( indexed (00000000) string = "X3") ; CHECK: DW_TAG_compile_unit -; CHECK: DW_AT_comp_dir [DW_FORM_strx1] ( indexed (00000002) string = "X2") +; CHECK: DW_AT_comp_dir [DW_FORM_strx1] ( indexed (00000001) string = "X2") ; CHECK: DW_TAG_compile_unit -; CHECK: DW_AT_comp_dir [DW_FORM_strx1] ( indexed (00000003) string = "X1") +; CHECK: DW_AT_comp_dir [DW_FORM_strx1] ( indexed (00000002) string = "X1") ; CHECK: .debug_info.dwo contents: ; CHECK: .debug_str contents: @@ -27,10 +27,10 @@ ; CHECK: .debug_str_offsets contents: ; CHECK: Format = DWARF32, Version = 5 -; CHECK-NEXT: 00000000 "foo.dwo" ; CHECK-NEXT: [[X3]] "X3" ; CHECK-NEXT: [[X2]] "X2" ; CHECK-NEXT: [[X1]] "X1" +; CHECK-NEXT: "foo.dwo" ; CHECK-EMPTY: diff --git a/llvm/test/DebugInfo/X86/string-offsets-table.ll b/llvm/test/DebugInfo/X86/string-offsets-table.ll index b0615106de4..ae7797a3055 100644 --- a/llvm/test/DebugInfo/X86/string-offsets-table.ll +++ b/llvm/test/DebugInfo/X86/string-offsets-table.ll @@ -59,8 +59,8 @@ ; SPLIT: DW_TAG_compile_unit ; SPLIT-NOT: {{DW_TAG|contents:}} ; SPLIT: DW_AT_str_offsets_base [DW_FORM_sec_offset] (0x00000008) -; SPLIT: DW_AT_GNU_dwo_name [DW_FORM_strx1] ( indexed (00000000) string = "foo.dwo") -; SPLIT: DW_AT_comp_dir [DW_FORM_strx1] ( indexed (00000001) string = "/home/test") +; SPLIT: DW_AT_comp_dir [DW_FORM_strx1] ( indexed (00000000) string = "/home/test") +; SPLIT: DW_AT_GNU_dwo_name [DW_FORM_strx1] ( indexed (00000001) string = "foo.dwo") ; Check for the split CU in .debug_info.dwo. ; SPLIT: .debug_info.dwo contents: @@ -73,18 +73,18 @@ ; SPLIT-NOT: contents: ; SPLIT: DW_TAG_enumerator ; SPLIT-NOT: {{DW_TAG|NULL}} -; SPLIT: DW_AT_name [DW_FORM_strx1] ( indexed (00000004) string = "a") +; SPLIT: DW_AT_name [DW_FORM_strx1] ( indexed (00000001) string = "a") ; SPLIT-NOT: contents: ; SPLIT: DW_TAG_enumerator ; SPLIT-NOT: {{DW_TAG|NULL}} -; SPLIT: DW_AT_name [DW_FORM_strx1] ( indexed (00000005) string = "b") +; SPLIT: DW_AT_name [DW_FORM_strx1] ( indexed (00000002) string = "b") ; ; Extract the string offsets referenced in the main file by the skeleton unit. ; SPLIT: .debug_str contents: -; SPLIT-NEXT: 0x00000000: "foo.dwo" -; SPLIT-NEXT: 0x[[STRING2SPLIT:[0-9a-f]*]]: "/home/test" -; SPLIT-NEXT: 0x[[STRING3SPLIT:[0-9a-f]*]]: "E" -; SPLIT-NEXT: 0x[[STRING4SPLIT:[0-9a-f]*]]: "glob" +; SPLIT-NEXT: 0x[[STRHOMETESTSPLIT:[0-9a-f]*]]: "/home/test" +; SPLIT-NEXT: 0x[[STRESPLIT:[0-9a-f]*]]: "E" +; SPLIT-NEXT: 0x[[STRGLOBSPLIT:[0-9a-f]*]]: "glob" +; SPLIT-NEXT: 0x[[STRFOODWOSPLIT:[0-9a-f]*]]: "foo.dwo" ; ; Extract the string offsets referenced in the .dwo file by the split unit. ; SPLIT: .debug_str.dwo contents: @@ -98,8 +98,8 @@ ; referenced by the debug info. ; SPLIT: .debug_str_offsets contents: ; SPLIT-NEXT: 0x00000000: Contribution size = 12, Format = DWARF32, Version = 5 -; SPLIT-NEXT: 0x00000008: 00000000 "foo.dwo" -; SPLIT-NEXT: 0x0000000c: [[STRING2SPLIT]] "/home/test" +; SPLIT-NEXT: 0x00000008: [[STRHOMETESTSPLIT]] "/home/test" +; SPLIT-NEXT: 0x0000000c: [[STRFOODWOSPLIT]] "foo.dwo" ; SPLIT-EMPTY: ; SPLIT: .debug_str_offsets.dwo contents: |