diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h --- a/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h +++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h @@ -294,6 +294,7 @@ dwarf::DwarfFormat getFormat() const { return Header.getFormat(); } uint8_t getUnitType() const { return Header.getUnitType(); } bool isTypeUnit() const { return Header.isTypeUnit(); } + uint64_t getAbbrOffset() const { return Header.getAbbrOffset(); } uint64_t getNextUnitOffset() const { return Header.getNextUnitOffset(); } const DWARFSection &getLineSection() const { return LineSection; } StringRef getStringSection() const { return StringSection; } @@ -480,7 +481,6 @@ /// The unit needs to have its DIEs extracted for this method to work. DWARFDie getDIEForOffset(uint64_t Offset) { extractDIEsIfNeeded(false); - assert(!DieArray.empty()); auto It = llvm::partition_point(DieArray, [=](const DWARFDebugInfoEntry &DIE) { return DIE.getOffset() < Offset; diff --git a/llvm/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp b/llvm/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp --- a/llvm/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp @@ -22,9 +22,10 @@ << ", version = " << format("0x%04x", getVersion()); if (getVersion() >= 5) OS << ", unit_type = " << dwarf::UnitTypeString(getUnitType()); - OS << ", abbr_offset = " - << format("0x%04" PRIx64, getAbbreviations()->getOffset()) - << ", addr_size = " << format("0x%02x", getAddressByteSize()); + OS << ", abbr_offset = " << format("0x%04" PRIx64, getAbbrOffset()); + if (!getAbbreviations()) + OS << " (invalid)"; + OS << ", addr_size = " << format("0x%02x", getAddressByteSize()); if (getVersion() >= 5 && getUnitType() != dwarf::DW_UT_compile) OS << ", DWO_id = " << format("0x%016" PRIx64, *getDWOId()); OS << " (next unit at " << format("0x%08" PRIx64, getNextUnitOffset()) diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp --- a/llvm/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp @@ -38,7 +38,8 @@ AbbrevDecl = nullptr; return true; } - AbbrevDecl = U.getAbbreviations()->getAbbreviationDeclaration(AbbrCode); + if (const auto *AbbrevSet = U.getAbbreviations()) + AbbrevDecl = AbbrevSet->getAbbreviationDeclaration(AbbrCode); if (nullptr == AbbrevDecl) { // Restore the original offset. *OffsetPtr = Offset; diff --git a/llvm/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp b/llvm/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp --- a/llvm/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp @@ -36,9 +36,10 @@ << ", version = " << format("0x%04x", getVersion()); if (getVersion() >= 5) OS << ", unit_type = " << dwarf::UnitTypeString(getUnitType()); - OS << ", abbr_offset = " - << format("0x%04" PRIx64, getAbbreviations()->getOffset()) - << ", addr_size = " << format("0x%02x", getAddressByteSize()) + OS << ", abbr_offset = " << format("0x%04" PRIx64, getAbbrOffset()); + if (!getAbbreviations()) + OS << " (invalid)"; + OS << ", addr_size = " << format("0x%02x", getAddressByteSize()) << ", name = '" << Name << "'" << ", type_signature = " << format("0x%016" PRIx64, getTypeHash()) << ", type_offset = " << format("0x%04" PRIx64, getTypeOffset()) diff --git a/llvm/test/tools/llvm-dwarfdump/X86/invalid_abbrev_offset.s b/llvm/test/tools/llvm-dwarfdump/X86/invalid_abbrev_offset.s new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-dwarfdump/X86/invalid_abbrev_offset.s @@ -0,0 +1,32 @@ +# RUN: llvm-mc %s -filetype obj -triple x86_64 -o %t +# RUN: llvm-dwarfdump -debug-info -debug-types %t | FileCheck %s + +# CHECK: .debug_info contents: +# CHECK-NEXT: Compile Unit: {{.+}}, abbr_offset = 0x00a5 (invalid), +# CHECK-NEXT: + +# CHECK: .debug_types contents: +# CHECK-NEXT: Type Unit: {{.+}}, abbr_offset = 0x00a5 (invalid), addr_size = 0x08, name = '', +# CHECK-NEXT: + + .section .debug_info,"",@progbits + .long .LCUEnd-.LCUVersion # Length of Unit +.LCUVersion: + .short 4 # DWARF version number + .long 0xa5 # Offset Into Abbrev. Section (invalid) + .byte 8 # Address Size + .byte 1 # Abbreviation code +.LCUEnd: + + .section .debug_types,"",@progbits +.LTUBegin: + .long .LTUEnd-.LTUVersion # Length of Unit +.LTUVersion: + .short 4 # DWARF version number + .long 0xa5 # Offset Into Abbrev. Section (invalid) + .byte 8 # Address Size + .quad 0x0011223344556677 # Type Signature + .long .LTUType-.LTUBegin # Type offset +.LTUType: + .byte 1 # Abbreviation code +.LTUEnd: