]> granicus.if.org Git - llvm/commitdiff
[DWARF] Added verification checks for the .apple_names section.
authorSpyridoula Gravani <sgravani@apple.com>
Thu, 29 Jun 2017 20:13:05 +0000 (20:13 +0000)
committerSpyridoula Gravani <sgravani@apple.com>
Thu, 29 Jun 2017 20:13:05 +0000 (20:13 +0000)
This patch verifies the number of atoms, the validity of the form for each atom, as well as the validity of the
hashdata. For hashdata, we're verifying that the hashdata offset is correct and that the offset in the .debug_info for
each DIE in the hashdata is also valid.

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

include/llvm/BinaryFormat/Dwarf.h
include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h
lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp
lib/DebugInfo/DWARF/DWARFVerifier.cpp
test/DebugInfo/dwarfdump-accel.test
test/tools/llvm-dwarfdump/X86/apple_names_verify_buckets.s [deleted file]
test/tools/llvm-dwarfdump/X86/apple_names_verify_data.s [new file with mode: 0644]
test/tools/llvm-dwarfdump/X86/apple_names_verify_form.s [new file with mode: 0644]
test/tools/llvm-dwarfdump/X86/apple_names_verify_num_atoms.s [new file with mode: 0644]
test/tools/llvm-dwarfdump/X86/no_apple_names_verify.s [new file with mode: 0644]
test/tools/llvm-dwarfdump/X86/no_apple_names_verify_buckets.s [deleted file]

index ab927565d05d565bd48ad4e5ad04d6d0d47742a5..80456a0808f2dcae4a479d428f43dcb410b80bdd 100644 (file)
@@ -62,6 +62,9 @@ enum LLVMConstants : uint32_t {
 const uint32_t DW_CIE_ID = UINT32_MAX;
 const uint64_t DW64_CIE_ID = UINT64_MAX;
 
+// Identifier of an invalid DIE offset in the .debug_info section.
+const uint32_t DW_INVALID_OFFSET = UINT32_MAX;
+
 enum Tag : uint16_t {
 #define HANDLE_DW_TAG(ID, NAME, VERSION, VENDOR) DW_TAG_##NAME = ID,
 #include "llvm/BinaryFormat/Dwarf.def"
index c19690a325ee7e2508a5773cefc21e447e170a69..eb6d0f541c1ed44409e1ffa46ddd208f2fe245d9 100644 (file)
@@ -54,6 +54,18 @@ public:
   uint32_t getNumHashes();
   uint32_t getSizeHdr();
   uint32_t getHeaderDataLength();
+  ArrayRef<std::pair<HeaderData::AtomType, HeaderData::Form>> getAtomsDesc();
+  bool validateForms();
+
+  /// Return information related to the DWARF DIE we're looking for when
+  /// performing a lookup by name.
+  ///
+  /// \param HashDataOffset an offset into the hash data table
+  /// \returns DIEOffset the offset into the .debug_info section for the DIE
+  /// related to the input hash data offset. Currently this function returns
+  /// only the DIEOffset but it can be modified to return more data regarding
+  /// the DIE
+  uint32_t readAtoms(uint32_t &HashDataOffset);
   void dump(raw_ostream &OS) const;
 };
 
index 5c2254cb476d8d374839ce07a64864dfe7d9e96a..9ae7c9a07f76d4960787393bee18570044dadcb0 100644 (file)
@@ -62,6 +62,45 @@ uint32_t DWARFAcceleratorTable::getHeaderDataLength() {
   return Hdr.HeaderDataLength;
 }
 
+ArrayRef<std::pair<DWARFAcceleratorTable::HeaderData::AtomType,
+                   DWARFAcceleratorTable::HeaderData::Form>>
+DWARFAcceleratorTable::getAtomsDesc() {
+  return HdrData.Atoms;
+}
+
+bool DWARFAcceleratorTable::validateForms() {
+  for (auto Atom : getAtomsDesc()) {
+    DWARFFormValue FormValue(Atom.second);
+    switch (Atom.first) {
+    case dwarf::DW_ATOM_die_offset:
+      if ((!FormValue.isFormClass(DWARFFormValue::FC_Constant) &&
+           !FormValue.isFormClass(DWARFFormValue::FC_Flag)) ||
+          FormValue.getForm() == dwarf::DW_FORM_sdata)
+        return false;
+    default:
+      break;
+    }
+  }
+  return true;
+}
+
+uint32_t DWARFAcceleratorTable::readAtoms(uint32_t &HashDataOffset) {
+  uint32_t DieOffset = dwarf::DW_INVALID_OFFSET;
+
+  for (auto Atom : getAtomsDesc()) {
+    DWARFFormValue FormValue(Atom.second);
+    FormValue.extractValue(AccelSection, &HashDataOffset, NULL);
+    switch (Atom.first) {
+    case dwarf::DW_ATOM_die_offset:
+      DieOffset = *FormValue.getAsUnsignedConstant();
+      break;
+    default:
+      break;
+    }
+  }
+  return DieOffset;
+}
+
 LLVM_DUMP_METHOD void DWARFAcceleratorTable::dump(raw_ostream &OS) const {
   // Dump the header.
   OS << "Magic = " << format("0x%08x", Hdr.Magic) << '\n'
index 488649ced130ddf8e01d2d8356c42acb8b118460..0a10e6b78911ddaa04c9b91101c9c8443661e9c6 100644 (file)
@@ -291,20 +291,80 @@ bool DWARFVerifier::handleAppleNames() {
 
   OS << "Verifying .apple_names...\n";
 
-  // Verify that all buckets have a valid hash index or are empty
+  // Verify that all buckets have a valid hash index or are empty.
   uint32_t NumBuckets = AppleNames.getNumBuckets();
   uint32_t NumHashes = AppleNames.getNumHashes();
 
   uint32_t BucketsOffset =
       AppleNames.getSizeHdr() + AppleNames.getHeaderDataLength();
+  uint32_t HashesBase = BucketsOffset + NumBuckets * 4;
+  uint32_t OffsetsBase = HashesBase + NumHashes * 4;
 
   for (uint32_t BucketIdx = 0; BucketIdx < NumBuckets; ++BucketIdx) {
     uint32_t HashIdx = AppleNamesSection.getU32(&BucketsOffset);
     if (HashIdx >= NumHashes && HashIdx != UINT32_MAX) {
-      OS << format("error: Bucket[%d] has invalid hash index: [%d]\n",
-                   BucketIdx, HashIdx);
+      OS << format("error: Bucket[%d] has invalid hash index: %u\n", BucketIdx,
+                   HashIdx);
       ++NumAppleNamesErrors;
     }
   }
+
+  uint32_t NumAtoms = AppleNames.getAtomsDesc().size();
+  if (NumAtoms == 0) {
+    OS << "error: no atoms; failed to read HashData\n";
+    ++NumAppleNamesErrors;
+    return false;
+  }
+
+  if (!AppleNames.validateForms()) {
+    OS << "error: unsupported form; failed to read HashData\n";
+    ++NumAppleNamesErrors;
+    return false;
+  }
+
+  for (uint32_t HashIdx = 0; HashIdx < NumHashes; ++HashIdx) {
+    uint32_t HashOffset = HashesBase + 4 * HashIdx;
+    uint32_t DataOffset = OffsetsBase + 4 * HashIdx;
+    uint32_t Hash = AppleNamesSection.getU32(&HashOffset);
+    uint32_t HashDataOffset = AppleNamesSection.getU32(&DataOffset);
+    if (!AppleNamesSection.isValidOffsetForDataOfSize(HashDataOffset,
+                                                      sizeof(uint64_t))) {
+      OS << format("error: Hash[%d] has invalid HashData offset: 0x%08x\n",
+                   HashIdx, HashDataOffset);
+      ++NumAppleNamesErrors;
+    }
+
+    uint32_t StrpOffset;
+    uint32_t StringOffset;
+    uint32_t StringCount = 0;
+    uint32_t DieOffset = dwarf::DW_INVALID_OFFSET;
+
+    while ((StrpOffset = AppleNamesSection.getU32(&HashDataOffset)) != 0) {
+      const uint32_t NumHashDataObjects =
+          AppleNamesSection.getU32(&HashDataOffset);
+      for (uint32_t HashDataIdx = 0; HashDataIdx < NumHashDataObjects;
+           ++HashDataIdx) {
+        DieOffset = AppleNames.readAtoms(HashDataOffset);
+        if (!DCtx.getDIEForOffset(DieOffset)) {
+          const uint32_t BucketIdx =
+              NumBuckets ? (Hash % NumBuckets) : UINT32_MAX;
+          StringOffset = StrpOffset;
+          const char *Name = StrData.getCStr(&StringOffset);
+          if (!Name)
+            Name = "<NULL>";
+
+          OS << format(
+              "error: .apple_names Bucket[%d] Hash[%d] = 0x%08x "
+              "Str[%u] = 0x%08x "
+              "DIE[%d] = 0x%08x is not a valid DIE offset for \"%s\".\n",
+              BucketIdx, HashIdx, Hash, StringCount, StrpOffset, HashDataIdx,
+              DieOffset, Name);
+
+          ++NumAppleNamesErrors;
+        }
+      }
+      ++StringCount;
+    }
+  }
   return NumAppleNamesErrors == 0;
 }
index c6a971a2b9aa1f4813ce8cf33cf2de0607acbee4..a49d024992c2692996c11e67456d2e96f15f59a8 100644 (file)
@@ -1,4 +1,5 @@
 RUN: llvm-dwarfdump %p/Inputs/dwarfdump-objc.x86_64.o | FileCheck %s
+RUN: llvm-dwarfdump -verify %p/Inputs/dwarfdump-objc.x86_64.o | FileCheck %s --check-prefix=VERIFY
 
 Gather some DIE indexes to verify the accelerator table contents.
 CHECK: .debug_info contents
@@ -63,3 +64,7 @@ CHECK-NOT: Name
 CHECK:     {Atom[0]: [[READONLY]]}
 CHECK:     {Atom[0]: [[ASSIGN]]}
 CHECK:     {Atom[0]: [[SETASSIGN]]}
+
+Verify the debug info in the apple_names accelerator table.
+VERIFY: Verifying .apple_names
+VERIFY-NEXT: No errors.
diff --git a/test/tools/llvm-dwarfdump/X86/apple_names_verify_buckets.s b/test/tools/llvm-dwarfdump/X86/apple_names_verify_buckets.s
deleted file mode 100644 (file)
index 7b61a94..0000000
+++ /dev/null
@@ -1,192 +0,0 @@
-# RUN: llvm-mc %s -filetype obj -triple x86_64-apple-darwin -o - \
-# RUN: | not llvm-dwarfdump -verify - \
-# RUN: | FileCheck %s
-
-# CHECK: Verifying .apple_names...
-# CHECK-NEXT: error: Bucket[0] has invalid hash index: [-2]
-
-# This test is meant to verify that the -verify option 
-# in llvm-dwarfdump, correctly identifies
-# an invalid hash index for bucket[0] in the .apple_names section. 
-
-  .section  __TEXT,__text,regular,pure_instructions
-  .file 1 "basic.c"
-  .comm _i,4,2                  ## @i
-  .section  __DWARF,__debug_str,regular,debug
-Linfo_string:
-  .asciz  "basic.c"               ## string offset=42
-  .asciz  "i"                     ## string offset=84
-  .asciz  "int"                   ## string offset=86
-  .section  __DWARF,__debug_loc,regular,debug
-Lsection_debug_loc:
-  .section  __DWARF,__debug_abbrev,regular,debug
-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 3                       ## DW_AT_name
-  .byte 14                      ## DW_FORM_strp
-  .byte 16                      ## DW_AT_stmt_list
-  .byte 23                      ## DW_FORM_sec_offset
-  .byte 27                      ## DW_AT_comp_dir
-  .byte 14                      ## DW_FORM_strp
-  .byte 0                       ## EOM(1)
-  .byte 0                       ## EOM(2)
-  .byte 2                       ## Abbreviation Code
-  .byte 52                      ## DW_TAG_variable
-  .byte 0                       ## DW_CHILDREN_no
-  .byte 3                       ## DW_AT_name
-  .byte 14                      ## DW_FORM_strp
-  .byte 73                      ## DW_AT_type
-  .byte 19                      ## DW_FORM_ref4
-  .byte 63                      ## DW_AT_external
-  .byte 25                      ## DW_FORM_flag_present
-  .byte 58                      ## DW_AT_decl_file
-  .byte 11                      ## DW_FORM_data1
-  .byte 59                      ## DW_AT_decl_line
-  .byte 11                      ## DW_FORM_data1
-  .byte 2                       ## DW_AT_location
-  .byte 24                      ## DW_FORM_exprloc
-  .byte 0                       ## EOM(1)
-  .byte 0                       ## EOM(2)
-  .byte 3                       ## Abbreviation Code
-  .byte 36                      ## DW_TAG_base_type
-  .byte 0                       ## DW_CHILDREN_no
-  .byte 3                       ## DW_AT_name
-  .byte 14                      ## DW_FORM_strp
-  .byte 62                      ## DW_AT_encoding
-  .byte 11                      ## DW_FORM_data1
-  .byte 11                      ## DW_AT_byte_size
-  .byte 11                      ## DW_FORM_data1
-  .byte 0                       ## EOM(1)
-  .byte 0                       ## EOM(2)
-  .byte 0                       ## EOM(3)
-  .section  __DWARF,__debug_info,regular,debug
-Lsection_info:
-Lcu_begin0:
-  .long 55                      ## Length of Unit
-  .short  4                       ## DWARF version number
-Lset0 = Lsection_abbrev-Lsection_abbrev ## Offset Into Abbrev. Section
-  .long Lset0
-  .byte 8                       ## Address Size (in bytes)
-  .byte 1                       ## Abbrev [1] 0xb:0x30 DW_TAG_compile_unit
-  .long 0                       ## DW_AT_producer
-  .short  12                      ## DW_AT_language
-  .long 42                      ## DW_AT_name
-Lset1 = Lline_table_start0-Lsection_line ## DW_AT_stmt_list
-  .long Lset1
-  .long 50                      ## DW_AT_comp_dir
-  .byte 2                       ## Abbrev [2] 0x1e:0x15 DW_TAG_variable
-  .long 84                      ## DW_AT_name
-  .long 51                      ## DW_AT_type
-                                        ## DW_AT_external
-  .byte 1                       ## DW_AT_decl_file
-  .byte 1                       ## DW_AT_decl_line
-  .byte 9                       ## DW_AT_location
-  .byte 3
-  .quad _i
-  .byte 3                       ## Abbrev [3] 0x33:0x7 DW_TAG_base_type
-  .long 86                      ## DW_AT_name
-  .byte 5                       ## DW_AT_encoding
-  .byte 4                       ## DW_AT_byte_size
-  .byte 0                       ## End Of Children Mark
-  .section  __DWARF,__debug_ranges,regular,debug
-Ldebug_range:
-  .section  __DWARF,__debug_macinfo,regular,debug
-Ldebug_macinfo:
-Lcu_macro_begin0:
-  .byte 0                       ## End Of Macro List Mark
-  .section  __DWARF,__apple_names,regular,debug
-Lnames_begin:
-  .long 1212240712              ## Header Magic
-  .short  1                       ## Header Version
-  .short  0                       ## Header Hash Function
-  .long 1                       ## Header Bucket Count
-  .long 1                       ## Header Hash Count
-  .long 12                      ## Header Data Length
-  .long 0                       ## HeaderData Die Offset Base
-  .long 1                       ## HeaderData Atom Count
-  .short  1                       ## DW_ATOM_die_offset
-  .short  6                       ## DW_FORM_data4
-  .long -2                      ## Bucket 0 -- error: Bucket[0] has invalid hash index: [-2]
-  .long 177678                  ## Hash in Bucket 0
-  .long LNames0-Lnames_begin    ## Offset in Bucket 0
-LNames0:
-  .long 84                      ## i
-  .long 1                       ## Num DIEs
-  .long 30
-  .long 0
-  .section  __DWARF,__apple_objc,regular,debug
-Lobjc_begin:
-  .long 1212240712              ## Header Magic
-  .short  1                       ## Header Version
-  .short  0                       ## Header Hash Function
-  .long 1                       ## Header Bucket Count
-  .long 0                       ## Header Hash Count
-  .long 12                      ## Header Data Length
-  .long 0                       ## HeaderData Die Offset Base
-  .long 1                       ## HeaderData Atom Count
-  .short  1                       ## DW_ATOM_die_offset
-  .short  6                       ## DW_FORM_data4
-  .long -1                      ## Bucket 0
-  .section  __DWARF,__apple_namespac,regular,debug
-Lnamespac_begin:
-  .long 1212240712              ## Header Magic
-  .short  1                       ## Header Version
-  .short  0                       ## Header Hash Function
-  .long 1                       ## Header Bucket Count
-  .long 0                       ## Header Hash Count
-  .long 12                      ## Header Data Length
-  .long 0                       ## HeaderData Die Offset Base
-  .long 1                       ## HeaderData Atom Count
-  .short  1                       ## DW_ATOM_die_offset
-  .short  6                       ## DW_FORM_data4
-  .long -1                      ## Bucket 0
-  .section  __DWARF,__apple_types,regular,debug
-Ltypes_begin:
-  .long 1212240712              ## Header Magic
-  .short  1                       ## Header Version
-  .short  0                       ## Header Hash Function
-  .long 1                       ## Header Bucket Count
-  .long 1                       ## Header Hash Count
-  .long 20                      ## Header Data Length
-  .long 0                       ## HeaderData Die Offset Base
-  .long 3                       ## HeaderData Atom Count
-  .short  1                       ## DW_ATOM_die_offset
-  .short  6                       ## DW_FORM_data4
-  .short  3                       ## DW_ATOM_die_tag
-  .short  5                       ## DW_FORM_data2
-  .short  4                       ## DW_ATOM_type_flags
-  .short  11                      ## DW_FORM_data1
-  .long 0                       ## Bucket 0
-  .long 193495088               ## Hash in Bucket 0
-  .long Ltypes0-Ltypes_begin    ## Offset in Bucket 0
-Ltypes0:
-  .long 86                      ## int
-  .long 1                       ## Num DIEs
-  .long 51
-  .short  36
-  .byte 0
-  .long 0
-  .section  __DWARF,__apple_exttypes,regular,debug
-Lexttypes_begin:
-  .long 1212240712              ## Header Magic
-  .short  1                       ## Header Version
-  .short  0                       ## Header Hash Function
-  .long 1                       ## Header Bucket Count
-  .long 0                       ## Header Hash Count
-  .long 12                      ## Header Data Length
-  .long 0                       ## HeaderData Die Offset Base
-  .long 1                       ## HeaderData Atom Count
-  .short  7                       ## DW_ATOM_ext_types
-  .short  6                       ## DW_FORM_data4
-  .long -1                      ## Bucket 0
-
-.subsections_via_symbols
-  .section  __DWARF,__debug_line,regular,debug
-Lsection_line:
-Lline_table_start0:
diff --git a/test/tools/llvm-dwarfdump/X86/apple_names_verify_data.s b/test/tools/llvm-dwarfdump/X86/apple_names_verify_data.s
new file mode 100644 (file)
index 0000000..6d54854
--- /dev/null
@@ -0,0 +1,64 @@
+# RUN: llvm-mc %s -filetype obj -triple x86_64-apple-darwin -o - \
+# RUN: | not llvm-dwarfdump -verify - \
+# RUN: | FileCheck %s
+
+# CHECK: Verifying .apple_names...
+# CHECK-NEXT: error: Bucket[0] has invalid hash index: 4294967294
+# CHECK-NEXT: error: Hash[0] has invalid HashData offset: 0x000000b4
+# CHECK-NEXT: error: .apple_names Bucket[1] Hash[1] = 0x0002b60f Str[0] = 0x0000005a DIE[0] = 0x00000001 is not a valid DIE offset for "j".
+
+# This test is meant to verify that the -verify option 
+# in llvm-dwarfdump, correctly identifies
+# an invalid hash index for bucket[0] in the .apple_names section, 
+# an invalid HashData offset for Hash[0], as well as
+# an invalid DIE offset in the .debug_info section.
+# We're reading an invalid DIE due to the incorrect interpretation of DW_FORM for the DIE.
+# Instead of DW_FORM_data4 the Atom[0].form is: DW_FORM_flag_present.
+
+       .section        __TEXT,__text,regular,pure_instructions
+       .file   1 "basic.c"
+       .comm   _i,4,2                  ## @i
+       .comm   _j,4,2                  ## @j
+       .section        __DWARF,__debug_str,regular,debug
+Linfo_string:
+       .asciz  "Apple LLVM version 8.1.0 (clang-802.0.35)" ## string offset=0
+       .asciz  "basic.c"               ## string offset=42
+       .asciz  "/Users/sgravani/Development/tests" ## string offset=50
+       .asciz  "i"                     ## string offset=84
+       .asciz  "int"                   ## string offset=86
+       .asciz  "j"                     ## string offset=90
+       .section        __DWARF,__debug_info,regular,debug
+Lsection_info:
+       .section        __DWARF,__apple_names,regular,debug
+Lnames_begin:
+       .long   1212240712              ## Header Magic
+       .short  1                       ## Header Version
+       .short  0                       ## Header Hash Function
+       .long   2                       ## Header Bucket Count
+       .long   2                       ## Header Hash Count
+       .long   12                      ## Header Data Length
+       .long   0                       ## HeaderData Die Offset Base
+       .long   1                       ## HeaderData Atom Count
+       .short  1                       ## DW_ATOM_die_offset
+       .short  25                       ## DW_FORM_data4 -- error: .apple_names Bucket[1] Hash[1] = 0x0002b60f Str[0] = 0x0000005a DIE[0] = 0x00000001 is not a valid DIE offset for "j".
+       .long   -2                      ## Bucket 0 -- error: Bucket[0] has invalid hash index: 4294967294
+       .long   1                       ## Bucket 1
+       .long   177678                  ## Hash in Bucket 0
+       .long   177679                  ## Hash in Bucket 1
+       .long   Lsection_line    ## Offset in Bucket 0 -- error: Hash[0] has invalid HashData offset: 0x000000b4
+       .long   LNames1-Lnames_begin    ## Offset in Bucket 1
+LNames0:
+       .long   84                      ## i
+       .long   1                       ## Num DIEs
+       .long   30
+       .long   0
+LNames1:
+       .long   90                      ## j
+       .long   1                       ## Num DIEs
+       .long   58
+       .long   0
+
+.subsections_via_symbols
+       .section        __DWARF,__debug_line,regular,debug
+Lsection_line:
+Lline_table_start0:
diff --git a/test/tools/llvm-dwarfdump/X86/apple_names_verify_form.s b/test/tools/llvm-dwarfdump/X86/apple_names_verify_form.s
new file mode 100644 (file)
index 0000000..ed4bf57
--- /dev/null
@@ -0,0 +1,58 @@
+# RUN: llvm-mc %s -filetype obj -triple x86_64-apple-darwin -o - \
+# RUN: | not llvm-dwarfdump -verify - \
+# RUN: | FileCheck %s
+
+# CHECK: Verifying .apple_names...
+# CHECK-NEXT: error: unsupported form; failed to read HashData
+
+# This test is meant to verify that the -verify option 
+# in llvm-dwarfdump, correctly identifies that Atom[0].form is unsupported.
+# As a result, the hashdata cannot be read.
+
+       .section        __TEXT,__text,regular,pure_instructions
+       .file   1 "basic.c"
+       .comm   _i,4,2                  ## @i
+       .comm   _j,4,2                  ## @j
+       .section        __DWARF,__debug_str,regular,debug
+Linfo_string:
+       .asciz  "Apple LLVM version 8.1.0 (clang-802.0.35)" ## string offset=0
+       .asciz  "basic.c"               ## string offset=42
+       .asciz  "/Users/sgravani/Development/tests" ## string offset=50
+       .asciz  "i"                     ## string offset=84
+       .asciz  "int"                   ## string offset=86
+       .asciz  "j"                     ## string offset=90
+       .section        __DWARF,__debug_info,regular,debug
+Lsection_info:
+       .section        __DWARF,__apple_names,regular,debug
+Lnames_begin:
+       .long   1212240712              ## Header Magic
+       .short  1                       ## Header Version
+       .short  0                       ## Header Hash Function
+       .long   2                       ## Header Bucket Count
+       .long   2                       ## Header Hash Count
+       .long   12                      ## Header Data Length
+       .long   0                       ## HeaderData Die Offset Base
+       .long   1                       ## HeaderData Atom Count
+       .short  1                       ## DW_ATOM_die_offset
+       .short  400                     ## DW_FORM_data4 -- error: unsupported form; failed to read HashData
+       .long   0                       ## Bucket 0
+       .long   1                       ## Bucket 1
+       .long   177678                  ## Hash in Bucket 0
+       .long   177679                  ## Hash in Bucket 1
+       .long   LNames0-Lnames_begin    ## Offset in Bucket 0
+       .long   LNames1-Lnames_begin    ## Offset in Bucket 1
+LNames0:
+       .long   84                      ## i
+       .long   1                       ## Num DIEs
+       .long   30
+       .long   0
+LNames1:
+       .long   90                      ## j
+       .long   1                       ## Num DIEs
+       .long   58
+       .long   0
+
+.subsections_via_symbols
+       .section        __DWARF,__debug_line,regular,debug
+Lsection_line:
+Lline_table_start0:
diff --git a/test/tools/llvm-dwarfdump/X86/apple_names_verify_num_atoms.s b/test/tools/llvm-dwarfdump/X86/apple_names_verify_num_atoms.s
new file mode 100644 (file)
index 0000000..dffb39c
--- /dev/null
@@ -0,0 +1,59 @@
+# RUN: llvm-mc %s -filetype obj -triple x86_64-apple-darwin -o - \
+# RUN: | not llvm-dwarfdump -verify - \
+# RUN: | FileCheck %s
+
+# CHECK: Verifying .apple_names...
+# CHECK-NEXT: error: no atoms; failed to read HashData
+
+# This test is meant to verify that the -verify option 
+# in llvm-dwarfdump, correctly identifies that there is not Atom.
+# As a result, the hashdata cannot be read.
+
+       .section        __TEXT,__text,regular,pure_instructions
+       .file   1 "basic.c"
+       .comm   _i,4,2                  ## @i
+       .comm   _j,4,2                  ## @j
+       .section        __DWARF,__debug_str,regular,debug
+Linfo_string:
+       .asciz  "Apple LLVM version 8.1.0 (clang-802.0.35)" ## string offset=0
+       .asciz  "basic.c"               ## string offset=42
+       .asciz  "/Users/sgravani/Development/tests" ## string offset=50
+       .asciz  "i"                     ## string offset=84
+       .asciz  "int"                   ## string offset=86
+       .asciz  "j"                     ## string offset=90
+       
+       .section        __DWARF,__debug_info,regular,debug
+Lsection_info:
+       .section        __DWARF,__apple_names,regular,debug
+Lnames_begin:
+       .long   1212240712              ## Header Magic
+       .short  1                       ## Header Version
+       .short  0                       ## Header Hash Function
+       .long   2                       ## Header Bucket Count
+       .long   2                       ## Header Hash Count
+       .long   12                      ## Header Data Length
+       .long   0                       ## HeaderData Die Offset Base
+       .long   0                       ## HeaderData Atom Count -- error: no atoms; failed to read HashData
+       .short  1                       ## DW_ATOM_die_offset
+       .short  6                       ## DW_FORM_data4
+       .long   0                       ## Bucket 0
+       .long   1                       ## Bucket 1
+       .long   177678                  ## Hash in Bucket 0
+       .long   177679                  ## Hash in Bucket 1
+       .long   LNames0-Lnames_begin    ## Offset in Bucket 0
+       .long   LNames1-Lnames_begin    ## Offset in Bucket 1
+LNames0:
+       .long   84                      ## i
+       .long   1                       ## Num DIEs
+       .long   30
+       .long   0
+LNames1:
+       .long   90                      ## j
+       .long   1                       ## Num DIEs
+       .long   58
+       .long   0
+
+.subsections_via_symbols
+       .section        __DWARF,__debug_line,regular,debug
+Lsection_line:
+Lline_table_start0:
diff --git a/test/tools/llvm-dwarfdump/X86/no_apple_names_verify.s b/test/tools/llvm-dwarfdump/X86/no_apple_names_verify.s
new file mode 100644 (file)
index 0000000..76606bd
--- /dev/null
@@ -0,0 +1,33 @@
+# RUN: llvm-mc %s -filetype obj -triple x86_64-apple-darwin -o - \
+# RUN: | llvm-dwarfdump -verify - \
+# RUN: | FileCheck %s
+
+# CHECK-NOT: Verifying .apple_names...
+
+# This test is meant to verify that the -verify option 
+# in llvm-dwarfdump doesn't produce any .apple_names related
+# output when there's no such section in the object.
+# The test was manually modified to exclude the 
+# .apple_names section from the apple_names_verify_num_atoms.s
+# test file in the same directory.
+
+  .section  __TEXT,__text,regular,pure_instructions
+  .file 1 "basic.c"
+  .comm _i,4,2                  ## @i
+  .comm _j,4,2                  ## @j
+  .section  __DWARF,__debug_str,regular,debug
+Linfo_string:
+  .asciz  "Apple LLVM version 8.1.0 (clang-802.0.35)" ## string offset=0
+  .asciz  "basic.c"               ## string offset=42
+  .asciz  "/Users/sgravani/Development/tests" ## string offset=50
+  .asciz  "i"                     ## string offset=84
+  .asciz  "int"                   ## string offset=86
+  .asciz  "j"                     ## string offset=90
+  
+  .section  __DWARF,__debug_info,regular,debug
+Lsection_info:
+
+.subsections_via_symbols
+  .section  __DWARF,__debug_line,regular,debug
+Lsection_line:
+Lline_table_start0:
diff --git a/test/tools/llvm-dwarfdump/X86/no_apple_names_verify_buckets.s b/test/tools/llvm-dwarfdump/X86/no_apple_names_verify_buckets.s
deleted file mode 100644 (file)
index 472ff71..0000000
+++ /dev/null
@@ -1,174 +0,0 @@
-# RUN: llvm-mc %s -filetype obj -triple x86_64-apple-darwin -o - \
-# RUN: | not llvm-dwarfdump -verify - \
-# RUN: | FileCheck %s
-
-# CHECK-NOT: Verifying .apple_names...
-
-# This test is meant to verify that the -verify option 
-# in llvm-dwarfdump doesn't produce any .apple_names related
-# output when there's no such section int he object.
-# The test was manually modified to exclude the 
-# .apple_names section from the apple_names_verify_buckets.s
-# test file in the same directory.
-
-  .section  __TEXT,__text,regular,pure_instructions
-  .file 1 "basic.c"
-  .comm _i,4,2                  ## @i
-  .section  __DWARF,__debug_str,regular,debug
-Linfo_string:
-  .asciz  "basic.c"               ## string offset=42
-  .asciz  "i"                     ## string offset=84
-  .asciz  "int"                   ## string offset=86
-  .section  __DWARF,__debug_loc,regular,debug
-Lsection_debug_loc:
-  .section  __DWARF,__debug_abbrev,regular,debug
-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 3                       ## DW_AT_name
-  .byte 14                      ## DW_FORM_strp
-  .byte 16                      ## DW_AT_stmt_list
-  .byte 23                      ## DW_FORM_sec_offset
-  .byte 27                      ## DW_AT_comp_dir
-  .byte 14                      ## DW_FORM_strp
-  .byte 0                       ## EOM(1)
-  .byte 0                       ## EOM(2)
-  .byte 2                       ## Abbreviation Code
-  .byte 52                      ## DW_TAG_variable
-  .byte 0                       ## DW_CHILDREN_no
-  .byte 3                       ## DW_AT_name
-  .byte 14                      ## DW_FORM_strp
-  .byte 73                      ## DW_AT_type
-  .byte 19                      ## DW_FORM_ref4
-  .byte 63                      ## DW_AT_external
-  .byte 25                      ## DW_FORM_flag_present
-  .byte 58                      ## DW_AT_decl_file
-  .byte 11                      ## DW_FORM_data1
-  .byte 59                      ## DW_AT_decl_line
-  .byte 11                      ## DW_FORM_data1
-  .byte 2                       ## DW_AT_location
-  .byte 24                      ## DW_FORM_exprloc
-  .byte 0                       ## EOM(1)
-  .byte 0                       ## EOM(2)
-  .byte 3                       ## Abbreviation Code
-  .byte 36                      ## DW_TAG_base_type
-  .byte 0                       ## DW_CHILDREN_no
-  .byte 3                       ## DW_AT_name
-  .byte 14                      ## DW_FORM_strp
-  .byte 62                      ## DW_AT_encoding
-  .byte 11                      ## DW_FORM_data1
-  .byte 11                      ## DW_AT_byte_size
-  .byte 11                      ## DW_FORM_data1
-  .byte 0                       ## EOM(1)
-  .byte 0                       ## EOM(2)
-  .byte 0                       ## EOM(3)
-  .section  __DWARF,__debug_info,regular,debug
-Lsection_info:
-Lcu_begin0:
-  .long 55                      ## Length of Unit
-  .short  4                       ## DWARF version number
-Lset0 = Lsection_abbrev-Lsection_abbrev ## Offset Into Abbrev. Section
-  .long Lset0
-  .byte 8                       ## Address Size (in bytes)
-  .byte 1                       ## Abbrev [1] 0xb:0x30 DW_TAG_compile_unit
-  .long 0                       ## DW_AT_producer
-  .short  12                      ## DW_AT_language
-  .long 42                      ## DW_AT_name
-Lset1 = Lline_table_start0-Lsection_line ## DW_AT_stmt_list
-  .long Lset1
-  .long 50                      ## DW_AT_comp_dir
-  .byte 2                       ## Abbrev [2] 0x1e:0x15 DW_TAG_variable
-  .long 84                      ## DW_AT_name
-  .long 51                      ## DW_AT_type
-                                        ## DW_AT_external
-  .byte 1                       ## DW_AT_decl_file
-  .byte 1                       ## DW_AT_decl_line
-  .byte 9                       ## DW_AT_location
-  .byte 3
-  .quad _i
-  .byte 3                       ## Abbrev [3] 0x33:0x7 DW_TAG_base_type
-  .long 86                      ## DW_AT_name
-  .byte 5                       ## DW_AT_encoding
-  .byte 4                       ## DW_AT_byte_size
-  .byte 0                       ## End Of Children Mark
-  .section  __DWARF,__debug_ranges,regular,debug
-Ldebug_range:
-  .section  __DWARF,__debug_macinfo,regular,debug
-Ldebug_macinfo:
-Lcu_macro_begin0:
-  .byte 0                       ## End Of Macro List Mark
-  .section  __DWARF,__apple_objc,regular,debug
-Lobjc_begin:
-  .long 1212240712              ## Header Magic
-  .short  1                       ## Header Version
-  .short  0                       ## Header Hash Function
-  .long 1                       ## Header Bucket Count
-  .long 0                       ## Header Hash Count
-  .long 12                      ## Header Data Length
-  .long 0                       ## HeaderData Die Offset Base
-  .long 1                       ## HeaderData Atom Count
-  .short  1                       ## DW_ATOM_die_offset
-  .short  6                       ## DW_FORM_data4
-  .long -1                      ## Bucket 0
-  .section  __DWARF,__apple_namespac,regular,debug
-Lnamespac_begin:
-  .long 1212240712              ## Header Magic
-  .short  1                       ## Header Version
-  .short  0                       ## Header Hash Function
-  .long 1                       ## Header Bucket Count
-  .long 0                       ## Header Hash Count
-  .long 12                      ## Header Data Length
-  .long 0                       ## HeaderData Die Offset Base
-  .long 1                       ## HeaderData Atom Count
-  .short  1                       ## DW_ATOM_die_offset
-  .short  6                       ## DW_FORM_data4
-  .long -1                      ## Bucket 0
-  .section  __DWARF,__apple_types,regular,debug
-Ltypes_begin:
-  .long 1212240712              ## Header Magic
-  .short  1                       ## Header Version
-  .short  0                       ## Header Hash Function
-  .long 1                       ## Header Bucket Count
-  .long 1                       ## Header Hash Count
-  .long 20                      ## Header Data Length
-  .long 0                       ## HeaderData Die Offset Base
-  .long 3                       ## HeaderData Atom Count
-  .short  1                       ## DW_ATOM_die_offset
-  .short  6                       ## DW_FORM_data4
-  .short  3                       ## DW_ATOM_die_tag
-  .short  5                       ## DW_FORM_data2
-  .short  4                       ## DW_ATOM_type_flags
-  .short  11                      ## DW_FORM_data1
-  .long 0                       ## Bucket 0
-  .long 193495088               ## Hash in Bucket 0
-  .long Ltypes0-Ltypes_begin    ## Offset in Bucket 0
-Ltypes0:
-  .long 86                      ## int
-  .long 1                       ## Num DIEs
-  .long 51
-  .short  36
-  .byte 0
-  .long 0
-  .section  __DWARF,__apple_exttypes,regular,debug
-Lexttypes_begin:
-  .long 1212240712              ## Header Magic
-  .short  1                       ## Header Version
-  .short  0                       ## Header Hash Function
-  .long 1                       ## Header Bucket Count
-  .long 0                       ## Header Hash Count
-  .long 12                      ## Header Data Length
-  .long 0                       ## HeaderData Die Offset Base
-  .long 1                       ## HeaderData Atom Count
-  .short  7                       ## DW_ATOM_ext_types
-  .short  6                       ## DW_FORM_data4
-  .long -1                      ## Bucket 0
-
-.subsections_via_symbols
-  .section  __DWARF,__debug_line,regular,debug
-Lsection_line:
-Lline_table_start0: