Skip to content

Commit 1a8935a

Browse files
authored
[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.
1 parent 9e95951 commit 1a8935a

File tree

5 files changed

+152
-11
lines changed

5 files changed

+152
-11
lines changed

llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ class DWARFUnitHeader {
8585
uint64_t *offset_ptr, DWARFSectionKind SectionKind);
8686
// For units in DWARF Package File, remember the index entry and update
8787
// the abbreviation offset read by extract().
88-
bool applyIndexEntry(const DWARFUnitIndex::Entry *Entry);
88+
Error applyIndexEntry(const DWARFUnitIndex::Entry *Entry);
8989
uint64_t getOffset() const { return Offset; }
9090
const dwarf::FormParams &getFormParams() const { return FormParams; }
9191
uint16_t getVersion() const { return FormParams.Version; }

llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,12 @@ void DWARFUnitVector::addUnitsImpl(
9898
if (!IndexEntry)
9999
IndexEntry = Index.getFromOffset(Header.getOffset());
100100
}
101-
if (IndexEntry && !Header.applyIndexEntry(IndexEntry))
102-
return nullptr;
101+
if (IndexEntry) {
102+
if (Error ApplicationErr = Header.applyIndexEntry(IndexEntry)) {
103+
Context.getWarningHandler()(std::move(ApplicationErr));
104+
return nullptr;
105+
}
106+
}
103107
std::unique_ptr<DWARFUnit> U;
104108
if (Header.isTypeUnit())
105109
U = std::make_unique<DWARFTypeUnit>(Context, InfoSection, Header, DA,
@@ -334,21 +338,40 @@ Error DWARFUnitHeader::extract(DWARFContext &Context,
334338
return Error::success();
335339
}
336340

337-
bool DWARFUnitHeader::applyIndexEntry(const DWARFUnitIndex::Entry *Entry) {
341+
Error DWARFUnitHeader::applyIndexEntry(const DWARFUnitIndex::Entry *Entry) {
338342
assert(Entry);
339343
assert(!IndexEntry);
340344
IndexEntry = Entry;
341345
if (AbbrOffset)
342-
return false;
346+
return createStringError(errc::invalid_argument,
347+
"DWARF package unit at offset 0x%8.8" PRIx64
348+
" has a non-zero abbreviation offset",
349+
Offset);
350+
343351
auto *UnitContrib = IndexEntry->getContribution();
344-
if (!UnitContrib ||
345-
UnitContrib->getLength() != (getLength() + getUnitLengthFieldByteSize()))
346-
return false;
352+
if (!UnitContrib)
353+
return createStringError(errc::invalid_argument,
354+
"DWARF package unit at offset 0x%8.8" PRIx64
355+
" has no contribution index",
356+
Offset);
357+
358+
uint64_t IndexLength = getLength() + getUnitLengthFieldByteSize();
359+
if (UnitContrib->getLength() != IndexLength)
360+
return createStringError(errc::invalid_argument,
361+
"DWARF package unit at offset 0x%8.8" PRIx64
362+
" has an inconsistent index (expected: %" PRIu64
363+
", actual: %" PRIu64 ")",
364+
Offset, UnitContrib->getLength(), IndexLength);
365+
347366
auto *AbbrEntry = IndexEntry->getContribution(DW_SECT_ABBREV);
348367
if (!AbbrEntry)
349-
return false;
368+
return createStringError(errc::invalid_argument,
369+
"DWARF package unit at offset 0x%8.8" PRIx64
370+
" missing abbreviation column",
371+
Offset);
372+
350373
AbbrOffset = AbbrEntry->getOffset();
351-
return true;
374+
return Error::success();
352375
}
353376

354377
Error DWARFUnit::extractRangeList(uint64_t RangeListOffset,
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# RUN: llvm-mc -triple x86_64-unknown-linux %s -filetype=obj -o - | \
2+
# RUN: llvm-dwarfdump -debug-info - 2>&1 | FileCheck %s
3+
4+
# CHECK: warning: DWARF package unit at offset 0x00000000 missing abbreviation column
5+
6+
.section .debug_abbrev.dwo, "e", @progbits
7+
.LAbbrBegin:
8+
.uleb128 1 # Abbreviation Code
9+
.uleb128 17 # DW_TAG_compile_unit
10+
.byte 0 # DW_CHILDREN_no
11+
.uleb128 3 # DW_AT_name
12+
.uleb128 8 # DW_FORM_string
13+
.uleb128 0x2131 # DW_AT_GNU_dwo_id
14+
.uleb128 7 # DW_FORM_data8
15+
.byte 0 # EOM(1)
16+
.byte 0 # EOM(2)
17+
.byte 0 # EOM(3)
18+
.LAbbrEnd:
19+
20+
.section .debug_info.dwo, "e", @progbits
21+
.LCUBegin:
22+
.long .LCUEnd-.LCUVersion # Length
23+
.LCUVersion:
24+
.short 4 # Version
25+
.long 0 # Abbrev offset
26+
.byte 4 # Address size
27+
.uleb128 1 # Abbrev [1] DW_TAG_compile_unit
28+
.asciz "a.c" # DW_AT_name
29+
.quad 0x1100001122222222 # DW_AT_GNU_dwo_id
30+
.LCUEnd:
31+
32+
.section .debug_cu_index, "", @progbits
33+
## Header:
34+
.short 2 # Version
35+
.space 2 # Padding
36+
.long 1 # Section count (Invalid, should be 2)
37+
.long 1 # Unit count
38+
.long 4 # Slot count
39+
## Hash Table of Signatures:
40+
.quad 0
41+
.quad 0
42+
.quad 0x1100001122222222
43+
.quad 0
44+
## Parallel Table of Indexes:
45+
.long 0
46+
.long 0
47+
.long 1
48+
.long 0
49+
## Table of Section Offsets:
50+
## Row 0:
51+
.long 1 # DW_SECT_INFO
52+
# .long 3 # DW_SECT_ABBREV (Intentionally omitted)
53+
## Row 1:
54+
.long .LCUBegin-.debug_info.dwo # Offset in .debug_info.dwo
55+
# .long .LAbbrBegin-.debug_abbrev.dwo # Offset in .debug_abbrev.dwo (Intentionally omitted)
56+
## Table of Section Sizes:
57+
.long .LCUEnd-.LCUBegin # Size of the contribution in .debug_info.dwo
58+
.long .LAbbrEnd-.LAbbrBegin # Size of the contribution in .debug_abbrev.dwo (Intentionally omitted)
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# RUN: llvm-mc -triple x86_64-unknown-linux %s -filetype=obj -o - | \
2+
# RUN: llvm-dwarfdump -debug-info - 2>&1 | FileCheck %s
3+
4+
# CHECK: warning: DWARF package unit at offset 0x00000000 has a non-zero abbreviation offset
5+
6+
.section .debug_abbrev.dwo, "e", @progbits
7+
.LAbbrBegin:
8+
.uleb128 1 # Abbreviation Code
9+
.uleb128 17 # DW_TAG_compile_unit
10+
.byte 0 # DW_CHILDREN_no
11+
.uleb128 3 # DW_AT_name
12+
.uleb128 8 # DW_FORM_string
13+
.uleb128 0x2131 # DW_AT_GNU_dwo_id
14+
.uleb128 7 # DW_FORM_data8
15+
.byte 0 # EOM(1)
16+
.byte 0 # EOM(2)
17+
.byte 0 # EOM(3)
18+
.LAbbrEnd:
19+
20+
.section .debug_info.dwo, "e", @progbits
21+
.LCUBegin:
22+
.long .LCUEnd-.LCUVersion # Length
23+
.LCUVersion:
24+
.short 4 # Version
25+
.long 1 # Abbrev offset (Invalid, should be 0)
26+
.byte 4 # Address size
27+
.uleb128 1 # Abbrev [1] DW_TAG_compile_unit
28+
.asciz "a.c" # DW_AT_name
29+
.quad 0x1100001122222222 # DW_AT_GNU_dwo_id
30+
.LCUEnd:
31+
32+
.section .debug_cu_index, "", @progbits
33+
## Header:
34+
.short 2 # Version
35+
.space 2 # Padding
36+
.long 2 # Section count
37+
.long 1 # Unit count
38+
.long 4 # Slot count
39+
## Hash Table of Signatures:
40+
.quad 0
41+
.quad 0
42+
.quad 0x1100001122222222
43+
.quad 0
44+
## Parallel Table of Indexes:
45+
.long 0
46+
.long 0
47+
.long 1
48+
.long 0
49+
## Table of Section Offsets:
50+
## Row 0:
51+
.long 1 # DW_SECT_INFO
52+
.long 3 # DW_SECT_ABBREV
53+
## Row 1:
54+
.long .LCUBegin-.debug_info.dwo # Offset in .debug_info.dwo
55+
.long .LAbbrBegin-.debug_abbrev.dwo # Offset in .debug_abbrev.dwo
56+
## Table of Section Sizes:
57+
.long .LCUEnd-.LCUBegin
58+
.long .LAbbrEnd-.LAbbrBegin

llvm/test/DebugInfo/X86/invalid-cu-length-dwp.s

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
# RUN: llvm-mc -triple x86_64-unknown-linux %s -filetype=obj -o - | \
2-
# RUN: llvm-dwarfdump -debug-info -
2+
# RUN: llvm-dwarfdump -debug-info - 2>&1 | FileCheck %s
33

44
## llvm-dwarfdump used to crash with this input because of an invalid size
55
## of the compilation unit contribution in the .debug_cu_index section.
66

7+
# CHECK: warning: DWARF package unit at offset 0x00000000 has an inconsistent index (expected: 23, actual: 24)
8+
79
.section .debug_abbrev.dwo, "e", @progbits
810
.LAbbrBegin:
911
.uleb128 1 # Abbreviation Code

0 commit comments

Comments
 (0)