Index: include/llvm/BinaryFormat/Dwarf.def =================================================================== --- include/llvm/BinaryFormat/Dwarf.def +++ include/llvm/BinaryFormat/Dwarf.def @@ -823,21 +823,16 @@ HANDLE_DW_UT(0x05, split_compile) HANDLE_DW_UT(0x06, split_type) -// DWARF section types. (enum name, ELF name, cmdline name) +// DWARF section types. (enum name, ELF name, ELF DWO name, cmdline name) // Note that these IDs don't mean anything. // TODO: Add Mach-O and COFF names. // Official DWARF sections. HANDLE_DWARF_SECTION(DebugAbbrev, ".debug_abbrev", "debug-abbrev") -HANDLE_DWARF_SECTION(DebugAbbrevDwo, ".debug_abbrev.dwo", "debug-abbrev-dwo") HANDLE_DWARF_SECTION(DebugAranges, ".debug_aranges", "debug-aranges") HANDLE_DWARF_SECTION(DebugInfo, ".debug_info", "debug-info") -HANDLE_DWARF_SECTION(DebugInfoDwo, ".debug_info.dwo", "debug-info-dwo") HANDLE_DWARF_SECTION(DebugTypes, ".debug_types", "debug-types") -HANDLE_DWARF_SECTION(DebugTypesDwo, ".debug_types.dwo", "debug-types-dwo") HANDLE_DWARF_SECTION(DebugLine, ".debug_line", "debug-line") -HANDLE_DWARF_SECTION(DebugLineDwo, ".debug_line.dwo", "debug-line-dwo") HANDLE_DWARF_SECTION(DebugLoc, ".debug_loc", "debug-loc") -HANDLE_DWARF_SECTION(DebugLocDwo, ".debug_loc.dwo", "debug-loc-dwo") HANDLE_DWARF_SECTION(DebugFrames, ".debug_frames", "debug-frames") HANDLE_DWARF_SECTION(DebugMacro, ".debug_macro", "debug-macro") HANDLE_DWARF_SECTION(DebugRanges, ".debug_ranges", "debug-ranges") @@ -847,8 +842,6 @@ HANDLE_DWARF_SECTION(DebugGnuPubtypes, ".debug_gnu_pubtypes", "debug-gnu-pubtypes") HANDLE_DWARF_SECTION(DebugStr, ".debug_str", "debug-str") HANDLE_DWARF_SECTION(DebugStrOffsets, ".debug_str_offsets", "debug-str-offsets") -HANDLE_DWARF_SECTION(DebugStrDwo, ".debug_str.dwo", "debug-str-dwo") -HANDLE_DWARF_SECTION(DebugStrOffsetsDwo, ".debug_str_offsets.dwo", "debug-str-offsets-dwo") HANDLE_DWARF_SECTION(DebugCUIndex, ".debug_cu_index", "debug-cu-index") HANDLE_DWARF_SECTION(DebugTUIndex, ".debug_tu_index", "debug-tu-index") // Vendor extensions. Index: include/llvm/DebugInfo/DIContext.h =================================================================== --- include/llvm/DebugInfo/DIContext.h +++ include/llvm/DebugInfo/DIContext.h @@ -121,14 +121,14 @@ #undef HANDLE_DWARF_SECTION DIDT_ID_Count, }; - static_assert(DIDT_ID_Count <= 64, "section types overflow storage"); + static_assert(DIDT_ID_Count <= 32, "section types overflow storage"); /// Selects which debug sections get dumped. -enum DIDumpType : uint64_t { +enum DIDumpType : unsigned { DIDT_Null, - DIDT_All = ~0ULL, + DIDT_All = ~0U, #define HANDLE_DWARF_SECTION(ENUM_NAME, ELF_NAME, CMDLINE_NAME) \ - DIDT_##ENUM_NAME = 1 << (DIDT_ID##ENUM_NAME - 1), + DIDT_##ENUM_NAME = 1U << (DIDT_ID##ENUM_NAME - 1), #include "llvm/BinaryFormat/Dwarf.def" #undef HANDLE_DWARF_SECTION }; @@ -136,7 +136,7 @@ /// Container for dump options that control which debug information will be /// dumped. struct DIDumpOptions { - uint64_t DumpType = DIDT_All; + unsigned DumpType = DIDT_All; bool DumpEH = false; bool SummarizeTypes = false; bool Brief = false; @@ -156,7 +156,7 @@ virtual void dump(raw_ostream &OS, DIDumpOptions DumpOpts) = 0; - virtual bool verify(raw_ostream &OS, uint64_t DumpType = DIDT_All) { + virtual bool verify(raw_ostream &OS, unsigned DumpType = DIDT_All) { // No verifier? Just say things went well. return true; } Index: include/llvm/DebugInfo/DWARF/DWARFContext.h =================================================================== --- include/llvm/DebugInfo/DWARF/DWARFContext.h +++ include/llvm/DebugInfo/DWARF/DWARFContext.h @@ -123,7 +123,7 @@ void dump(raw_ostream &OS, DIDumpOptions DumpOpts) override; - bool verify(raw_ostream &OS, uint64_t DumpType = DIDT_All) override; + bool verify(raw_ostream &OS, unsigned DumpType = DIDT_All) override; using cu_iterator_range = DWARFUnitSection::iterator_range; using tu_iterator_range = DWARFUnitSection::iterator_range; Index: include/llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h =================================================================== --- include/llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h +++ include/llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h @@ -67,6 +67,7 @@ void dump(raw_ostream &OS) const; void extract(DataExtractor Data); + bool empty() const { return begin() == end(); } DWARFAbbreviationDeclarationSetMap::const_iterator begin() const { return AbbrDeclSets.begin(); Index: include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h =================================================================== --- include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h +++ include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h @@ -36,6 +36,9 @@ /// data is assumed to be pointing to the beginning of the section. void parse(DataExtractor Data); + /// Return whether the section has any entries. + bool empty() const { return Entries.empty(); } + private: std::vector> Entries; }; Index: lib/DebugInfo/DWARF/DWARFContext.cpp =================================================================== --- lib/DebugInfo/DWARF/DWARFContext.cpp +++ lib/DebugInfo/DWARF/DWARFContext.cpp @@ -207,56 +207,49 @@ if (DumpType & DIDT_DebugAbbrev) { OS << ".debug_abbrev contents:\n"; getDebugAbbrev()->dump(OS); - } - - if (DumpType & DIDT_DebugAbbrevDwo) - if (const DWARFDebugAbbrev *D = getDebugAbbrevDWO()) { + if (!getDebugAbbrevDWO()->empty()) { OS << "\n.debug_abbrev.dwo contents:\n"; - D->dump(OS); + getDebugAbbrevDWO()->dump(OS); } + } if (DumpType & DIDT_DebugInfo) { OS << "\n.debug_info contents:\n"; for (const auto &CU : compile_units()) CU->dump(OS, DumpOpts); + if (getNumDWOCompileUnits()) { + OS << "\n.debug_info.dwo contents:\n"; + for (const auto &DWOCU : dwo_compile_units()) + DWOCU->dump(OS, DumpOpts); + } } - if ((DumpType & DIDT_DebugInfoDwo) && - getNumDWOCompileUnits()) { - OS << "\n.debug_info.dwo contents:\n"; - for (const auto &DWOCU : dwo_compile_units()) - DWOCU->dump(OS, DumpOpts); - } - - if ((DumpType & DIDT_DebugTypes) && getNumTypeUnits()) { + if ((DumpType & DIDT_DebugTypes)) { OS << "\n.debug_types contents:\n"; for (const auto &TUS : type_unit_sections()) for (const auto &TU : TUS) TU->dump(OS, SummarizeTypes); - } - - if ((DumpType & DIDT_DebugTypesDwo) && - getNumDWOTypeUnits()) { - OS << "\n.debug_types.dwo contents:\n"; - for (const auto &DWOTUS : dwo_type_unit_sections()) - for (const auto &DWOTU : DWOTUS) - DWOTU->dump(OS, SummarizeTypes); + if (getNumDWOTypeUnits()) { + OS << "\n.debug_types.dwo contents:\n"; + for (const auto &DWOTUS : dwo_type_unit_sections()) + for (const auto &DWOTU : DWOTUS) + DWOTU->dump(OS, SummarizeTypes); + } } if (DumpType & DIDT_DebugLoc) { OS << "\n.debug_loc contents:\n"; getDebugLoc()->dump(OS, getRegisterInfo()); - } - - if (DumpType & DIDT_DebugLocDwo) { - OS << "\n.debug_loc.dwo contents:\n"; - getDebugLocDWO()->dump(OS, getRegisterInfo()); + if (getDebugLocDWO()) { + OS << "\n.debug_loc.dwo contents:\n"; + getDebugLocDWO()->dump(OS, getRegisterInfo()); + } } if (DumpType & DIDT_DebugFrames) { OS << "\n.debug_frame contents:\n"; getDebugFrame()->dump(OS); - if (DumpEH) { + if (DumpEH && !getEHFrame()->empty()) { OS << "\n.eh_frame contents:\n"; getEHFrame()->dump(OS); } @@ -293,6 +286,17 @@ LineTable.dump(OS); } } + if (!DObj->getLineDWOSection().Data.empty()) { + OS << "\n.debug_line.dwo contents:\n"; + unsigned stmtOffset = 0; + DWARFDataExtractor lineData(*DObj, DObj->getLineDWOSection(), + isLittleEndian(), savedAddressByteSize); + DWARFDebugLine::LineTable LineTable; + while (LineTable.Prologue.parse(lineData, &stmtOffset)) { + LineTable.dump(OS); + LineTable.clear(); + } + } } if (DumpType & DIDT_DebugCUIndex) { @@ -305,18 +309,6 @@ getTUIndex().dump(OS); } - if (DumpType & DIDT_DebugLineDwo) { - OS << "\n.debug_line.dwo contents:\n"; - unsigned stmtOffset = 0; - DWARFDataExtractor lineData(*DObj, DObj->getLineDWOSection(), - isLittleEndian(), savedAddressByteSize); - DWARFDebugLine::LineTable LineTable; - while (LineTable.Prologue.parse(lineData, &stmtOffset)) { - LineTable.dump(OS); - LineTable.clear(); - } - } - if (DumpType & DIDT_DebugStr) { OS << "\n.debug_str contents:\n"; DataExtractor strData(DObj->getStringSection(), isLittleEndian(), 0); @@ -326,17 +318,16 @@ OS << format("0x%8.8x: \"%s\"\n", strOffset, s); strOffset = offset; } - } - - if ((DumpType & DIDT_DebugStrDwo) && - !DObj->getStringDWOSection().empty()) { - OS << "\n.debug_str.dwo contents:\n"; - DataExtractor strDWOData(DObj->getStringDWOSection(), isLittleEndian(), 0); - offset = 0; - uint32_t strDWOOffset = 0; - while (const char *s = strDWOData.getCStr(&offset)) { - OS << format("0x%8.8x: \"%s\"\n", strDWOOffset, s); - strDWOOffset = offset; + if (!DObj->getStringDWOSection().empty()) { + OS << "\n.debug_str.dwo contents:\n"; + DataExtractor strDWOData(DObj->getStringDWOSection(), isLittleEndian(), + 0); + offset = 0; + uint32_t strDWOOffset = 0; + while (const char *s = strDWOData.getCStr(&offset)) { + OS << format("0x%8.8x: \"%s\"\n", strDWOOffset, s); + strDWOOffset = offset; + } } } @@ -372,15 +363,15 @@ true /* GnuStyle */) .dump("debug_gnu_pubtypes", OS); - if (DumpType & DIDT_DebugStrOffsets) - dumpStringOffsetsSection( - OS, "debug_str_offsets", *DObj, DObj->getStringOffsetSection(), - DObj->getStringSection(), isLittleEndian(), getMaxVersion()); - - if (DumpType & DIDT_DebugStrOffsetsDwo) { - dumpStringOffsetsSection( - OS, "debug_str_offsets.dwo", *DObj, DObj->getStringOffsetDWOSection(), - DObj->getStringDWOSection(), isLittleEndian(), getMaxVersion()); + if (DumpType & DIDT_DebugStrOffsets) { + if (!DObj->getStringOffsetSection().Data.empty()) + dumpStringOffsetsSection( + OS, "debug_str_offsets", *DObj, DObj->getStringOffsetSection(), + DObj->getStringSection(), isLittleEndian(), getMaxVersion()); + if (!DObj->getStringOffsetDWOSection().Data.empty()) + dumpStringOffsetsSection( + OS, "debug_str_offsets.dwo", *DObj, DObj->getStringOffsetDWOSection(), + DObj->getStringDWOSection(), isLittleEndian(), getMaxVersion()); } if ((DumpType & DIDT_GdbIndex) && @@ -434,7 +425,7 @@ return DWARFDie(); } -bool DWARFContext::verify(raw_ostream &OS, uint64_t DumpType) { +bool DWARFContext::verify(raw_ostream &OS, unsigned DumpType) { bool Success = true; DWARFVerifier verifier(OS, *this); Index: test/DebugInfo/X86/fission-inline.ll =================================================================== --- test/DebugInfo/X86/fission-inline.ll +++ test/DebugInfo/X86/fission-inline.ll @@ -71,6 +71,7 @@ ; CHECK: DW_AT_call_file ; CHECK-NEXT: DW_AT_call_line {{.*}} (18) ; CHECK-NOT: DW_ +; CHECK: .debug_info.dwo contents: ; RELOCS-NOT: RELOCATION RECORDS FOR [.rela.debug_ranges] Index: test/DebugInfo/X86/fission-no-inlining.ll =================================================================== --- test/DebugInfo/X86/fission-no-inlining.ll +++ test/DebugInfo/X86/fission-no-inlining.ll @@ -1,6 +1,8 @@ ; RUN: llc -split-dwarf-file=foo.dwo -O0 < %s -mtriple=x86_64-unknown-linux-gnu -filetype=obj | llvm-dwarfdump -debug-info - | FileCheck %s +; CHECK: .debug_info contents: ; CHECK-NOT: DW_TAG_subprogram +; CHECK: .debug_info.dwo contents: ; IR generated from the following source: ; void f1(); Index: test/DebugInfo/X86/generate-odr-hash.ll =================================================================== --- test/DebugInfo/X86/generate-odr-hash.ll +++ test/DebugInfo/X86/generate-odr-hash.ll @@ -74,8 +74,7 @@ ; CHECK-NEXT: DW_AT_signature {{.*}} (0xfd756cee88f8a118) ; SINGLE-LABEL: .debug_types contents: -; FISSION-NOT: .debug_types contents: -; FISSION-LABEL: .debug_types.dwo contents: +; FISSION: .debug_types contents: ; Check that we generate a hash for bar and the value. ; CHECK-NOT: type_signature @@ -127,7 +126,8 @@ ; CHECK: file_names{{.*}} bar.cpp ; CHECK-NOT: file_names[ -; CHECK-LABEL: .debug_line.dwo contents: +; FISSION: .debug_line.dwo contents: +; CHECK-NOT: .debug_line.dwo contents: ; FISSION: Line table prologue ; FISSION: opcode_base: 1 ; FISSION-NOT: standard_opcode_lengths Index: test/DebugInfo/X86/live-debug-variables.ll =================================================================== --- test/DebugInfo/X86/live-debug-variables.ll +++ test/DebugInfo/X86/live-debug-variables.ll @@ -27,6 +27,7 @@ ; CHECK-NEXT: 0x000000000000001f - 0x000000000000003c: DW_OP_reg3 RBX ; We should only have one entry ; CHECK-NOT: : +; CHECK: .debug_loc.dwo contents: declare i32 @foobar(i32, i32, i32, i32, i32) Index: test/DebugInfo/X86/split-dwarf-cross-unit-reference.ll =================================================================== --- test/DebugInfo/X86/split-dwarf-cross-unit-reference.ll +++ test/DebugInfo/X86/split-dwarf-cross-unit-reference.ll @@ -1,11 +1,11 @@ ; RUN: llc -mtriple=x86_64-linux -split-dwarf-cross-cu-references -split-dwarf-file=foo.dwo -filetype=obj -o %t < %s ; RUN: llvm-objdump -r %t | FileCheck %s -; RUN: llvm-dwarfdump -v -debug-info-dwo %t | FileCheck --check-prefix=ALL --check-prefix=INFO --check-prefix=DWO --check-prefix=CROSS %s +; RUN: llvm-dwarfdump -v -debug-info %t | FileCheck --check-prefix=ALL --check-prefix=INFO --check-prefix=DWO --check-prefix=CROSS %s ; RUN: llvm-dwarfdump -v -debug-info %t | FileCheck --check-prefix=ALL --check-prefix=INFO %s ; RUN: llc -mtriple=x86_64-linux -split-dwarf-file=foo.dwo -filetype=obj -o %t < %s ; RUN: llvm-objdump -r %t | FileCheck %s -; RUN: llvm-dwarfdump -v -debug-info-dwo %t | FileCheck --check-prefix=ALL --check-prefix=DWO --check-prefix=NOCROSS %s +; RUN: llvm-dwarfdump -v -debug-info %t | FileCheck --check-prefix=ALL --check-prefix=DWO --check-prefix=NOCROSS %s ; RUN: llvm-dwarfdump -v -debug-info %t | FileCheck --check-prefix=ALL --check-prefix=INFO %s ; Testing cross-CU references for types, subprograms, and variables @@ -42,6 +42,7 @@ ; * debug_info.dwo contains duplicate types, abstract subprograms and abstract ; variables otherwise to avoid the need for cross-cu references +; DWO: .debug_info.dwo contents: ; CHECK-NOT: .rel{{a?}}.debug_info.dwo ; CHECK: RELOCATION RECORDS FOR [.rel{{a?}}.debug_info]: ; CHECK-NOT: RELOCATION RECORDS Index: test/DebugInfo/X86/split-dwarf-multiple-cu-hash.ll =================================================================== --- test/DebugInfo/X86/split-dwarf-multiple-cu-hash.ll +++ test/DebugInfo/X86/split-dwarf-multiple-cu-hash.ll @@ -3,8 +3,10 @@ ; RUN: %llc_dwarf -split-dwarf-file=bar.dwo %s -filetype=obj -o %t/b.o ; RUN: llvm-dwarfdump -debug-info %t/a.o %t/b.o | FileCheck %s +; CHECK: .debug_info contents: ; CHECK: dwo_id {{.*}}([[HASH:.*]]) ; CHECK-NOT: dwo_id {{.*}}([[HASH]]) +; CHECK: .debug_info.dwo contents: target triple = "x86_64-pc-linux" Index: test/DebugInfo/X86/split-dwarf-omit-empty.ll =================================================================== --- test/DebugInfo/X86/split-dwarf-omit-empty.ll +++ test/DebugInfo/X86/split-dwarf-omit-empty.ll @@ -15,8 +15,10 @@ ; will be emitted. This emulates something more like the available_externally ; import performed by ThinLTO. +; CHECK: .debug_info contents: ; CHECK: Compile Unit ; CHECK-NOT: Compile Unit +; CHECK: .debug_info.dwo contents: target triple = "x86_64-pc-linux" Index: tools/llvm-dwarfdump/llvm-dwarfdump.cpp =================================================================== --- tools/llvm-dwarfdump/llvm-dwarfdump.cpp +++ tools/llvm-dwarfdump/llvm-dwarfdump.cpp @@ -44,7 +44,7 @@ static cl::alias DumpAllAlias("a", cl::desc("Alias for --all"), cl::aliasopt(DumpAll)); -static uint64_t DumpType = DIDT_Null; +static unsigned DumpType = DIDT_Null; #define HANDLE_DWARF_SECTION(ENUM_NAME, ELF_NAME, CMDLINE_NAME) \ static cl::opt Dump##ENUM_NAME( \ CMDLINE_NAME, cl::desc("Dump the " ELF_NAME " section"));