diff options
author | Alex Langford <alangford@apple.com> | 2024-04-23 11:01:54 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-04-23 11:01:54 -0700 |
commit | 1a8935ada7cb0bb7943e18f2bc9f6d7a89887aa8 (patch) | |
tree | 7404510e53fdd710e9815a8e881bf7d895ec624b | |
parent | 9e9595183001991a7d31d8880c4a2b33594ca30f (diff) |
[DebugInfo] Report errors when DWARFUnitHeader::applyIndexEntry fails (#89156)
Motivation: LLDB is able to report errors about these scenarios whereas
LLVM's DWARF parser only gives a boolean success/fail. I want to migrate
LLDB to using LLVM's DWARFUnitHeader class, but I don't want to lose
some of the error reporting, so I'm adding it to the LLVM class first.
-rw-r--r-- | llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h | 2 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp | 41 | ||||
-rw-r--r-- | llvm/test/DebugInfo/X86/invalid-cu-abbrev-contribution-dwp.s | 58 | ||||
-rw-r--r-- | llvm/test/DebugInfo/X86/invalid-cu-abbrev-offset-dwp.s | 58 | ||||
-rw-r--r-- | llvm/test/DebugInfo/X86/invalid-cu-length-dwp.s | 4 |
5 files changed, 152 insertions, 11 deletions
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h index f20e71781f46..80c27aea8931 100644 --- a/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h +++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h @@ -85,7 +85,7 @@ public: uint64_t *offset_ptr, DWARFSectionKind SectionKind); // For units in DWARF Package File, remember the index entry and update // the abbreviation offset read by extract(). - bool applyIndexEntry(const DWARFUnitIndex::Entry *Entry); + Error applyIndexEntry(const DWARFUnitIndex::Entry *Entry); uint64_t getOffset() const { return Offset; } const dwarf::FormParams &getFormParams() const { return FormParams; } uint16_t getVersion() const { return FormParams.Version; } diff --git a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp index 9f455fa7e96a..bdd04b00f557 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp @@ -98,8 +98,12 @@ void DWARFUnitVector::addUnitsImpl( if (!IndexEntry) IndexEntry = Index.getFromOffset(Header.getOffset()); } - if (IndexEntry && !Header.applyIndexEntry(IndexEntry)) - return nullptr; + if (IndexEntry) { + if (Error ApplicationErr = Header.applyIndexEntry(IndexEntry)) { + Context.getWarningHandler()(std::move(ApplicationErr)); + return nullptr; + } + } std::unique_ptr<DWARFUnit> U; if (Header.isTypeUnit()) U = std::make_unique<DWARFTypeUnit>(Context, InfoSection, Header, DA, @@ -334,21 +338,40 @@ Error DWARFUnitHeader::extract(DWARFContext &Context, return Error::success(); } -bool DWARFUnitHeader::applyIndexEntry(const DWARFUnitIndex::Entry *Entry) { +Error DWARFUnitHeader::applyIndexEntry(const DWARFUnitIndex::Entry *Entry) { assert(Entry); assert(!IndexEntry); IndexEntry = Entry; if (AbbrOffset) - return false; + return createStringError(errc::invalid_argument, + "DWARF package unit at offset 0x%8.8" PRIx64 + " has a non-zero abbreviation offset", + Offset); + auto *UnitContrib = IndexEntry->getContribution(); - if (!UnitContrib || - UnitContrib->getLength() != (getLength() + getUnitLengthFieldByteSize())) - return false; + if (!UnitContrib) + return createStringError(errc::invalid_argument, + "DWARF package unit at offset 0x%8.8" PRIx64 + " has no contribution index", + Offset); + + uint64_t IndexLength = getLength() + getUnitLengthFieldByteSize(); + if (UnitContrib->getLength() != IndexLength) + return createStringError(errc::invalid_argument, + "DWARF package unit at offset 0x%8.8" PRIx64 + " has an inconsistent index (expected: %" PRIu64 + ", actual: %" PRIu64 ")", + Offset, UnitContrib->getLength(), IndexLength); + auto *AbbrEntry = IndexEntry->getContribution(DW_SECT_ABBREV); if (!AbbrEntry) - return false; + return createStringError(errc::invalid_argument, + "DWARF package unit at offset 0x%8.8" PRIx64 + " missing abbreviation column", + Offset); + AbbrOffset = AbbrEntry->getOffset(); - return true; + return Error::success(); } Error DWARFUnit::extractRangeList(uint64_t RangeListOffset, diff --git a/llvm/test/DebugInfo/X86/invalid-cu-abbrev-contribution-dwp.s b/llvm/test/DebugInfo/X86/invalid-cu-abbrev-contribution-dwp.s new file mode 100644 index 000000000000..6cc539cf8594 --- /dev/null +++ b/llvm/test/DebugInfo/X86/invalid-cu-abbrev-contribution-dwp.s @@ -0,0 +1,58 @@ +# RUN: llvm-mc -triple x86_64-unknown-linux %s -filetype=obj -o - | \ +# RUN: llvm-dwarfdump -debug-info - 2>&1 | FileCheck %s + +# CHECK: warning: DWARF package unit at offset 0x00000000 missing abbreviation column + + .section .debug_abbrev.dwo, "e", @progbits +.LAbbrBegin: + .uleb128 1 # Abbreviation Code + .uleb128 17 # DW_TAG_compile_unit + .byte 0 # DW_CHILDREN_no + .uleb128 3 # DW_AT_name + .uleb128 8 # DW_FORM_string + .uleb128 0x2131 # DW_AT_GNU_dwo_id + .uleb128 7 # DW_FORM_data8 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) +.LAbbrEnd: + + .section .debug_info.dwo, "e", @progbits +.LCUBegin: + .long .LCUEnd-.LCUVersion # Length +.LCUVersion: + .short 4 # Version + .long 0 # Abbrev offset + .byte 4 # Address size + .uleb128 1 # Abbrev [1] DW_TAG_compile_unit + .asciz "a.c" # DW_AT_name + .quad 0x1100001122222222 # DW_AT_GNU_dwo_id +.LCUEnd: + + .section .debug_cu_index, "", @progbits +## Header: + .short 2 # Version + .space 2 # Padding + .long 1 # Section count (Invalid, should be 2) + .long 1 # Unit count + .long 4 # Slot count +## Hash Table of Signatures: + .quad 0 + .quad 0 + .quad 0x1100001122222222 + .quad 0 +## Parallel Table of Indexes: + .long 0 + .long 0 + .long 1 + .long 0 +## Table of Section Offsets: +## Row 0: + .long 1 # DW_SECT_INFO +# .long 3 # DW_SECT_ABBREV (Intentionally omitted) +## Row 1: + .long .LCUBegin-.debug_info.dwo # Offset in .debug_info.dwo +# .long .LAbbrBegin-.debug_abbrev.dwo # Offset in .debug_abbrev.dwo (Intentionally omitted) +## Table of Section Sizes: + .long .LCUEnd-.LCUBegin # Size of the contribution in .debug_info.dwo + .long .LAbbrEnd-.LAbbrBegin # Size of the contribution in .debug_abbrev.dwo (Intentionally omitted) diff --git a/llvm/test/DebugInfo/X86/invalid-cu-abbrev-offset-dwp.s b/llvm/test/DebugInfo/X86/invalid-cu-abbrev-offset-dwp.s new file mode 100644 index 000000000000..b9e769e3ed4a --- /dev/null +++ b/llvm/test/DebugInfo/X86/invalid-cu-abbrev-offset-dwp.s @@ -0,0 +1,58 @@ +# RUN: llvm-mc -triple x86_64-unknown-linux %s -filetype=obj -o - | \ +# RUN: llvm-dwarfdump -debug-info - 2>&1 | FileCheck %s + +# CHECK: warning: DWARF package unit at offset 0x00000000 has a non-zero abbreviation offset + + .section .debug_abbrev.dwo, "e", @progbits +.LAbbrBegin: + .uleb128 1 # Abbreviation Code + .uleb128 17 # DW_TAG_compile_unit + .byte 0 # DW_CHILDREN_no + .uleb128 3 # DW_AT_name + .uleb128 8 # DW_FORM_string + .uleb128 0x2131 # DW_AT_GNU_dwo_id + .uleb128 7 # DW_FORM_data8 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) +.LAbbrEnd: + + .section .debug_info.dwo, "e", @progbits +.LCUBegin: + .long .LCUEnd-.LCUVersion # Length +.LCUVersion: + .short 4 # Version + .long 1 # Abbrev offset (Invalid, should be 0) + .byte 4 # Address size + .uleb128 1 # Abbrev [1] DW_TAG_compile_unit + .asciz "a.c" # DW_AT_name + .quad 0x1100001122222222 # DW_AT_GNU_dwo_id +.LCUEnd: + + .section .debug_cu_index, "", @progbits +## Header: + .short 2 # Version + .space 2 # Padding + .long 2 # Section count + .long 1 # Unit count + .long 4 # Slot count +## Hash Table of Signatures: + .quad 0 + .quad 0 + .quad 0x1100001122222222 + .quad 0 +## Parallel Table of Indexes: + .long 0 + .long 0 + .long 1 + .long 0 +## Table of Section Offsets: +## Row 0: + .long 1 # DW_SECT_INFO + .long 3 # DW_SECT_ABBREV +## Row 1: + .long .LCUBegin-.debug_info.dwo # Offset in .debug_info.dwo + .long .LAbbrBegin-.debug_abbrev.dwo # Offset in .debug_abbrev.dwo +## Table of Section Sizes: + .long .LCUEnd-.LCUBegin + .long .LAbbrEnd-.LAbbrBegin diff --git a/llvm/test/DebugInfo/X86/invalid-cu-length-dwp.s b/llvm/test/DebugInfo/X86/invalid-cu-length-dwp.s index 299bea1bf1a7..d67416736093 100644 --- a/llvm/test/DebugInfo/X86/invalid-cu-length-dwp.s +++ b/llvm/test/DebugInfo/X86/invalid-cu-length-dwp.s @@ -1,9 +1,11 @@ # RUN: llvm-mc -triple x86_64-unknown-linux %s -filetype=obj -o - | \ -# RUN: llvm-dwarfdump -debug-info - +# RUN: llvm-dwarfdump -debug-info - 2>&1 | FileCheck %s ## llvm-dwarfdump used to crash with this input because of an invalid size ## of the compilation unit contribution in the .debug_cu_index section. +# CHECK: warning: DWARF package unit at offset 0x00000000 has an inconsistent index (expected: 23, actual: 24) + .section .debug_abbrev.dwo, "e", @progbits .LAbbrBegin: .uleb128 1 # Abbreviation Code |