[llvm] r304759 - [DWARF] Adding support for the DWARF v5 string offsets table (consumer/reader part only).

Wolfgang Pieb via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 5 18:22:34 PDT 2017


Author: wolfgangp
Date: Mon Jun  5 20:22:34 2017
New Revision: 304759

URL: http://llvm.org/viewvc/llvm-project?rev=304759&view=rev
Log:
[DWARF] Adding support for the DWARF v5 string offsets table (consumer/reader part only).

Reviewers: dblaikie, aprantl

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


Added:
    llvm/trunk/test/DebugInfo/Inputs/dwarfdump-str-offsets-dwp.s
    llvm/trunk/test/DebugInfo/Inputs/dwarfdump-str-offsets-invalid-1.s
    llvm/trunk/test/DebugInfo/Inputs/dwarfdump-str-offsets-invalid-1.x86_64.o   (with props)
    llvm/trunk/test/DebugInfo/Inputs/dwarfdump-str-offsets-invalid-2.s
    llvm/trunk/test/DebugInfo/Inputs/dwarfdump-str-offsets-invalid-2.x86_64.o   (with props)
    llvm/trunk/test/DebugInfo/Inputs/dwarfdump-str-offsets-invalid-3.s
    llvm/trunk/test/DebugInfo/Inputs/dwarfdump-str-offsets-invalid-3.x86_64.o   (with props)
    llvm/trunk/test/DebugInfo/Inputs/dwarfdump-str-offsets-invalid-4.s
    llvm/trunk/test/DebugInfo/Inputs/dwarfdump-str-offsets-invalid-4.x86_64.o   (with props)
    llvm/trunk/test/DebugInfo/Inputs/dwarfdump-str-offsets-invalid-5.s
    llvm/trunk/test/DebugInfo/Inputs/dwarfdump-str-offsets-invalid-5.x86_64.o   (with props)
    llvm/trunk/test/DebugInfo/Inputs/dwarfdump-str-offsets.s
    llvm/trunk/test/DebugInfo/Inputs/dwarfdump-str-offsets.x86_64.o   (with props)
    llvm/trunk/test/DebugInfo/dwarfdump-str-offsets-invalid.test
    llvm/trunk/test/DebugInfo/dwarfdump-str-offsets.test
Modified:
    llvm/trunk/include/llvm/DebugInfo/DIContext.h
    llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h
    llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFContext.h
    llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h
    llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h
    llvm/trunk/include/llvm/MC/MCObjectFileInfo.h
    llvm/trunk/include/llvm/Object/MachO.h
    llvm/trunk/include/llvm/Object/ObjectFile.h
    llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp
    llvm/trunk/lib/DebugInfo/DWARF/DWARFFormValue.cpp
    llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp
    llvm/trunk/lib/MC/MCObjectFileInfo.cpp
    llvm/trunk/lib/Object/MachOObjectFile.cpp
    llvm/trunk/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
    llvm/trunk/tools/obj2yaml/dwarf2yaml.cpp

Modified: llvm/trunk/include/llvm/DebugInfo/DIContext.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/DIContext.h?rev=304759&r1=304758&r2=304759&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/DIContext.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/DIContext.h Mon Jun  5 20:22:34 2017
@@ -135,6 +135,7 @@ enum DIDumpType {
   DIDT_GnuPubnames,
   DIDT_GnuPubtypes,
   DIDT_Str,
+  DIDT_StrOffsets,
   DIDT_StrDwo,
   DIDT_StrOffsetsDwo,
   DIDT_AppleNames,

Modified: llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h?rev=304759&r1=304758&r2=304759&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h Mon Jun  5 20:22:34 2017
@@ -19,8 +19,8 @@ class DWARFCompileUnit : public DWARFUni
 public:
   DWARFCompileUnit(DWARFContext &Context, const DWARFSection &Section,
                    const DWARFDebugAbbrev *DA, const DWARFSection *RS,
-                   StringRef SS, StringRef SOS, const DWARFSection *AOS,
-                   StringRef LS, bool LE, bool IsDWO,
+                   StringRef SS, const DWARFSection &SOS,
+                   const DWARFSection *AOS, StringRef LS, bool LE, bool IsDWO,
                    const DWARFUnitSectionBase &UnitSection,
                    const DWARFUnitIndex::Entry *Entry)
       : DWARFUnit(Context, Section, DA, RS, SS, SOS, AOS, LS, LE, IsDWO,

Modified: llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFContext.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFContext.h?rev=304759&r1=304758&r2=304759&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFContext.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFContext.h Mon Jun  5 20:22:34 2017
@@ -72,6 +72,9 @@ class DWARFContext : public DIContext {
   std::unique_ptr<DWARFDebugAbbrev> AbbrevDWO;
   std::unique_ptr<DWARFDebugLocDWO> LocDWO;
 
+  /// The maximum DWARF version of all units.
+  unsigned MaxVersion;
+
   struct DWOFile {
     object::OwningBinary<object::ObjectFile> File;
     std::unique_ptr<DWARFContext> Context;
@@ -97,7 +100,7 @@ class DWARFContext : public DIContext {
   void parseDWOTypeUnits();
 
 public:
-  DWARFContext() : DIContext(CK_DWARF) {}
+  DWARFContext() : DIContext(CK_DWARF), MaxVersion(0) {}
   DWARFContext(DWARFContext &) = delete;
   DWARFContext &operator=(DWARFContext &) = delete;
 
@@ -178,6 +181,13 @@ public:
   /// Get a DIE given an exact offset.
   DWARFDie getDIEForOffset(uint32_t Offset);
 
+  unsigned getMaxVersion() const { return MaxVersion; }
+
+  void setMaxVersionIfGreater(unsigned Version) {
+    if (Version > MaxVersion)
+      MaxVersion = Version;
+  }
+
   const DWARFUnitIndex &getCUIndex();
   DWARFGdbIndex &getGdbIndex();
   const DWARFUnitIndex &getTUIndex();
@@ -237,6 +247,11 @@ public:
   virtual StringRef getGnuPubNamesSection() = 0;
   virtual StringRef getGnuPubTypesSection() = 0;
 
+  /// DWARF v5
+  /// @{
+  virtual const DWARFSection &getStringOffsetSection() = 0;
+  /// @}
+
   // Sections for DWARF5 split dwarf proposal.
   virtual const DWARFSection &getInfoDWOSection() = 0;
   virtual const TypeSectionMap &getTypesDWOSections() = 0;
@@ -244,7 +259,7 @@ public:
   virtual const DWARFSection &getLineDWOSection() = 0;
   virtual const DWARFSection &getLocDWOSection() = 0;
   virtual StringRef getStringDWOSection() = 0;
-  virtual StringRef getStringOffsetDWOSection() = 0;
+  virtual const DWARFSection &getStringOffsetDWOSection() = 0;
   virtual const DWARFSection &getRangeDWOSection() = 0;
   virtual const DWARFSection &getAddrSection() = 0;
   virtual const DWARFSection& getAppleNamesSection() = 0;
@@ -295,6 +310,11 @@ class DWARFContextInMemory : public DWAR
   StringRef GnuPubNamesSection;
   StringRef GnuPubTypesSection;
 
+  /// DWARF v5
+  /// @{
+  DWARFSection StringOffsetSection;
+  /// @}
+
   // Sections for DWARF5 split dwarf proposal.
   DWARFSection InfoDWOSection;
   TypeSectionMap TypesDWOSections;
@@ -302,7 +322,7 @@ class DWARFContextInMemory : public DWAR
   DWARFSection LineDWOSection;
   DWARFSection LocDWOSection;
   StringRef StringDWOSection;
-  StringRef StringOffsetDWOSection;
+  DWARFSection StringOffsetDWOSection;
   DWARFSection RangeDWOSection;
   DWARFSection AddrSection;
   DWARFSection AppleNamesSection;
@@ -353,6 +373,11 @@ public:
   const DWARFSection& getAppleNamespacesSection() override { return AppleNamespacesSection; }
   const DWARFSection& getAppleObjCSection() override { return AppleObjCSection; }
 
+  // DWARF v5
+  const DWARFSection &getStringOffsetSection() override {
+    return StringOffsetSection;
+  }
+
   // Sections for DWARF5 split dwarf proposal.
   const DWARFSection &getInfoDWOSection() override { return InfoDWOSection; }
 
@@ -365,7 +390,7 @@ public:
   const DWARFSection &getLocDWOSection() override { return LocDWOSection; }
   StringRef getStringDWOSection() override { return StringDWOSection; }
 
-  StringRef getStringOffsetDWOSection() override {
+  const DWARFSection &getStringOffsetDWOSection() override {
     return StringOffsetDWOSection;
   }
 

Modified: llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h?rev=304759&r1=304758&r2=304759&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h Mon Jun  5 20:22:34 2017
@@ -31,7 +31,7 @@ private:
 public:
   DWARFTypeUnit(DWARFContext &Context, const DWARFSection &Section,
                 const DWARFDebugAbbrev *DA, const DWARFSection *RS,
-                StringRef SS, StringRef SOS, const DWARFSection *AOS,
+                StringRef SS, const DWARFSection &SOS, const DWARFSection *AOS,
                 StringRef LS, bool LE, bool IsDWO,
                 const DWARFUnitSectionBase &UnitSection,
                 const DWARFUnitIndex::Entry *Entry)

Modified: llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h?rev=304759&r1=304758&r2=304759&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h Mon Jun  5 20:22:34 2017
@@ -57,8 +57,9 @@ protected:
 
   virtual void parseImpl(DWARFContext &Context, const DWARFSection &Section,
                          const DWARFDebugAbbrev *DA, const DWARFSection *RS,
-                         StringRef SS, StringRef SOS, const DWARFSection *AOS,
-                         StringRef LS, bool isLittleEndian, bool isDWO) = 0;
+                         StringRef SS, const DWARFSection &SOS,
+                         const DWARFSection *AOS, StringRef LS,
+                         bool isLittleEndian, bool isDWO) = 0;
 };
 
 const DWARFUnitIndex &getDWARFUnitIndex(DWARFContext &Context,
@@ -89,7 +90,7 @@ public:
 private:
   void parseImpl(DWARFContext &Context, const DWARFSection &Section,
                  const DWARFDebugAbbrev *DA, const DWARFSection *RS,
-                 StringRef SS, StringRef SOS, const DWARFSection *AOS,
+                 StringRef SS, const DWARFSection &SOS, const DWARFSection *AOS,
                  StringRef LS, bool LE, bool IsDWO) override {
     if (Parsed)
       return;
@@ -119,7 +120,8 @@ class DWARFUnit {
   uint32_t RangeSectionBase;
   StringRef LineSection;
   StringRef StringSection;
-  StringRef StringOffsetSection;
+  const DWARFSection &StringOffsetSection;
+  uint64_t StringOffsetSectionBase = 0;
   const DWARFSection *AddrOffsetSection;
   uint32_t AddrOffsetSectionBase;
   bool isLittleEndian;
@@ -162,8 +164,8 @@ protected:
 public:
   DWARFUnit(DWARFContext &Context, const DWARFSection &Section,
             const DWARFDebugAbbrev *DA, const DWARFSection *RS, StringRef SS,
-            StringRef SOS, const DWARFSection *AOS, StringRef LS, bool LE,
-            bool IsDWO, const DWARFUnitSectionBase &UnitSection,
+            const DWARFSection &SOS, const DWARFSection *AOS, StringRef LS,
+            bool LE, bool IsDWO, const DWARFUnitSectionBase &UnitSection,
             const DWARFUnitIndex::Entry *IndexEntry = nullptr);
 
   virtual ~DWARFUnit();
@@ -172,7 +174,9 @@ public:
 
   StringRef getLineSection() const { return LineSection; }
   StringRef getStringSection() const { return StringSection; }
-  StringRef getStringOffsetSection() const { return StringOffsetSection; }
+  const DWARFSection &getStringOffsetSection() const {
+    return StringOffsetSection;
+  }
 
   void setAddrOffsetSection(const DWARFSection *AOS, uint32_t Base) {
     AddrOffsetSection = AOS;
@@ -189,7 +193,8 @@ public:
 
   bool getAddrOffsetSectionItem(uint32_t Index, uint64_t &Result) const;
   // FIXME: Result should be uint64_t in DWARF64.
-  bool getStringOffsetSectionItem(uint32_t Index, uint32_t &Result) const;
+  bool getStringOffsetSectionItem(uint32_t Index, uint64_t &Result) const;
+  uint64_t getStringOffsetSectionRelocation(uint32_t Index) const;
 
   DataExtractor getDebugInfoExtractor() const {
     return DataExtractor(InfoSection.Data, isLittleEndian, AddrSize);
@@ -200,6 +205,9 @@ public:
   }
 
   const RelocAddrMap *getRelocMap() const { return &InfoSection.Relocs; }
+  const RelocAddrMap &getStringOffsetsRelocMap() const {
+    return StringOffsetSection.Relocs;
+  }
 
   bool extract(DataExtractor debug_info, uint32_t* offset_ptr);
 

Modified: llvm/trunk/include/llvm/MC/MCObjectFileInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCObjectFileInfo.h?rev=304759&r1=304758&r2=304759&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCObjectFileInfo.h (original)
+++ llvm/trunk/include/llvm/MC/MCObjectFileInfo.h Mon Jun  5 20:22:34 2017
@@ -109,6 +109,9 @@ protected:
   MCSection *DwarfLineDWOSection;
   MCSection *DwarfLocDWOSection;
   MCSection *DwarfStrOffDWOSection;
+
+  /// The DWARF v5 string offset and address table sections.
+  MCSection *DwarfStrOffSection;
   MCSection *DwarfAddrSection;
 
   // These are for Fission DWP files.
@@ -260,6 +263,7 @@ public:
   MCSection *getDwarfLineDWOSection() const { return DwarfLineDWOSection; }
   MCSection *getDwarfLocDWOSection() const { return DwarfLocDWOSection; }
   MCSection *getDwarfStrOffDWOSection() const { return DwarfStrOffDWOSection; }
+  MCSection *getDwarfStrOffSection() const { return DwarfStrOffSection; }
   MCSection *getDwarfAddrSection() const { return DwarfAddrSection; }
   MCSection *getDwarfCUIndexSection() const { return DwarfCUIndexSection; }
   MCSection *getDwarfTUIndexSection() const { return DwarfTUIndexSection; }

Modified: llvm/trunk/include/llvm/Object/MachO.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/MachO.h?rev=304759&r1=304758&r2=304759&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Object/MachO.h (original)
+++ llvm/trunk/include/llvm/Object/MachO.h Mon Jun  5 20:22:34 2017
@@ -550,6 +550,8 @@ public:
 
   bool isRelocatableObject() const override;
 
+  StringRef mapDebugSectionName(StringRef Name) const override;
+
   bool hasPageZeroSegment() const { return HasPageZeroSegment; }
 
   static bool classof(const Binary *v) {

Modified: llvm/trunk/include/llvm/Object/ObjectFile.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/ObjectFile.h?rev=304759&r1=304758&r2=304759&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Object/ObjectFile.h (original)
+++ llvm/trunk/include/llvm/Object/ObjectFile.h Mon Jun  5 20:22:34 2017
@@ -292,6 +292,9 @@ public:
       return std::error_code();
     }
 
+  /// Maps a debug section name to a standard DWARF section name.
+  virtual StringRef mapDebugSectionName(StringRef Name) const { return Name; }
+
   /// True if this is a relocatable object (.o/.obj).
   virtual bool isRelocatableObject() const = 0;
 

Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp?rev=304759&r1=304758&r2=304759&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp Mon Jun  5 20:22:34 2017
@@ -84,6 +84,123 @@ static void dumpAccelSection(raw_ostream
   Accel.dump(OS);
 }
 
+static void
+dumpDWARFv5StringOffsetsSection(raw_ostream &OS, StringRef SectionName,
+                                const DWARFSection &StringOffsetsSection,
+                                StringRef StringSection, bool LittleEndian) {
+  DataExtractor StrOffsetExt(StringOffsetsSection.Data, LittleEndian, 0);
+  uint32_t Offset = 0;
+  uint64_t SectionSize = StringOffsetsSection.Data.size();
+
+  while (Offset < SectionSize) {
+    unsigned Version = 0;
+    DwarfFormat Format = DWARF32;
+    unsigned EntrySize = 4;
+    // Perform validation and extract the segment size from the header.
+    if (!StrOffsetExt.isValidOffsetForDataOfSize(Offset, 4)) {
+      OS << "error: invalid contribution to string offsets table in section ."
+         << SectionName << ".\n";
+      return;
+    }
+    uint32_t ContributionStart = Offset;
+    uint64_t ContributionSize = StrOffsetExt.getU32(&Offset);
+    // A contribution size of 0xffffffff indicates DWARF64, with the actual size
+    // in the following 8 bytes. Otherwise, the DWARF standard mandates that
+    // the contribution size must be at most 0xfffffff0.
+    if (ContributionSize == 0xffffffff) {
+      if (!StrOffsetExt.isValidOffsetForDataOfSize(Offset, 8)) {
+        OS << "error: invalid contribution to string offsets table in section ."
+           << SectionName << ".\n";
+        return;
+      }
+      Format = DWARF64;
+      EntrySize = 8;
+      ContributionSize = StrOffsetExt.getU64(&Offset);
+    } else if (ContributionSize > 0xfffffff0) {
+      OS << "error: invalid contribution to string offsets table in section ."
+         << SectionName << ".\n";
+      return;
+    }
+
+    // We must ensure that we don't read a partial record at the end, so we
+    // validate for a multiple of EntrySize. Also, we're expecting a version
+    // number and padding, which adds an additional 4 bytes.
+    uint64_t ValidationSize =
+        4 + ((ContributionSize + EntrySize - 1) & (-(uint64_t)EntrySize));
+    if (!StrOffsetExt.isValidOffsetForDataOfSize(Offset, ValidationSize)) {
+      OS << "error: contribution to string offsets table in section ."
+         << SectionName << " has invalid length.\n";
+      return;
+    }
+
+    Version = StrOffsetExt.getU16(&Offset);
+    Offset += 2;
+    OS << format("0x%8.8x: ", ContributionStart);
+    OS << "Contribution size = " << ContributionSize
+       << ", Version = " << Version << "\n";
+
+    uint32_t ContributionBase = Offset;
+    DataExtractor StrData(StringSection, LittleEndian, 0);
+    while (Offset - ContributionBase < ContributionSize) {
+      OS << format("0x%8.8x: ", Offset);
+      // FIXME: We can only extract strings in DWARF32 format at the moment.
+      uint64_t StringOffset = getRelocatedValue(
+          StrOffsetExt, EntrySize, &Offset, &StringOffsetsSection.Relocs);
+      if (Format == DWARF32) {
+        OS << format("%8.8x ", StringOffset);
+        uint32_t StringOffset32 = (uint32_t)StringOffset;
+        const char *S = StrData.getCStr(&StringOffset32);
+        if (S)
+          OS << format("\"%s\"", S);
+      } else
+        OS << format("%16.16x ", StringOffset);
+      OS << "\n";
+    }
+  }
+}
+
+// Dump a DWARF string offsets section. This may be a DWARF v5 formatted
+// string offsets section, where each compile or type unit contributes a
+// number of entries (string offsets), with each contribution preceded by
+// a header containing size and version number. Alternatively, it may be a
+// monolithic series of string offsets, as generated by the pre-DWARF v5
+// implementation of split DWARF.
+static void dumpStringOffsetsSection(raw_ostream &OS, StringRef SectionName,
+                                     const DWARFSection &StringOffsetsSection,
+                                     StringRef StringSection, bool LittleEndian,
+                                     unsigned MaxVersion) {
+  if (StringOffsetsSection.Data.empty())
+    return;
+  OS << "\n." << SectionName << " contents:\n";
+  // If we have at least one (compile or type) unit with DWARF v5 or greater,
+  // we assume that the section is formatted like a DWARF v5 string offsets
+  // section.
+  if (MaxVersion >= 5)
+    dumpDWARFv5StringOffsetsSection(OS, SectionName, StringOffsetsSection,
+                                    StringSection, LittleEndian);
+  else {
+    DataExtractor strOffsetExt(StringOffsetsSection.Data, LittleEndian, 0);
+    uint32_t offset = 0;
+    uint64_t size = StringOffsetsSection.Data.size();
+    // Ensure that size is a multiple of the size of an entry.
+    if (size & ((uint64_t)(sizeof(uint32_t) - 1))) {
+      OS << "error: size of ." << SectionName << " is not a multiple of "
+         << sizeof(uint32_t) << ".\n";
+      size &= -(uint64_t)sizeof(uint32_t);
+    }
+    DataExtractor StrData(StringSection, LittleEndian, 0);
+    while (offset < size) {
+      OS << format("0x%8.8x: ", offset);
+      uint32_t StringOffset = strOffsetExt.getU32(&offset);
+      OS << format("%8.8x  ", StringOffset);
+      const char *S = StrData.getCStr(&StringOffset);
+      if (S)
+        OS << format("\"%s\"", S);
+      OS << "\n";
+    }
+  }
+}
+
 void DWARFContext::dump(raw_ostream &OS, DIDumpOptions DumpOpts){
 
   DIDumpType DumpType = DumpOpts.DumpType;
@@ -258,17 +375,15 @@ void DWARFContext::dump(raw_ostream &OS,
                        true /* GnuStyle */)
         .dump("debug_gnu_pubtypes", OS);
 
-  if ((DumpType == DIDT_All || DumpType == DIDT_StrOffsetsDwo) &&
-      !getStringOffsetDWOSection().empty()) {
-    OS << "\n.debug_str_offsets.dwo contents:\n";
-    DataExtractor strOffsetExt(getStringOffsetDWOSection(), isLittleEndian(),
-                               0);
-    offset = 0;
-    uint64_t size = getStringOffsetDWOSection().size();
-    while (offset < size) {
-      OS << format("0x%8.8x: ", offset);
-      OS << format("%8.8x\n", strOffsetExt.getU32(&offset));
-    }
+  if (DumpType == DIDT_All || DumpType == DIDT_StrOffsets)
+    dumpStringOffsetsSection(OS, "debug_str_offsets", getStringOffsetSection(),
+                             getStringSection(), isLittleEndian(),
+                             getMaxVersion());
+
+  if (DumpType == DIDT_All || DumpType == DIDT_StrOffsetsDwo) {
+    dumpStringOffsetsSection(OS, "debug_str_offsets.dwo",
+                             getStringOffsetDWOSection(), getStringDWOSection(),
+                             isLittleEndian(), getMaxVersion());
   }
 
   if ((DumpType == DIDT_All || DumpType == DIDT_GdbIndex) &&
@@ -1109,6 +1224,10 @@ DWARFContextInMemory::DWARFContextInMemo
       TypesDWOSections[Section].Data = data;
     }
 
+    // Map platform specific debug section names to DWARF standard section
+    // names.
+    name = Obj.mapDebugSectionName(name);
+
     if (RelocatedSection == Obj.section_end())
       continue;
 
@@ -1141,6 +1260,7 @@ DWARFContextInMemory::DWARFContextInMemo
             .Case("debug_loc", &LocSection.Relocs)
             .Case("debug_info.dwo", &InfoDWOSection.Relocs)
             .Case("debug_line", &LineSection.Relocs)
+            .Case("debug_str_offsets", &StringOffsetSection.Relocs)
             .Case("debug_ranges", &RangeSection.Relocs)
             .Case("debug_addr", &AddrSection.Relocs)
             .Case("apple_names", &AppleNamesSection.Relocs)
@@ -1211,6 +1331,7 @@ StringRef *DWARFContextInMemory::MapSect
       .Case("debug_frame", &DebugFrameSection)
       .Case("eh_frame", &EHFrameSection)
       .Case("debug_str", &StringSection)
+      .Case("debug_str_offsets", &StringOffsetSection.Data)
       .Case("debug_ranges", &RangeSection.Data)
       .Case("debug_macinfo", &MacinfoSection)
       .Case("debug_pubnames", &PubNamesSection)
@@ -1222,7 +1343,7 @@ StringRef *DWARFContextInMemory::MapSect
       .Case("debug_loc.dwo", &LocDWOSection.Data)
       .Case("debug_line.dwo", &LineDWOSection.Data)
       .Case("debug_str.dwo", &StringDWOSection)
-      .Case("debug_str_offsets.dwo", &StringOffsetDWOSection)
+      .Case("debug_str_offsets.dwo", &StringOffsetDWOSection.Data)
       .Case("debug_addr", &AddrSection.Data)
       .Case("apple_names", &AppleNamesSection.Data)
       .Case("apple_types", &AppleTypesSection.Data)

Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFFormValue.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFFormValue.cpp?rev=304759&r1=304758&r2=304759&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFFormValue.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFFormValue.cpp Mon Jun  5 20:22:34 2017
@@ -301,6 +301,7 @@ bool DWARFFormValue::isFormClass(DWARFFo
     return (FC == FC_Address);
   case DW_FORM_GNU_str_index:
   case DW_FORM_GNU_strp_alt:
+  case DW_FORM_strx:
     return (FC == FC_String);
   case DW_FORM_implicit_const:
     return (FC == FC_Constant);
@@ -415,6 +416,7 @@ bool DWARFFormValue::extractValue(const
       break;
     case DW_FORM_GNU_addr_index:
     case DW_FORM_GNU_str_index:
+    case DW_FORM_strx:
       Value.uval = Data.getULEB128(OffsetPtr);
       break;
     default:
@@ -542,6 +544,7 @@ void DWARFFormValue::dump(raw_ostream &O
     OS << format(" .debug_str[0x%8.8x] = ", (uint32_t)UValue);
     dumpString(OS);
     break;
+  case DW_FORM_strx:
   case DW_FORM_GNU_str_index:
     OS << format(" indexed (%8.8x) string = ", (uint32_t)UValue);
     dumpString(OS);
@@ -620,10 +623,11 @@ Optional<const char *> DWARFFormValue::g
   if (Form == DW_FORM_GNU_strp_alt || U == nullptr)
     return None;
   uint32_t Offset = Value.uval;
-  if (Form == DW_FORM_GNU_str_index) {
-    uint32_t StrOffset;
+  if (Form == DW_FORM_GNU_str_index || Form == DW_FORM_strx) {
+    uint64_t StrOffset;
     if (!U->getStringOffsetSectionItem(Offset, StrOffset))
       return None;
+    StrOffset += U->getStringOffsetSectionRelocation(Offset);
     Offset = StrOffset;
   }
   if (const char *Str = U->getStringExtractor().getCStr(&Offset)) {

Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp?rev=304759&r1=304758&r2=304759&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp Mon Jun  5 20:22:34 2017
@@ -33,8 +33,9 @@ using namespace dwarf;
 
 void DWARFUnitSectionBase::parse(DWARFContext &C, const DWARFSection &Section) {
   parseImpl(C, Section, C.getDebugAbbrev(), &C.getRangeSection(),
-            C.getStringSection(), StringRef(), &C.getAddrSection(),
-            C.getLineSection().Data, C.isLittleEndian(), false);
+            C.getStringSection(), C.getStringOffsetSection(),
+            &C.getAddrSection(), C.getLineSection().Data, C.isLittleEndian(),
+            false);
 }
 
 void DWARFUnitSectionBase::parseDWO(DWARFContext &C,
@@ -48,19 +49,14 @@ void DWARFUnitSectionBase::parseDWO(DWAR
 
 DWARFUnit::DWARFUnit(DWARFContext &DC, const DWARFSection &Section,
                      const DWARFDebugAbbrev *DA, const DWARFSection *RS,
-                     StringRef SS, StringRef SOS, const DWARFSection *AOS,
-                     StringRef LS, bool LE, bool IsDWO,
+                     StringRef SS, const DWARFSection &SOS,
+                     const DWARFSection *AOS, StringRef LS, bool LE, bool IsDWO,
                      const DWARFUnitSectionBase &UnitSection,
                      const DWARFUnitIndex::Entry *IndexEntry)
     : Context(DC), InfoSection(Section), Abbrev(DA), RangeSection(RS),
-      LineSection(LS), StringSection(SS), StringOffsetSection([&]() {
-        if (IndexEntry)
-          if (const auto *C = IndexEntry->getOffset(DW_SECT_STR_OFFSETS))
-            return SOS.slice(C->Offset, C->Offset + C->Length);
-        return SOS;
-      }()),
-      AddrOffsetSection(AOS), isLittleEndian(LE), isDWO(IsDWO),
-      UnitSection(UnitSection), IndexEntry(IndexEntry) {
+      LineSection(LS), StringSection(SS), StringOffsetSection(SOS),
+      StringOffsetSectionBase(0), AddrOffsetSection(AOS), isLittleEndian(LE),
+      isDWO(IsDWO), UnitSection(UnitSection), IndexEntry(IndexEntry) {
   clear();
 }
 
@@ -77,17 +73,25 @@ bool DWARFUnit::getAddrOffsetSectionItem
 }
 
 bool DWARFUnit::getStringOffsetSectionItem(uint32_t Index,
-                                                  uint32_t &Result) const {
-  // FIXME: string offset section entries are 8-byte for DWARF64.
-  const uint32_t ItemSize = 4;
-  uint32_t Offset = Index * ItemSize;
-  if (StringOffsetSection.size() < Offset + ItemSize)
+                                           uint64_t &Result) const {
+  unsigned ItemSize = getFormat() == DWARF64 ? 8 : 4;
+  uint32_t Offset = StringOffsetSectionBase + Index * ItemSize;
+  if (StringOffsetSection.Data.size() < Offset + ItemSize)
     return false;
-  DataExtractor DA(StringOffsetSection, isLittleEndian, 0);
-  Result = DA.getU32(&Offset);
+  DataExtractor DA(StringOffsetSection.Data, isLittleEndian, 0);
+  Result = ItemSize == 4 ? DA.getU32(&Offset) : DA.getU64(&Offset);
   return true;
 }
 
+uint64_t DWARFUnit::getStringOffsetSectionRelocation(uint32_t Index) const {
+  unsigned ItemSize = getFormat() == DWARF64 ? 8 : 4;
+  uint64_t ByteOffset = StringOffsetSectionBase + Index * ItemSize;
+  RelocAddrMap::const_iterator AI = getStringOffsetsRelocMap().find(ByteOffset);
+  if (AI != getStringOffsetsRelocMap().end())
+    return AI->second.Value;
+  return 0;
+}
+
 bool DWARFUnit::extractImpl(DataExtractor debug_info, uint32_t *offset_ptr) {
   Length = debug_info.getU32(offset_ptr);
   Version = debug_info.getU16(offset_ptr);
@@ -119,6 +123,9 @@ bool DWARFUnit::extractImpl(DataExtracto
   if (!LengthOK || !VersionOK || !AddrSizeOK)
     return false;
 
+  // Keep track of the highest DWARF version we encounter across all units.
+  Context.setMaxVersionIfGreater(Version);
+
   Abbrevs = Abbrev->getAbbreviationDeclarationSet(AbbrOffset);
   return Abbrevs != nullptr;
 }
@@ -242,6 +249,17 @@ size_t DWARFUnit::extractDIEsIfNeeded(bo
       setBaseAddress(*BaseAddr);
     AddrOffsetSectionBase = toSectionOffset(UnitDie.find(DW_AT_GNU_addr_base), 0);
     RangeSectionBase = toSectionOffset(UnitDie.find(DW_AT_rnglists_base), 0);
+
+    // In general, we derive the offset of the unit's contibution to the
+    // debug_str_offsets{.dwo} section from the unit DIE's
+    // DW_AT_str_offsets_base attribute. In dwp files we add to it the offset
+    // we get from the index table.
+    StringOffsetSectionBase =
+        toSectionOffset(UnitDie.find(DW_AT_str_offsets_base), 0);
+    if (IndexEntry)
+      if (const auto *C = IndexEntry->getOffset(DW_SECT_STR_OFFSETS))
+        StringOffsetSectionBase += C->Offset;
+
     // Don't fall back to DW_AT_GNU_ranges_base: it should be ignored for
     // skeleton CU DIE, so that DWARF users not aware of it are not broken.
   }

Modified: llvm/trunk/lib/MC/MCObjectFileInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCObjectFileInfo.cpp?rev=304759&r1=304758&r2=304759&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCObjectFileInfo.cpp (original)
+++ llvm/trunk/lib/MC/MCObjectFileInfo.cpp Mon Jun  5 20:22:34 2017
@@ -241,6 +241,9 @@ void MCObjectFileInfo::initMachOMCObject
   DwarfStrSection =
       Ctx->getMachOSection("__DWARF", "__debug_str", MachO::S_ATTR_DEBUG,
                            SectionKind::getMetadata(), "info_string");
+  DwarfStrOffSection =
+      Ctx->getMachOSection("__DWARF", "__debug_str_offs", MachO::S_ATTR_DEBUG,
+                           SectionKind::getMetadata(), "section_str_off");
   DwarfLocSection =
       Ctx->getMachOSection("__DWARF", "__debug_loc", MachO::S_ATTR_DEBUG,
                            SectionKind::getMetadata(), "section_debug_loc");
@@ -557,6 +560,11 @@ void MCObjectFileInfo::initELFMCObjectFi
   DwarfAccelTypesSection =
       Ctx->getELFSection(".apple_types", ELF::SHT_PROGBITS, 0);
 
+  // String Offset and Address Sections
+  DwarfStrOffSection =
+      Ctx->getELFSection(".debug_str_offsets", DebugSecType, 0);
+  DwarfAddrSection = Ctx->getELFSection(".debug_addr", DebugSecType, 0);
+
   // Fission Sections
   DwarfInfoDWOSection =
       Ctx->getELFSection(".debug_info.dwo", DebugSecType, 0);
@@ -573,7 +581,6 @@ void MCObjectFileInfo::initELFMCObjectFi
       Ctx->getELFSection(".debug_loc.dwo", DebugSecType, 0);
   DwarfStrOffDWOSection =
       Ctx->getELFSection(".debug_str_offsets.dwo", DebugSecType, 0);
-  DwarfAddrSection = Ctx->getELFSection(".debug_addr", DebugSecType, 0);
 
   // DWP Sections
   DwarfCUIndexSection =
@@ -695,6 +702,11 @@ void MCObjectFileInfo::initCOFFMCObjectF
       COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
           COFF::IMAGE_SCN_MEM_READ,
       SectionKind::getMetadata(), "info_string");
+  DwarfStrOffSection = Ctx->getCOFFSection(
+      ".debug_str_offsets",
+      COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
+          COFF::IMAGE_SCN_MEM_READ,
+      SectionKind::getMetadata(), "section_str_off");
   DwarfLocSection = Ctx->getCOFFSection(
       ".debug_loc",
       COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
@@ -749,7 +761,7 @@ void MCObjectFileInfo::initCOFFMCObjectF
       ".debug_str_offsets.dwo",
       COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
           COFF::IMAGE_SCN_MEM_READ,
-      SectionKind::getMetadata());
+      SectionKind::getMetadata(), "section_str_off_dwo");
   DwarfAddrSection = Ctx->getCOFFSection(
       ".debug_addr",
       COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |

Modified: llvm/trunk/lib/Object/MachOObjectFile.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/MachOObjectFile.cpp?rev=304759&r1=304758&r2=304759&view=diff
==============================================================================
--- llvm/trunk/lib/Object/MachOObjectFile.cpp (original)
+++ llvm/trunk/lib/Object/MachOObjectFile.cpp Mon Jun  5 20:22:34 2017
@@ -4314,3 +4314,9 @@ ObjectFile::createMachOObjectFile(Memory
   return make_error<GenericBinaryError>("Unrecognized MachO magic number",
                                         object_error::invalid_file_type);
 }
+
+StringRef MachOObjectFile::mapDebugSectionName(StringRef Name) const {
+  return StringSwitch<StringRef>(Name)
+      .Case("debug_str_offs", "debug_str_offsets")
+      .Default(Name);
+}

Added: llvm/trunk/test/DebugInfo/Inputs/dwarfdump-str-offsets-dwp.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/Inputs/dwarfdump-str-offsets-dwp.s?rev=304759&view=auto
==============================================================================
--- llvm/trunk/test/DebugInfo/Inputs/dwarfdump-str-offsets-dwp.s (added)
+++ llvm/trunk/test/DebugInfo/Inputs/dwarfdump-str-offsets-dwp.s Mon Jun  5 20:22:34 2017
@@ -0,0 +1,277 @@
+# Test object to verify that dwarfdump handles dwp files with DWARF v5 string
+# offset tables. We have 2 CUs and 2 TUs, where it is assumed that 
+# CU1 and TU1 came from one object file, CU2 and TU2 from a second object
+# file.
+#
+# To generate the test object:
+# llvm-mc -triple x86_64-unknown-linux dwarfdump-str-offsets-dwp.s -filetype=obj \
+#         -o dwarfdump-str_offsets-dwp.x86_64.o
+
+        .section .debug_str.dwo,"MS", at progbits,1
+str_producer:
+        .asciz "Handmade DWARF producer"
+str_CU1:
+        .asciz "Compile_Unit_1"
+str_CU1_dir:
+        .asciz "/home/test/CU1"
+str_CU2:
+        .asciz "Compile_Unit_2"
+str_CU2_dir:
+        .asciz "/home/test/CU2"
+str_TU1:
+        .asciz "Type_Unit_1"
+str_TU1_type:
+        .asciz "MyStruct_1"
+str_TU2:
+        .asciz "Type_Unit_2"
+str_TU2_type:
+        .asciz "MyStruct_2"
+
+        .section .debug_str_offsets.dwo,"", at progbits
+# Object files 1's portion of the .debug_str_offsets.dwo section.
+.debug_str_offsets_object_file1:
+
+# CU1's contribution (from object file 1)
+.debug_str_offsets_start_CU1:
+        .long .debug_str_offsets_end_CU1-.debug_str_offsets_base_CU1
+        .short 5    # DWARF version
+        .short 0    # Padding
+.debug_str_offsets_base_CU1:
+        .long str_producer-.debug_str.dwo
+        .long str_CU1-.debug_str.dwo
+        .long str_CU1_dir-.debug_str.dwo
+.debug_str_offsets_end_CU1:
+
+# TU1's contribution (from object file 1)
+.debug_str_offsets_start_TU1:
+        .long .debug_str_offsets_end_TU1-.debug_str_offsets_base_TU1
+        .short 5    # DWARF version
+        .short 0    # Padding
+.debug_str_offsets_base_TU1:
+        .long str_TU1-.debug_str.dwo
+        .long str_TU1_type-.debug_str.dwo
+.debug_str_offsets_end_TU1:
+
+# Object files 2's portion of the .debug_str_offsets.dwo section.
+.debug_str_offsets_object_file2:
+
+# CU2's contribution (from object file 2)
+.debug_str_offsets_start_CU2:
+        .long .debug_str_offsets_end_CU2-.debug_str_offsets_base_CU2
+        .short 5    # DWARF version
+        .short 0    # Padding
+.debug_str_offsets_base_CU2:
+        .long str_producer-.debug_str.dwo
+        .long str_CU2-.debug_str.dwo
+        .long str_CU2_dir-.debug_str.dwo
+.debug_str_offsets_end_CU2:
+
+# TU2's contribution (from object file 2)
+.debug_str_offsets_start_TU2:
+        .long .debug_str_offsets_end_TU2-.debug_str_offsets_base_TU2
+        .short 5    # DWARF version
+        .short 0    # Padding
+.debug_str_offsets_base_TU2:
+        .long str_TU2-.debug_str.dwo
+        .long str_TU2_type-.debug_str.dwo
+.debug_str_offsets_end_TU2:
+
+
+# Abbrevs are shared for all compile and type units
+        .section .debug_abbrev.dwo,"", at progbits
+        .byte 0x01  # Abbrev code
+        .byte 0x11  # DW_TAG_compile_unit
+        .byte 0x00  # DW_CHILDREN_no
+        .byte 0x25  # DW_AT_producer
+        .byte 0x1a  # DW_FORM_strx
+        .byte 0x03  # DW_AT_name
+        .byte 0x1a  # DW_FORM_strx
+        .byte 0x72  # DW_AT_str_offsets_base
+        .byte 0x17  # DW_FORM_sec_offset
+        .byte 0x03  # DW_AT_name
+        .byte 0x1a  # DW_FORM_strx
+        .byte 0x00  # EOM(1)
+        .byte 0x00  # EOM(2)
+        .byte 0x02  # Abbrev code
+        .byte 0x41  # DW_TAG_type_unit
+        .byte 0x01  # DW_CHILDREN_yes
+        .byte 0x03  # DW_AT_name
+        .byte 0x1a  # DW_FORM_strx
+        .byte 0x72  # DW_AT_str_offsets_base
+        .byte 0x17  # DW_FORM_sec_offset
+        .byte 0x00  # EOM(1)
+        .byte 0x00  # EOM(2)
+        .byte 0x03  # Abbrev code
+        .byte 0x13  # DW_TAG_structure_type
+        .byte 0x00  # DW_CHILDREN_no (no members)
+        .byte 0x03  # DW_AT_name
+        .byte 0x1a  # DW_FORM_strx
+        .byte 0x00  # EOM(1)
+        .byte 0x00  # EOM(2)
+        .byte 0x00  # EOM(3)
+abbrev_end:
+
+        .section .debug_info.dwo,"", at progbits
+
+# DWARF v5 CU header.
+CU1_5_start:
+        .long  CU1_5_end-CU1_5_version  # Length of Unit
+CU1_5_version:
+        .short 5               # DWARF version number
+        .byte 1                # DWARF Unit Type
+        .byte 8                # Address Size (in bytes)
+        .long .debug_abbrev.dwo # Offset Into Abbrev. Section
+# The compile-unit DIE, which has a DW_AT_producer, DW_AT_name,
+# DW_AT_str_offsets and DW_AT_compdir.
+        .byte 1                # Abbreviation code
+        .byte 0                # The index of the producer string
+        .byte 1                # The index of the CU name string
+# The DW_AT_str_offsets_base attribute for CU1 contains the offset of CU1's
+# contribution relative to the start of object file 1's portion of the
+# .debug_str_offsets section.
+        .long .debug_str_offsets_base_CU1-.debug_str_offsets_object_file1
+        .byte 2                # The index of the comp dir string
+        .byte 0 # NULL
+CU1_5_end:
+
+CU2_5_start:
+        .long  CU2_5_end-CU2_5_version  # Length of Unit
+CU2_5_version:
+        .short 5               # DWARF version number
+        .byte 1                # DWARF Unit Type
+        .byte 8                # Address Size (in bytes)
+        .long .debug_abbrev.dwo # Offset Into Abbrev. Section
+# The compile-unit DIE, which has a DW_AT_producer, DW_AT_name,
+# DW_AT_str_offsets and DW_AT_compdir.
+        .byte 1                # Abbreviation code
+        .byte 0                # The index of the producer string
+        .byte 1                # The index of the CU name string
+# The DW_AT_str_offsets_base attribute for CU2 contains the offset of CU2's
+# contribution relative to the start of object file 2's portion of the
+# .debug_str_offsets section.
+        .long .debug_str_offsets_base_CU2-.debug_str_offsets_object_file2
+        .byte 2                # The index of the comp dir string
+        .byte 0 # NULL
+CU2_5_end:
+
+        .section .debug_types.dwo,"", at progbits
+# DWARF v5 Type unit header.
+TU1_5_start:
+        .long  TU1_5_end-TU1_5_version  # Length of Unit
+TU1_5_version:
+        .short 5               # DWARF version number
+        .byte 2                # DWARF Unit Type
+        .byte 8                # Address Size (in bytes)
+        .long .debug_abbrev.dwo    # Offset Into Abbrev. Section
+        .quad 0x0011223344556677 # Type Signature
+        .long TU1_5_type-TU1_5_start # Type offset
+# The type-unit DIE, which has a name.
+        .byte 2                # Abbreviation code
+        .byte 0                # Index of the unit type name string
+# The DW_AT_str_offsets_base attribute for TU1 contains the offset of TU1's
+# contribution relative to the start of object file 1's portion of the
+# .debug_str_offsets section.
+        .long .debug_str_offsets_base_TU1-.debug_str_offsets_object_file1
+# The type DIE, which has a name.
+TU1_5_type:
+        .byte 3                # Abbreviation code
+        .byte 1                # Index of the type name string
+        .byte 0 # NULL
+        .byte 0 # NULL
+TU1_5_end:
+
+TU2_5_start:
+        .long  TU2_5_end-TU2_5_version  # Length of Unit
+TU2_5_version:
+        .short 5               # DWARF version number
+        .byte 2                # DWARF Unit Type
+        .byte 8                # Address Size (in bytes)
+        .long .debug_abbrev.dwo    # Offset Into Abbrev. Section
+        .quad 0x00aabbccddeeff99 # Type Signature
+        .long TU2_5_type-TU2_5_start # Type offset
+# The type-unit DIE, which has a name.
+        .byte 2                # Abbreviation code
+        .byte 0                # Index of the unit type name string
+# The DW_AT_str_offsets_base attribute for TU2 contains the offset of TU2's
+# contribution relative to the start of object file 2's portion of the
+# .debug_str_offsets section.
+        .long .debug_str_offsets_base_TU2-.debug_str_offsets_object_file2
+# The type DIE, which has a name.
+TU2_5_type:
+        .byte 3                # Abbreviation code
+        .byte 1                # Index of the type name string
+        .byte 0 # NULL
+        .byte 0 # NULL
+TU2_5_end:
+
+        .section .debug_cu_index,"", at progbits
+        # The index header
+        .long 2                # Version 
+        .long 3                # Columns of contribution matrix
+        .long 2                # number of units
+        .long 2                # number of hash buckets in table
+
+        # The signatures for both CUs.
+        .quad 0xddeeaaddbbaabbee # signature 1
+        .quad 0xff00ffeeffaaff00 # signature 2
+        # The indexes for both CUs.
+        .long 1                # index 1
+        .long 2                # index 2
+        # The sections to which both CUs contribute.
+        .long 1                # DW_SECT_INFO
+        .long 3                # DW_SECT_ABBREV
+        .long 6                # DW_SECT_STR_OFFSETS
+
+        # The starting offsets of both CU's contributions to info,
+        # abbrev and string offsets table.
+        .long CU1_5_start-.debug_info.dwo                   
+        .long 0
+        .long .debug_str_offsets_object_file1-.debug_str_offsets.dwo
+        .long CU2_5_start-.debug_info.dwo
+        .long 0
+        .long .debug_str_offsets_object_file2-.debug_str_offsets.dwo
+
+        # The lengths of both CU's contributions to info, abbrev and
+        # string offsets table.
+        .long CU1_5_end-CU1_5_start
+        .long abbrev_end-.debug_abbrev.dwo
+        .long .debug_str_offsets_end_CU1-.debug_str_offsets_start_CU1
+        .long CU2_5_end-CU2_5_start
+        .long abbrev_end-.debug_abbrev.dwo
+        .long .debug_str_offsets_end_CU2-.debug_str_offsets_start_CU2
+
+        .section .debug_tu_index,"", at progbits
+        # The index header
+        .long 2                # Version 
+        .long 3                # Columns of contribution matrix
+        .long 2                # number of units
+        .long 2                # number of hash buckets in table
+
+        # The signatures for both TUs.
+        .quad 0xeeaaddbbaabbeedd # signature 1
+        .quad 0x00ffeeffaaff00ff # signature 2
+        # The indexes for both TUs.
+        .long 1                # index 1
+        .long 2                # index 2
+        # The sections to which both TUs contribute.
+        .long 2                # DW_SECT_TYPES
+        .long 3                # DW_SECT_ABBREV
+        .long 6                # DW_SECT_STR_OFFSETS
+
+        # The starting offsets of both TU's contributions to info,
+        # abbrev and string offsets table.
+        .long TU1_5_start-.debug_types.dwo
+        .long 0
+        .long .debug_str_offsets_object_file1-.debug_str_offsets.dwo
+        .long TU2_5_start-.debug_types.dwo
+        .long 0
+        .long .debug_str_offsets_object_file2-.debug_str_offsets.dwo
+
+        # The lengths of both TU's contributions to info, abbrev and
+        # string offsets table.
+        .long TU1_5_end-TU1_5_start
+        .long abbrev_end-.debug_abbrev.dwo
+        .long .debug_str_offsets_end_TU1-.debug_str_offsets_start_TU1
+        .long TU2_5_end-TU2_5_start
+        .long abbrev_end-.debug_abbrev.dwo
+        .long .debug_str_offsets_end_TU2-.debug_str_offsets_start_TU2

Added: llvm/trunk/test/DebugInfo/Inputs/dwarfdump-str-offsets-invalid-1.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/Inputs/dwarfdump-str-offsets-invalid-1.s?rev=304759&view=auto
==============================================================================
--- llvm/trunk/test/DebugInfo/Inputs/dwarfdump-str-offsets-invalid-1.s (added)
+++ llvm/trunk/test/DebugInfo/Inputs/dwarfdump-str-offsets-invalid-1.s Mon Jun  5 20:22:34 2017
@@ -0,0 +1,34 @@
+# Test object to verify that llvm-dwarfdump handles an invalid string offsets
+# table.
+#
+# To generate the test object:
+# llvm-mc -triple x86_64-unknown-linux dwarfdump-str-offsets-invalid-1.s -filetype=obj \
+#         -o dwarfdump-str-offsets-invalid-1.x86_64.o
+#
+# A rudimentary abbrev section.
+        .section .debug_abbrev,"", at progbits
+        .byte 0x01  # Abbrev code
+        .byte 0x11  # DW_TAG_compile_unit
+        .byte 0x00  # DW_CHILDREN_no
+        .byte 0x00  # EOM(1)
+        .byte 0x00  # EOM(2)
+        .byte 0x00  # EOM(3)
+
+# A rudimentary compile unit to convince dwarfdump that we are dealing with a 
+# DWARF v5 string offsets table.
+        .section .debug_info,"", at progbits
+
+# DWARF v5 CU header.
+        .long  CU1_5_end-CU1_5_version  # Length of Unit
+CU1_5_version:
+        .short 5               # DWARF version number
+        .byte 1                # DWARF Unit Type
+        .byte 8                # Address Size (in bytes)
+        .long .debug_abbrev    # Offset Into Abbrev. Section
+# A compile-unit DIE, which has no attributes.
+        .byte 1                # Abbreviation code
+CU1_5_end:
+
+        .section .debug_str_offsets,"", at progbits
+# A degenerate section, not enough for a single contribution size.
+        .byte 2

Added: llvm/trunk/test/DebugInfo/Inputs/dwarfdump-str-offsets-invalid-1.x86_64.o
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/Inputs/dwarfdump-str-offsets-invalid-1.x86_64.o?rev=304759&view=auto
==============================================================================
Binary file - no diff available.

Propchange: llvm/trunk/test/DebugInfo/Inputs/dwarfdump-str-offsets-invalid-1.x86_64.o
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: llvm/trunk/test/DebugInfo/Inputs/dwarfdump-str-offsets-invalid-2.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/Inputs/dwarfdump-str-offsets-invalid-2.s?rev=304759&view=auto
==============================================================================
--- llvm/trunk/test/DebugInfo/Inputs/dwarfdump-str-offsets-invalid-2.s (added)
+++ llvm/trunk/test/DebugInfo/Inputs/dwarfdump-str-offsets-invalid-2.s Mon Jun  5 20:22:34 2017
@@ -0,0 +1,36 @@
+# Test object to verify that llvm-dwarfdump handles an invalid string offsets
+# table.
+#
+# To generate the test object:
+# llvm-mc -triple x86_64-unknown-linux dwarfdump-str-offsets-invalid-2.s -filetype=obj \
+#         -o dwarfdump-str-offsets-invalid-2.x86_64.o
+
+# A rudimentary abbrev section.
+        .section .debug_abbrev,"", at progbits
+        .byte 0x01  # Abbrev code
+        .byte 0x11  # DW_TAG_compile_unit
+        .byte 0x00  # DW_CHILDREN_no
+        .byte 0x00  # EOM(1)
+        .byte 0x00  # EOM(2)
+        .byte 0x00  # EOM(3)
+
+# A rudimentary compile unit to convince dwarfdump that we are dealing with a
+# DWARF v5 string offsets table.
+        .section .debug_info,"", at progbits
+
+# DWARF v5 CU header.
+        .long  CU1_5_end-CU1_5_version  # Length of Unit
+CU1_5_version:
+        .short 5               # DWARF version number
+        .byte 1                # DWARF Unit Type
+        .byte 8                # Address Size (in bytes)
+        .long .debug_abbrev    # Offset Into Abbrev. Section
+# A compile-unit DIE, which has no attributes.
+        .byte 1                # Abbreviation code
+CU1_5_end:
+
+        .section .debug_str_offsets,"", at progbits
+# A degenerate section with fewer bytes than required for a DWARF64 size.
+        .long 0xffffffff
+        .long 0
+        .short 4

Added: llvm/trunk/test/DebugInfo/Inputs/dwarfdump-str-offsets-invalid-2.x86_64.o
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/Inputs/dwarfdump-str-offsets-invalid-2.x86_64.o?rev=304759&view=auto
==============================================================================
Binary file - no diff available.

Propchange: llvm/trunk/test/DebugInfo/Inputs/dwarfdump-str-offsets-invalid-2.x86_64.o
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: llvm/trunk/test/DebugInfo/Inputs/dwarfdump-str-offsets-invalid-3.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/Inputs/dwarfdump-str-offsets-invalid-3.s?rev=304759&view=auto
==============================================================================
--- llvm/trunk/test/DebugInfo/Inputs/dwarfdump-str-offsets-invalid-3.s (added)
+++ llvm/trunk/test/DebugInfo/Inputs/dwarfdump-str-offsets-invalid-3.s Mon Jun  5 20:22:34 2017
@@ -0,0 +1,88 @@
+# Test object to verify that llvm-dwarfdump handles an invalid string offsets
+# table.
+#
+# To generate the test object:
+# llvm-mc -triple x86_64-unknown-linux dwarfdump-str-offsets-invalid-3.s -filetype=obj \
+#         -o dwarfdump-str-offsets-invalid-3.x86_64.o
+
+        .section .debug_str,"MS", at progbits,1
+str_producer:
+        .asciz "Handmade DWARF producer"
+str_CU1:
+        .asciz "Compile_Unit_1"
+str_CU1_dir:
+        .asciz "/home/test/CU1"
+str_CU2:
+        .asciz "Compile_Unit_2"
+str_CU2_dir:
+        .asciz "/home/test/CU2"
+str_TU:
+        .asciz "Type_Unit"
+str_TU_type:
+        .asciz "MyStruct"
+
+        .section .debug_str.dwo,"MS", at progbits,1
+dwo_str_CU_5_producer:
+        .asciz "Handmade split DWARF producer"
+dwo_str_CU_5_name:
+        .asciz "V5_split_compile_unit"
+dwo_str_CU_5_comp_dir:
+        .asciz "/home/test/splitCU"
+dwo_str_TU_5:
+        .asciz "V5_split_type_unit"
+dwo_str_TU_5_type:
+        .asciz "V5_split_Mystruct"
+
+# A rudimentary abbrev section.
+        .section .debug_abbrev,"", at progbits
+        .byte 0x01  # Abbrev code
+        .byte 0x11  # DW_TAG_compile_unit
+        .byte 0x00  # DW_CHILDREN_no
+        .byte 0x00  # EOM(1)
+        .byte 0x00  # EOM(2)
+        .byte 0x00  # EOM(3)
+
+# A rudimentary compile unit to convince dwarfdump that we are dealing with a
+# DWARF v5 string offsets table.
+        .section .debug_info,"", at progbits
+
+# DWARF v5 CU header.
+        .long  CU1_5_end-CU1_5_version  # Length of Unit
+CU1_5_version:
+        .short 5               # DWARF version number
+        .byte 1                # DWARF Unit Type
+        .byte 8                # Address Size (in bytes)
+        .long .debug_abbrev    # Offset Into Abbrev. Section
+# A compile-unit DIE, which has no attributes.
+        .byte 1                # Abbreviation code
+CU1_5_end:
+
+        .section .debug_str_offsets,"", at progbits
+# CU1's contribution
+# Invalid length
+        .long 0xfffffffe
+        .long .debug_str_offsets_segment0_end-.debug_str_offsets_base0
+        .short 5    # DWARF version
+        .short 0    # Padding
+.debug_str_offsets_base0:
+        .long str_producer
+        .long str_CU1
+        .long str_CU1_dir
+.debug_str_offsets_segment0_end:
+# CU2's contribution
+        .long .debug_str_offsets_segment1_end-.debug_str_offsets_base1
+        .short 5    # DWARF version
+        .short 0    # Padding
+.debug_str_offsets_base1:
+        .long str_producer
+        .long str_CU2
+        .long str_CU2_dir
+.debug_str_offsets_segment1_end:
+# The TU's contribution
+        .long .debug_str_offsets_segment2_end-.debug_str_offsets_base2
+        .short 5    # DWARF version
+        .short 0    # Padding
+.debug_str_offsets_base2:
+        .long str_TU
+        .long str_TU_type
+.debug_str_offsets_segment2_end:

Added: llvm/trunk/test/DebugInfo/Inputs/dwarfdump-str-offsets-invalid-3.x86_64.o
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/Inputs/dwarfdump-str-offsets-invalid-3.x86_64.o?rev=304759&view=auto
==============================================================================
Binary file - no diff available.

Propchange: llvm/trunk/test/DebugInfo/Inputs/dwarfdump-str-offsets-invalid-3.x86_64.o
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: llvm/trunk/test/DebugInfo/Inputs/dwarfdump-str-offsets-invalid-4.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/Inputs/dwarfdump-str-offsets-invalid-4.s?rev=304759&view=auto
==============================================================================
--- llvm/trunk/test/DebugInfo/Inputs/dwarfdump-str-offsets-invalid-4.s (added)
+++ llvm/trunk/test/DebugInfo/Inputs/dwarfdump-str-offsets-invalid-4.s Mon Jun  5 20:22:34 2017
@@ -0,0 +1,50 @@
+# Test object to verify that llvm-dwarfdump handles an invalid string offsets
+# table.
+#
+# To generate the test object:
+# llvm-mc -triple x86_64-unknown-linux dwarfdump-str-offsets-invalid-4.s -filetype=obj \
+#         -o dwarfdump-str-offsets-invalid-4.x86_64.o
+
+        .section .debug_str,"MS", at progbits,1
+str_producer:
+        .asciz "Handmade DWARF producer"
+str_CU1:
+        .asciz "Compile_Unit_1"
+
+# A rudimentary abbrev section.
+        .section .debug_abbrev,"", at progbits
+        .byte 0x01  # Abbrev code
+        .byte 0x11  # DW_TAG_compile_unit
+        .byte 0x00  # DW_CHILDREN_no
+        .byte 0x00  # EOM(1)
+        .byte 0x00  # EOM(2)
+        .byte 0x00  # EOM(3)
+
+# A rudimentary compile unit to convince dwarfdump that we are dealing with a
+# DWARF v5 string offsets table.
+        .section .debug_info,"", at progbits
+
+# DWARF v5 CU header.
+        .long  CU1_5_end-CU1_5_version  # Length of Unit
+CU1_5_version:
+        .short 5               # DWARF version number
+        .byte 1                # DWARF Unit Type
+        .byte 8                # Address Size (in bytes)
+        .long .debug_abbrev    # Offset Into Abbrev. Section
+# A compile-unit DIE, which has no attributes.
+        .byte 1                # Abbreviation code
+CU1_5_end:
+
+# Every unit contributes to the string_offsets table.
+        .section .debug_str_offsets,"", at progbits
+# CU1's contribution
+# The length is not a multiple of 4. Check that we don't read off the
+# end.
+        .long .debug_str_offsets_segment0_end-.debug_str_offsets_base0
+        .short 5    # DWARF version
+        .short 0    # Padding
+.debug_str_offsets_base0:
+        .long str_producer
+        .long str_CU1
+        .byte 0
+.debug_str_offsets_segment0_end:

Added: llvm/trunk/test/DebugInfo/Inputs/dwarfdump-str-offsets-invalid-4.x86_64.o
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/Inputs/dwarfdump-str-offsets-invalid-4.x86_64.o?rev=304759&view=auto
==============================================================================
Binary file - no diff available.

Propchange: llvm/trunk/test/DebugInfo/Inputs/dwarfdump-str-offsets-invalid-4.x86_64.o
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: llvm/trunk/test/DebugInfo/Inputs/dwarfdump-str-offsets-invalid-5.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/Inputs/dwarfdump-str-offsets-invalid-5.s?rev=304759&view=auto
==============================================================================
--- llvm/trunk/test/DebugInfo/Inputs/dwarfdump-str-offsets-invalid-5.s (added)
+++ llvm/trunk/test/DebugInfo/Inputs/dwarfdump-str-offsets-invalid-5.s Mon Jun  5 20:22:34 2017
@@ -0,0 +1,10 @@
+# Test object to verify that llvm-dwarfdump handles a degenerate string offsets
+# section.
+#
+# To generate the test object:
+# llvm-mc -triple x86_64-unknown-linux dwarfdump-str-offsets-invalid-5.s -filetype=obj \
+#         -o dwarfdump-str-offsets-invalid-5.x86_64.o
+# Every unit contributes to the string_offsets table.
+        .section .debug_str_offsets,"", at progbits
+# A degenerate section, not enough for a single entry.
+        .byte 2

Added: llvm/trunk/test/DebugInfo/Inputs/dwarfdump-str-offsets-invalid-5.x86_64.o
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/Inputs/dwarfdump-str-offsets-invalid-5.x86_64.o?rev=304759&view=auto
==============================================================================
Binary file - no diff available.

Propchange: llvm/trunk/test/DebugInfo/Inputs/dwarfdump-str-offsets-invalid-5.x86_64.o
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: llvm/trunk/test/DebugInfo/Inputs/dwarfdump-str-offsets.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/Inputs/dwarfdump-str-offsets.s?rev=304759&view=auto
==============================================================================
--- llvm/trunk/test/DebugInfo/Inputs/dwarfdump-str-offsets.s (added)
+++ llvm/trunk/test/DebugInfo/Inputs/dwarfdump-str-offsets.s Mon Jun  5 20:22:34 2017
@@ -0,0 +1,500 @@
+# Test object to verify dwarfdump handles v5 string offset tables.
+# We have 2 v5 CUs, a v5 TU, and a split v5 CU and TU.
+#
+# To generate the test object:
+# llvm-mc -triple x86_64-unknown-linux dwarfdump-str-offsets.s -filetype=obj \
+#         -o dwarfdump-str-offsets.x86_64.o
+
+        .section .debug_str,"MS", at progbits,1
+str_producer:
+        .asciz "Handmade DWARF producer"
+str_CU1:
+        .asciz "Compile_Unit_1"
+str_CU1_dir:
+        .asciz "/home/test/CU1"
+str_CU2:
+        .asciz "Compile_Unit_2"
+str_CU2_dir:
+        .asciz "/home/test/CU2"
+str_TU:
+        .asciz "Type_Unit"
+str_TU_type:
+        .asciz "MyStruct"
+
+# Every unit contributes to the string_offsets table.
+        .section .debug_str_offsets,"", at progbits
+# CU1's contribution
+        .long .debug_str_offsets_segment0_end-.debug_str_offsets_base0
+        .short 5    # DWARF version
+        .short 0    # Padding
+.debug_str_offsets_base0:
+        .long str_producer
+        .long str_CU1
+        .long str_CU1_dir
+.debug_str_offsets_segment0_end:
+# CU2's contribution
+        .long .debug_str_offsets_segment1_end-.debug_str_offsets_base1
+        .short 5    # DWARF version
+        .short 0    # Padding
+.debug_str_offsets_base1:
+        .long str_producer
+        .long str_CU2
+        .long str_CU2_dir
+.debug_str_offsets_segment1_end:
+# The TU's contribution
+        .long .debug_str_offsets_segment2_end-.debug_str_offsets_base2
+        .short 5    # DWARF version
+        .short 0    # Padding
+.debug_str_offsets_base2:
+        .long str_TU
+        .long str_TU_type
+.debug_str_offsets_segment2_end:
+
+        .section .debug_str.dwo,"MS", at progbits,1
+dwo_str_CU_5_producer:
+        .asciz "Handmade split DWARF producer"
+dwo_str_CU_5_name:
+        .asciz "V5_split_compile_unit"
+dwo_str_CU_5_comp_dir:
+        .asciz "/home/test/splitCU"
+dwo_str_TU_5:
+        .asciz "V5_split_type_unit"
+dwo_str_TU_5_type:
+        .asciz "V5_split_Mystruct"
+
+        .section .debug_str_offsets.dwo,"", at progbits
+# The split CU's contribution
+        .long .debug_dwo_str_offsets_segment0_end-.debug_dwo_str_offsets_base0
+        .short 5    # DWARF version
+        .short 0    # Padding
+.debug_dwo_str_offsets_base0:
+        .long dwo_str_CU_5_producer-.debug_str.dwo
+        .long dwo_str_CU_5_name-.debug_str.dwo
+        .long dwo_str_CU_5_comp_dir-.debug_str.dwo
+.debug_dwo_str_offsets_segment0_end:
+# The split TU's contribution
+        .long .debug_dwo_str_offsets_segment1_end-.debug_dwo_str_offsets_base1
+        .short 5    # DWARF version
+        .short 0    # Padding
+.debug_dwo_str_offsets_base1:
+        .long dwo_str_TU_5-.debug_str.dwo
+        .long dwo_str_TU_5_type-.debug_str.dwo
+.debug_dwo_str_offsets_segment1_end:
+
+# All CUs/TUs use the same abbrev section for simplicity.
+        .section .debug_abbrev,"", at progbits
+        .byte 0x01  # Abbrev code
+        .byte 0x11  # DW_TAG_compile_unit
+        .byte 0x00  # DW_CHILDREN_no
+        .byte 0x25  # DW_AT_producer
+        .byte 0x1a  # DW_FORM_strx
+        .byte 0x03  # DW_AT_name
+        .byte 0x1a  # DW_FORM_strx
+        .byte 0x72  # DW_AT_str_offsets_base
+        .byte 0x17  # DW_FORM_sec_offset
+        .byte 0x1b  # DW_AT_comp_dir
+        .byte 0x1a  # DW_FORM_strx
+        .byte 0x00  # EOM(1)
+        .byte 0x00  # EOM(2)
+        .byte 0x02  # Abbrev code
+        .byte 0x41  # DW_TAG_type_unit
+        .byte 0x01  # DW_CHILDREN_yes
+        .byte 0x03  # DW_AT_name
+        .byte 0x1a  # DW_FORM_strx
+        .byte 0x72  # DW_AT_str_offsets_base
+        .byte 0x17  # DW_FORM_sec_offset
+        .byte 0x00  # EOM(1)
+        .byte 0x00  # EOM(2)
+        .byte 0x03  # Abbrev code
+        .byte 0x13  # DW_TAG_structure_type
+        .byte 0x00  # DW_CHILDREN_no (no members)
+        .byte 0x03  # DW_AT_name
+        .byte 0x1a  # DW_FORM_strx
+        .byte 0x00  # EOM(1)
+        .byte 0x00  # EOM(2)
+        .byte 0x00  # EOM(3)
+
+# And a .dwo copy for the .dwo sections.
+        .section .debug_abbrev.dwo,"", at progbits
+        .byte 0x01  # Abbrev code
+        .byte 0x11  # DW_TAG_compile_unit
+        .byte 0x00  # DW_CHILDREN_no
+        .byte 0x25  # DW_AT_producer
+        .byte 0x1a  # DW_FORM_strx
+        .byte 0x03  # DW_AT_name
+        .byte 0x1a  # DW_FORM_strx
+        .byte 0x72  # DW_AT_str_offsets_base
+        .byte 0x17  # DW_FORM_sec_offset
+        .byte 0x1b  # DW_AT_comp_dir
+        .byte 0x1a  # DW_FORM_strx
+        .byte 0x00  # EOM(1)
+        .byte 0x00  # EOM(2)
+        .byte 0x02  # Abbrev code
+        .byte 0x41  # DW_TAG_type_unit
+        .byte 0x01  # DW_CHILDREN_yes
+        .byte 0x03  # DW_AT_name
+        .byte 0x1a  # DW_FORM_strx
+        .byte 0x72  # DW_AT_str_offsets_base
+        .byte 0x17  # DW_FORM_sec_offset
+        .byte 0x00  # EOM(1)
+        .byte 0x00  # EOM(2)
+        .byte 0x03  # Abbrev code
+        .byte 0x13  # DW_TAG_structure_type
+        .byte 0x00  # DW_CHILDREN_no (no members)
+        .byte 0x03  # DW_AT_name
+        .byte 0x1a  # DW_FORM_strx
+        .byte 0x00  # EOM(1)
+        .byte 0x00  # EOM(2)
+        .byte 0x00  # EOM(3)
+        
+        .section .debug_info,"", at progbits
+
+# DWARF v5 CU header.
+        .long  CU1_5_end-CU1_5_version  # Length of Unit
+CU1_5_version:
+        .short 5               # DWARF version number
+        .byte 1                # DWARF Unit Type
+        .byte 8                # Address Size (in bytes)
+        .long .debug_abbrev    # Offset Into Abbrev. Section
+# The compile-unit DIE, which has a DW_AT_producer, DW_AT_name, 
+# DW_AT_str_offsets and DW_AT_compdir.
+        .byte 1                # Abbreviation code
+        .byte 0                # The index of the producer string
+        .byte 1                # The index of the CU name string
+        .long .debug_str_offsets_base0
+        .byte 2                # The index of the comp dir string
+        .byte 0 # NULL
+CU1_5_end:
+
+# DWARF v5 CU header
+        .long  CU2_5_end-CU2_5_version  # Length of Unit
+CU2_5_version:
+        .short 5               # DWARF version number
+        .byte 1                # DWARF Unit Type
+        .byte 8                # Address Size (in bytes)
+        .long .debug_abbrev    # Offset Into Abbrev. Section
+# The compile-unit DIE, which has a DW_AT_producer, DW_AT_name, 
+# DW_AT_str_offsets and DW_AT_compdir.
+        .byte 1                # Abbreviation code
+        .byte 0                # The index of the producer string
+        .byte 1                # The index of the CU name string
+        .long .debug_str_offsets_base1
+        .byte 2                # The index of the comp dir string
+        .byte 0 # NULL
+CU2_5_end:
+
+        .section .debug_types,"", at progbits
+# DWARF v5 Type unit header.
+TU_5_start:
+        .long  TU_5_end-TU_5_version  # Length of Unit
+TU_5_version:
+        .short 5               # DWARF version number
+        .byte 2                # DWARF Unit Type
+        .byte 8                # Address Size (in bytes)
+        .long .debug_abbrev    # Offset Into Abbrev. Section
+        .quad 0x0011223344556677 # Type Signature
+        .long TU_5_type-TU_5_start # Type offset
+# The type-unit DIE, which has a name.
+        .byte 2                # Abbreviation code
+        .byte 0                # Index of the unit type name string
+        .long .debug_str_offsets_base2  # offset into the str_offsets section
+# The type DIE, which has a name.
+TU_5_type:
+        .byte 3                # Abbreviation code
+        .byte 1                # Index of the type name string
+        .byte 0 # NULL
+        .byte 0 # NULL
+TU_5_end:
+        
+        .section .debug_info.dwo,"", at progbits
+
+# DWARF v5 split CU header.
+        .long  CU_split_5_end-CU_split_5_version  # Length of Unit
+CU_split_5_version:
+        .short 5               # DWARF version number
+        .byte 1                # DWARF Unit Type
+        .byte 8                # Address Size (in bytes)
+        .long .debug_abbrev.dwo  # Offset Into Abbrev Section
+# The compile-unit DIE, which has a DW_AT_producer, DW_AT_name, 
+# DW_AT_str_offsets and DW_AT_compdir.
+        .byte 1                # Abbreviation code
+        .byte 0                # The index of the producer string
+        .byte 1                # The index of the CU name string
+        .long .debug_dwo_str_offsets_base0-.debug_str_offsets.dwo
+        .byte 2                # The index of the comp dir string
+        .byte 0 # NULL
+CU_split_5_end:
+        
+        .section .debug_types.dwo,"", at progbits
+
+# DWARF v5 split type unit header.
+TU_split_5_start:
+        .long  TU_split_5_end-TU_split_5_version  # Length of Unit
+TU_split_5_version:
+        .short 5               # DWARF version number
+        .byte 6                # DWARF Unit Type
+        .byte 8                # Address Size (in bytes)
+        .long .debug_abbrev.dwo  # Offset Into Abbrev Section
+        .quad 0x8899aabbccddeeff # Type Signature
+        .long TU_split_5_type-TU_split_5_start  # Type offset
+# The type-unit DIE, which has a name.
+        .byte 2                # Abbreviation code
+        .byte 0                # The index of the type unit name string
+        .long .debug_dwo_str_offsets_base1-.debug_str_offsets.dwo 
+# The type DIE, which has a name.
+TU_split_5_type:
+        .byte 3                # Abbreviation code
+        .byte 1                # The index of the type name string
+        .byte 0 # NULL
+        .byte 0 # NULL
+TU_split_5_end:
+# Test object to verify dwarfdump handles v5 string offset tables.
+# We have 2 v5 CUs, a v5 TU, and a split v5 CU and TU.
+#
+# To generate the test object:
+# llvm-mc -triple x86_64-unknown-linux dwarfdump-str-offsets.s -filetype=obj \
+#         -o dwarfdump-str-offsets.elf-x86-64
+
+        .section .debug_str,"MS", at progbits,1
+str_producer:
+        .asciz "Handmade DWARF producer"
+str_CU1:
+        .asciz "Compile_Unit_1"
+str_CU1_dir:
+        .asciz "/home/test/CU1"
+str_CU2:
+        .asciz "Compile_Unit_2"
+str_CU2_dir:
+        .asciz "/home/test/CU2"
+str_TU:
+        .asciz "Type_Unit"
+str_TU_type:
+        .asciz "MyStruct"
+
+# Every unit contributes to the string_offsets table.
+        .section .debug_str_offsets,"", at progbits
+# CU1's contribution
+        .long .debug_str_offsets_segment0_end-.debug_str_offsets_base0
+        .short 5    # DWARF version
+        .short 0    # Padding
+.debug_str_offsets_base0:
+        .long str_producer
+        .long str_CU1
+        .long str_CU1_dir
+.debug_str_offsets_segment0_end:
+# CU2's contribution
+        .long .debug_str_offsets_segment1_end-.debug_str_offsets_base1
+        .short 5    # DWARF version
+        .short 0    # Padding
+.debug_str_offsets_base1:
+        .long str_producer
+        .long str_CU2
+        .long str_CU2_dir
+.debug_str_offsets_segment1_end:
+# The TU's contribution
+        .long .debug_str_offsets_segment2_end-.debug_str_offsets_base2
+        .short 5    # DWARF version
+        .short 0    # Padding
+.debug_str_offsets_base2:
+        .long str_TU
+        .long str_TU_type
+.debug_str_offsets_segment2_end:
+
+        .section .debug_str.dwo,"MS", at progbits,1
+dwo_str_CU_5_producer:
+        .asciz "Handmade split DWARF producer"
+dwo_str_CU_5_name:
+        .asciz "V5_split_compile_unit"
+dwo_str_CU_5_comp_dir:
+        .asciz "/home/test/splitCU"
+dwo_str_TU_5:
+        .asciz "V5_split_type_unit"
+dwo_str_TU_5_type:
+        .asciz "V5_split_Mystruct"
+
+        .section .debug_str_offsets.dwo,"", at progbits
+# The split CU's contribution
+        .long .debug_dwo_str_offsets_segment0_end-.debug_dwo_str_offsets_base0
+        .short 5    # DWARF version
+        .short 0    # Padding
+.debug_dwo_str_offsets_base0:
+        .long dwo_str_CU_5_producer-.debug_str.dwo
+        .long dwo_str_CU_5_name-.debug_str.dwo
+        .long dwo_str_CU_5_comp_dir-.debug_str.dwo
+.debug_dwo_str_offsets_segment0_end:
+# The split TU's contribution
+        .long .debug_dwo_str_offsets_segment1_end-.debug_dwo_str_offsets_base1
+        .short 5    # DWARF version
+        .short 0    # Padding
+.debug_dwo_str_offsets_base1:
+        .long dwo_str_TU_5-.debug_str.dwo
+        .long dwo_str_TU_5_type-.debug_str.dwo
+.debug_dwo_str_offsets_segment1_end:
+
+# All CUs/TUs use the same abbrev section for simplicity.
+        .section .debug_abbrev,"", at progbits
+        .byte 0x01  # Abbrev code
+        .byte 0x11  # DW_TAG_compile_unit
+        .byte 0x00  # DW_CHILDREN_no
+        .byte 0x25  # DW_AT_producer
+        .byte 0x1a  # DW_FORM_strx
+        .byte 0x03  # DW_AT_name
+        .byte 0x1a  # DW_FORM_strx
+        .byte 0x72  # DW_AT_str_offsets_base
+        .byte 0x17  # DW_FORM_sec_offset
+        .byte 0x1b  # DW_AT_comp_dir
+        .byte 0x1a  # DW_FORM_strx
+        .byte 0x00  # EOM(1)
+        .byte 0x00  # EOM(2)
+        .byte 0x02  # Abbrev code
+        .byte 0x41  # DW_TAG_type_unit
+        .byte 0x01  # DW_CHILDREN_yes
+        .byte 0x03  # DW_AT_name
+        .byte 0x1a  # DW_FORM_strx
+        .byte 0x72  # DW_AT_str_offsets_base
+        .byte 0x17  # DW_FORM_sec_offset
+        .byte 0x00  # EOM(1)
+        .byte 0x00  # EOM(2)
+        .byte 0x03  # Abbrev code
+        .byte 0x13  # DW_TAG_structure_type
+        .byte 0x00  # DW_CHILDREN_no (no members)
+        .byte 0x03  # DW_AT_name
+        .byte 0x1a  # DW_FORM_strx
+        .byte 0x00  # EOM(1)
+        .byte 0x00  # EOM(2)
+        .byte 0x00  # EOM(3)
+
+# And a .dwo copy for the .dwo sections.
+        .section .debug_abbrev.dwo,"", at progbits
+        .byte 0x01  # Abbrev code
+        .byte 0x11  # DW_TAG_compile_unit
+        .byte 0x00  # DW_CHILDREN_no
+        .byte 0x25  # DW_AT_producer
+        .byte 0x1a  # DW_FORM_strx
+        .byte 0x03  # DW_AT_name
+        .byte 0x1a  # DW_FORM_strx
+        .byte 0x72  # DW_AT_str_offsets_base
+        .byte 0x17  # DW_FORM_sec_offset
+        .byte 0x1b  # DW_AT_comp_dir
+        .byte 0x1a  # DW_FORM_strx
+        .byte 0x00  # EOM(1)
+        .byte 0x00  # EOM(2)
+        .byte 0x02  # Abbrev code
+        .byte 0x41  # DW_TAG_type_unit
+        .byte 0x01  # DW_CHILDREN_yes
+        .byte 0x03  # DW_AT_name
+        .byte 0x1a  # DW_FORM_strx
+        .byte 0x72  # DW_AT_str_offsets_base
+        .byte 0x17  # DW_FORM_sec_offset
+        .byte 0x00  # EOM(1)
+        .byte 0x00  # EOM(2)
+        .byte 0x03  # Abbrev code
+        .byte 0x13  # DW_TAG_structure_type
+        .byte 0x00  # DW_CHILDREN_no (no members)
+        .byte 0x03  # DW_AT_name
+        .byte 0x1a  # DW_FORM_strx
+        .byte 0x00  # EOM(1)
+        .byte 0x00  # EOM(2)
+        .byte 0x00  # EOM(3)
+        
+        .section .debug_info,"", at progbits
+
+# DWARF v5 CU header.
+        .long  CU1_5_end-CU1_5_version  # Length of Unit
+CU1_5_version:
+        .short 5               # DWARF version number
+        .byte 1                # DWARF Unit Type
+        .byte 8                # Address Size (in bytes)
+        .long .debug_abbrev    # Offset Into Abbrev. Section
+# The compile-unit DIE, which has a DW_AT_producer, DW_AT_name, 
+# DW_AT_str_offsets and DW_AT_compdir.
+        .byte 1                # Abbreviation code
+        .byte 0                # The index of the producer string
+        .byte 1                # The index of the CU name string
+        .long .debug_str_offsets_base0
+        .byte 2                # The index of the comp dir string
+        .byte 0 # NULL
+CU1_5_end:
+
+# DWARF v5 CU header
+        .long  CU2_5_end-CU2_5_version  # Length of Unit
+CU2_5_version:
+        .short 5               # DWARF version number
+        .byte 1                # DWARF Unit Type
+        .byte 8                # Address Size (in bytes)
+        .long .debug_abbrev    # Offset Into Abbrev. Section
+# The compile-unit DIE, which has a DW_AT_producer, DW_AT_name, 
+# DW_AT_str_offsets and DW_AT_compdir.
+        .byte 1                # Abbreviation code
+        .byte 0                # The index of the producer string
+        .byte 1                # The index of the CU name string
+        .long .debug_str_offsets_base1
+        .byte 2                # The index of the comp dir string
+        .byte 0 # NULL
+CU2_5_end:
+
+        .section .debug_types,"", at progbits
+# DWARF v5 Type unit header.
+TU_5_start:
+        .long  TU_5_end-TU_5_version  # Length of Unit
+TU_5_version:
+        .short 5               # DWARF version number
+        .byte 2                # DWARF Unit Type
+        .byte 8                # Address Size (in bytes)
+        .long .debug_abbrev    # Offset Into Abbrev. Section
+        .quad 0x0011223344556677 # Type Signature
+        .long TU_5_type-TU_5_start # Type offset
+# The type-unit DIE, which has a name.
+        .byte 2                # Abbreviation code
+        .byte 0                # Index of the unit type name string
+        .long .debug_str_offsets_base2  # offset into the str_offsets section
+# The type DIE, which has a name.
+TU_5_type:
+        .byte 3                # Abbreviation code
+        .byte 1                # Index of the type name string
+        .byte 0 # NULL
+        .byte 0 # NULL
+TU_5_end:
+        
+        .section .debug_info.dwo,"", at progbits
+
+# DWARF v5 split CU header.
+        .long  CU_split_5_end-CU_split_5_version  # Length of Unit
+CU_split_5_version:
+        .short 5               # DWARF version number
+        .byte 1                # DWARF Unit Type
+        .byte 8                # Address Size (in bytes)
+        .long .debug_abbrev.dwo  # Offset Into Abbrev Section
+# The compile-unit DIE, which has a DW_AT_producer, DW_AT_name, 
+# DW_AT_str_offsets and DW_AT_compdir.
+        .byte 1                # Abbreviation code
+        .byte 0                # The index of the producer string
+        .byte 1                # The index of the CU name string
+        .long .debug_dwo_str_offsets_base0-.debug_str_offsets.dwo
+        .byte 2                # The index of the comp dir string
+        .byte 0 # NULL
+CU_split_5_end:
+        
+        .section .debug_types.dwo,"", at progbits
+
+# DWARF v5 split type unit header.
+TU_split_5_start:
+        .long  TU_split_5_end-TU_split_5_version  # Length of Unit
+TU_split_5_version:
+        .short 5               # DWARF version number
+        .byte 6                # DWARF Unit Type
+        .byte 8                # Address Size (in bytes)
+        .long .debug_abbrev.dwo  # Offset Into Abbrev Section
+        .quad 0x8899aabbccddeeff # Type Signature
+        .long TU_split_5_type-TU_split_5_start  # Type offset
+# The type-unit DIE, which has a name.
+        .byte 2                # Abbreviation code
+        .byte 0                # The index of the type unit name string
+        .long .debug_dwo_str_offsets_base1-.debug_str_offsets.dwo 
+# The type DIE, which has a name.
+TU_split_5_type:
+        .byte 3                # Abbreviation code
+        .byte 1                # The index of the type name string
+        .byte 0 # NULL
+        .byte 0 # NULL
+TU_split_5_end:

Added: llvm/trunk/test/DebugInfo/Inputs/dwarfdump-str-offsets.x86_64.o
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/Inputs/dwarfdump-str-offsets.x86_64.o?rev=304759&view=auto
==============================================================================
Binary file - no diff available.

Propchange: llvm/trunk/test/DebugInfo/Inputs/dwarfdump-str-offsets.x86_64.o
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: llvm/trunk/test/DebugInfo/dwarfdump-str-offsets-invalid.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/dwarfdump-str-offsets-invalid.test?rev=304759&view=auto
==============================================================================
--- llvm/trunk/test/DebugInfo/dwarfdump-str-offsets-invalid.test (added)
+++ llvm/trunk/test/DebugInfo/dwarfdump-str-offsets-invalid.test Mon Jun  5 20:22:34 2017
@@ -0,0 +1,24 @@
+; Verify that llvm-dwarfdump handles invalid string offset tables.
+
+RUN: llvm-dwarfdump %p/Inputs/dwarfdump-str-offsets-invalid-1.x86_64.o | \
+RUN:   FileCheck --check-prefix=INVALIDCONTRIB %s
+RUN: llvm-dwarfdump %p/Inputs/dwarfdump-str-offsets-invalid-2.x86_64.o | \
+RUN:   FileCheck --check-prefix=INVALIDCONTRIB %s
+RUN: llvm-dwarfdump %p/Inputs/dwarfdump-str-offsets-invalid-3.x86_64.o | \
+RUN:   FileCheck --check-prefix=INVALIDCONTRIB %s
+RUN: llvm-dwarfdump %p/Inputs/dwarfdump-str-offsets-invalid-4.x86_64.o | \
+RUN:   FileCheck --check-prefix=INVALIDLENGTH %s
+RUN: llvm-dwarfdump %p/Inputs/dwarfdump-str-offsets-invalid-5.x86_64.o | \
+RUN:   FileCheck --check-prefix=INVALIDSECTIONLENGTH %s
+
+INVALIDCONTRIB:            .debug_str_offsets contents:
+INVALIDCONTRIB-NOT:        contents:
+INVALIDCONTRIB:            error: invalid contribution to string offsets table in section .debug_str_offsets.
+
+INVALIDLENGTH:             .debug_str_offsets contents:
+INVALIDLENGTH-NOT:         contents:
+INVALIDLENGTH:             error: contribution to string offsets table in section .debug_str_offsets has invalid length.
+
+INVALIDSECTIONLENGTH:      .debug_str_offsets contents:
+INVALIDSECTIONLENGTH-NOT:  contents:
+INVALIDSECTIONLENGTH:      error: size of .debug_str_offsets is not a multiple of 4.

Added: llvm/trunk/test/DebugInfo/dwarfdump-str-offsets.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/dwarfdump-str-offsets.test?rev=304759&view=auto
==============================================================================
--- llvm/trunk/test/DebugInfo/dwarfdump-str-offsets.test (added)
+++ llvm/trunk/test/DebugInfo/dwarfdump-str-offsets.test Mon Jun  5 20:22:34 2017
@@ -0,0 +1,76 @@
+RUN: llvm-dwarfdump %p/Inputs/dwarfdump-str-offsets.x86_64.o | FileCheck %s
+
+; We are using a hand-constructed object file and are interest in the correct
+; diplay of the DW_str_offsetsbase attribute, the correct display of strings
+; and the dump of the .debug_str_offsets[.dwo] table.
+;
+; Abbreviation for DW_AT_str_offsets_base
+CHECK:      .debug_abbrev contents:
+CHECK-NOT:  contents:
+CHECK:      DW_TAG_compile_unit
+CHECK-NOT:  DW_TAG
+CHECK:      DW_AT_str_offsets_base DW_FORM_sec_offset
+
+; Verify that strings are displayed correctly as indexed strings
+CHECK:      .debug_info contents:
+CHECK-NOT:  contents:     
+CHECK:      DW_TAG_compile_unit
+CHECK-NEXT: DW_AT_producer [DW_FORM_strx] ( indexed (00000000) string = "Handmade DWARF producer")
+CHECK-NEXT: DW_AT_name [DW_FORM_strx] ( indexed (00000001) string = "Compile_Unit_1")
+CHECK-NEXT: DW_AT_str_offsets_base [DW_FORM_sec_offset] (0x00000008)
+CHECK-NEXT: DW_AT_comp_dir [DW_FORM_strx] ( indexed (00000002) string = "/home/test/CU1")
+
+; Second compile unit (b.cpp)
+CHECK:      DW_TAG_compile_unit
+CHECK-NEXT: DW_AT_producer [DW_FORM_strx] ( indexed (00000000) string = "Handmade DWARF producer")
+CHECK-NEXT: DW_AT_name [DW_FORM_strx] ( indexed (00000001) string = "Compile_Unit_2")
+CHECK-NEXT: DW_AT_str_offsets_base [DW_FORM_sec_offset] (0x0000001c)
+CHECK-NEXT: DW_AT_comp_dir [DW_FORM_strx] ( indexed (00000002) string = "/home/test/CU2")
+
+; The split CU
+CHECK:      .debug_info.dwo contents:
+CHECK-NOT:  contents:
+CHECK:      DW_TAG_compile_unit
+CHECK-NEXT: DW_AT_producer [DW_FORM_strx] ( indexed (00000000) string = "Handmade split DWARF producer")
+CHECK-NEXT: DW_AT_name [DW_FORM_strx] ( indexed (00000001) string = "V5_split_compile_unit")
+CHECK-NEXT: DW_AT_str_offsets_base [DW_FORM_sec_offset] (0x00000008)
+CHECK-NEXT: DW_AT_comp_dir [DW_FORM_strx] ( indexed (00000002) string = "/home/test/splitCU")
+
+; The type unit
+CHECK:      .debug_types contents:
+CHECK:      DW_TAG_type_unit
+CHECK-NEXT: DW_AT_name [DW_FORM_strx] ( indexed (00000000) string = "Type_Unit")
+CHECK-NEXT: DW_AT_str_offsets_base [DW_FORM_sec_offset]       (0x00000030)
+CHECK:      DW_TAG_structure_type
+CHECK-NEXT: DW_AT_name [DW_FORM_strx] ( indexed (00000001) string = "MyStruct")
+
+; The split type unit
+CHECK:      .debug_types.dwo contents:
+CHECK:      DW_TAG_type_unit
+CHECK-NEXT: DW_AT_name [DW_FORM_strx] ( indexed (00000000) string = "V5_split_type_unit")
+CHECK-NEXT: DW_AT_str_offsets_base [DW_FORM_sec_offset]       (0x0000001c)
+CHECK:      DW_TAG_structure_type
+CHECK-NEXT: DW_AT_name [DW_FORM_strx] ( indexed (00000001) string = "V5_split_Mystruct")
+
+; The .debug_str_offsets section
+CHECK:      .debug_str_offsets contents:
+CHECK-NEXT: 0x00000000: Contribution size = 12, Version = 5
+CHECK-NEXT: 0x00000008: 00000000 "Handmade DWARF producer"
+CHECK-NEXT: 0x0000000c: 00000018 "Compile_Unit_1"
+CHECK-NEXT: 0x00000010: 00000027 "/home/test/CU1"
+CHECK-NEXT: 0x00000014: Contribution size = 12, Version = 5
+CHECK-NEXT: 0x0000001c: 00000000 "Handmade DWARF producer"
+CHECK-NEXT: 0x00000020: 00000036 "Compile_Unit_2"
+CHECK-NEXT: 0x00000024: 00000045 "/home/test/CU2"
+CHECK-NEXT: 0x00000028: Contribution size = 8, Version = 5
+CHECK-NEXT: 0x00000030: 00000054 "Type_Unit"
+CHECK-NEXT: 0x00000034: 0000005e "MyStruct"
+
+CHECK:      .debug_str_offsets.dwo contents:
+CHECK-NEXT: 0x00000000: Contribution size = 12, Version = 5
+CHECK-NEXT: 0x00000008: 00000000 "Handmade split DWARF producer"
+CHECK-NEXT: 0x0000000c: 0000001e "V5_split_compile_unit"
+CHECK-NEXT: 0x00000010: 00000034 "/home/test/splitCU"
+CHECK-NEXT: 0x00000014: Contribution size = 8, Version = 5
+CHECK-NEXT: 0x0000001c: 00000047 "V5_split_type_unit"
+CHECK-NEXT: 0x00000020: 0000005a "V5_split_Mystruct"

Modified: llvm/trunk/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-dwarfdump/llvm-dwarfdump.cpp?rev=304759&r1=304758&r2=304759&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-dwarfdump/llvm-dwarfdump.cpp (original)
+++ llvm/trunk/tools/llvm-dwarfdump/llvm-dwarfdump.cpp Mon Jun  5 20:22:34 2017
@@ -67,6 +67,7 @@ static cl::opt<DIDumpType> DumpType(
         clEnumValN(DIDT_GnuPubnames, "gnu_pubnames", ".debug_gnu_pubnames"),
         clEnumValN(DIDT_GnuPubtypes, "gnu_pubtypes", ".debug_gnu_pubtypes"),
         clEnumValN(DIDT_Str, "str", ".debug_str"),
+        clEnumValN(DIDT_StrOffsets, "str_offsets", ".debug_str_offsets"),
         clEnumValN(DIDT_StrDwo, "str.dwo", ".debug_str.dwo"),
         clEnumValN(DIDT_StrOffsetsDwo, "str_offsets.dwo",
                    ".debug_str_offsets.dwo"),

Modified: llvm/trunk/tools/obj2yaml/dwarf2yaml.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/obj2yaml/dwarf2yaml.cpp?rev=304759&r1=304758&r2=304759&view=diff
==============================================================================
--- llvm/trunk/tools/obj2yaml/dwarf2yaml.cpp (original)
+++ llvm/trunk/tools/obj2yaml/dwarf2yaml.cpp Mon Jun  5 20:22:34 2017
@@ -203,6 +203,7 @@ void dumpDebugInfo(DWARFContextInMemory
             case dwarf::DW_FORM_line_strp:
             case dwarf::DW_FORM_strp_sup:
             case dwarf::DW_FORM_GNU_str_index:
+            case dwarf::DW_FORM_strx:
               if (auto Val = FormValue.getValue().getAsCStringOffset())
                 NewValue.Value = Val.getValue();
               break;




More information about the llvm-commits mailing list