[llvm] r329392 - DWARFVerifier: validate information in name index entries

Pavel Labath via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 6 06:34:12 PDT 2018


Author: labath
Date: Fri Apr  6 06:34:12 2018
New Revision: 329392

URL: http://llvm.org/viewvc/llvm-project?rev=329392&view=rev
Log:
DWARFVerifier: validate information in name index entries

Summary:
This patch add checks to verify that the information in the name index
entries is consistent with the debug_info section. Specifically, we
check that entries point to valid DIEs, and their names, tags, and
compile units match the information in the debug_info sections.

These checks are only run if the previous checks did not find any errors
in the name index headers. Attempting to proceed with the checks anyway
would likely produce a lot of spurious errors and the verification code
would need to be very careful to avoid crashing.

I also add a couple of more checks to the abbreviation-validation code
to verify that some attributes are always present (an index without a
DW_IDX_die_offset attribute is fairly useless).

The entry verification works only on indexes without any type units - I
haven't attempted to extend it to type units, as we don't even have a
DWARF v5-compatible type unit generator at the moment.

Reviewers: JDevlieghere, aprantl, dblaikie

Subscribers: llvm-commits

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

Added:
    llvm/trunk/test/tools/llvm-dwarfdump/X86/debug-names-verify-entries.s
Modified:
    llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h
    llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFVerifier.h
    llvm/trunk/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp
    llvm/trunk/lib/DebugInfo/DWARF/DWARFVerifier.cpp
    llvm/trunk/test/tools/llvm-dwarfdump/X86/debug-names-verify-abbrev-forms.s

Modified: llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h?rev=329392&r1=329391&r2=329392&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h Fri Apr  6 06:34:12 2018
@@ -283,6 +283,11 @@ public:
 
     Entry(const NameIndex &NameIdx, const Abbrev &Abbr);
 
+  public:
+    Optional<uint64_t> getCUOffset() const override;
+    Optional<uint64_t> getDIESectionOffset() const override;
+    Optional<dwarf::Tag> getTag() const override { return tag(); }
+
     /// Returns the Index into the Compilation Unit list of the owning Name
     /// Index or None if this Accelerator Entry does not have an associated
     /// Compilation Unit. It is up to the user to verify that the returned Index
@@ -293,11 +298,6 @@ public:
     /// DW_IDX_compile_unit attribute.
     Optional<uint64_t> getCUIndex() const;
 
-  public:
-    Optional<uint64_t> getCUOffset() const override;
-    Optional<uint64_t> getDIESectionOffset() const override;
-    Optional<dwarf::Tag> getTag() const override { return tag(); }
-
     /// .debug_names-specific getter, which always succeeds (DWARF v5 index
     /// entries always have a tag).
     dwarf::Tag tag() const { return Abbr->Tag; }
@@ -319,7 +319,6 @@ public:
     friend class ValueIterator;
   };
 
-private:
   /// Error returned by NameIndex::getEntry to report it has reached the end of
   /// the entry list.
   class SentinelError : public ErrorInfo<SentinelError> {
@@ -330,6 +329,7 @@ private:
     std::error_code convertToErrorCode() const override;
   };
 
+private:
   /// DenseMapInfo for struct Abbrev.
   struct AbbrevMapInfo {
     static Abbrev getEmptyKey();
@@ -373,8 +373,6 @@ public:
     uint32_t EntryOffsetsBase;
     uint32_t EntriesBase;
 
-    Expected<Entry> getEntry(uint32_t *Offset) const;
-
     void dumpCUs(ScopedPrinter &W) const;
     void dumpLocalTUs(ScopedPrinter &W) const;
     void dumpForeignTUs(ScopedPrinter &W) const;
@@ -429,6 +427,8 @@ public:
       return Abbrevs;
     }
 
+    Expected<Entry> getEntry(uint32_t *Offset) const;
+
     llvm::Error extract();
     uint32_t getUnitOffset() const { return Base; }
     uint32_t getNextUnitOffset() const { return Base + 4 + Hdr.UnitLength; }

Modified: llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFVerifier.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFVerifier.h?rev=329392&r1=329391&r2=329392&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFVerifier.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFVerifier.h Fri Apr  6 06:34:12 2018
@@ -240,6 +240,8 @@ private:
   unsigned verifyNameIndexAttribute(const DWARFDebugNames::NameIndex &NI,
                                     const DWARFDebugNames::Abbrev &Abbr,
                                     DWARFDebugNames::AttributeEncoding AttrEnc);
+  unsigned verifyNameIndexEntries(const DWARFDebugNames::NameIndex &NI,
+                                  uint32_t Name, const DataExtractor &StrData);
 
   /// Verify that the DWARF v5 accelerator table is valid.
   ///
@@ -251,6 +253,8 @@ private:
   /// - The buckets have a valid index, or they are empty.
   /// - All names are reachable via the hash table (they have the correct hash,
   ///   and the hash is in the correct bucket).
+  /// - Information in the index entries is consistent with the debug_info
+  ///   section DIEs.
   ///
   /// \param AccelSection section containing the acceleration table
   /// \param StrData string section

Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp?rev=329392&r1=329391&r2=329392&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp Fri Apr  6 06:34:12 2018
@@ -601,7 +601,7 @@ Expected<DWARFDebugNames::Entry>
 DWARFDebugNames::NameIndex::getEntry(uint32_t *Offset) const {
   const DWARFDataExtractor &AS = Section.AccelSection;
   if (!AS.isValidOffset(*Offset))
-    return make_error<StringError>("Incorrectly terminated entry list",
+    return make_error<StringError>("Incorrectly terminated entry list.",
                                    inconvertibleErrorCode());
 
   uint32_t AbbrevCode = AS.getULEB128(Offset);
@@ -610,7 +610,7 @@ DWARFDebugNames::NameIndex::getEntry(uin
 
   const auto AbbrevIt = Abbrevs.find_as(AbbrevCode);
   if (AbbrevIt == Abbrevs.end())
-    return make_error<StringError>("Invalid abbreviation",
+    return make_error<StringError>("Invalid abbreviation.",
                                    inconvertibleErrorCode());
 
   Entry E(*this, *AbbrevIt);
@@ -618,7 +618,7 @@ DWARFDebugNames::NameIndex::getEntry(uin
   dwarf::FormParams FormParams = {Hdr.Version, 0, dwarf::DwarfFormat::DWARF32};
   for (auto &Value : E.Values) {
     if (!Value.extractValue(AS, Offset, FormParams))
-      return make_error<StringError>("Error extracting index attribute values",
+      return make_error<StringError>("Error extracting index attribute values.",
                                      inconvertibleErrorCode());
   }
   return std::move(E);

Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFVerifier.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFVerifier.cpp?rev=329392&r1=329391&r2=329392&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFVerifier.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFVerifier.cpp Fri Apr  6 06:34:12 2018
@@ -1000,6 +1000,13 @@ unsigned DWARFVerifier::verifyNameIndexA
 
 unsigned
 DWARFVerifier::verifyNameIndexAbbrevs(const DWARFDebugNames::NameIndex &NI) {
+  if (NI.getLocalTUCount() + NI.getForeignTUCount() > 0) {
+    warn() << formatv("Name Index @ {0:x}: Verifying indexes of type units is "
+                      "not currently supported.\n",
+                      NI.getUnitOffset());
+    return 0;
+  }
+
   unsigned NumErrors = 0;
   for (const auto &Abbrev : NI.getAbbrevs()) {
     StringRef TagName = dwarf::TagString(Abbrev.Tag);
@@ -1019,7 +1026,119 @@ DWARFVerifier::verifyNameIndexAbbrevs(co
       }
       NumErrors += verifyNameIndexAttribute(NI, Abbrev, AttrEnc);
     }
+
+    if (NI.getCUCount() > 1 && !Attributes.count(dwarf::DW_IDX_compile_unit)) {
+      error() << formatv("NameIndex @ {0:x}: Indexing multiple compile units "
+                         "and abbreviation {1:x} has no {2} attribute.\n",
+                         NI.getUnitOffset(), Abbrev.Code,
+                         dwarf::DW_IDX_compile_unit);
+      ++NumErrors;
+    }
+    if (!Attributes.count(dwarf::DW_IDX_die_offset)) {
+      error() << formatv(
+          "NameIndex @ {0:x}: Abbreviation {1:x} has no {2} attribute.\n",
+          NI.getUnitOffset(), Abbrev.Code, dwarf::DW_IDX_die_offset);
+      ++NumErrors;
+    }
+  }
+  return NumErrors;
+}
+
+static SmallVector<StringRef, 2> getNames(const DWARFDie &DIE) {
+  SmallVector<StringRef, 2> Result;
+  if (const char *Str = DIE.getName(DINameKind::ShortName))
+    Result.emplace_back(Str);
+  else if (DIE.getTag() == dwarf::DW_TAG_namespace)
+    Result.emplace_back("(anonymous namespace)");
+
+  if (const char *Str = DIE.getName(DINameKind::LinkageName)) {
+    if (Result.empty() || Result[0] != Str)
+      Result.emplace_back(Str);
+  }
+
+  return Result;
+}
+
+unsigned
+DWARFVerifier::verifyNameIndexEntries(const DWARFDebugNames::NameIndex &NI,
+                                      uint32_t Name,
+                                      const DataExtractor &StrData) {
+  // Verifying type unit indexes not supported.
+  if (NI.getLocalTUCount() + NI.getForeignTUCount() > 0)
+    return 0;
+
+  DWARFDebugNames::NameTableEntry NTE = NI.getNameTableEntry(Name);
+  const char *CStr = StrData.getCStr(&NTE.StringOffset);
+  if (!CStr) {
+    error() << formatv(
+        "Name Index @ {0:x}: Unable to get string associated with name {1}.\n",
+        NI.getUnitOffset(), Name);
+    return 1;
+  }
+  StringRef Str(CStr);
+
+  unsigned NumErrors = 0;
+  unsigned NumEntries = 0;
+  uint32_t EntryID = NTE.EntryOffset;
+  Expected<DWARFDebugNames::Entry> EntryOr = NI.getEntry(&NTE.EntryOffset);
+  for (; EntryOr; ++NumEntries, EntryID = NTE.EntryOffset,
+                                EntryOr = NI.getEntry(&NTE.EntryOffset)) {
+    uint32_t CUIndex = *EntryOr->getCUIndex();
+    if (CUIndex > NI.getCUCount()) {
+      error() << formatv("Name Index @ {0:x}: Entry @ {1:x} contains an "
+                         "invalid CU index ({2}).\n",
+                         NI.getUnitOffset(), EntryID, CUIndex);
+      ++NumErrors;
+      continue;
+    }
+    uint32_t CUOffset = NI.getCUOffset(CUIndex);
+    uint64_t DIEOffset = *EntryOr->getDIESectionOffset();
+    DWARFDie DIE = DCtx.getDIEForOffset(DIEOffset);
+    if (!DIE) {
+      error() << formatv("Name Index @ {0:x}: Entry @ {1:x} references a "
+                         "non-existing DIE @ {2:x}.\n",
+                         NI.getUnitOffset(), EntryID, DIEOffset);
+      ++NumErrors;
+      continue;
+    }
+    if (DIE.getDwarfUnit()->getOffset() != CUOffset) {
+      error() << formatv("Name Index @ {0:x}: Entry @ {1:x}: mismatched CU of "
+                         "DIE @ {2:x}: index - {3:x}; debug_info - {4:x}.\n",
+                         NI.getUnitOffset(), EntryID, DIEOffset, CUOffset,
+                         DIE.getDwarfUnit()->getOffset());
+      ++NumErrors;
+    }
+    if (DIE.getTag() != EntryOr->tag()) {
+      error() << formatv("Name Index @ {0:x}: Entry @ {1:x}: mismatched Tag of "
+                         "DIE @ {2:x}: index - {3}; debug_info - {4}.\n",
+                         NI.getUnitOffset(), EntryID, DIEOffset, EntryOr->tag(),
+                         DIE.getTag());
+      ++NumErrors;
+    }
+
+    auto EntryNames = getNames(DIE);
+    if (!is_contained(EntryNames, Str)) {
+      error() << formatv("Name Index @ {0:x}: Entry @ {1:x}: mismatched Name "
+                         "of DIE @ {2:x}: index - {3}; debug_info - {4}.\n",
+                         NI.getUnitOffset(), EntryID, DIEOffset, Str,
+                         make_range(EntryNames.begin(), EntryNames.end()));
+    }
   }
+  handleAllErrors(EntryOr.takeError(),
+                  [&](const DWARFDebugNames::SentinelError &) {
+                    if (NumEntries > 0)
+                      return;
+                    error() << formatv("Name Index @ {0:x}: Name {1} ({2}) is "
+                                       "not associated with any entries.\n",
+                                       NI.getUnitOffset(), Name, Str);
+                    ++NumErrors;
+                  },
+                  [&](const ErrorInfoBase &Info) {
+                    error() << formatv(
+                        "Name Index @ {0:x}: Name {1} ({2}): {3}\n",
+                        NI.getUnitOffset(), Name, Str, Info.message());
+                    ++NumErrors;
+                  });
   return NumErrors;
 }
 
@@ -1045,6 +1164,13 @@ unsigned DWARFVerifier::verifyDebugNames
   for (const auto &NI : AccelTable)
     NumErrors += verifyNameIndexAbbrevs(NI);
 
+  // Don't attempt Entry validation if any of the previous checks found errors
+  if (NumErrors > 0)
+    return NumErrors;
+  for (const auto &NI : AccelTable)
+    for (uint64_t Name = 1; Name <= NI.getNameCount(); ++Name)
+      NumErrors += verifyNameIndexEntries(NI, Name, StrData);
+
   return NumErrors;
 }
 

Modified: llvm/trunk/test/tools/llvm-dwarfdump/X86/debug-names-verify-abbrev-forms.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-dwarfdump/X86/debug-names-verify-abbrev-forms.s?rev=329392&r1=329391&r2=329392&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-dwarfdump/X86/debug-names-verify-abbrev-forms.s (original)
+++ llvm/trunk/test/tools/llvm-dwarfdump/X86/debug-names-verify-abbrev-forms.s Fri Apr  6 06:34:12 2018
@@ -8,6 +8,8 @@
 # CHECK: error: NameIndex @ 0x0: Abbreviation 0x4 contains multiple DW_IDX_die_offset attributes.
 # CHECK: NameIndex @ 0x0: Abbreviation 0x1: DW_IDX_die_offset uses an unknown form: DW_FORM_unknown_1fff.
 # CHECK: warning: NameIndex @ 0x0: Abbreviation 0x3 references an unknown tag: DW_TAG_unknown_8080.
+# CHECK: error: NameIndex @ 0x0: Abbreviation 0x5 has no DW_IDX_die_offset attribute.
+# CHECK: error: NameIndex @ 0x55: Indexing multiple compile units and abbreviation 0x1 has no DW_IDX_compile_unit attribute.
 
 	.section	.debug_str,"MS", at progbits,1
 .Lstring_producer:
@@ -39,6 +41,30 @@
 	.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:
+
+.Lcu_begin2:
+	.long	.Lcu_end2-.Lcu_start2   # Length of Unit
+.Lcu_start2:
+	.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_end2:
+
 	.section	.debug_names,"", at progbits
 	.long	.Lnames_end0-.Lnames_start0 # Header: contribution length
 .Lnames_start0:
@@ -87,6 +113,36 @@
 	.byte   17                      # DW_FORM_ref1
 	.byte	0                       # End of abbrev
 	.byte	0                       # End of abbrev
+	.byte	5                       # Abbrev code
+	.byte	46                      # DW_TAG_subprogram
+	.byte	4                       # DW_IDX_parent
+	.byte   5                       # DW_FORM_data2
+	.byte	0                       # End of abbrev
+	.byte	0                       # End of abbrev
 	.byte	0                       # End of abbrev list
 .Lnames_abbrev_end0:
 .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_begin1             # Compilation unit 0
+	.long	.Lcu_begin2             # Compilation unit 1
+.Lnames_abbrev_start1:
+	.byte	1                       # Abbrev code
+	.byte	46                      # DW_TAG_subprogram
+	.byte	3                       # DW_IDX_die_offset
+	.byte   17                      # DW_FORM_ref1
+	.byte	0                       # End of abbrev
+	.byte	0                       # End of abbrev
+	.byte	0                       # End of abbrev list
+.Lnames_abbrev_end1:
+.Lnames_end1:

Added: llvm/trunk/test/tools/llvm-dwarfdump/X86/debug-names-verify-entries.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-dwarfdump/X86/debug-names-verify-entries.s?rev=329392&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-dwarfdump/X86/debug-names-verify-entries.s (added)
+++ llvm/trunk/test/tools/llvm-dwarfdump/X86/debug-names-verify-entries.s Fri Apr  6 06:34:12 2018
@@ -0,0 +1,188 @@
+# RUN: llvm-mc -triple x86_64-pc-linux %s -filetype=obj -o - | not llvm-dwarfdump -verify - | FileCheck %s
+
+# CHECK: error: Name Index @ 0x0: Unable to get string associated with name 1.
+# CHECK: error: Name Index @ 0x0: Entry @ 0x73 contains an invalid CU index (47).
+# CHECK: error: Name Index @ 0x0: Entry @ 0x79 references a non-existing DIE @ 0x3fa.
+# CHECK: error: Name Index @ 0x0: Entry @ 0x85: mismatched CU of DIE @ 0x30: index - 0x0; debug_info - 0x1e.
+# CHECK: error: Name Index @ 0x0: Entry @ 0x8b: mismatched Tag of DIE @ 0x17: index - DW_TAG_subprogram; debug_info - DW_TAG_variable.
+# CHECK: error: Name Index @ 0x0: Entry @ 0x91: mismatched Name of DIE @ 0x35: index - foo; debug_info - bar, _Z3bar.
+# CHECK: error: Name Index @ 0x0: Name 2 (foo): Incorrectly terminated entry list.
+# CHECK: error: Name Index @ 0x0: Name 3 (bar) is not associated with any entries.
+# CHECK: error: Name Index @ 0x0: Entry @ 0x69: mismatched Name of DIE @ 0x1c: index - (pseudonymous namespace); debug_info - (anonymous namespace).
+
+	.section	.debug_str,"MS", at progbits,1
+.Lstring_foo:
+	.asciz	"foo"
+.Lstring_bar:
+	.asciz	"bar"
+.Lstring_bar_mangled:
+	.asciz	"_Z3bar"
+.Lstring_pseudo_namespace:
+	.asciz	"(pseudonymous namespace)"
+.Lstring_producer:
+	.asciz	"Hand-written dwarf"
+
+	.section	.debug_abbrev,"", at 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	3                       # Abbreviation Code
+	.byte	52                      # DW_TAG_variable
+	.byte	0                       # DW_CHILDREN_no
+	.byte	3                       # DW_AT_name
+	.byte	14                      # DW_FORM_strp
+	.byte	0                       # EOM(1)
+	.byte	0                       # EOM(2)
+	.byte	4                       # Abbreviation Code
+	.byte	57                      # DW_TAG_namespace
+	.byte	0                       # DW_CHILDREN_no
+	.byte	0                       # EOM(1)
+	.byte	0                       # EOM(2)
+	.byte	5                       # Abbreviation Code
+	.byte	52                      # DW_TAG_variable
+	.byte	0                       # DW_CHILDREN_no
+	.byte	3                       # DW_AT_name
+	.byte	14                      # DW_FORM_strp
+	.byte	110                     # DW_AT_linkage_name
+	.byte	14                      # DW_FORM_strp
+	.byte	0                       # EOM(1)
+	.byte	0                       # EOM(2)
+	.byte	0                       # EOM(3)
+
+	.section	.debug_info,"", at 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
+.Ldie_foo_var:
+	.byte	3                       # Abbrev [3] DW_TAG_variable
+	.long	.Lstring_foo            # DW_AT_name
+.Ldie_namespace:
+	.byte	4                       # Abbrev [3] DW_TAG_namespace
+	.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
+.Ldie_foo2:
+	.byte	2                       # Abbrev [2] DW_TAG_subprogram
+	.long	.Lstring_foo            # DW_AT_name
+                                        # DW_AT_external
+.Ldie_bar_linkage:
+	.byte	5                       # Abbrev [2] DW_TAG_variable
+	.long	.Lstring_bar            # DW_AT_name
+	.long	.Lstring_bar_mangled    # DW_AT_linkage_name
+	.byte	0                       # End Of Children Mark
+.Lcu_end1:
+
+
+	.section	.debug_names,"", at progbits
+	.long	.Lnames_end0-.Lnames_start0 # Header: contribution length
+.Lnames_start0:
+	.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	4                       # 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	.Lcu_begin1             # Compilation unit 1
+	.long	.Lstring_foo+1000       # String 1: <broken>
+	.long	.Lstring_foo            # String 2: foo
+	.long	.Lstring_bar            # String 3: bar
+	.long	.Lstring_pseudo_namespace # String 4: (pseudonymous namespace)
+	.long	.Lnames0-.Lnames_entries0 # Offset 1
+	.long	.Lnames0-.Lnames_entries0 # Offset 2
+	.long	.Lnames1-.Lnames_entries0 # Offset 3
+	.long	.Lnames2-.Lnames_entries0 # Offset 4
+.Lnames_abbrev_start0:
+	.byte	46                      # Abbrev code
+	.byte	46                      # DW_TAG_subprogram
+	.byte	1                       # DW_IDX_compile_unit
+	.byte	11                      # DW_FORM_data1
+	.byte	3                       # DW_IDX_die_offset
+	.byte	19                      # DW_FORM_ref4
+	.byte	0                       # End of abbrev
+	.byte	0                       # End of abbrev
+	.byte	57                      # Abbrev code
+	.byte	57                      # DW_TAG_namespace
+	.byte	1                       # DW_IDX_compile_unit
+	.byte	11                      # DW_FORM_data1
+	.byte	3                       # DW_IDX_die_offset
+	.byte	19                      # DW_FORM_ref4
+	.byte	0                       # End of abbrev
+	.byte	0                       # End of abbrev
+	.byte	52                      # Abbrev code
+	.byte	52                      # DW_TAG_variable
+	.byte	1                       # DW_IDX_compile_unit
+	.byte	11                      # DW_FORM_data1
+	.byte	3                       # DW_IDX_die_offset
+	.byte	19                      # DW_FORM_ref4
+	.byte	0                       # End of abbrev
+	.byte	0                       # End of abbrev
+	.byte	0                       # End of abbrev list
+.Lnames_abbrev_end0:
+.Lnames_entries0:
+.Lnames1:
+	.long	0                       # End of list: bar
+.Lnames2:
+	.byte	57                      # Abbrev code
+	.byte	0                       # DW_IDX_compile_unit
+	.long	.Ldie_namespace-.Lcu_begin0 # DW_IDX_die_offset
+	.long	0                       # End of list: (pseudonymous namespace)
+.Lnames0:
+	.byte	46                      # Abbrev code
+	.byte	47                      # DW_IDX_compile_unit
+	.long	.Ldie_foo-.Lcu_begin0   # DW_IDX_die_offset
+	.byte	46                      # Abbrev code
+	.byte	0                       # DW_IDX_compile_unit
+	.long	.Ldie_foo-.Lcu_begin0+1000 # DW_IDX_die_offset
+	.byte	46                      # Abbrev code
+	.byte	0                       # DW_IDX_compile_unit
+	.long	.Ldie_foo-.Lcu_begin0   # DW_IDX_die_offset
+	.byte	46                      # Abbrev code
+	.byte	0                       # DW_IDX_compile_unit
+	.long	.Ldie_foo2-.Lcu_begin0  # DW_IDX_die_offset
+	.byte	46                      # Abbrev code
+	.byte	0                       # DW_IDX_compile_unit
+	.long	.Ldie_foo_var-.Lcu_begin0 # DW_IDX_die_offset
+	.byte	52                      # Abbrev code
+	.byte	1                       # DW_IDX_compile_unit
+	.long	.Ldie_bar_linkage-.Lcu_begin1 # DW_IDX_die_offset
+	#.long	0                       # End of list deliberately missing
+.Lnames_end0:




More information about the llvm-commits mailing list