Skip to content

Commit

Permalink
[DebugInfo] Report errors when DWARFUnitHeader::applyIndexEntry fails (
Browse files Browse the repository at this point in the history
…#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.
  • Loading branch information
bulbazord committed Apr 23, 2024
1 parent 9e95951 commit 1a8935a
Show file tree
Hide file tree
Showing 5 changed files with 152 additions and 11 deletions.
2 changes: 1 addition & 1 deletion llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ class DWARFUnitHeader {
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; }
Expand Down
41 changes: 32 additions & 9 deletions llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
58 changes: 58 additions & 0 deletions llvm/test/DebugInfo/X86/invalid-cu-abbrev-contribution-dwp.s
Original file line number Diff line number Diff line change
@@ -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)
58 changes: 58 additions & 0 deletions llvm/test/DebugInfo/X86/invalid-cu-abbrev-offset-dwp.s
Original file line number Diff line number Diff line change
@@ -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
4 changes: 3 additions & 1 deletion llvm/test/DebugInfo/X86/invalid-cu-length-dwp.s
Original file line number Diff line number Diff line change
@@ -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
Expand Down

0 comments on commit 1a8935a

Please sign in to comment.