From deeb5d51e3e36b99a73155adee73fc67d6b726cf Mon Sep 17 00:00:00 2001 From: David Blaikie Date: Fri, 24 May 2019 01:05:52 +0000 Subject: [PATCH] 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) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@361582 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/DebugInfo/DWARF/DWARFUnit.h | 11 +++++++---- lib/DebugInfo/DWARF/DWARFUnit.cpp | 12 ++++++++---- lib/DebugInfo/DWARF/DWARFVerifier.cpp | 13 +++++-------- test/DebugInfo/X86/dwarfdump-str-offsets.s | 7 ++++--- 4 files changed, 24 insertions(+), 19 deletions(-) diff --git a/include/llvm/DebugInfo/DWARF/DWARFUnit.h b/include/llvm/DebugInfo/DWARF/DWARFUnit.h index c89451b2027..4e92df2fdb1 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFUnit.h +++ b/include/llvm/DebugInfo/DWARF/DWARFUnit.h @@ -48,7 +48,7 @@ class DWARFUnitHeader { uint32_t Offset = 0; // Version, address size, and DWARF format. dwarf::FormParams FormParams; - uint32_t Length = 0; + uint64_t Length = 0; uint64_t AbbrOffset = 0; // For DWO units only. @@ -82,7 +82,7 @@ public: uint8_t getDwarfOffsetByteSize() const { return FormParams.getDwarfOffsetByteSize(); } - uint32_t getLength() const { return Length; } + uint64_t getLength() const { return Length; } uint64_t getAbbrOffset() const { return AbbrOffset; } Optional getDWOId() const { return DWOId; } void setDWOId(uint64_t Id) { @@ -97,8 +97,11 @@ public: return UnitType == dwarf::DW_UT_type || UnitType == dwarf::DW_UT_split_type; } uint8_t getSize() const { return Size; } - // FIXME: Support DWARF64. - uint32_t getNextUnitOffset() const { return Offset + Length + 4; } + uint32_t getNextUnitOffset() const { + return Offset + Length + + (FormParams.Format == llvm::dwarf::DwarfFormat::DWARF64 ? 4 : 0) + + FormParams.getDwarfOffsetByteSize(); + } }; const DWARFUnitIndex &getDWARFUnitIndex(DWARFContext &Context, diff --git a/lib/DebugInfo/DWARF/DWARFUnit.cpp b/lib/DebugInfo/DWARF/DWARFUnit.cpp index 65b118f6091..7bc52215490 100644 --- a/lib/DebugInfo/DWARF/DWARFUnit.cpp +++ b/lib/DebugInfo/DWARF/DWARFUnit.cpp @@ -242,16 +242,20 @@ bool DWARFUnitHeader::extract(DWARFContext &Context, if (!IndexEntry && Index) IndexEntry = Index->getFromOffset(*offset_ptr); Length = debug_info.getU32(offset_ptr); - // FIXME: Support DWARF64. - unsigned SizeOfLength = 4; 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); if (FormParams.Version >= 5) { UnitType = 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 { - AbbrOffset = debug_info.getRelocatedValue(4, offset_ptr); + AbbrOffset = debug_info.getRelocatedValue(FormParams.getDwarfOffsetByteSize(), offset_ptr); FormParams.AddrSize = debug_info.getU8(offset_ptr); // Fake a unit type based on the section type. This isn't perfect, // but distinguishing compile and type units is generally enough. diff --git a/lib/DebugInfo/DWARF/DWARFVerifier.cpp b/lib/DebugInfo/DWARF/DWARFVerifier.cpp index 8fea97aa3c2..c2b3189514a 100644 --- a/lib/DebugInfo/DWARF/DWARFVerifier.cpp +++ b/lib/DebugInfo/DWARF/DWARFVerifier.cpp @@ -100,7 +100,7 @@ bool DWARFVerifier::DieRangeInfo::intersects(const DieRangeInfo &RHS) const { bool DWARFVerifier::verifyUnitHeader(const DWARFDataExtractor DebugInfoData, uint32_t *Offset, unsigned UnitIndex, uint8_t &UnitType, bool &isUnitDWARF64) { - uint32_t AbbrOffset, Length; + uint64_t AbbrOffset, Length; uint8_t AddrSize = 0; uint16_t Version; bool Success = true; @@ -114,22 +114,19 @@ bool DWARFVerifier::verifyUnitHeader(const DWARFDataExtractor DebugInfoData, uint32_t OffsetStart = *Offset; Length = DebugInfoData.getU32(Offset); if (Length == UINT32_MAX) { + Length = DebugInfoData.getU64(Offset); 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); if (Version >= 5) { UnitType = DebugInfoData.getU8(Offset); AddrSize = DebugInfoData.getU8(Offset); - AbbrOffset = DebugInfoData.getU32(Offset); + AbbrOffset = isUnitDWARF64 ? DebugInfoData.getU64(Offset) : DebugInfoData.getU32(Offset); ValidType = dwarf::isUnitType(UnitType); } else { UnitType = 0; - AbbrOffset = DebugInfoData.getU32(Offset); + AbbrOffset = isUnitDWARF64 ? DebugInfoData.getU64(Offset) : DebugInfoData.getU32(Offset); AddrSize = DebugInfoData.getU8(Offset); } @@ -157,7 +154,7 @@ bool DWARFVerifier::verifyUnitHeader(const DWARFDataExtractor DebugInfoData, if (!ValidAddrSize) note() << "The address size is unsupported.\n"; } - *Offset = OffsetStart + Length + 4; + *Offset = OffsetStart + Length + (isUnitDWARF64 ? 12 : 4); return Success; } diff --git a/test/DebugInfo/X86/dwarfdump-str-offsets.s b/test/DebugInfo/X86/dwarfdump-str-offsets.s index 230c6608506..064061b5847 100644 --- a/test/DebugInfo/X86/dwarfdump-str-offsets.s +++ b/test/DebugInfo/X86/dwarfdump-str-offsets.s @@ -239,18 +239,19 @@ TypeDie: CU1_5_end: # 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: .short 5 # DWARF version number .byte 1 # DWARF Unit Type .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, # DW_AT_str_offsets and DW_AT_compdir. .byte 1 # Abbreviation code .byte 0 # The index of the producer 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 0 # NULL CU2_5_end: -- 2.50.1