Skip to content

Commit 9ceb192

Browse files
committed
[llvm-dwarfdump] Avoid crashing if an abbreviation offset is invalid.
Note that DWARFUnit::getAbbreviations() returns nullptr if the abbreviations could not be read, but callers used the returned pointer without checking. Differential Revision: https://reviews.llvm.org/D85738
1 parent 6716e78 commit 9ceb192

File tree

5 files changed

+43
-8
lines changed

5 files changed

+43
-8
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,7 @@ class DWARFUnit {
294294
dwarf::DwarfFormat getFormat() const { return Header.getFormat(); }
295295
uint8_t getUnitType() const { return Header.getUnitType(); }
296296
bool isTypeUnit() const { return Header.isTypeUnit(); }
297+
uint64_t getAbbrOffset() const { return Header.getAbbrOffset(); }
297298
uint64_t getNextUnitOffset() const { return Header.getNextUnitOffset(); }
298299
const DWARFSection &getLineSection() const { return LineSection; }
299300
StringRef getStringSection() const { return StringSection; }
@@ -480,7 +481,6 @@ class DWARFUnit {
480481
/// The unit needs to have its DIEs extracted for this method to work.
481482
DWARFDie getDIEForOffset(uint64_t Offset) {
482483
extractDIEsIfNeeded(false);
483-
assert(!DieArray.empty());
484484
auto It =
485485
llvm::partition_point(DieArray, [=](const DWARFDebugInfoEntry &DIE) {
486486
return DIE.getOffset() < Offset;

llvm/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,10 @@ void DWARFCompileUnit::dump(raw_ostream &OS, DIDumpOptions DumpOpts) {
2222
<< ", version = " << format("0x%04x", getVersion());
2323
if (getVersion() >= 5)
2424
OS << ", unit_type = " << dwarf::UnitTypeString(getUnitType());
25-
OS << ", abbr_offset = "
26-
<< format("0x%04" PRIx64, getAbbreviations()->getOffset())
27-
<< ", addr_size = " << format("0x%02x", getAddressByteSize());
25+
OS << ", abbr_offset = " << format("0x%04" PRIx64, getAbbrOffset());
26+
if (!getAbbreviations())
27+
OS << " (invalid)";
28+
OS << ", addr_size = " << format("0x%02x", getAddressByteSize());
2829
if (getVersion() >= 5 && getUnitType() != dwarf::DW_UT_compile)
2930
OS << ", DWO_id = " << format("0x%016" PRIx64, *getDWOId());
3031
OS << " (next unit at " << format("0x%08" PRIx64, getNextUnitOffset())

llvm/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ bool DWARFDebugInfoEntry::extractFast(const DWARFUnit &U, uint64_t *OffsetPtr,
3838
AbbrevDecl = nullptr;
3939
return true;
4040
}
41-
AbbrevDecl = U.getAbbreviations()->getAbbreviationDeclaration(AbbrCode);
41+
if (const auto *AbbrevSet = U.getAbbreviations())
42+
AbbrevDecl = AbbrevSet->getAbbreviationDeclaration(AbbrCode);
4243
if (nullptr == AbbrevDecl) {
4344
// Restore the original offset.
4445
*OffsetPtr = Offset;

llvm/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,10 @@ void DWARFTypeUnit::dump(raw_ostream &OS, DIDumpOptions DumpOpts) {
3636
<< ", version = " << format("0x%04x", getVersion());
3737
if (getVersion() >= 5)
3838
OS << ", unit_type = " << dwarf::UnitTypeString(getUnitType());
39-
OS << ", abbr_offset = "
40-
<< format("0x%04" PRIx64, getAbbreviations()->getOffset())
41-
<< ", addr_size = " << format("0x%02x", getAddressByteSize())
39+
OS << ", abbr_offset = " << format("0x%04" PRIx64, getAbbrOffset());
40+
if (!getAbbreviations())
41+
OS << " (invalid)";
42+
OS << ", addr_size = " << format("0x%02x", getAddressByteSize())
4243
<< ", name = '" << Name << "'"
4344
<< ", type_signature = " << format("0x%016" PRIx64, getTypeHash())
4445
<< ", type_offset = " << format("0x%04" PRIx64, getTypeOffset())
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# RUN: llvm-mc %s -filetype obj -triple x86_64 -o %t
2+
# RUN: llvm-dwarfdump -debug-info -debug-types %t | FileCheck %s
3+
4+
# CHECK: .debug_info contents:
5+
# CHECK-NEXT: Compile Unit: {{.+}}, abbr_offset = 0x00a5 (invalid),
6+
# CHECK-NEXT: <compile unit can't be parsed!>
7+
8+
# CHECK: .debug_types contents:
9+
# CHECK-NEXT: Type Unit: {{.+}}, abbr_offset = 0x00a5 (invalid), addr_size = 0x08, name = '',
10+
# CHECK-NEXT: <type unit can't be parsed!>
11+
12+
.section .debug_info,"",@progbits
13+
.long .LCUEnd-.LCUVersion # Length of Unit
14+
.LCUVersion:
15+
.short 4 # DWARF version number
16+
.long 0xa5 # Offset Into Abbrev. Section (invalid)
17+
.byte 8 # Address Size
18+
.byte 1 # Abbreviation code
19+
.LCUEnd:
20+
21+
.section .debug_types,"",@progbits
22+
.LTUBegin:
23+
.long .LTUEnd-.LTUVersion # Length of Unit
24+
.LTUVersion:
25+
.short 4 # DWARF version number
26+
.long 0xa5 # Offset Into Abbrev. Section (invalid)
27+
.byte 8 # Address Size
28+
.quad 0x0011223344556677 # Type Signature
29+
.long .LTUType-.LTUBegin # Type offset
30+
.LTUType:
31+
.byte 1 # Abbreviation code
32+
.LTUEnd:

0 commit comments

Comments
 (0)