DWARFVerifier: Basic verification of .debug_names
authorPavel Labath <labath@google.com>
Thu, 8 Mar 2018 15:34:42 +0000 (15:34 +0000)
committerPavel Labath <labath@google.com>
Thu, 8 Mar 2018 15:34:42 +0000 (15:34 +0000)
Summary:
This patch adds basic .debug_names verification capabilities to the
DWARF verifier. Right now, it checks that the headers and abbreviation
tables of the individual name indexes can be parsed correctly, it
verifies the buckets table and the cross-checks the CU lists for
consistency. I intend to add further checks in follow-up patches.

Reviewers: JDevlieghere, aprantl, probinson, dblaikie

Subscribers: vleschuk, echristo, clayborg, llvm-commits

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

llvm-svn: 327011

llvm/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h
llvm/include/llvm/DebugInfo/DWARF/DWARFVerifier.h
llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
llvm/test/tools/llvm-dwarfdump/X86/debug-names-verify-abbrev-duplicate.s [new file with mode: 0644]
llvm/test/tools/llvm-dwarfdump/X86/debug-names-verify-abbrev-short.s [new file with mode: 0644]
llvm/test/tools/llvm-dwarfdump/X86/debug-names-verify-buckets.s [new file with mode: 0644]
llvm/test/tools/llvm-dwarfdump/X86/debug-names-verify-cu-lists.s [new file with mode: 0644]
llvm/test/tools/llvm-dwarfdump/X86/debug-names-verify-short1.s [new file with mode: 0644]
llvm/test/tools/llvm-dwarfdump/X86/debug-names-verify-short2.s [new file with mode: 0644]
llvm/test/tools/llvm-dwarfdump/X86/debug-names-verify-short3.s [new file with mode: 0644]

index b0de1ff..e52d54a 100644 (file)
@@ -364,11 +364,6 @@ public:
     uint32_t EntryOffsetsBase;
     uint32_t EntriesBase;
 
-    /// Reads an entry in the Bucket Array for the given Bucket. The returned
-    /// value is a (1-based) index into the Names, StringOffsets and
-    /// EntryOffsets arrays. The input Bucket index is 0-based.
-    uint32_t getBucketArrayEntry(uint32_t Bucket) const;
-
     /// Reads an entry in the Hash Array for the given Index. The input Index
     /// is 1-based.
     uint32_t getHashArrayEntry(uint32_t Index) const;
@@ -413,7 +408,16 @@ public:
     uint64_t getForeignTUSignature(uint32_t TU) const;
     uint32_t getForeignTUCount() const { return Hdr.ForeignTypeUnitCount; }
 
+    /// Reads an entry in the Bucket Array for the given Bucket. The returned
+    /// value is a (1-based) index into the Names, StringOffsets and
+    /// EntryOffsets arrays. The input Bucket index is 0-based.
+    uint32_t getBucketArrayEntry(uint32_t Bucket) const;
+    uint32_t getBucketCount() const { return Hdr.BucketCount; }
+
+    uint32_t getNameCount() const { return Hdr.NameCount; }
+
     llvm::Error extract();
+    uint32_t getUnitOffset() const { return Base; }
     uint32_t getNextUnitOffset() const { return Base + 4 + Hdr.UnitLength; }
     void dump(ScopedPrinter &W) const;
 
@@ -470,7 +474,7 @@ public:
   };
 
 private:
-  llvm::SmallVector<NameIndex, 0> NameIndices;
+  SmallVector<NameIndex, 0> NameIndices;
 
 public:
   DWARFDebugNames(const DWARFDataExtractor &AccelSection,
@@ -482,6 +486,10 @@ public:
 
   /// Look up all entries in the accelerator table matching \c Key.
   iterator_range<ValueIterator> equal_range(StringRef Key) const;
+
+  using const_iterator = SmallVector<NameIndex, 0>::const_iterator;
+  const_iterator begin() const { return NameIndices.begin(); }
+  const_iterator end() const { return NameIndices.end(); }
 };
 
 } // end namespace llvm
index 589a5eb..42f5140 100644 (file)
@@ -26,6 +26,7 @@ class DWARFDie;
 class DWARFUnit;
 class DWARFDataExtractor;
 class DWARFDebugAbbrev;
+class DWARFDebugNames;
 class DataExtractor;
 struct DWARFSection;
 
@@ -232,6 +233,23 @@ private:
                                  DataExtractor *StrData,
                                  const char *SectionName);
 
+  unsigned verifyDebugNamesCULists(const DWARFDebugNames &AccelTable);
+
+  /// Verify that the DWARF v5 accelerator table is valid.
+  ///
+  /// This function currently checks that:
+  /// - Headers and abbreviation tables of individual Name Indices fit into the
+  ///   section and can be parsed.
+  /// - The CU lists reference existing compile units.
+  /// - The buckets have a valid index, or they are empty.
+  ///
+  /// \param AccelSection section containing the acceleration table
+  /// \param StrData string section
+  ///
+  /// \returns The number of errors occurred during verification
+  unsigned verifyDebugNames(const DWARFSection &AccelSection,
+                            const DataExtractor &StrData);
+
 public:
   DWARFVerifier(raw_ostream &S, DWARFContext &D,
                 DIDumpOptions DumpOpts = DIDumpOptions::getForSingleDIE())
index bfc0675..171ff63 100644 (file)
@@ -778,6 +778,90 @@ unsigned DWARFVerifier::verifyAppleAccelTable(const DWARFSection *AccelSection,
   return NumErrors;
 }
 
+unsigned
+DWARFVerifier::verifyDebugNamesCULists(const DWARFDebugNames &AccelTable) {
+  // A map from CU offset to the (first) Name Index offset which claims to index
+  // this CU.
+  DenseMap<uint32_t, uint32_t> CUMap;
+  const uint32_t NotIndexed = std::numeric_limits<uint32_t>::max();
+
+  CUMap.reserve(DCtx.getNumCompileUnits());
+  for (const auto &CU : DCtx.compile_units())
+    CUMap[CU->getOffset()] = NotIndexed;
+
+  unsigned NumErrors = 0;
+  for (const DWARFDebugNames::NameIndex &NI : AccelTable) {
+    if (NI.getCUCount() == 0) {
+      error() << formatv("Name Index @ {0:x} does not index any CU\n",
+                         NI.getUnitOffset());
+      ++NumErrors;
+      continue;
+    }
+    for (uint32_t CU = 0, End = NI.getCUCount(); CU < End; ++CU) {
+      uint32_t Offset = NI.getCUOffset(CU);
+      auto Iter = CUMap.find(Offset);
+
+      if (Iter == CUMap.end()) {
+        error() << formatv(
+            "Name Index @ {0:x} references a non-existing CU @ {1:x}\n",
+            NI.getUnitOffset(), Offset);
+        ++NumErrors;
+        continue;
+      }
+
+      if (Iter->second != NotIndexed) {
+        error() << formatv("Name Index @ {0:x} references a CU @ {1:x}, but "
+                          "this CU is already indexed by Name Index @ {2:x}\n",
+                          NI.getUnitOffset(), Offset, Iter->second);
+        continue;
+      }
+      Iter->second = NI.getUnitOffset();
+    }
+  }
+
+  for (const auto &KV : CUMap) {
+    if (KV.second == NotIndexed)
+      warn() << formatv("CU @ {0:x} not covered by any Name Index\n", KV.first);
+  }
+
+  return NumErrors;
+}
+
+unsigned DWARFVerifier::verifyDebugNames(const DWARFSection &AccelSection,
+                                         const DataExtractor &StrData) {
+  unsigned NumErrors = 0;
+  DWARFDataExtractor AccelSectionData(DCtx.getDWARFObj(), AccelSection,
+                                      DCtx.isLittleEndian(), 0);
+  DWARFDebugNames AccelTable(AccelSectionData, StrData);
+
+  OS << "Verifying .debug_names...\n";
+
+  // This verifies that we can read individual name indices and their
+  // abbreviation tables.
+  if (Error E = AccelTable.extract()) {
+    error() << toString(std::move(E)) << '\n';
+    return 1;
+  }
+
+  NumErrors += verifyDebugNamesCULists(AccelTable);
+
+  for (const DWARFDebugNames::NameIndex &NI : AccelTable) {
+    for (uint32_t Bucket = 0, End = NI.getBucketCount(); Bucket < End;
+         ++Bucket) {
+      uint32_t Index = NI.getBucketArrayEntry(Bucket);
+      if (Index > NI.getNameCount()) {
+        error() << formatv("Bucket {0} of Name Index @ {1:x} contains invalid "
+                           "value {2}. Valid range is [0, {3}].\n",
+                           Bucket, NI.getUnitOffset(), Index,
+                           NI.getNameCount());
+        ++NumErrors;
+      }
+    }
+  }
+
+  return NumErrors;
+}
+
 bool DWARFVerifier::handleAccelTables() {
   const DWARFObject &D = DCtx.getDWARFObj();
   DataExtractor StrData(D.getStringSection(), DCtx.isLittleEndian(), 0);
@@ -794,6 +878,9 @@ bool DWARFVerifier::handleAccelTables() {
   if (!D.getAppleObjCSection().Data.empty())
     NumErrors +=
         verifyAppleAccelTable(&D.getAppleObjCSection(), &StrData, ".apple_objc");
+
+  if (!D.getDebugNamesSection().Data.empty())
+    NumErrors += verifyDebugNames(D.getDebugNamesSection(), StrData);
   return NumErrors == 0;
 }
 
diff --git a/llvm/test/tools/llvm-dwarfdump/X86/debug-names-verify-abbrev-duplicate.s b/llvm/test/tools/llvm-dwarfdump/X86/debug-names-verify-abbrev-duplicate.s
new file mode 100644 (file)
index 0000000..5c5075c
--- /dev/null
@@ -0,0 +1,64 @@
+# RUN: llvm-mc -triple x86_64-pc-linux %s -filetype=obj | \
+# RUN:   not llvm-dwarfdump -verify - | FileCheck %s
+
+# CHECK: Duplicate abbreviation code.
+
+       .section        .debug_str,"MS",@progbits,1
+.Lstring_producer:
+       .asciz  "Hand-written dwarf"
+
+       .section        .debug_abbrev,"",@progbits
+.Lsection_abbrev:
+       .byte   1                       # Abbreviation Code
+       .byte   17                      # DW_TAG_compile_unit
+       .byte   1                       # DW_CHILDREN_yes
+       .byte   37                      # DW_AT_producer
+       .byte   14                      # DW_FORM_strp
+       .byte   19                      # DW_AT_language
+       .byte   5                       # DW_FORM_data2
+       .byte   0                       # EOM(1)
+       .byte   0                       # EOM(2)
+       .byte   0                       # EOM(3)
+
+       .section        .debug_info,"",@progbits
+.Lcu_begin0:
+       .long   .Lcu_end0-.Lcu_start0   # Length of Unit
+.Lcu_start0:
+       .short  4                       # DWARF version number
+       .long   .Lsection_abbrev        # Offset Into Abbrev. Section
+       .byte   8                       # Address Size (in bytes)
+       .byte   1                       # Abbrev [1] DW_TAG_compile_unit
+       .long   .Lstring_producer       # DW_AT_producer
+       .short  12                      # DW_AT_language
+       .byte   0                       # End Of Children Mark
+.Lcu_end0:
+
+       .section        .debug_names,"",@progbits
+       .long   .Lnames_end0-.Lnames_start0 # Header: contribution length
+.Lnames_start0:
+       .short  5                       # Header: version
+       .short  0                       # Header: padding
+       .long   1                       # Header: compilation unit count
+       .long   0                       # Header: local type unit count
+       .long   0                       # Header: foreign type unit count
+       .long   0                       # Header: bucket count
+       .long   0                       # Header: name count
+       .long   .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size
+       .long   0                       # Header: augmentation length
+       .long   .Lcu_begin0             # Compilation unit 0
+.Lnames_abbrev_start0:
+       .byte   46                      # Abbrev code
+       .byte   46                      # DW_TAG_subprogram
+       .byte   3                       # DW_IDX_die_offset
+       .byte   6                       # DW_FORM_data4
+       .byte   0                       # End of abbrev
+       .byte   0                       # End of abbrev
+       .byte   46                      # Abbrev code
+       .byte   46                      # DW_TAG_subprogram
+       .byte   3                       # DW_IDX_die_offset
+       .byte   6                       # DW_FORM_data4
+       .byte   0                       # End of abbrev
+       .byte   0                       # End of abbrev
+       .byte   0                       # End of abbrev list
+.Lnames_abbrev_end0:
+.Lnames_end0:
diff --git a/llvm/test/tools/llvm-dwarfdump/X86/debug-names-verify-abbrev-short.s b/llvm/test/tools/llvm-dwarfdump/X86/debug-names-verify-abbrev-short.s
new file mode 100644 (file)
index 0000000..7b6aca5
--- /dev/null
@@ -0,0 +1,53 @@
+# RUN: llvm-mc -triple x86_64-pc-linux %s -filetype=obj | \
+# RUN:   not llvm-dwarfdump -verify - | FileCheck %s
+
+# CHECK: Incorrectly terminated abbreviation table.
+
+       .section        .debug_str,"MS",@progbits,1
+.Lstring_producer:
+       .asciz  "Hand-written dwarf"
+
+       .section        .debug_abbrev,"",@progbits
+.Lsection_abbrev:
+       .byte   1                       # Abbreviation Code
+       .byte   17                      # DW_TAG_compile_unit
+       .byte   1                       # DW_CHILDREN_yes
+       .byte   37                      # DW_AT_producer
+       .byte   14                      # DW_FORM_strp
+       .byte   19                      # DW_AT_language
+       .byte   5                       # DW_FORM_data2
+       .byte   0                       # EOM(1)
+       .byte   0                       # EOM(2)
+       .byte   0                       # EOM(3)
+
+       .section        .debug_info,"",@progbits
+.Lcu_begin0:
+       .long   .Lcu_end0-.Lcu_start0   # Length of Unit
+.Lcu_start0:
+       .short  4                       # DWARF version number
+       .long   .Lsection_abbrev        # Offset Into Abbrev. Section
+       .byte   8                       # Address Size (in bytes)
+       .byte   1                       # Abbrev [1] DW_TAG_compile_unit
+       .long   .Lstring_producer       # DW_AT_producer
+       .short  12                      # DW_AT_language
+       .byte   0                       # End Of Children Mark
+.Lcu_end0:
+
+       .section        .debug_names,"",@progbits
+       .long   .Lnames_end0-.Lnames_start0 # Header: contribution length
+.Lnames_start0:
+       .short  5                       # Header: version
+       .short  0                       # Header: padding
+       .long   1                       # Header: compilation unit count
+       .long   0                       # Header: local type unit count
+       .long   0                       # Header: foreign type unit count
+       .long   0                       # Header: bucket count
+       .long   0                       # Header: name count
+       .long   .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size
+       .long   0                       # Header: augmentation length
+       .long   .Lcu_begin0             # Compilation unit 0
+.Lnames_abbrev_start0:
+       .byte   46                      # Abbrev code
+       .byte   46                      # DW_TAG_subprogram
+.Lnames_abbrev_end0:
+.Lnames_end0:
diff --git a/llvm/test/tools/llvm-dwarfdump/X86/debug-names-verify-buckets.s b/llvm/test/tools/llvm-dwarfdump/X86/debug-names-verify-buckets.s
new file mode 100644 (file)
index 0000000..5934d6d
--- /dev/null
@@ -0,0 +1,83 @@
+# RUN: llvm-mc -triple x86_64-pc-linux %s -filetype=obj | \
+# RUN:   not llvm-dwarfdump -verify - | FileCheck %s
+
+# CHECK: error: Bucket 0 of Name Index @ 0x0 contains invalid value 2. Valid range is [0, 1].
+       .section        .debug_str,"MS",@progbits,1
+.Lstring_foo:
+       .asciz  "foo"
+.Lstring_producer:
+       .asciz  "Hand-written dwarf"
+
+       .section        .debug_abbrev,"",@progbits
+.Lsection_abbrev:
+       .byte   1                       # Abbreviation Code
+       .byte   17                      # DW_TAG_compile_unit
+       .byte   1                       # DW_CHILDREN_yes
+       .byte   37                      # DW_AT_producer
+       .byte   14                      # DW_FORM_strp
+       .byte   19                      # DW_AT_language
+       .byte   5                       # DW_FORM_data2
+       .byte   0                       # EOM(1)
+       .byte   0                       # EOM(2)
+       .byte   2                       # Abbreviation Code
+       .byte   46                      # DW_TAG_subprogram
+       .byte   0                       # DW_CHILDREN_no
+       .byte   3                       # DW_AT_name
+       .byte   14                      # DW_FORM_strp
+       .byte   63                      # DW_AT_external
+       .byte   25                      # DW_FORM_flag_present
+       .byte   0                       # EOM(1)
+       .byte   0                       # EOM(2)
+       .byte   0                       # EOM(3)
+
+       .section        .debug_info,"",@progbits
+.Lcu_begin0:
+       .long   .Lcu_end0-.Lcu_start0   # Length of Unit
+.Lcu_start0:
+       .short  4                       # DWARF version number
+       .long   .Lsection_abbrev        # Offset Into Abbrev. Section
+       .byte   8                       # Address Size (in bytes)
+       .byte   1                       # Abbrev [1] DW_TAG_compile_unit
+       .long   .Lstring_producer       # DW_AT_producer
+       .short  12                      # DW_AT_language
+.Ldie_foo:
+       .byte   2                       # Abbrev [2] DW_TAG_subprogram
+       .long   .Lstring_foo            # DW_AT_name
+                                        # DW_AT_external
+       .byte   0                       # End Of Children Mark
+.Lcu_end0:
+
+       .section        .debug_names,"",@progbits
+       .long   .Lnames_end0-.Lnames_start0 # Header: contribution length
+.Lnames_start0:
+       .short  5                       # Header: version
+       .short  0                       # Header: padding
+       .long   1                       # Header: compilation unit count
+       .long   0                       # Header: local type unit count
+       .long   0                       # Header: foreign type unit count
+       .long   2                       # Header: bucket count
+       .long   1                       # Header: name count
+       .long   .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size
+       .long   0                       # Header: augmentation length
+       .long   .Lcu_begin0             # Compilation unit 0
+       .long   2                       # Bucket 0
+       .long   1                       # Bucket 1
+       .long   193491849               # Hash in Bucket 1
+       .long   .Lstring_foo            # String in Bucket 1: foo
+       .long   .Lnames0-.Lnames_entries0 # Offset in Bucket 1
+.Lnames_abbrev_start0:
+       .byte   46                      # Abbrev code
+       .byte   46                      # DW_TAG_subprogram
+       .byte   3                       # DW_IDX_die_offset
+       .byte   6                       # DW_FORM_data4
+       .byte   0                       # End of abbrev
+       .byte   0                       # End of abbrev
+       .byte   0                       # End of abbrev list
+.Lnames_abbrev_end0:
+.Lnames_entries0:
+.Lnames0:
+       .byte   46                      # Abbrev code
+       .long   .Ldie_foo-.Lcu_begin0   # DW_IDX_die_offset
+       .long   0                       # End of list: foo
+       .p2align        2
+.Lnames_end0:
diff --git a/llvm/test/tools/llvm-dwarfdump/X86/debug-names-verify-cu-lists.s b/llvm/test/tools/llvm-dwarfdump/X86/debug-names-verify-cu-lists.s
new file mode 100644 (file)
index 0000000..809fa81
--- /dev/null
@@ -0,0 +1,110 @@
+# RUN: llvm-mc -triple x86_64-pc-linux %s -filetype=obj | \
+# RUN:   not llvm-dwarfdump -verify - | FileCheck %s
+
+# CHECK: error: Name Index @ 0x0 does not index any CU
+# CHECK: error: Name Index @ 0x28 references a non-existing CU @ 0x1
+# CHECK: error: Name Index @ 0x58 references a CU @ 0x0, but this CU is already indexed by Name Index @ 0x28
+# CHECK: warning: CU @ 0x13 not covered by any Name Index
+
+       .section        .debug_str,"MS",@progbits,1
+.Lstring_foo:
+       .asciz  "foo"
+.Lstring_foo_mangled:
+       .asciz  "_Z3foov"
+.Lstring_bar:
+       .asciz  "bar"
+.Lstring_producer:
+       .asciz  "Hand-written dwarf"
+
+       .section        .debug_abbrev,"",@progbits
+.Lsection_abbrev:
+       .byte   1                       # Abbreviation Code
+       .byte   17                      # DW_TAG_compile_unit
+       .byte   1                       # DW_CHILDREN_yes
+       .byte   37                      # DW_AT_producer
+       .byte   14                      # DW_FORM_strp
+       .byte   19                      # DW_AT_language
+       .byte   5                       # DW_FORM_data2
+       .byte   0                       # EOM(1)
+       .byte   0                       # EOM(2)
+       .byte   0                       # EOM(3)
+
+       .section        .debug_info,"",@progbits
+.Lcu_begin0:
+       .long   .Lcu_end0-.Lcu_start0   # Length of Unit
+.Lcu_start0:
+       .short  4                       # DWARF version number
+       .long   .Lsection_abbrev        # Offset Into Abbrev. Section
+       .byte   8                       # Address Size (in bytes)
+       .byte   1                       # Abbrev [1] DW_TAG_compile_unit
+       .long   .Lstring_producer       # DW_AT_producer
+       .short  12                      # DW_AT_language
+       .byte   0                       # End Of Children Mark
+.Lcu_end0:
+
+.Lcu_begin1:
+       .long   .Lcu_end1-.Lcu_start1   # Length of Unit
+.Lcu_start1:
+       .short  4                       # DWARF version number
+       .long   .Lsection_abbrev        # Offset Into Abbrev. Section
+       .byte   8                       # Address Size (in bytes)
+       .byte   1                       # Abbrev [1] DW_TAG_compile_unit
+       .long   .Lstring_producer       # DW_AT_producer
+       .short  12                      # DW_AT_language
+       .byte   0                       # End Of Children Mark
+.Lcu_end1:
+
+       .section        .debug_names,"",@progbits
+       .long   .Lnames_end0-.Lnames_start0 # Header: contribution length
+.Lnames_start0:
+       .short  5                       # Header: version
+       .short  0                       # Header: padding
+       .long   0                       # Header: compilation unit count
+       .long   0                       # Header: local type unit count
+       .long   0                       # Header: foreign type unit count
+       .long   0                       # Header: bucket count
+       .long   0                       # Header: name count
+       .long   .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size
+       .long   0                       # Header: augmentation length
+.Lnames_abbrev_start0:
+       .byte   0                       # End of abbrev list
+.Lnames_abbrev_end0:
+.p2align 2
+.Lnames_end0:
+
+       .long   .Lnames_end1-.Lnames_start1 # Header: contribution length
+.Lnames_start1:
+       .short  5                       # Header: version
+       .short  0                       # Header: padding
+       .long   2                       # Header: compilation unit count
+       .long   0                       # Header: local type unit count
+       .long   0                       # Header: foreign type unit count
+       .long   0                       # Header: bucket count
+       .long   0                       # Header: name count
+       .long   .Lnames_abbrev_end1-.Lnames_abbrev_start1 # Header: abbreviation table size
+       .long   0                       # Header: augmentation length
+       .long   .Lcu_begin0             # Compilation unit 0
+       .long   .Lcu_begin0+1           # Compilation unit 0
+.Lnames_abbrev_start1:
+       .byte   0                       # End of abbrev list
+.Lnames_abbrev_end1:
+.p2align 2
+.Lnames_end1:
+
+       .long   .Lnames_end2-.Lnames_start2 # Header: contribution length
+.Lnames_start2:
+       .short  5                       # Header: version
+       .short  0                       # Header: padding
+       .long   1                       # Header: compilation unit count
+       .long   0                       # Header: local type unit count
+       .long   0                       # Header: foreign type unit count
+       .long   0                       # Header: bucket count
+       .long   0                       # Header: name count
+       .long   .Lnames_abbrev_end2-.Lnames_abbrev_start2 # Header: abbreviation table size
+       .long   0                       # Header: augmentation length
+       .long   .Lcu_begin0             # Compilation unit 0
+.Lnames_abbrev_start2:
+       .byte   0                       # End of abbrev list
+.Lnames_abbrev_end2:
+.p2align 2
+.Lnames_end2:
diff --git a/llvm/test/tools/llvm-dwarfdump/X86/debug-names-verify-short1.s b/llvm/test/tools/llvm-dwarfdump/X86/debug-names-verify-short1.s
new file mode 100644 (file)
index 0000000..9c11972
--- /dev/null
@@ -0,0 +1,47 @@
+# RUN: llvm-mc -triple x86_64-pc-linux %s -filetype=obj | \
+# RUN:   not llvm-dwarfdump -verify - | FileCheck %s
+
+# CHECK: Section too small: cannot read header.
+
+       .section        .debug_str,"MS",@progbits,1
+.Lstring_producer:
+       .asciz  "Hand-written dwarf"
+
+       .section        .debug_abbrev,"",@progbits
+.Lsection_abbrev:
+       .byte   1                       # Abbreviation Code
+       .byte   17                      # DW_TAG_compile_unit
+       .byte   1                       # DW_CHILDREN_yes
+       .byte   37                      # DW_AT_producer
+       .byte   14                      # DW_FORM_strp
+       .byte   19                      # DW_AT_language
+       .byte   5                       # DW_FORM_data2
+       .byte   0                       # EOM(1)
+       .byte   0                       # EOM(2)
+       .byte   0                       # EOM(3)
+
+       .section        .debug_info,"",@progbits
+.Lcu_begin0:
+       .long   .Lcu_end0-.Lcu_start0   # Length of Unit
+.Lcu_start0:
+       .short  4                       # DWARF version number
+       .long   .Lsection_abbrev        # Offset Into Abbrev. Section
+       .byte   8                       # Address Size (in bytes)
+       .byte   1                       # Abbrev [1] DW_TAG_compile_unit
+       .long   .Lstring_producer       # DW_AT_producer
+       .short  12                      # DW_AT_language
+       .byte   0                       # End Of Children Mark
+.Lcu_end0:
+
+       .section        .debug_names,"",@progbits
+       .long   .Lnames_end0-.Lnames_start0 # Header: contribution length
+.Lnames_start0:
+       .short  5                       # Header: version
+       .short  0                       # Header: padding
+       .long   1                       # Header: compilation unit count
+       .long   0                       # Header: local type unit count
+       .long   0                       # Header: foreign type unit count
+       .long   2                       # Header: bucket count
+       .long   3                       # Header: name count
+       .long   47                      # Header: abbreviation table size
+.Lnames_end0:
diff --git a/llvm/test/tools/llvm-dwarfdump/X86/debug-names-verify-short2.s b/llvm/test/tools/llvm-dwarfdump/X86/debug-names-verify-short2.s
new file mode 100644 (file)
index 0000000..60d9c78
--- /dev/null
@@ -0,0 +1,49 @@
+# RUN: llvm-mc -triple x86_64-pc-linux %s -filetype=obj | \
+# RUN:   not llvm-dwarfdump -verify - | FileCheck %s
+
+# CHECK: Section too small: cannot read header augmentation.
+
+       .section        .debug_str,"MS",@progbits,1
+.Lstring_producer:
+       .asciz  "Hand-written dwarf"
+
+       .section        .debug_abbrev,"",@progbits
+.Lsection_abbrev:
+       .byte   1                       # Abbreviation Code
+       .byte   17                      # DW_TAG_compile_unit
+       .byte   1                       # DW_CHILDREN_yes
+       .byte   37                      # DW_AT_producer
+       .byte   14                      # DW_FORM_strp
+       .byte   19                      # DW_AT_language
+       .byte   5                       # DW_FORM_data2
+       .byte   0                       # EOM(1)
+       .byte   0                       # EOM(2)
+       .byte   0                       # EOM(3)
+
+       .section        .debug_info,"",@progbits
+.Lcu_begin0:
+       .long   .Lcu_end0-.Lcu_start0   # Length of Unit
+.Lcu_start0:
+       .short  4                       # DWARF version number
+       .long   .Lsection_abbrev        # Offset Into Abbrev. Section
+       .byte   8                       # Address Size (in bytes)
+       .byte   1                       # Abbrev [1] DW_TAG_compile_unit
+       .long   .Lstring_producer       # DW_AT_producer
+       .short  12                      # DW_AT_language
+       .byte   0                       # End Of Children Mark
+.Lcu_end0:
+
+       .section        .debug_names,"",@progbits
+       .long   .Lnames_end0-.Lnames_start0 # Header: contribution length
+.Lnames_start0:
+       .short  5                       # Header: version
+       .short  0                       # Header: padding
+       .long   1                       # Header: compilation unit count
+       .long   0                       # Header: local type unit count
+       .long   0                       # Header: foreign type unit count
+       .long   2                       # Header: bucket count
+       .long   3                       # Header: name count
+       .long   47                      # Header: abbreviation table size
+       .long   8                       # Header: augmentation length
+        .asciz "short"                  # Header: augmentation
+.Lnames_end0:
diff --git a/llvm/test/tools/llvm-dwarfdump/X86/debug-names-verify-short3.s b/llvm/test/tools/llvm-dwarfdump/X86/debug-names-verify-short3.s
new file mode 100644 (file)
index 0000000..a9e4ec0
--- /dev/null
@@ -0,0 +1,52 @@
+# RUN: llvm-mc -triple x86_64-pc-linux %s -filetype=obj | \
+# RUN:   not llvm-dwarfdump -verify - | FileCheck %s
+
+# CHECK: Section too small: cannot read abbreviations.
+
+       .section        .debug_str,"MS",@progbits,1
+.Lstring_producer:
+       .asciz  "Hand-written dwarf"
+
+       .section        .debug_abbrev,"",@progbits
+.Lsection_abbrev:
+       .byte   1                       # Abbreviation Code
+       .byte   17                      # DW_TAG_compile_unit
+       .byte   1                       # DW_CHILDREN_yes
+       .byte   37                      # DW_AT_producer
+       .byte   14                      # DW_FORM_strp
+       .byte   19                      # DW_AT_language
+       .byte   5                       # DW_FORM_data2
+       .byte   0                       # EOM(1)
+       .byte   0                       # EOM(2)
+       .byte   0                       # EOM(3)
+
+       .section        .debug_info,"",@progbits
+.Lcu_begin0:
+       .long   .Lcu_end0-.Lcu_start0   # Length of Unit
+.Lcu_start0:
+       .short  4                       # DWARF version number
+       .long   .Lsection_abbrev        # Offset Into Abbrev. Section
+       .byte   8                       # Address Size (in bytes)
+       .byte   1                       # Abbrev [1] DW_TAG_compile_unit
+       .long   .Lstring_producer       # DW_AT_producer
+       .short  12                      # DW_AT_language
+       .byte   0                       # End Of Children Mark
+.Lcu_end0:
+
+       .section        .debug_names,"",@progbits
+       .long   .Lnames_end0-.Lnames_start0 # Header: contribution length
+.Lnames_start0:
+       .short  5                       # Header: version
+       .short  0                       # Header: padding
+       .long   1                       # Header: compilation unit count
+       .long   0                       # Header: local type unit count
+       .long   0                       # Header: foreign type unit count
+       .long   0                       # Header: bucket count
+       .long   0                       # Header: name count
+       .long   47                      # Header: abbreviation table size
+       .long   0                       # Header: augmentation length
+       .long   .Lcu_begin0             # Compilation unit 0
+.Lnames_abbrev_start0:
+       .byte   46                      # Abbrev code
+       .byte   46                      # DW_TAG_subprogram
+.Lnames_end0: