]> granicus.if.org Git - llvm/commitdiff
[DWARF] Fix reading 64-bit DWARF type units.
authorIgor Kudrin <ikudrin@accesssoftek.com>
Tue, 20 Aug 2019 12:52:32 +0000 (12:52 +0000)
committerIgor Kudrin <ikudrin@accesssoftek.com>
Tue, 20 Aug 2019 12:52:32 +0000 (12:52 +0000)
The type_offset field is 8 bytes long in DWARF64. The patch extends
TypeOffset to uint64_t and fixes its reading. The patch also fixes
checking of TypeOffset bounds as it was inaccurate in DWARF64 case.

Differential Revision: https://reviews.llvm.org/D66465

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@369378 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h
include/llvm/DebugInfo/DWARF/DWARFUnit.h
lib/DebugInfo/DWARF/DWARFTypeUnit.cpp
lib/DebugInfo/DWARF/DWARFUnit.cpp
test/tools/llvm-dwarfdump/X86/typeunit-v4-dwarf64.s [new file with mode: 0644]
test/tools/llvm-dwarfdump/X86/typeunit-v5-dwarf64.s [new file with mode: 0644]

index 90d89375fd353bb2d5d0cffba42b0112a0b211de..c95bdcbd8a43fc543963425cab9ae7140dfdb09a 100644 (file)
@@ -34,7 +34,7 @@ public:
                   LS, LE, IsDWO, UnitVector) {}
 
   uint64_t getTypeHash() const { return getHeader().getTypeHash(); }
-  uint32_t getTypeOffset() const { return getHeader().getTypeOffset(); }
+  uint64_t getTypeOffset() const { return getHeader().getTypeOffset(); }
 
   void dump(raw_ostream &OS, DIDumpOptions DumpOpts = {}) override;
   // Enable LLVM-style RTTI.
index 4762fd02e067bfbbbde74008d24b945366759f7f..5b674f120cbd3d1a50a98cc65af517ca26e6d252 100644 (file)
@@ -56,7 +56,7 @@ class DWARFUnitHeader {
 
   // For type units only.
   uint64_t TypeHash = 0;
-  uint32_t TypeOffset = 0;
+  uint64_t TypeOffset = 0;
 
   // For v5 split or skeleton compile units only.
   Optional<uint64_t> DWOId;
@@ -91,7 +91,7 @@ public:
   }
   const DWARFUnitIndex::Entry *getIndexEntry() const { return IndexEntry; }
   uint64_t getTypeHash() const { return TypeHash; }
