[DWARF] Check that all fields of a Unit Header are read.

Tests "dwarfdump-rnglists-dwarf64.s" and "dwarfdump-rnglists.s" were
malformed because they had missing required DWO ID fields in split
compilation unit headers. The patch fixes the tests and checks
the reading of a unit header more thoroughly.

Differential Revision: https://reviews.llvm.org/D71704
This commit is contained in:
Igor Kudrin 2019-12-20 17:36:52 +07:00
parent ebcb36d4a1
commit 6f635f9092
4 changed files with 49 additions and 12 deletions

View File

@ -259,23 +259,26 @@ bool DWARFUnitHeader::extract(DWARFContext &Context,
const DWARFUnitIndex *Index,
const DWARFUnitIndex::Entry *Entry) {
Offset = *offset_ptr;
Error Err = Error::success();
IndexEntry = Entry;
if (!IndexEntry && Index)
IndexEntry = Index->getFromOffset(*offset_ptr);
Length = debug_info.getRelocatedValue(4, offset_ptr);
Length = debug_info.getRelocatedValue(4, offset_ptr, nullptr, &Err);
FormParams.Format = DWARF32;
if (Length == dwarf::DW_LENGTH_DWARF64) {
Length = debug_info.getU64(offset_ptr);
Length = debug_info.getU64(offset_ptr, &Err);
FormParams.Format = DWARF64;
}
FormParams.Version = debug_info.getU16(offset_ptr);
FormParams.Version = debug_info.getU16(offset_ptr, &Err);
if (FormParams.Version >= 5) {
UnitType = debug_info.getU8(offset_ptr);
FormParams.AddrSize = debug_info.getU8(offset_ptr);
AbbrOffset = debug_info.getRelocatedValue(FormParams.getDwarfOffsetByteSize(), offset_ptr);
UnitType = debug_info.getU8(offset_ptr, &Err);
FormParams.AddrSize = debug_info.getU8(offset_ptr, &Err);
AbbrOffset = debug_info.getRelocatedValue(
FormParams.getDwarfOffsetByteSize(), offset_ptr, nullptr, &Err);
} else {
AbbrOffset = debug_info.getRelocatedValue(FormParams.getDwarfOffsetByteSize(), offset_ptr);
FormParams.AddrSize = debug_info.getU8(offset_ptr);
AbbrOffset = debug_info.getRelocatedValue(
FormParams.getDwarfOffsetByteSize(), offset_ptr, nullptr, &Err);
FormParams.AddrSize = debug_info.getU8(offset_ptr, &Err);
// Fake a unit type based on the section type. This isn't perfect,
// but distinguishing compile and type units is generally enough.
if (SectionKind == DW_SECT_TYPES)
@ -295,11 +298,14 @@ bool DWARFUnitHeader::extract(DWARFContext &Context,
AbbrOffset = AbbrEntry->Offset;
}
if (isTypeUnit()) {
TypeHash = debug_info.getU64(offset_ptr);
TypeOffset =
debug_info.getUnsigned(offset_ptr, FormParams.getDwarfOffsetByteSize());
TypeHash = debug_info.getU64(offset_ptr, &Err);
TypeOffset = debug_info.getUnsigned(
offset_ptr, FormParams.getDwarfOffsetByteSize(), &Err);
} else if (UnitType == DW_UT_split_compile || UnitType == DW_UT_skeleton)
DWOId = debug_info.getU64(offset_ptr);
DWOId = debug_info.getU64(offset_ptr, &Err);
if (errorToBool(std::move(Err)))
return false;
// Header fields all parsed, capture the size of this unit header.
assert(*offset_ptr - Offset <= 255 && "unexpected header size");

View File

@ -109,6 +109,7 @@ CU_split_5_64_version:
.byte 5 # DWARF Unit Type
.byte 4 # Address Size (in bytes)
.quad 0 # Offset Into Abbrev Section
.quad 0xdeadbeefbaadf00d # DWO id
# The compile-unit DIE, which has DW_AT_rnglists_base and DW_AT_ranges.
.byte 1 # Abbreviation code
.uleb128 1 # DW_AT_ranges

View File

@ -106,6 +106,7 @@ CU_split_5_version:
.byte 5 # DWARF Unit Type
.byte 4 # Address Size (in bytes)
.long 0 # Offset Into Abbrev Section
.quad 0xdeadbeefbaadf00d # DWO id
# The compile-unit DIE, which has DW_AT_rnglists_base and DW_AT_ranges.
.byte 1 # Abbreviation code
.uleb128 1 # DW_AT_ranges

View File

@ -0,0 +1,29 @@
# RUN: llvm-mc -triple x86_64-unknown-linux %s -filetype=obj -o - | \
# RUN: llvm-dwarfdump -debug-info - | \
# RUN: FileCheck %s
.section .debug_abbrev.dwo,"",@progbits
.byte 0x01 # Abbrev code
.byte 0x11 # DW_TAG_compile_unit
.byte 0x00 # DW_CHILDREN_no
.byte 0x13 # DW_AT_language
.byte 0x05 # DW_FORM_data2
.byte 0x00 # EOM(1)
.byte 0x00 # EOM(2)
.byte 0x00 # EOM(3)
# The CU was considered valid even though there were some required fields
# missing in the header.
.section .debug_info.dwo,"",@progbits
.long .CUend - .CUver # Length of Unit
.CUver:
.short 5 # DWARF version number
.byte 5 # DW_UT_split_compile
.byte 4 # Address Size (in bytes)
# .long 0 # Missing: Offset Into Abbrev Section
# .quad 0 # Missing: DWO id
.byte 1 # Abbreviation code
.short 4 # DW_LANG_C_plus_plus
.CUend:
# CHECK-NOT: Compile Unit: