dwarfdump: Add a bit more DWARF64 support

This test case was incorrect because it mixed DWARF32 and DWARF64 for a
single unit (DWARF32 unit referencing a DWARF64 str_offsets section). So
fix enough of the unit parsing for DWARF64 and make the test valid.

(not sure if anyone needs DWARF64 support though - support in
libDebugInfoDWARF has been added piecemeal and LLVM doesn't produce it
at all)

llvm-svn: 361582
This commit is contained in:
David Blaikie 2019-05-24 01:05:52 +00:00
parent 052f87ae36
commit 79872a88a0
4 changed files with 24 additions and 19 deletions

View File

@ -48,7 +48,7 @@ class DWARFUnitHeader {
uint32_t Offset = 0; uint32_t Offset = 0;
// Version, address size, and DWARF format. // Version, address size, and DWARF format.
dwarf::FormParams FormParams; dwarf::FormParams FormParams;
uint32_t Length = 0; uint64_t Length = 0;
uint64_t AbbrOffset = 0; uint64_t AbbrOffset = 0;
// For DWO units only. // For DWO units only.
@ -82,7 +82,7 @@ public:
uint8_t getDwarfOffsetByteSize() const { uint8_t getDwarfOffsetByteSize() const {
return FormParams.getDwarfOffsetByteSize(); return FormParams.getDwarfOffsetByteSize();
} }
uint32_t getLength() const { return Length; } uint64_t getLength() const { return Length; }
uint64_t getAbbrOffset() const { return AbbrOffset; } uint64_t getAbbrOffset() const { return AbbrOffset; }
Optional<uint64_t> getDWOId() const { return DWOId; } Optional<uint64_t> getDWOId() const { return DWOId; }
void setDWOId(uint64_t Id) { void setDWOId(uint64_t Id) {
@ -97,8 +97,11 @@ public:
return UnitType == dwarf::DW_UT_type || UnitType == dwarf::DW_UT_split_type; return UnitType == dwarf::DW_UT_type || UnitType == dwarf::DW_UT_split_type;
} }
uint8_t getSize() const { return Size; } uint8_t getSize() const { return Size; }
// FIXME: Support DWARF64. uint32_t getNextUnitOffset() const {
uint32_t getNextUnitOffset() const { return Offset + Length + 4; } return Offset + Length +
(FormParams.Format == llvm::dwarf::DwarfFormat::DWARF64 ? 4 : 0) +
FormParams.getDwarfOffsetByteSize();
}
}; };
const DWARFUnitIndex &getDWARFUnitIndex(DWARFContext &Context, const DWARFUnitIndex &getDWARFUnitIndex(DWARFContext &Context,

View File

@ -242,16 +242,20 @@ bool DWARFUnitHeader::extract(DWARFContext &Context,
if (!IndexEntry && Index) if (!IndexEntry && Index)
IndexEntry = Index->getFromOffset(*offset_ptr); IndexEntry = Index->getFromOffset(*offset_ptr);
Length = debug_info.getU32(offset_ptr); Length = debug_info.getU32(offset_ptr);
// FIXME: Support DWARF64.
unsigned SizeOfLength = 4;
FormParams.Format = DWARF32; FormParams.Format = DWARF32;
unsigned SizeOfLength = 4;
if (Length == 0xffffffff) {
Length = debug_info.getU64(offset_ptr);
FormParams.Format = DWARF64;
SizeOfLength = 8;
}
FormParams.Version = debug_info.getU16(offset_ptr); FormParams.Version = debug_info.getU16(offset_ptr);
if (FormParams.Version >= 5) { if (FormParams.Version >= 5) {
UnitType = debug_info.getU8(offset_ptr); UnitType = debug_info.getU8(offset_ptr);
FormParams.AddrSize = debug_info.getU8(offset_ptr); FormParams.AddrSize = debug_info.getU8(offset_ptr);
AbbrOffset = debug_info.getU32(offset_ptr); AbbrOffset = debug_info.getRelocatedValue(FormParams.getDwarfOffsetByteSize(), offset_ptr);
} else { } else {
AbbrOffset = debug_info.getRelocatedValue(4, offset_ptr); AbbrOffset = debug_info.getRelocatedValue(FormParams.getDwarfOffsetByteSize(), offset_ptr);
FormParams.AddrSize = debug_info.getU8(offset_ptr); FormParams.AddrSize = debug_info.getU8(offset_ptr);
// Fake a unit type based on the section type. This isn't perfect, // Fake a unit type based on the section type. This isn't perfect,
// but distinguishing compile and type units is generally enough. // but distinguishing compile and type units is generally enough.

View File

@ -100,7 +100,7 @@ bool DWARFVerifier::DieRangeInfo::intersects(const DieRangeInfo &RHS) const {
bool DWARFVerifier::verifyUnitHeader(const DWARFDataExtractor DebugInfoData, bool DWARFVerifier::verifyUnitHeader(const DWARFDataExtractor DebugInfoData,
uint32_t *Offset, unsigned UnitIndex, uint32_t *Offset, unsigned UnitIndex,
uint8_t &UnitType, bool &isUnitDWARF64) { uint8_t &UnitType, bool &isUnitDWARF64) {
uint32_t AbbrOffset, Length; uint64_t AbbrOffset, Length;
uint8_t AddrSize = 0; uint8_t AddrSize = 0;
uint16_t Version; uint16_t Version;
bool Success = true; bool Success = true;
@ -114,22 +114,19 @@ bool DWARFVerifier::verifyUnitHeader(const DWARFDataExtractor DebugInfoData,
uint32_t OffsetStart = *Offset; uint32_t OffsetStart = *Offset;
Length = DebugInfoData.getU32(Offset); Length = DebugInfoData.getU32(Offset);
if (Length == UINT32_MAX) { if (Length == UINT32_MAX) {
Length = DebugInfoData.getU64(Offset);
isUnitDWARF64 = true; isUnitDWARF64 = true;
OS << format(
"Unit[%d] is in 64-bit DWARF format; cannot verify from this point.\n",
UnitIndex);
return false;
} }
Version = DebugInfoData.getU16(Offset); Version = DebugInfoData.getU16(Offset);
if (Version >= 5) { if (Version >= 5) {
UnitType = DebugInfoData.getU8(Offset); UnitType = DebugInfoData.getU8(Offset);
AddrSize = DebugInfoData.getU8(Offset); AddrSize = DebugInfoData.getU8(Offset);
AbbrOffset = DebugInfoData.getU32(Offset); AbbrOffset = isUnitDWARF64 ? DebugInfoData.getU64(Offset) : DebugInfoData.getU32(Offset);
ValidType = dwarf::isUnitType(UnitType); ValidType = dwarf::isUnitType(UnitType);
} else { } else {
UnitType = 0; UnitType = 0;
AbbrOffset = DebugInfoData.getU32(Offset); AbbrOffset = isUnitDWARF64 ? DebugInfoData.getU64(Offset) : DebugInfoData.getU32(Offset);
AddrSize = DebugInfoData.getU8(Offset); AddrSize = DebugInfoData.getU8(Offset);
} }
@ -157,7 +154,7 @@ bool DWARFVerifier::verifyUnitHeader(const DWARFDataExtractor DebugInfoData,
if (!ValidAddrSize) if (!ValidAddrSize)
note() << "The address size is unsupported.\n"; note() << "The address size is unsupported.\n";
} }
*Offset = OffsetStart + Length + 4; *Offset = OffsetStart + Length + (isUnitDWARF64 ? 12 : 4);
return Success; return Success;
} }

View File

@ -239,18 +239,19 @@ TypeDie:
CU1_5_end: CU1_5_end:
# DWARF v5 CU header # DWARF v5 CU header
.long CU2_5_end-CU2_5_version # Length of Unit .long 0xffffffff
.quad CU2_5_end-CU2_5_version # Length of Unit
CU2_5_version: CU2_5_version:
.short 5 # DWARF version number .short 5 # DWARF version number
.byte 1 # DWARF Unit Type .byte 1 # DWARF Unit Type
.byte 8 # Address Size (in bytes) .byte 8 # Address Size (in bytes)
.long .debug_abbrev # Offset Into Abbrev. Section .quad .debug_abbrev # Offset Into Abbrev. Section
# The compile-unit DIE, which has a DW_AT_producer, DW_AT_name, # The compile-unit DIE, which has a DW_AT_producer, DW_AT_name,
# DW_AT_str_offsets and DW_AT_compdir. # DW_AT_str_offsets and DW_AT_compdir.
.byte 1 # Abbreviation code .byte 1 # Abbreviation code
.byte 0 # The index of the producer string .byte 0 # The index of the producer string
.byte 1 # The index of the CU name string .byte 1 # The index of the CU name string
.long .debug_str_offsets_base1 .quad .debug_str_offsets_base1
.byte 2 # The index of the comp dir string .byte 2 # The index of the comp dir string
.byte 0 # NULL .byte 0 # NULL
CU2_5_end: CU2_5_end: