Skip to content

[DebugInfo] Report errors when DWARFUnitHeader::applyIndexEntry fails #89156

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Apr 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading