[llvm] r321295 - [DWARF v5] Rework of string offsets table reader

Wolfgang Pieb via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 21 11:38:13 PST 2017


Author: wolfgangp
Date: Thu Dec 21 11:38:13 2017
New Revision: 321295

URL: http://llvm.org/viewvc/llvm-project?rev=321295&view=rev
Log:
[DWARF v5] Rework of string offsets table reader

Reorganizes the DWARF consumer to derive the string offsets table 
contribution's format from the contribution header instead of 
(incorrectly) from the unit's format.

Reviewers: JDevliegehere, aprantl

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

Added:
    llvm/trunk/test/DebugInfo/X86/dwarfdump-str-offsets-invalid-6.s
Modified:
    llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h
    llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp
    llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp
    llvm/trunk/test/DebugInfo/X86/dwarfdump-str-offsets-dwp.s
    llvm/trunk/test/DebugInfo/X86/dwarfdump-str-offsets-invalid-3.s
    llvm/trunk/test/DebugInfo/X86/dwarfdump-str-offsets-invalid-4.s
    llvm/trunk/test/DebugInfo/X86/dwarfdump-str-offsets-macho.s
    llvm/trunk/test/DebugInfo/X86/dwarfdump-str-offsets.s

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=321295&r1=321294&r2=321295&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h Thu Dec 21 11:38:13 2017
@@ -165,6 +165,29 @@ struct BaseAddress {
   uint64_t SectionIndex;
 };
 