-  uint32_t getTypeOffset() const { return TypeOffset; }
+  uint64_t getTypeOffset() const { return TypeOffset; }
   uint8_t getUnitType() const { return UnitType; }
   bool isTypeUnit() const {
     return UnitType == dwarf::DW_UT_type || UnitType == dwarf::DW_UT_split_type;
index c526c7b91c80b073fb1d56f3af46dc47005e984f..d428790d290a0a03b49e4fda0b37400cb318496c 100644 (file)
@@ -38,7 +38,7 @@ void DWARFTypeUnit::dump(raw_ostream &OS, DIDumpOptions DumpOpts) {
      << " addr_size = " << format("0x%02x", getAddressByteSize())
      << " name = '" << Name << "'"
      << " type_signature = " << format("0x%016" PRIx64, getTypeHash())
-     << " type_offset = " << format("0x%04x", getTypeOffset())
+     << " type_offset = " << format("0x%04" PRIx64, getTypeOffset())
      << " (next unit at " << format("0x%08" PRIx64, getNextUnitOffset())
      << ")\n";
 
index 833377e14bb119bf1a9ae72b18a5b6dd6cdc2f5b..51b5f59f83545a70bdceadd665a5b9e0cd0a3c99 100644 (file)
@@ -243,11 +243,9 @@ bool DWARFUnitHeader::extract(DWARFContext &Context,
     IndexEntry = Index->getFromOffset(*offset_ptr);
   Length = debug_info.getRelocatedValue(4, offset_ptr);
   FormParams.Format = DWARF32;
-  unsigned SizeOfLength = 4;
   if (Length == dwarf::DW_LENGTH_DWARF64) {
     Length = debug_info.getU64(offset_ptr);
     FormParams.Format = DWARF64;
-    SizeOfLength = 8;
   }
   FormParams.Version = debug_info.getU16(offset_ptr);
   if (FormParams.Version >= 5) {
@@ -277,7 +275,8 @@ bool DWARFUnitHeader::extract(DWARFContext &Context,
   }
   if (isTypeUnit()) {
     TypeHash = debug_info.getU64(offset_ptr);
-    TypeOffset = debug_info.getU32(offset_ptr);
+    TypeOffset =
+        debug_info.getUnsigned(offset_ptr, FormParams.getDwarfOffsetByteSize());
   } else if (UnitType == DW_UT_split_compile || UnitType == DW_UT_skeleton)
     DWOId = debug_info.getU64(offset_ptr);
 
@@ -290,7 +289,8 @@ bool DWARFUnitHeader::extract(DWARFContext &Context,
   bool TypeOffsetOK =
       !isTypeUnit()
           ? true
-          : TypeOffset >= Size && TypeOffset < getLength() + SizeOfLength;
+          : TypeOffset >= Size &&
+                TypeOffset < getLength() + getUnitLengthFieldByteSize();
   bool LengthOK = debug_info.isValidOffset(getNextUnitOffset() - 1);
   bool VersionOK = DWARFContext::isSupportedVersion(getVersion());
   bool AddrSizeOK = getAddressByteSize() == 4 || getAddressByteSize() == 8;
diff --git a/test/tools/llvm-dwarfdump/X86/typeunit-v4-dwarf64.s b/test/tools/llvm-dwarfdump/X86/typeunit-v4-dwarf64.s
new file mode 100644 (file)
index 0000000..a785f8a
--- /dev/null
@@ -0,0 +1,57 @@
+# RUN: llvm-mc %s -filetype obj -triple x86_64-unknown-elf -o - | \
+# RUN:   llvm-dwarfdump -debug-types - | \
+# RUN:   FileCheck %s
+
+        .section .debug_abbrev,"",@progbits
+        .byte 0x01  # Abbrev code
+        .byte 0x41  # DW_TAG_type_unit
+        .byte 0x01  # DW_CHILDREN_yes
+        .byte 0x17  # DW_AT_visibility
+        .byte 0x0b  # DW_FORM_data1
+        .byte 0x00  # EOM(1)
+        .byte 0x00  # EOM(2)
+        .byte 0x02  # Abbrev code
+        .byte 0x13  # DW_TAG_structure_type
+        .byte 0x00  # DW_CHILDREN_no (no members)
+        .byte 0x17  # DW_AT_visibility
+        .byte 0x0b  # DW_FORM_data1
+        .byte 0x00  # EOM(1)
+        .byte 0x00  # EOM(2)
+        .byte 0x00  # EOM(3)
+
+        .section .debug_types,"",@progbits
+# CHECK: .debug_types contents:
+# CHECK-NEXT: 0x00000000: Type Unit:
+TU_4_64_start:
+        .long 0xffffffff            # DWARF64 mark
+        .quad TU_4_64_end-TU_4_64_version  # Length of Unit
+# CHECK-SAME: length = 0x00000021
+TU_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: name = ''
+        .quad 0x0011223344556677    # Type Signature
+# CHECK-SAME: type_signature = 0x0011223344556677
+        .quad TU_4_64_type-TU_4_64_start # Type offset
+# CHECK-SAME: type_offset = 0x0029
+# CHECK-SAME: (next unit at 0x0000002d)
+
+        .byte 1                     # Abbreviation code
+# CHECK: 0x00000027: DW_TAG_type_unit
+        .byte 1                     # DW_VIS_local
+# CHECK-NEXT: DW_AT_visibility (DW_VIS_local)
+
+TU_4_64_type:
+        .byte 2                     # Abbreviation code
+# CHECK: 0x00000029: DW_TAG_structure_type
+        .byte 1                     # DW_VIS_local
+# CHECK-NEXT: DW_AT_visibility (DW_VIS_local)
+
+        .byte 0 # NULL
+# CHECK: 0x0000002b: NULL
+        .byte 0 # NULL
+TU_4_64_end:
diff --git a/test/tools/llvm-dwarfdump/X86/typeunit-v5-dwarf64.s b/test/tools/llvm-dwarfdump/X86/typeunit-v5-dwarf64.s
new file mode 100644 (file)
index 0000000..1a82a05
--- /dev/null
@@ -0,0 +1,58 @@
+# 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 0x41  # DW_TAG_type_unit
+        .byte 0x01  # DW_CHILDREN_yes
+        .byte 0x17  # DW_AT_visibility
+        .byte 0x0b  # DW_FORM_data1
+        .byte 0x00  # EOM(1)
+        .byte 0x00  # EOM(2)
+        .byte 0x02  # Abbrev code
+        .byte 0x13  # DW_TAG_structure_type
+        .byte 0x00  # DW_CHILDREN_no (no members)
+        .byte 0x17  # DW_AT_visibility
+        .byte 0x0b  # DW_FORM_data1
+        .byte 0x00  # EOM(1)
+        .byte 0x00  # EOM(2)
+        .byte 0x00  # EOM(3)
+
+        .section .debug_info,"",@progbits
+# CHECK: .debug_info contents:
+# CHECK-NEXT: 0x00000000: Type Unit:
+TU_5_64_start:
+        .long 0xffffffff            # DWARF64 mark
+        .quad TU_5_64_end-TU_5_64_version  # Length of Unit
+# CHECK-SAME: length = 0x00000022
+TU_5_64_version:
+        .short 5                    # DWARF version number
+# CHECK-SAME: version = 0x0005
+        .byte 2                     # DW_UT_type
+        .byte 8                     # Address Size (in bytes)
+        .quad .debug_abbrev         # Offset Into Abbrev. Section
+# CHECK-SAME: abbr_offset = 0x0000
+# CHECK-SAME: addr_size = 0x08
+# CHECK-SAME: name = ''
+        .quad 0x0011223344556677    # Type Signature
+# CHECK-SAME: type_signature = 0x0011223344556677
+        .quad TU_5_64_type-TU_5_64_start # Type offset
+# CHECK-SAME: type_offset = 0x002a
+# CHECK-SAME: (next unit at 0x0000002e)
+
+        .byte 1                     # Abbreviation code
+# CHECK: 0x00000028: DW_TAG_type_unit
+        .byte 1                     # DW_VIS_local
+# CHECK-NEXT: DW_AT_visibility (DW_VIS_local)
+
+TU_5_64_type:
+        .byte 2                     # Abbreviation code
+# CHECK: 0x0000002a: DW_TAG_structure_type
+        .byte 1                     # DW_VIS_local
+# CHECK-NEXT: DW_AT_visibility (DW_VIS_local)
+
+        .byte 0 # NULL
+# CHECK: 0x0000002c: NULL
+        .byte 0 # NULL
+TU_5_64_end: