summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Langford <alangford@apple.com>2024-04-23 11:01:54 -0700
committerGitHub <noreply@github.com>2024-04-23 11:01:54 -0700
commit1a8935ada7cb0bb7943e18f2bc9f6d7a89887aa8 (patch)
tree7404510e53fdd710e9815a8e881bf7d895ec624b
parent9e9595183001991a7d31d8880c4a2b33594ca30f (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.h2
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp41
-rw-r--r--llvm/test/DebugInfo/X86/invalid-cu-abbrev-contribution-dwp.s58
-rw-r--r--llvm/test/DebugInfo/X86/invalid-cu-abbrev-offset-dwp.s58
-rw-r--r--llvm/test/DebugInfo/X86/invalid-cu-length-dwp.s4
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