+/// Represents a unit's contribution to the string offsets table.
+struct StrOffsetsContributionDescriptor {
+  uint64_t Base = 0;
+  uint64_t Size = 0;
+  /// Format and version.
+  DWARFFormParams FormParams = {0, 0, dwarf::DwarfFormat::DWARF32};
+
+  StrOffsetsContributionDescriptor(uint64_t Base, uint64_t Size,
+                                   uint8_t Version, dwarf::DwarfFormat Format)
+      : Base(Base), Size(Size), FormParams({Version, 0, Format}) {}
+
+  uint8_t getVersion() const { return FormParams.Version; }
+  dwarf::DwarfFormat getFormat() const { return FormParams.Format; }
+  uint8_t getDwarfOffsetByteSize() const {
+    return FormParams.getDwarfOffsetByteSize();
+  }
+  /// Determine whether a contribution to the string offsets table is
+  /// consistent with the relevant section size and that its length is
+  /// a multiple of the size of one of its entries.
+  Optional<StrOffsetsContributionDescriptor>
+  validateContributionSize(DWARFDataExtractor &DA);
+};
+
 class DWARFUnit {
   DWARFContext &Context;
   /// Section containing this DWARFUnit.
@@ -176,7 +199,6 @@ class DWARFUnit {
   const DWARFSection &LineSection;
   StringRef StringSection;
   const DWARFSection &StringOffsetSection;
-  uint64_t StringOffsetSectionBase = 0;
   const DWARFSection *AddrOffsetSection;
   uint32_t AddrOffsetSectionBase = 0;
   bool isLittleEndian;
@@ -185,6 +207,9 @@ class DWARFUnit {
 
   // Version, address size, and DWARF format.
   DWARFFormParams FormParams;
+  /// Start, length, and DWARF format of the unit's contribution to the string
+  /// offsets table (DWARF v5).
+  Optional<StrOffsetsContributionDescriptor> StringOffsetsTableContribution;
 
   uint32_t Offset;
   uint32_t Length;
@@ -219,6 +244,21 @@ protected:
   /// Size in bytes of the unit header.
   virtual uint32_t getHeaderSize() const { return getVersion() <= 4 ? 11 : 12; }
 
+  /// Find the unit's contribution to the string offsets table and determine its
+  /// length and form. The given offset is expected to be derived from the unit
+  /// DIE's DW_AT_str_offsets_base attribute.
+  Optional<StrOffsetsContributionDescriptor>
+  determineStringOffsetsTableContribution(DWARFDataExtractor &DA,
+                                          uint64_t Offset);
+
+  /// Find the unit's contribution to the string offsets table and determine its
+  /// length and form. The given offset is expected to be 0 in a dwo file or,
+  /// in a dwp file, the start of the unit's contribution to the string offsets
+  /// table section (as determined by the index table).
+  Optional<StrOffsetsContributionDescriptor>
+  determineStringOffsetsTableContributionDWO(DWARFDataExtractor &DA,
+                                             uint64_t Offset);
+
 public:
   DWARFUnit(DWARFContext &Context, const DWARFSection &Section,
             const DWARFDebugAbbrev *DA, const DWARFSection *RS, StringRef SS,
@@ -272,6 +312,10 @@ public:
   uint32_t getNextUnitOffset() const { return Offset + Length + 4; }
   uint32_t getLength() const { return Length; }
 
+  const Optional<StrOffsetsContributionDescriptor> &
+  getStringOffsetsTableContribution() const {
+    return StringOffsetsTableContribution;
+  }
   const DWARFFormParams &getFormParams() const { return FormParams; }
   uint16_t getVersion() const { return FormParams.Version; }
   dwarf::DwarfFormat getFormat() const { return FormParams.Format; }
@@ -281,6 +325,16 @@ public:
     return FormParams.getDwarfOffsetByteSize();
   }
 
+  uint8_t getDwarfStringOffsetsByteSize() const {
+    assert(StringOffsetsTableContribution);
+    return StringOffsetsTableContribution->getDwarfOffsetByteSize();
+  }
+
+  uint64_t getStringOffsetsBase() const {
+    assert(StringOffsetsTableContribution);
+    return StringOffsetsTableContribution->Base;
+  }
+
   const DWARFAbbreviationDeclarationSet *getAbbreviations() const;
 
   uint8_t getUnitType() const { return UnitType; }

Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp?rev=321295&r1=321294&r2=321295&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp Thu Dec 21 11:38:13 2017
@@ -88,70 +88,101 @@ static void dumpUUID(raw_ostream &OS, co
   }
 }
 
-static void
-dumpDWARFv5StringOffsetsSection(raw_ostream &OS, StringRef SectionName,
-                                const DWARFObject &Obj,
-                                const DWARFSection &StringOffsetsSection,
-                                StringRef StringSection, bool LittleEndian) {
+using ContributionCollection =
+    std::vector<Optional<StrOffsetsContributionDescriptor>>;
+
+// Collect all the contributions to the string offsets table from all units,
+// sort them by their starting offsets and remove duplicates.
+static ContributionCollection
+collectContributionData(DWARFContext::cu_iterator_range CUs,
+                        DWARFContext::tu_section_iterator_range TUSs) {
+  ContributionCollection Contributions;
+  for (const auto &CU : CUs)
+    Contributions.push_back(CU->getStringOffsetsTableContribution());
+  for (const auto &TUS : TUSs)
+    for (const auto &TU : TUS)
+      Contributions.push_back(TU->getStringOffsetsTableContribution());
+
+  // Sort the contributions so that any invalid ones are placed at
+  // the start of the contributions vector. This way they are reported
+  // first.
+  std::sort(Contributions.begin(), Contributions.end(),
+            [](const Optional<StrOffsetsContributionDescriptor> &L,
+               const Optional<StrOffsetsContributionDescriptor> &R) {
+              if (L && R) return L->Base < R->Base;
+              return R.hasValue();
+            });
+
+  // Uniquify contributions, as it is possible that units (specifically
+  // type units in dwo or dwp files) share contributions. We don't want
+  // to report them more than once.
+  Contributions.erase(
+      std::unique(Contributions.begin(), Contributions.end(),
+                  [](const Optional<StrOffsetsContributionDescriptor> &L,
+                     const Optional<StrOffsetsContributionDescriptor> &R) {
+                    if (L && R)
+                      return L->Base == R->Base && L->Size == R->Size;
+                    return false;
+                  }),
+      Contributions.end());
+  return Contributions;
+}
+
+static void dumpDWARFv5StringOffsetsSection(
+    raw_ostream &OS, StringRef SectionName, const DWARFObject &Obj,
+    const DWARFSection &StringOffsetsSection, StringRef StringSection,
+    DWARFContext::cu_iterator_range CUs,
+    DWARFContext::tu_section_iterator_range TUSs, bool LittleEndian) {
+  auto Contributions = collectContributionData(CUs, TUSs);
   DWARFDataExtractor StrOffsetExt(Obj, StringOffsetsSection, LittleEndian, 0);
-  uint32_t Offset = 0;
+  DataExtractor StrData(StringSection, LittleEndian, 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) {
+  uint32_t Offset = 0;
+  for (auto &Contribution : Contributions) {
+    // Report an ill-formed contribution.
+    if (!Contribution) {
       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";
+    dwarf::DwarfFormat Format = Contribution->getFormat();
+    uint16_t Version = Contribution->getVersion();
+    uint64_t ContributionHeader = Contribution->Base;
+    // In DWARF v5 there is a contribution header that immediately precedes
+    // the string offsets base (the location we have previously retrieved from
+    // the CU DIE's DW_AT_str_offsets attribute). The header is located either
+    // 8 or 16 bytes before the base, depending on the contribution's format.
+    if (Version >= 5)
+      ContributionHeader -= Format == DWARF32 ? 8 : 16;
+
+    // Detect overlapping contributions.
+    if (Offset > ContributionHeader) {
+      OS << "error: overlapping contributions to string offsets table in "
+            "section ."
+         << SectionName << ".\n";
       return;
     }
-
-    Version = StrOffsetExt.getU16(&Offset);
-    Offset += 2;
-    OS << format("0x%8.8x: ", ContributionStart);
-    OS << "Contribution size = " << ContributionSize
+    // Report a gap in the table.
+    if (Offset < ContributionHeader) {
+      OS << format("0x%8.8x: Gap, length = ", Offset);
+      OS << (ContributionHeader - Offset) << "\n";
+    }
+    OS << format("0x%8.8x: ", ContributionHeader);
+    OS << "Contribution size = " << Contribution->Size
+       << ", Format = " << (Format == DWARF32 ? "DWARF32" : "DWARF64")
        << ", Version = " << Version << "\n";
 
-    uint32_t ContributionBase = Offset;
-    DataExtractor StrData(StringSection, LittleEndian, 0);
-    while (Offset - ContributionBase < ContributionSize) {
+    Offset = Contribution->Base;
+    unsigned EntrySize = Contribution->getDwarfOffsetByteSize();
+    while (Offset - Contribution->Base < Contribution->Size) {
       OS << format("0x%8.8x: ", Offset);
-      // FIXME: We can only extract strings in DWARF32 format at the moment.
+      // FIXME: We can only extract strings if the offset fits in 32 bits.
       uint64_t StringOffset =
           StrOffsetExt.getRelocatedValue(EntrySize, &Offset);
-      if (Format == DWARF32) {
+      // Extract the string if we can and display it. Otherwise just report
+      // the offset.
+      if (StringOffset <= std::numeric_limits<uint32_t>::max()) {
         uint32_t StringOffset32 = (uint32_t)StringOffset;
         OS << format("%8.8x ", StringOffset32);
         const char *S = StrData.getCStr(&StringOffset32);
@@ -162,6 +193,11 @@ dumpDWARFv5StringOffsetsSection(raw_ostr
       OS << "\n";
     }
   }
+  // Report a gap at the end of the table.
+  if (Offset < SectionSize) {
+    OS << format("0x%8.8x: Gap, length = ", Offset);
+    OS << (SectionSize - Offset) << "\n";
+  }
 }
 
 // Dump a DWARF string offsets section. This may be a DWARF v5 formatted
@@ -170,17 +206,18 @@ dumpDWARFv5StringOffsetsSection(raw_ostr
 // 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 DWARFObject &Obj,
-                                     const DWARFSection &StringOffsetsSection,
-                                     StringRef StringSection, bool LittleEndian,
-                                     unsigned MaxVersion) {
+static void dumpStringOffsetsSection(
+    raw_ostream &OS, StringRef SectionName, const DWARFObject &Obj,
+    const DWARFSection &StringOffsetsSection, StringRef StringSection,
+    DWARFContext::cu_iterator_range CUs,
+    DWARFContext::tu_section_iterator_range TUSs, bool LittleEndian,
+    unsigned MaxVersion) {
   // 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, Obj, StringOffsetsSection,
-                                    StringSection, LittleEndian);
+                                    StringSection, CUs, TUSs, LittleEndian);
   else {
     DataExtractor strOffsetExt(StringOffsetsSection.Data, LittleEndian, 0);
     uint32_t offset = 0;
@@ -468,12 +505,14 @@ void DWARFContext::dump(
                  DObj->getStringOffsetSection().Data))
     dumpStringOffsetsSection(
         OS, "debug_str_offsets", *DObj, DObj->getStringOffsetSection(),
-        DObj->getStringSection(), isLittleEndian(), getMaxVersion());
+        DObj->getStringSection(), compile_units(), type_unit_sections(),
+        isLittleEndian(), getMaxVersion());
   if (shouldDump(ExplicitDWO, ".debug_str_offsets.dwo", DIDT_ID_DebugStrOffsets,
                  DObj->getStringOffsetDWOSection().Data))
     dumpStringOffsetsSection(
         OS, "debug_str_offsets.dwo", *DObj, DObj->getStringOffsetDWOSection(),
-        DObj->getStringDWOSection(), isLittleEndian(), getMaxVersion());
+        DObj->getStringDWOSection(), dwo_compile_units(),
+        dwo_type_unit_sections(), isLittleEndian(), getMaxVersion());
 
   if (shouldDump(Explicit, ".gnu_index", DIDT_ID_GdbIndex,
                  DObj->getGdbIndexSection())) {

Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp?rev=321295&r1=321294&r2=321295&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp Thu Dec 21 11:38:13 2017
@@ -79,8 +79,10 @@ bool DWARFUnit::getAddrOffsetSectionItem
 
 bool DWARFUnit::getStringOffsetSectionItem(uint32_t Index,
                                            uint64_t &Result) const {
-  unsigned ItemSize = getDwarfOffsetByteSize();
-  uint32_t Offset = StringOffsetSectionBase + Index * ItemSize;
+  if (!StringOffsetsTableContribution)
+    return false;
+  unsigned ItemSize = getDwarfStringOffsetsByteSize();
+  uint32_t Offset = getStringOffsetsBase() + Index * ItemSize;
   if (StringOffsetSection.Data.size() < Offset + ItemSize)
     return false;
   DWARFDataExtractor DA(Context.getDWARFObj(), StringOffsetSection,
@@ -251,15 +253,28 @@ size_t DWARFUnit::extractDIEsIfNeeded(bo
       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);
+    // In general, in DWARF v5 and beyond we derive the start of the unit's
+    // contribution to the string offsets table from the unit DIE's
+    // DW_AT_str_offsets_base attribute. Split DWARF units do not use this
+    // attribute, so we assume that there is a contribution to the string
+    // offsets table starting at offset 0 of the debug_str_offsets.dwo section.
+    // In both cases we need to determine the format of the contribution,
+    // which may differ from the unit's format.
+    uint64_t StringOffsetsContributionBase =
+        isDWO ? 0 : toSectionOffset(UnitDie.find(DW_AT_str_offsets_base), 0);
     if (IndexEntry)
       if (const auto *C = IndexEntry->getOffset(DW_SECT_STR_OFFSETS))
-        StringOffsetSectionBase += C->Offset;
+        StringOffsetsContributionBase += C->Offset;
+
+    DWARFDataExtractor DA(Context.getDWARFObj(), StringOffsetSection,
+                          isLittleEndian, 0);
+    if (isDWO)
+      StringOffsetsTableContribution =
+          determineStringOffsetsTableContributionDWO(
+              DA, StringOffsetsContributionBase);
+    else if (getVersion() >= 5)
+      StringOffsetsTableContribution = determineStringOffsetsTableContribution(
+          DA, StringOffsetsContributionBase);
 
     // 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.
@@ -466,3 +481,89 @@ const DWARFAbbreviationDeclarationSet *D
     Abbrevs = Abbrev->getAbbreviationDeclarationSet(AbbrOffset);
   return Abbrevs;
 }
+
+Optional<StrOffsetsContributionDescriptor>
+StrOffsetsContributionDescriptor::validateContributionSize(
+    DWARFDataExtractor &DA) {
+  uint8_t EntrySize = getDwarfOffsetByteSize();
+  // In order to ensure that we don't read a partial record at the end of
+  // the section we validate for a multiple of the entry size.
+  uint64_t ValidationSize = alignTo(Size, EntrySize);
+  // Guard against overflow.
+  if (ValidationSize >= Size)
+    if (DA.isValidOffsetForDataOfSize((uint32_t)Base, ValidationSize))
+      return *this;
+  return Optional<StrOffsetsContributionDescriptor>();
+}
+
+// Look for a DWARF64-formatted contribution to the string offsets table
+// starting at a given offset and record it in a descriptor.
+static Optional<StrOffsetsContributionDescriptor>
+parseDWARF64StringOffsetsTableHeader(DWARFDataExtractor &DA, uint32_t Offset) {
+  if (!DA.isValidOffsetForDataOfSize(Offset, 16))
+    return Optional<StrOffsetsContributionDescriptor>();
+
+  if (DA.getU32(&Offset) != 0xffffffff)
+    return Optional<StrOffsetsContributionDescriptor>();
+
+  uint64_t Size = DA.getU64(&Offset);
+  uint8_t Version = DA.getU16(&Offset);
+  (void)DA.getU16(&Offset); // padding
+  return StrOffsetsContributionDescriptor(Offset, Size, Version, DWARF64);
+  //return Optional<StrOffsetsContributionDescriptor>(Descriptor);
+}
+
+// Look for a DWARF32-formatted contribution to the string offsets table
+// starting at a given offset and record it in a descriptor.
+static Optional<StrOffsetsContributionDescriptor>
+parseDWARF32StringOffsetsTableHeader(DWARFDataExtractor &DA, uint32_t Offset) {
+  if (!DA.isValidOffsetForDataOfSize(Offset, 8))
+    return Optional<StrOffsetsContributionDescriptor>();
+  uint32_t ContributionSize = DA.getU32(&Offset);
+  if (ContributionSize >= 0xfffffff0)
+    return Optional<StrOffsetsContributionDescriptor>();
+  uint8_t Version = DA.getU16(&Offset);
+  (void)DA.getU16(&Offset); // padding
+  return StrOffsetsContributionDescriptor(Offset, ContributionSize, Version, DWARF32);
+  //return Optional<StrOffsetsContributionDescriptor>(Descriptor);
+}
+
+Optional<StrOffsetsContributionDescriptor>
+DWARFUnit::determineStringOffsetsTableContribution(DWARFDataExtractor &DA,
+                                                   uint64_t Offset) {
+  Optional<StrOffsetsContributionDescriptor> Descriptor;
+  // Attempt to find a DWARF64 contribution 16 bytes before the base.
+  if (Offset >= 16)
+    Descriptor =
+        parseDWARF64StringOffsetsTableHeader(DA, (uint32_t)Offset - 16);
+  // Try to find a DWARF32 contribution 8 bytes before the base.
+  if (!Descriptor && Offset >= 8)
+    Descriptor = parseDWARF32StringOffsetsTableHeader(DA, (uint32_t)Offset - 8);
+  return Descriptor ? Descriptor->validateContributionSize(DA) : Descriptor;
+}
+
+Optional<StrOffsetsContributionDescriptor>
+DWARFUnit::determineStringOffsetsTableContributionDWO(DWARFDataExtractor &DA,
+                                                      uint64_t Offset) {
+  if (getVersion() >= 5) {
+    // Look for a valid contribution at the given offset.
+    auto Descriptor =
+        parseDWARF64StringOffsetsTableHeader(DA, (uint32_t)Offset);
+    if (!Descriptor)
+      Descriptor = parseDWARF32StringOffsetsTableHeader(DA, (uint32_t)Offset);
+    return Descriptor ? Descriptor->validateContributionSize(DA) : Descriptor;
+  }
+  // Prior to DWARF v5, we derive the contribution size from the
+  // index table (in a package file). In a .dwo file it is simply
+  // the length of the string offsets section.
+  uint64_t Size = 0;
+  if (!IndexEntry)
+    Size = StringOffsetSection.Data.size();
+  else if (const auto *C = IndexEntry->getOffset(DW_SECT_STR_OFFSETS))
+    Size = C->Length;
+  // Return a descriptor with the given offset as base, version 4 and
+  // DWARF32 format.
+  //return Optional<StrOffsetsContributionDescriptor>(
+      //StrOffsetsContributionDescriptor(Offset, Size, 4, DWARF32));
+  return StrOffsetsContributionDescriptor(Offset, Size, 4, DWARF32);
+}

Modified: llvm/trunk/test/DebugInfo/X86/dwarfdump-str-offsets-dwp.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/X86/dwarfdump-str-offsets-dwp.s?rev=321295&r1=321294&r2=321295&view=diff
==============================================================================
--- llvm/trunk/test/DebugInfo/X86/dwarfdump-str-offsets-dwp.s (original)
+++ llvm/trunk/test/DebugInfo/X86/dwarfdump-str-offsets-dwp.s Thu Dec 21 11:38:13 2017
@@ -2,9 +2,10 @@
 # RUN: llvm-dwarfdump -v %t.o | FileCheck %s
 
 # 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 
+# offset tables. We have 3 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.
+# file, and CU3 from a third object file that was compiled with 
+# -gdwarf-4.
 #
         .section .debug_str.dwo,"MS", at progbits,1
 str_producer:
@@ -25,56 +26,50 @@ str_TU2:
         .asciz "Type_Unit_2"
 str_TU2_type:
         .asciz "MyStruct_2"
+str_CU3:
+        .asciz "Compile_Unit_3"
+str_CU3_dir:
+        .asciz "/home/test/CU3"
 
         .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
+# CU1 and TU1 share a contribution to the string offsets table.
+.debug_str_offsets_object_file1_start:
+        .long .debug_str_offsets_object_file1_end-.debug_str_offsets_base_1
         .short 5    # DWARF version
         .short 0    # Padding
-.debug_str_offsets_base_CU1:
+.debug_str_offsets_base_1:
         .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:
+.debug_str_offsets_object_file1_end:
 
 # 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
+# CU2 and TU2 share a contribution to the string offsets table.
+.debug_str_offsets_object_file2_start:
+        .long .debug_str_offsets_object_file2_end-.debug_str_offsets_base_2
         .short 5    # DWARF version
         .short 0    # Padding
-.debug_str_offsets_base_CU2:
+.debug_str_offsets_base_2:
         .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:
+.debug_str_offsets_object_file2_end:
 
+# Object files 3's portion of the .debug_str_offsets.dwo section.
+# This file is assumed to have been compiled with -gdwarf-4 and
+# therefore contains a version 4 CU and a GNU format contribution
+# to the .debug_str_offsets section.
+.debug_str_offsets_object_file3_start:
+.debug_str_offsets_base_3:
+        .long str_producer-.debug_str.dwo
+        .long str_CU3-.debug_str.dwo
+        .long str_CU3_dir-.debug_str.dwo
+.debug_str_offsets_object_file3_end:
 
 # Abbrevs are shared for all compile and type units
         .section .debug_abbrev.dwo,"", at progbits
@@ -85,8 +80,6 @@ str_TU2_type:
         .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)
@@ -96,8 +89,6 @@ str_TU2_type:
         .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
@@ -107,6 +98,17 @@ str_TU2_type:
         .byte 0x1a  # DW_FORM_strx
         .byte 0x00  # EOM(1)
         .byte 0x00  # EOM(2)
+        .byte 0x04  # Abbrev code
+        .byte 0x11  # DW_TAG_compile_unit
+        .byte 0x00  # DW_CHILDREN_no
+        .byte 0x25  # DW_AT_producer
+        .short 0x3e82  # DW_FORM_GNU_str_index
+        .byte 0x03  # DW_AT_name
+        .short 0x3e82  # DW_FORM_GNU_str_index
+        .byte 0x03  # DW_AT_name
+        .short 0x3e82  # DW_FORM_GNU_str_index
+        .byte 0x00  # EOM(1)
+        .byte 0x00  # EOM(2)
         .byte 0x00  # EOM(3)
 abbrev_end:
 
@@ -120,15 +122,11 @@ CU1_5_version:
         .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.
+# The compile-unit DIE, which has a DW_AT_producer, DW_AT_name
+# 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:
@@ -140,19 +138,30 @@ CU2_5_version:
         .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.
+# The compile-unit DIE, which has a DW_AT_producer, DW_AT_name
+# 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:
 
+CU3_4_start:
+        .long  CU3_4_end-CU3_4_version  # Length of Unit
+CU3_4_version:
+        .short 4               # DWARF version number
+        .long .debug_abbrev.dwo # Offset Into Abbrev. Section
+        .byte 8                # Address Size (in bytes)
+# The compile-unit DIE, which has a DW_AT_producer, DW_AT_name
+# and DW_AT_compdir.
+        .byte 4                # Abbreviation code
+        .byte 0                # The index of the producer string
+        .byte 1                # The index of the CU name string
+        .byte 2                # The index of the comp dir string
+        .byte 0 # NULL
+CU3_4_end:
+
         .section .debug_types.dwo,"", at progbits
 # DWARF v5 Type unit header.
 TU1_5_start:
@@ -166,15 +175,11 @@ TU1_5_version:
         .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
+        .byte 3                # Index of the unit type name string
 # The type DIE, which has a name.
 TU1_5_type:
         .byte 3                # Abbreviation code
-        .byte 1                # Index of the type name string
+        .byte 4                # Index of the type name string
         .byte 0 # NULL
         .byte 0 # NULL
 TU1_5_end:
@@ -190,15 +195,11 @@ TU2_5_version:
         .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
+        .byte 3                # Index of the unit type name string
 # The type DIE, which has a name.
 TU2_5_type:
         .byte 3                # Abbreviation code
-        .byte 1                # Index of the type name string
+        .byte 4                # Index of the type name string
         .byte 0 # NULL
         .byte 0 # NULL
 TU2_5_end:
@@ -207,37 +208,45 @@ TU2_5_end:
         # 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
+        .long 3                # number of units
+        .long 3                # number of hash buckets in table
 
-        # The signatures for both CUs.
+        # The signatures for all CUs.
         .quad 0xddeeaaddbbaabbee # signature 1
         .quad 0xff00ffeeffaaff00 # signature 2
+        .quad 0xf00df00df00df00d # signature 2
         # The indexes for both CUs.
         .long 1                # index 1
         .long 2                # index 2
-        # The sections to which both CUs contribute.
+        .long 3                # index 3
+        # The sections to which all 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,
+        # The starting offsets of all 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 .debug_str_offsets_object_file1_start-.debug_str_offsets.dwo
         .long CU2_5_start-.debug_info.dwo
         .long 0
-        .long .debug_str_offsets_object_file2-.debug_str_offsets.dwo
+        .long .debug_str_offsets_object_file2_start-.debug_str_offsets.dwo
+        .long CU3_4_start-.debug_info.dwo
+        .long 0
+        .long .debug_str_offsets_object_file3_start-.debug_str_offsets.dwo
 
-        # The lengths of both CU's contributions to info, abbrev and
+        # The lengths of all 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 .debug_str_offsets_object_file1_end-.debug_str_offsets_object_file1_start
         .long CU2_5_end-CU2_5_start
         .long abbrev_end-.debug_abbrev.dwo
-        .long .debug_str_offsets_end_CU2-.debug_str_offsets_start_CU2
+        .long .debug_str_offsets_object_file2_end-.debug_str_offsets_object_file2_start
+        .long CU3_4_end-CU3_4_start
+        .long abbrev_end-.debug_abbrev.dwo
+        .long .debug_str_offsets_object_file3_end-.debug_str_offsets_object_file3_start
 
         .section .debug_tu_index,"", at progbits
         # The index header
@@ -261,19 +270,19 @@ TU2_5_end:
         # 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 .debug_str_offsets_object_file1_start-.debug_str_offsets.dwo
         .long TU2_5_start-.debug_types.dwo
         .long 0
-        .long .debug_str_offsets_object_file2-.debug_str_offsets.dwo
+        .long .debug_str_offsets_object_file2_start-.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 .debug_str_offsets_object_file1_end-.debug_str_offsets_object_file1_start
         .long TU2_5_end-TU2_5_start
         .long abbrev_end-.debug_abbrev.dwo
-        .long .debug_str_offsets_end_TU2-.debug_str_offsets_start_TU2
+        .long .debug_str_offsets_object_file2_end-.debug_str_offsets_object_file2_start
 
 
 # Verify that the correct strings from each unit are displayed and that the
@@ -284,7 +293,6 @@ TU2_5_end:
 # 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_name [DW_FORM_strx] ( indexed (00000002) string = "/home/test/CU1")
 # CHECK-NOT:  NULL
 
@@ -293,26 +301,23 @@ TU2_5_end:
 # 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] (0x00000008)
 # CHECK-NEXT: DW_AT_name [DW_FORM_strx] ( indexed (00000002) string = "/home/test/CU2")
 # 
 # CHECK:      Type Unit
 # CHECK-NOT:  NULL
 # CHECK:      DW_TAG_type_unit
-# CHECK-NEXT: DW_AT_name [DW_FORM_strx] ( indexed (00000000) string = "Type_Unit_1")
-# CHECK-NEXT: DW_AT_str_offsets_base [DW_FORM_sec_offset] (0x0000001c)
+# CHECK-NEXT: DW_AT_name [DW_FORM_strx] ( indexed (00000003) string = "Type_Unit_1")
 # CHECK-NOT:  NULL
 # CHECK:      DW_TAG_structure_type
-# CHECK-NEXT: DW_AT_name [DW_FORM_strx] ( indexed (00000001) string = "MyStruct_1")
+# CHECK-NEXT: DW_AT_name [DW_FORM_strx] ( indexed (00000004) string = "MyStruct_1")
 #
 # CHECK:      Type Unit
 # CHECK-NOT:  NULL
 # CHECK:      DW_TAG_type_unit
-# CHECK-NEXT: DW_AT_name [DW_FORM_strx] ( indexed (00000000) string = "Type_Unit_2")
-# CHECK-NEXT: DW_AT_str_offsets_base [DW_FORM_sec_offset] (0x0000001c)
+# CHECK-NEXT: DW_AT_name [DW_FORM_strx] ( indexed (00000003) string = "Type_Unit_2")
 # CHECK-NOT:  NULL
 # CHECK:      DW_TAG_structure_type
-# CHECK-NEXT: DW_AT_name [DW_FORM_strx] ( indexed (00000001) string = "MyStruct_2")
+# CHECK-NEXT: DW_AT_name [DW_FORM_strx] ( indexed (00000004) string = "MyStruct_2")
 
 # Verify the correct offets of the compile and type units contributions in the
 # index tables.
@@ -322,11 +327,11 @@ TU2_5_end:
 # CHECK:      1 0xddeeaaddbbaabbee [{{0x[0-9a-f]*, 0x[0-9a-f]*}}) [{{0x[0-9a-f]*, 0x[0-9a-f]*}})
 # CHECK-SAME: [0x00000000
 # CHECK-NEXT: 2 0xff00ffeeffaaff00 [{{0x[0-9a-f]*, 0x[0-9a-f]*}}) [{{0x[0-9a-f]*, 0x[0-9a-f]*}})
-# CHECK-SAME: [0x00000024
+# CHECK-SAME: [0x0000001c
 
 # CHECK:      .debug_tu_index contents:
 # CHECK-NOT:  contents:
 # CHECK:      1 0xeeaaddbbaabbeedd [{{0x[0-9a-f]*, 0x[0-9a-f]*}}) [{{0x[0-9a-f]*, 0x[0-9a-f]*}})
 # CHECK-SAME: [0x00000000
 # CHECK-NEXT: 2 0x00ffeeffaaff00ff [{{0x[0-9a-f]*, 0x[0-9a-f]*}}) [{{0x[0-9a-f]*, 0x[0-9a-f]*}})
-# CHECK:      [0x00000024
+# CHECK:      [0x0000001c

Modified: llvm/trunk/test/DebugInfo/X86/dwarfdump-str-offsets-invalid-3.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/X86/dwarfdump-str-offsets-invalid-3.s?rev=321295&r1=321294&r2=321295&view=diff
==============================================================================
--- llvm/trunk/test/DebugInfo/X86/dwarfdump-str-offsets-invalid-3.s (original)
+++ llvm/trunk/test/DebugInfo/X86/dwarfdump-str-offsets-invalid-3.s Thu Dec 21 11:38:13 2017
@@ -37,6 +37,8 @@ dwo_str_TU_5_type:
         .byte 0x01  # Abbrev code
         .byte 0x11  # DW_TAG_compile_unit
         .byte 0x00  # DW_CHILDREN_no
+        .byte 0x72  # DW_AT_str_offsets_base
+        .byte 0x17  # DW_FORM_sec_offset
         .byte 0x00  # EOM(1)
         .byte 0x00  # EOM(2)
         .byte 0x00  # EOM(3)
@@ -54,13 +56,13 @@ CU1_5_version:
         .long .debug_abbrev    # Offset Into Abbrev. Section
 # A compile-unit DIE, which has no attributes.
         .byte 1                # Abbreviation code
+        .long .debug_str_offsets_base0
 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:

Modified: llvm/trunk/test/DebugInfo/X86/dwarfdump-str-offsets-invalid-4.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/X86/dwarfdump-str-offsets-invalid-4.s?rev=321295&r1=321294&r2=321295&view=diff
==============================================================================
--- llvm/trunk/test/DebugInfo/X86/dwarfdump-str-offsets-invalid-4.s (original)
+++ llvm/trunk/test/DebugInfo/X86/dwarfdump-str-offsets-invalid-4.s Thu Dec 21 11:38:13 2017
@@ -15,6 +15,8 @@ str_CU1:
         .byte 0x01  # Abbrev code
         .byte 0x11  # DW_TAG_compile_unit
         .byte 0x00  # DW_CHILDREN_no
+        .byte 0x72  # DW_AT_str_offsets_base
+        .byte 0x17  # DW_FORM_sec_offset
         .byte 0x00  # EOM(1)
         .byte 0x00  # EOM(2)
         .byte 0x00  # EOM(3)
@@ -32,6 +34,7 @@ CU1_5_version:
         .long .debug_abbrev    # Offset Into Abbrev. Section
 # A compile-unit DIE, which has no attributes.
         .byte 1                # Abbreviation code
+        .long .debug_str_offsets_base0
 CU1_5_end:
 
 # Every unit contributes to the string_offsets table.
@@ -50,4 +53,4 @@ CU1_5_end:
 
 # INVALIDLENGTH:             .debug_str_offsets contents:
 # INVALIDLENGTH-NOT:         contents:
-# INVALIDLENGTH:             error: contribution to string offsets table in section .debug_str_offsets has invalid length.
+# INVALIDLENGTH:             error: invalid contribution to string offsets table in section .debug_str_offsets.

Added: llvm/trunk/test/DebugInfo/X86/dwarfdump-str-offsets-invalid-6.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/X86/dwarfdump-str-offsets-invalid-6.s?rev=321295&view=auto
==============================================================================
--- llvm/trunk/test/DebugInfo/X86/dwarfdump-str-offsets-invalid-6.s (added)
+++ llvm/trunk/test/DebugInfo/X86/dwarfdump-str-offsets-invalid-6.s Thu Dec 21 11:38:13 2017
@@ -0,0 +1,94 @@
+# RUN: llvm-mc -triple x86_64-unknown-linux %s -filetype=obj -o %t.o
+# RUN: llvm-dwarfdump -v %t.o | FileCheck --check-prefix=OVERLAP %s
+#
+# Test object to verify that llvm-dwarfdump handles an invalid string offsets
+# table with overlapping contributions.
+
+        .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 0x72  # DW_AT_str_offsets_base
+        .byte 0x17  # DW_FORM_sec_offset
+        .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
+# A compile-unit DIE, which has no attributes.
+        .byte 1                # Abbreviation code
+        .long .debug_str_offsets_base0
+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
+# A compile-unit DIE, which has no attributes.
+        .byte 1                # Abbreviation code
+        .long .debug_str_offsets_base1
+CU2_5_end:
+
+        .section .debug_str_offsets,"", at progbits
+# CU1's contribution
+        .long .debug_str_offsets_segment1_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
+# Overlapping with CU1'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:
+
+# OVERLAP:            .debug_str_offsets contents:
+# OVERLAP-NOT:        contents:
+# OVERLAP:            error: overlapping contributions to string offsets table in section .debug_str_offsets.

Modified: llvm/trunk/test/DebugInfo/X86/dwarfdump-str-offsets-macho.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/X86/dwarfdump-str-offsets-macho.s?rev=321295&r1=321294&r2=321295&view=diff
==============================================================================
--- llvm/trunk/test/DebugInfo/X86/dwarfdump-str-offsets-macho.s (original)
+++ llvm/trunk/test/DebugInfo/X86/dwarfdump-str-offsets-macho.s Thu Dec 21 11:38:13 2017
@@ -43,14 +43,17 @@ Ldebug_str_offsets_base0:
         .long str_Variable2
         .long str_Variable3
 Ldebug_str_offsets_segment0_end:
-# CU2's contribution
-        .long Ldebug_str_offsets_segment1_end-Ldebug_str_offsets_base1
+# A 4-byte gap.
+        .long 0
+# CU2's contribution (DWARF64 format)
+        .long 0xffffffff
+        .quad Ldebug_str_offsets_segment1_end-Ldebug_str_offsets_base1
         .short 5    # DWARF version
         .short 0    # Padding
 Ldebug_str_offsets_base1:
-        .long str_producer
-        .long str_CU2
-        .long str_CU2_dir
+        .quad str_producer
+        .quad str_CU2
+        .quad str_CU2_dir
 Ldebug_str_offsets_segment1_end:
 # The TU's contribution
         .long Ldebug_str_offsets_segment2_end-Ldebug_str_offsets_base2
@@ -234,20 +237,20 @@ TU_5_end:
 # COMMON:      DW_TAG_compile_unit
 # COMMON-NEXT: DW_AT_producer [DW_FORM_strx] ( indexed (00000000) string = "Handmade DWARF producer")
 # COMMON-NEXT: DW_AT_name [DW_FORM_strx] ( indexed (00000001) string = "Compile_Unit_2")
-# COMMON-NEXT: DW_AT_str_offsets_base [DW_FORM_sec_offset] (0x0000002c)
+# COMMON-NEXT: DW_AT_str_offsets_base [DW_FORM_sec_offset] (0x00000038)
 # COMMON-NEXT: DW_AT_comp_dir [DW_FORM_strx] ( indexed (00000002) string = "/home/test/CU2")
 # 
 # The type unit
 # COMMON:      .debug_types contents:
 # COMMON:      DW_TAG_type_unit
 # COMMON-NEXT: DW_AT_name [DW_FORM_strx] ( indexed (00000000) string = "Type_Unit")
-# COMMON-NEXT: DW_AT_str_offsets_base [DW_FORM_sec_offset]       (0x00000040)
+# COMMON-NEXT: DW_AT_str_offsets_base [DW_FORM_sec_offset]       (0x00000058)
 # COMMON:      DW_TAG_structure_type
 # COMMON-NEXT: DW_AT_name [DW_FORM_strx] ( indexed (00000001) string = "MyStruct")
 # 
 # The .debug_str_offsets section
 # COMMON:      .debug_str_offsets contents:
-# COMMON-NEXT: 0x00000000: Contribution size = 28, Version = 5
+# COMMON-NEXT: 0x00000000: Contribution size = 28, Format = DWARF32, Version = 5
 # COMMON-NEXT: 0x00000008: 00000000 "Handmade DWARF producer"
 # COMMON-NEXT: 0x0000000c: 00000018 "Compile_Unit_1"
 # COMMON-NEXT: 0x00000010: 00000027 "/home/test/CU1"
@@ -255,10 +258,11 @@ TU_5_end:
 # COMMON-NEXT: 0x00000018: 0000006e "MyVar1"
 # COMMON-NEXT: 0x0000001c: 00000075 "MyVar2"
 # COMMON-NEXT: 0x00000020: 0000007c "MyVar3"
-# COMMON-NEXT: 0x00000024: Contribution size = 12, Version = 5
-# COMMON-NEXT: 0x0000002c: 00000000 "Handmade DWARF producer"
-# COMMON-NEXT: 0x00000030: 00000036 "Compile_Unit_2"
-# COMMON-NEXT: 0x00000034: 00000045 "/home/test/CU2"
-# COMMON-NEXT: 0x00000038: Contribution size = 8, Version = 5
-# COMMON-NEXT: 0x00000040: 00000054 "Type_Unit"
-# COMMON-NEXT: 0x00000044: 0000005e "MyStruct"
+# COMMON-NEXT: 0x00000024: Gap, length = 4
+# COMMON-NEXT: 0x00000028: Contribution size = 24, Format = DWARF64, Version = 5
+# COMMON-NEXT: 0x00000038: 00000000 "Handmade DWARF producer"
+# COMMON-NEXT: 0x00000040: 00000036 "Compile_Unit_2"
+# COMMON-NEXT: 0x00000048: 00000045 "/home/test/CU2"
+# COMMON-NEXT: 0x00000050: Contribution size = 8, Format = DWARF32, Version = 5
+# COMMON-NEXT: 0x00000058: 00000054 "Type_Unit"
+# COMMON-NEXT: 0x0000005c: 0000005e "MyStruct"

Modified: llvm/trunk/test/DebugInfo/X86/dwarfdump-str-offsets.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/X86/dwarfdump-str-offsets.s?rev=321295&r1=321294&r2=321295&view=diff
==============================================================================
--- llvm/trunk/test/DebugInfo/X86/dwarfdump-str-offsets.s (original)
+++ llvm/trunk/test/DebugInfo/X86/dwarfdump-str-offsets.s Thu Dec 21 11:38:13 2017
@@ -44,14 +44,17 @@ str_Variable3:
         .long str_Variable2
         .long str_Variable3
 .debug_str_offsets_segment0_end:
-# CU2's contribution
-        .long .debug_str_offsets_segment1_end-.debug_str_offsets_base1
+# A 4-byte gap.
+        .long 0
+# CU2's contribution in DWARF64 format
+        .long 0xffffffff
+        .quad .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
+        .quad str_producer
+        .quad str_CU2
+        .quad str_CU2_dir
 .debug_str_offsets_segment1_end:
 # The TU's contribution
         .long .debug_str_offsets_segment2_end-.debug_str_offsets_base2
@@ -75,7 +78,7 @@ dwo_str_TU_5_type:
         .asciz "V5_split_Mystruct"
 
         .section .debug_str_offsets.dwo,"", at progbits
-# The split CU's contribution
+# One contribution only in a .dwo file
         .long .debug_dwo_str_offsets_segment0_end-.debug_dwo_str_offsets_base0
         .short 5    # DWARF version
         .short 0    # Padding
@@ -83,15 +86,9 @@ dwo_str_TU_5_type:
         .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:
+.debug_dwo_str_offsets_segment0_end:
 
 # All CUs/TUs use the same abbrev section for simplicity.
         .section .debug_abbrev,"", at progbits
@@ -163,8 +160,6 @@ dwo_str_TU_5_type:
         .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)
@@ -174,8 +169,6 @@ dwo_str_TU_5_type:
         .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
@@ -275,7 +268,6 @@ CU_split_5_version:
         .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:
@@ -294,12 +286,11 @@ TU_split_5_version:
         .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 
+        .byte 3                # The index of the type unit name string
 # 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 4                # The index of the type name string
         .byte 0 # NULL
         .byte 0 # NULL
 TU_split_5_end:
@@ -340,7 +331,7 @@ TU_split_5_end:
 # COMMON:      DW_TAG_compile_unit
 # COMMON-NEXT: DW_AT_producer [DW_FORM_strx] ( indexed (00000000) string = "Handmade DWARF producer")
 # COMMON-NEXT: DW_AT_name [DW_FORM_strx] ( indexed (00000001) string = "Compile_Unit_2")
-# COMMON-NEXT: DW_AT_str_offsets_base [DW_FORM_sec_offset] (0x0000002c)
+# COMMON-NEXT: DW_AT_str_offsets_base [DW_FORM_sec_offset] (0x00000038)
 # COMMON-NEXT: DW_AT_comp_dir [DW_FORM_strx] ( indexed (00000002) string = "/home/test/CU2")
 # 
 # The split CU
@@ -349,28 +340,25 @@ TU_split_5_end:
 # SPLIT:       DW_TAG_compile_unit
 # SPLIT-NEXT:  DW_AT_producer [DW_FORM_strx] ( indexed (00000000) string = "Handmade split DWARF producer")
 # SPLIT-NEXT:  DW_AT_name [DW_FORM_strx] ( indexed (00000001) string = "V5_split_compile_unit")
-# SPLIT-NEXT:  DW_AT_str_offsets_base [DW_FORM_sec_offset] (0x00000008)
 # SPLIT-NEXT:  DW_AT_comp_dir [DW_FORM_strx] ( indexed (00000002) string = "/home/test/splitCU")
 # 
 # The type unit
 # COMMON:      .debug_types contents:
 # COMMON:      DW_TAG_type_unit
 # COMMON-NEXT: DW_AT_name [DW_FORM_strx] ( indexed (00000000) string = "Type_Unit")
-# COMMON-NEXT: DW_AT_str_offsets_base [DW_FORM_sec_offset]       (0x00000040)
 # COMMON:      DW_TAG_structure_type
 # COMMON-NEXT: DW_AT_name [DW_FORM_strx] ( indexed (00000001) string = "MyStruct")
 # 
 # The split type unit
 # SPLIT:       .debug_types.dwo contents:
 # SPLIT:       DW_TAG_type_unit
-# SPLIT-NEXT:  DW_AT_name [DW_FORM_strx] ( indexed (00000000) string = "V5_split_type_unit")
-# SPLIT-NEXT:  DW_AT_str_offsets_base [DW_FORM_sec_offset]       (0x0000001c)
+# SPLIT-NEXT:  DW_AT_name [DW_FORM_strx] ( indexed (00000003) string = "V5_split_type_unit")
 # SPLIT:       DW_TAG_structure_type
-# SPLIT-NEXT:  DW_AT_name [DW_FORM_strx] ( indexed (00000001) string = "V5_split_Mystruct")
+# SPLIT-NEXT:  DW_AT_name [DW_FORM_strx] ( indexed (00000004) string = "V5_split_Mystruct")
 # 
 # The .debug_str_offsets section
 # COMMON:      .debug_str_offsets contents:
-# COMMON-NEXT: 0x00000000: Contribution size = 28, Version = 5
+# COMMON-NEXT: 0x00000000: Contribution size = 28, Format = DWARF32, Version = 5
 # COMMON-NEXT: 0x00000008: 00000000 "Handmade DWARF producer"
 # COMMON-NEXT: 0x0000000c: 00000018 "Compile_Unit_1"
 # COMMON-NEXT: 0x00000010: 00000027 "/home/test/CU1"
@@ -378,19 +366,19 @@ TU_split_5_end:
 # COMMON-NEXT: 0x00000018: 0000006e "MyVar1"
 # COMMON-NEXT: 0x0000001c: 00000075 "MyVar2"
 # COMMON-NEXT: 0x00000020: 0000007c "MyVar3"
-# COMMON-NEXT: 0x00000024: Contribution size = 12, Version = 5
-# COMMON-NEXT: 0x0000002c: 00000000 "Handmade DWARF producer"
-# COMMON-NEXT: 0x00000030: 00000036 "Compile_Unit_2"
-# COMMON-NEXT: 0x00000034: 00000045 "/home/test/CU2"
-# COMMON-NEXT: 0x00000038: Contribution size = 8, Version = 5
-# COMMON-NEXT: 0x00000040: 00000054 "Type_Unit"
-# COMMON-NEXT: 0x00000044: 0000005e "MyStruct"
+# COMMON-NEXT: Gap, length = 4
+# COMMON-NEXT: 0x00000028: Contribution size = 24, Format = DWARF64, Version = 5
+# COMMON-NEXT: 0x00000038: 00000000 "Handmade DWARF producer"
+# COMMON-NEXT: 0x00000040: 00000036 "Compile_Unit_2"
+# COMMON-NEXT: 0x00000048: 00000045 "/home/test/CU2"
+# COMMON-NEXT: 0x00000050: Contribution size = 8, Format = DWARF32, Version = 5
+# COMMON-NEXT: 0x00000058: 00000054 "Type_Unit"
+# COMMON-NEXT: 0x0000005c: 0000005e "MyStruct"
 # 
 # SPLIT:       .debug_str_offsets.dwo contents:
-# SPLIT-NEXT:  0x00000000: Contribution size = 12, Version = 5
+# SPLIT-NEXT:  0x00000000: Contribution size = 20, Format = DWARF32, Version = 5
 # SPLIT-NEXT:  0x00000008: 00000000 "Handmade split DWARF producer"
 # SPLIT-NEXT:  0x0000000c: 0000001e "V5_split_compile_unit"
 # SPLIT-NEXT:  0x00000010: 00000034 "/home/test/splitCU"
-# SPLIT-NEXT:  0x00000014: Contribution size = 8, Version = 5
-# SPLIT-NEXT:  0x0000001c: 00000047 "V5_split_type_unit"
-# SPLIT-NEXT:  0x00000020: 0000005a "V5_split_Mystruct"
+# SPLIT-NEXT:  0x00000014: 00000047 "V5_split_type_unit"
+# SPLIT-NEXT:  0x00000018: 0000005a "V5_split_Mystruct"




More information about the llvm-commits mailing list