From 2ee027873121c1b4bdef76468e33567ade16e0b7 Mon Sep 17 00:00:00 2001 From: Igor Kudrin Date: Tue, 20 Aug 2019 09:50:44 +0000 Subject: [PATCH] [DWARF] Fix DWARFUnit::getDebugInfoSize() for 64-bit DWARF. The calculation there was correct only for DWARF32. Differential Revision: https://reviews.llvm.org/D66421 llvm-svn: 369356 --- include/llvm/BinaryFormat/Dwarf.h | 11 ++++++ include/llvm/DebugInfo/DWARF/DWARFUnit.h | 10 +++-- .../X86/debug_info_min_dwarf64.s | 37 +++++++++++++++++++ 3 files changed, 54 insertions(+), 4 deletions(-) create mode 100644 test/tools/llvm-dwarfdump/X86/debug_info_min_dwarf64.s diff --git a/include/llvm/BinaryFormat/Dwarf.h b/include/llvm/BinaryFormat/Dwarf.h index 45428f4cd6d..72f36c46a4a 100644 --- a/include/llvm/BinaryFormat/Dwarf.h +++ b/include/llvm/BinaryFormat/Dwarf.h @@ -513,6 +513,17 @@ struct FormParams { explicit operator bool() const { return Version && AddrSize; } }; +/// Get the byte size of the unit length field depending on the DWARF format. +inline uint8_t getUnitLengthFieldByteSize(DwarfFormat Format) { + switch (Format) { + case DwarfFormat::DWARF32: + return 4; + case DwarfFormat::DWARF64: + return 12; + } + llvm_unreachable("Invalid Format value"); +} + /// Get the fixed byte size for a given form. /// /// If the form has a fixed byte size, then an Optional with a value will be diff --git a/include/llvm/DebugInfo/DWARF/DWARFUnit.h b/include/llvm/DebugInfo/DWARF/DWARFUnit.h index bd7e3e967c3..4762fd02e06 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFUnit.h +++ b/include/llvm/DebugInfo/DWARF/DWARFUnit.h @@ -97,10 +97,11 @@ public: return UnitType == dwarf::DW_UT_type || UnitType == dwarf::DW_UT_split_type; } uint8_t getSize() const { return Size; } + uint8_t getUnitLengthFieldByteSize() const { + return dwarf::getUnitLengthFieldByteSize(FormParams.Format); + } uint64_t getNextUnitOffset() const { - return Offset + Length + - (FormParams.Format == llvm::dwarf::DwarfFormat::DWARF64 ? 4 : 0) + - FormParams.getDwarfOffsetByteSize(); + return Offset + Length + getUnitLengthFieldByteSize(); } }; @@ -501,7 +502,8 @@ public: private: /// Size in bytes of the .debug_info data associated with this compile unit. size_t getDebugInfoSize() const { - return Header.getLength() + 4 - getHeaderSize(); + return Header.getLength() + Header.getUnitLengthFieldByteSize() - + getHeaderSize(); } /// extractDIEsIfNeeded - Parses a compile unit and indexes its DIEs if it diff --git a/test/tools/llvm-dwarfdump/X86/debug_info_min_dwarf64.s b/test/tools/llvm-dwarfdump/X86/debug_info_min_dwarf64.s new file mode 100644 index 00000000000..9a9c9b3562c --- /dev/null +++ b/test/tools/llvm-dwarfdump/X86/debug_info_min_dwarf64.s @@ -0,0 +1,37 @@ +# RUN: llvm-mc %s -filetype obj -triple x86_64-unknown-elf -o - | \ +# RUN: llvm-dwarfdump -debug-info - | \ +# RUN: FileCheck %s + + .section .debug_abbrev,"",@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) + + .section .debug_info,"",@progbits +# CHECK: .debug_info contents: +# CHECK-NEXT: 0x00000000: Compile Unit: +DI_4_64_start: + .long 0xffffffff # DWARF64 mark + .quad DI_4_64_end - DI_4_64_version # Length of Unit +# CHECK-SAME: length = 0x0000000f +DI_4_64_version: + .short 4 # DWARF version number +# CHECK-SAME: version = 0x0004 + .quad .debug_abbrev # Offset Into Abbrev. Section +# CHECK-SAME: abbr_offset = 0x0000 + .byte 8 # Address Size (in bytes) +# CHECK-SAME: addr_size = 0x08 +# CHECK-SAME: (next unit at 0x0000001b) + + .byte 1 # Abbreviation code +# CHECK: 0x00000017: DW_TAG_compile_unit + .short 4 # DW_LANG_C_plus_plus +# CHECK-NEXT: DW_AT_language (DW_LANG_C_plus_plus) + .byte 0 # NULL +DI_4_64_end: +