[llvm] 714324b - [DebugInfo] Support DWARFv5 index sections.

Igor Kudrin via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 6 00:04:38 PDT 2020


Author: Igor Kudrin
Date: 2020-04-06T13:28:06+07:00
New Revision: 714324b79ae2d05bedfbbb061cfbff4645e6e01b

URL: https://github.com/llvm/llvm-project/commit/714324b79ae2d05bedfbbb061cfbff4645e6e01b
DIFF: https://github.com/llvm/llvm-project/commit/714324b79ae2d05bedfbbb061cfbff4645e6e01b.diff

LOG: [DebugInfo] Support DWARFv5 index sections.

DWARFv5 defines index sections in package files in a slightly different
way than the pre-standard GNU proposal, see Section 7.3.5 in the DWARF
standard and https://gcc.gnu.org/wiki/DebugFissionDWP for GNU proposal.
The main concern here is values for section identifiers, which are
partially overlapped with changed meanings. The patch adds support for
v5 index sections and resolves that difficulty by defining a set of
identifiers for internal use which can represent and distinct values
of both standards.

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

Added: 
    llvm/test/DebugInfo/X86/dwp-v2-cu-index.s
    llvm/test/DebugInfo/X86/dwp-v2-tu-index.s
    llvm/test/DebugInfo/X86/dwp-v5-cu-index.s
    llvm/test/DebugInfo/X86/dwp-v5-tu-index.s

Modified: 
    llvm/include/llvm/BinaryFormat/Dwarf.def
    llvm/include/llvm/DebugInfo/DWARF/DWARFUnitIndex.h
    llvm/lib/DebugInfo/DWARF/DWARFUnitIndex.cpp
    llvm/tools/llvm-dwp/llvm-dwp.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/BinaryFormat/Dwarf.def b/llvm/include/llvm/BinaryFormat/Dwarf.def
index f5078b3a7291..956c67c3e137 100644
--- a/llvm/include/llvm/BinaryFormat/Dwarf.def
+++ b/llvm/include/llvm/BinaryFormat/Dwarf.def
@@ -22,7 +22,7 @@
     (defined HANDLE_DW_CFA && defined HANDLE_DW_CFA_PRED) ||                   \
     defined HANDLE_DW_APPLE_PROPERTY || defined HANDLE_DW_UT ||                \
     defined HANDLE_DWARF_SECTION || defined HANDLE_DW_IDX ||                   \
-    defined HANDLE_DW_END)
+    defined HANDLE_DW_END || defined HANDLE_DW_SECT)
 #error "Missing macro definition of HANDLE_DW*"
 #endif
 
@@ -128,6 +128,10 @@
 #define HANDLE_DW_END(ID, NAME)
 #endif
 
+#ifndef HANDLE_DW_SECT
+#define HANDLE_DW_SECT(ID, NAME)
+#endif
+
 HANDLE_DW_TAG(0x0000, null, 2, DWARF, DW_KIND_NONE)
 HANDLE_DW_TAG(0x0001, array_type, 2, DWARF, DW_KIND_TYPE)
 HANDLE_DW_TAG(0x0002, class_type, 2, DWARF, DW_KIND_TYPE)
@@ -957,6 +961,15 @@ HANDLE_DW_IDX(0x03, die_offset)
 HANDLE_DW_IDX(0x04, parent)
 HANDLE_DW_IDX(0x05, type_hash)
 
+// DWARF package file section identifiers.
+// DWARFv5, section 7.3.5.3, table 7.1.
+HANDLE_DW_SECT(1, INFO)
+HANDLE_DW_SECT(3, ABBREV)
+HANDLE_DW_SECT(4, LINE)
+HANDLE_DW_SECT(5, LOCLISTS)
+HANDLE_DW_SECT(6, STR_OFFSETS)
+HANDLE_DW_SECT(7, MACRO)
+HANDLE_DW_SECT(8, RNGLISTS)
 
 #undef HANDLE_DW_TAG
 #undef HANDLE_DW_AT
@@ -981,3 +994,4 @@ HANDLE_DW_IDX(0x05, type_hash)
 #undef HANDLE_DWARF_SECTION
 #undef HANDLE_DW_IDX
 #undef HANDLE_DW_END
+#undef HANDLE_DW_SECT

diff  --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFUnitIndex.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFUnitIndex.h
index 018962c0bd50..b17b868f8431 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFUnitIndex.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFUnitIndex.h
@@ -19,17 +19,64 @@ namespace llvm {
 
 class raw_ostream;
 
+/// The enum of section identifiers to be used in internal interfaces.
+///
+/// Pre-standard implementation of package files defined a number of section
+/// identifiers with values that clash definitions in the DWARFv5 standard.
+/// See https://gcc.gnu.org/wiki/DebugFissionDWP and Section 7.3.5.3 in DWARFv5.
+///
+/// The following identifiers are the same in the proposal and in DWARFv5:
+/// - DW_SECT_INFO         = 1 (.debug_info.dwo)
+/// - DW_SECT_ABBREV       = 3 (.debug_abbrev.dwo)
+/// - DW_SECT_LINE         = 4 (.debug_line.dwo)
+/// - DW_SECT_STR_OFFSETS  = 6 (.debug_str_offsets.dwo)
+///
+/// The following identifiers are defined only in DWARFv5:
+/// - DW_SECT_LOCLISTS     = 5 (.debug_loclists.dwo)
+/// - DW_SECT_RNGLISTS     = 8 (.debug_rnglists.dwo)
+///
+/// The following identifiers are defined only in the GNU proposal:
+/// - DW_SECT_TYPES        = 2 (.debug_types.dwo)
+/// - DW_SECT_LOC          = 5 (.debug_loc.dwo)
+/// - DW_SECT_MACINFO      = 7 (.debug_macinfo.dwo)
+///
+/// DW_SECT_MACRO for the .debug_macro.dwo section is defined in both standards,
+/// but with 
diff erent values, 8 in GNU and 7 in DWARFv5.
+///
+/// This enum defines constants to represent the identifiers of both sets.
+/// For DWARFv5 ones, the values are the same as defined in the standard.
+/// For pre-standard ones that correspond to sections being deprecated in
+/// DWARFv5, the values are chosen arbitrary and a tag "_EXT_" is added to
+/// the names.
+///
+/// The enum is for internal use only. The user should not expect the values
+/// to correspond to any input/output constants. Special conversion functions,
+/// serializeSectionKind() and deserializeSectionKind(), should be used for
+/// the translation.
 enum DWARFSectionKind {
-  DW_SECT_INFO = 1,
-  DW_SECT_EXT_TYPES,
-  DW_SECT_ABBREV,
-  DW_SECT_LINE,
-  DW_SECT_EXT_LOC,
-  DW_SECT_STR_OFFSETS,
-  DW_SECT_EXT_MACINFO,
-  DW_SECT_MACRO,
+  /// Denotes a value read from an index section that does not correspond
+  /// to any of the supported standards.
+  DW_SECT_EXT_unknown = 0,
+#define HANDLE_DW_SECT(ID, NAME) DW_SECT_##NAME = ID,
+#include "llvm/BinaryFormat/Dwarf.def"
+  DW_SECT_EXT_TYPES = 2,
+  DW_SECT_EXT_LOC = 9,
+  DW_SECT_EXT_MACINFO = 10,
 };
 
+/// Convert the internal value for a section kind to an on-disk value.
+///
+/// The conversion depends on the version of the index section.
+/// IndexVersion is expected to be either 2 for pre-standard GNU proposal
+/// or 5 for DWARFv5 package file.
+uint32_t serializeSectionKind(DWARFSectionKind Kind, unsigned IndexVersion);
+
+/// Convert a value read from an index section to the internal representation.
+///
+/// The conversion depends on the index section version, which is expected
+/// to be either 2 for pre-standard GNU proposal or 5 for DWARFv5 package file.
+DWARFSectionKind deserializeSectionKind(uint32_t Value, unsigned IndexVersion);
+
 class DWARFUnitIndex {
   struct Header {
     uint32_t Version;
@@ -72,6 +119,10 @@ class DWARFUnitIndex {
   DWARFSectionKind InfoColumnKind;
   int InfoColumn = -1;
   std::unique_ptr<DWARFSectionKind[]> ColumnKinds;
+  // This is a parallel array of section identifiers as they read from the input
+  // file. The mapping from raw values to DWARFSectionKind is not revertable in
+  // case of unknown identifiers, so we keep them here.
+  std::unique_ptr<uint32_t[]> RawSectionIds;
   std::unique_ptr<Entry[]> Rows;
   mutable std::vector<Entry *> OffsetLookup;
 

diff  --git a/llvm/lib/DebugInfo/DWARF/DWARFUnitIndex.cpp b/llvm/lib/DebugInfo/DWARF/DWARFUnitIndex.cpp
index 61a8f45bcdbd..f783d47b3691 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFUnitIndex.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFUnitIndex.cpp
@@ -17,15 +17,98 @@
 
 using namespace llvm;
 
+namespace {
+
+enum class DWARFSectionKindV2 {
+  DW_SECT_INFO = 1,
+  DW_SECT_TYPES = 2,
+  DW_SECT_ABBREV = 3,
+  DW_SECT_LINE = 4,
+  DW_SECT_LOC = 5,
+  DW_SECT_STR_OFFSETS = 6,
+  DW_SECT_MACINFO = 7,
+  DW_SECT_MACRO = 8,
+};
+
+} // namespace
+
+// Return true if the section identifier is defined in the DWARFv5 standard.
+constexpr bool isKnownV5SectionID(uint32_t ID) {
+  return ID >= DW_SECT_INFO && ID <= DW_SECT_RNGLISTS &&
+         ID != DW_SECT_EXT_TYPES;
+}
+
+uint32_t llvm::serializeSectionKind(DWARFSectionKind Kind,
+                                    unsigned IndexVersion) {
+  if (IndexVersion == 5) {
+    assert(isKnownV5SectionID(Kind));
+    return static_cast<uint32_t>(Kind);
+  }
+  assert(IndexVersion == 2);
+  switch (Kind) {
+#define CASE(S,T) \
+  case DW_SECT_##S: \
+    return static_cast<uint32_t>(DWARFSectionKindV2::DW_SECT_##T)
+  CASE(INFO, INFO);
+  CASE(EXT_TYPES, TYPES);
+  CASE(ABBREV, ABBREV);
+  CASE(LINE, LINE);
+  CASE(EXT_LOC, LOC);
+  CASE(STR_OFFSETS, STR_OFFSETS);
+  CASE(EXT_MACINFO, MACINFO);
+  CASE(MACRO, MACRO);
+#undef CASE
+  default:
+    // All other section kinds have no corresponding values in v2 indexes.
+    llvm_unreachable("Invalid DWARFSectionKind");
+  }
+}
+
+DWARFSectionKind llvm::deserializeSectionKind(uint32_t Value,
+                                              unsigned IndexVersion) {
+  if (IndexVersion == 5)
+    return isKnownV5SectionID(Value)
+               ? static_cast<DWARFSectionKind>(Value)
+               : DW_SECT_EXT_unknown;
+  assert(IndexVersion == 2);
+  switch (static_cast<DWARFSectionKindV2>(Value)) {
+#define CASE(S,T) \
+  case DWARFSectionKindV2::DW_SECT_##S: \
+    return DW_SECT_##T
+  CASE(INFO, INFO);
+  CASE(TYPES, EXT_TYPES);
+  CASE(ABBREV, ABBREV);
+  CASE(LINE, LINE);
+  CASE(LOC, EXT_LOC);
+  CASE(STR_OFFSETS, STR_OFFSETS);
+  CASE(MACINFO, EXT_MACINFO);
+  CASE(MACRO, MACRO);
+#undef CASE
+  }
+  return DW_SECT_EXT_unknown;
+}
+
 bool DWARFUnitIndex::Header::parse(DataExtractor IndexData,
                                    uint64_t *OffsetPtr) {
+  const uint64_t BeginOffset = *OffsetPtr;
   if (!IndexData.isValidOffsetForDataOfSize(*OffsetPtr, 16))
     return false;
+  // GCC Debug Fission defines the version as an unsigned 32-bit field
+  // with value of 2, https://gcc.gnu.org/wiki/DebugFissionDWP.
+  // DWARFv5 defines the same space as an uhalf version field with value of 5
+  // and a 2 bytes long padding, see Section 7.3.5.3.
   Version = IndexData.getU32(OffsetPtr);
+  if (Version != 2) {
+    *OffsetPtr = BeginOffset;
+    Version = IndexData.getU16(OffsetPtr);
+    if (Version != 5)
+      return false;
+    *OffsetPtr += 2; // Skip padding.
+  }
   NumColumns = IndexData.getU32(OffsetPtr);
   NumUnits = IndexData.getU32(OffsetPtr);
   NumBuckets = IndexData.getU32(OffsetPtr);
-  return Version <= 2;
+  return true;
 }
 
 void DWARFUnitIndex::Header::dump(raw_ostream &OS) const {
@@ -49,6 +132,10 @@ bool DWARFUnitIndex::parseImpl(DataExtractor IndexData) {
   if (!Header.parse(IndexData, &Offset))
     return false;
 
+  // Fix InfoColumnKind: in DWARFv5, type units are in .debug_info.dwo.
+  if (Header.Version == 5)
+    InfoColumnKind = DW_SECT_INFO;
+
   if (!IndexData.isValidOffsetForDataOfSize(
           Offset, Header.NumBuckets * (8 + 4) +
                       (2 * Header.NumUnits + 1) * 4 * Header.NumColumns))
@@ -58,6 +145,7 @@ bool DWARFUnitIndex::parseImpl(DataExtractor IndexData) {
   auto Contribs =
       std::make_unique<Entry::SectionContribution *[]>(Header.NumUnits);
   ColumnKinds = std::make_unique<DWARFSectionKind[]>(Header.NumColumns);
+  RawSectionIds = std::make_unique<uint32_t[]>(Header.NumColumns);
 
   // Read Hash Table of Signatures
   for (unsigned i = 0; i != Header.NumBuckets; ++i)
@@ -76,7 +164,8 @@ bool DWARFUnitIndex::parseImpl(DataExtractor IndexData) {
 
   // Read the Column Headers
   for (unsigned i = 0; i != Header.NumColumns; ++i) {
-    ColumnKinds[i] = static_cast<DWARFSectionKind>(IndexData.getU32(&Offset));
+    RawSectionIds[i] = IndexData.getU32(&Offset);
+    ColumnKinds[i] = deserializeSectionKind(RawSectionIds[i], Header.Version);
     if (ColumnKinds[i] == InfoColumnKind) {
       if (InfoColumn != -1)
         return false;
@@ -105,23 +194,21 @@ bool DWARFUnitIndex::parseImpl(DataExtractor IndexData) {
 }
 
 StringRef DWARFUnitIndex::getColumnHeader(DWARFSectionKind DS) {
-#define CASE(DS)                                                               \
-  case DW_SECT_##DS:                                                           \
-    return #DS;
   switch (DS) {
-    CASE(INFO);
-    CASE(ABBREV);
-    CASE(LINE);
-    CASE(STR_OFFSETS);
-    CASE(MACRO);
+#define HANDLE_DW_SECT(ID, NAME)                                               \
+  case DW_SECT_##NAME:                                                         \
+    return #NAME;
+#include "llvm/BinaryFormat/Dwarf.def"
   case DW_SECT_EXT_TYPES:
     return "TYPES";
   case DW_SECT_EXT_LOC:
     return "LOC";
   case DW_SECT_EXT_MACINFO:
     return "MACINFO";
+  case DW_SECT_EXT_unknown:
+    return StringRef();
   }
-  return StringRef();
+  llvm_unreachable("Unknown DWARFSectionKind");
 }
 
 void DWARFUnitIndex::dump(raw_ostream &OS) const {
@@ -136,7 +223,7 @@ void DWARFUnitIndex::dump(raw_ostream &OS) const {
     if (!Name.empty())
       OS << ' ' << left_justify(Name, 24);
     else
-      OS << format(" Unknown: %-15u", static_cast<unsigned>(Kind));
+      OS << format(" Unknown: %-15" PRIu32, RawSectionIds[i]);
   }
   OS << "\n----- ------------------";
   for (unsigned i = 0; i != Header.NumColumns; ++i)

diff  --git a/llvm/test/DebugInfo/X86/dwp-v2-cu-index.s b/llvm/test/DebugInfo/X86/dwp-v2-cu-index.s
new file mode 100644
index 000000000000..43d7b074bf54
--- /dev/null
+++ b/llvm/test/DebugInfo/X86/dwp-v2-cu-index.s
@@ -0,0 +1,51 @@
+## The test checks that we can parse and dump a pre-standard CU index section.
+## See https://gcc.gnu.org/wiki/DebugFissionDWP for the proposal.
+
+# RUN: llvm-mc -triple x86_64-unknown-linux %s -filetype=obj -o - | \
+# RUN:   llvm-dwarfdump -debug-cu-index - | \
+# RUN:   FileCheck %s
+
+# CHECK:      .debug_cu_index contents:
+# CHECK-NEXT: version = 2 slots = 2
+# CHECK-EMPTY:
+# CHECK-NEXT: Index Signature          INFO                     ABBREV                   LINE                     LOC                      STR_OFFSETS              MACINFO                  MACRO
+# CHECK-NEXT: ----- ------------------ ------------------------ ------------------------ ------------------------ ------------------------ ------------------------ ------------------------ ------------------------
+# CHECK-NEXT:     1 0x1100001122222222 [0x00001000, 0x00001010) [0x00002000, 0x00002020) [0x00003000, 0x00003030) [0x00004000, 0x00004040) [0x00005000, 0x00005050) [0x00006000, 0x00006060) [0x00007000, 0x00007070)
+
+    .section .debug_cu_index, "", @progbits
+## Header:
+    .long 2             # Version
+    .long 7             # Section count
+    .long 1             # Unit count
+    .long 2             # Slot count
+## Hash Table of Signatures:
+    .quad 0x1100001122222222
+    .quad 0
+## Parallel Table of Indexes:
+    .long 1
+    .long 0
+## Table of Section Offsets:
+## Row 0:
+    .long 1             # DW_SECT_INFO
+    .long 3             # DW_SECT_ABBREV
+    .long 4             # DW_SECT_LINE
+    .long 5             # DW_SECT_LOC
+    .long 6             # DW_SECT_STR_OFFSETS
+    .long 7             # DW_SECT_MACINFO
+    .long 8             # DW_SECT_MACRO
+## Row 1:
+    .long 0x1000        # Offset in .debug_info.dwo
+    .long 0x2000        # Offset in .debug_abbrev.dwo
+    .long 0x3000        # Offset in .debug_line.dwo
+    .long 0x4000        # Offset in .debug_loc.dwo
+    .long 0x5000        # Offset in .debug_str_offsets.dwo
+    .long 0x6000        # Offset in .debug_macinfo.dwo
+    .long 0x7000        # Offset in .debug_macro.dwo
+## Table of Section Sizes:
+    .long 0x10          # Size in .debug_info.dwo
+    .long 0x20          # Size in .debug_abbrev.dwo
+    .long 0x30          # Size in .debug_line.dwo
+    .long 0x40          # Size in .debug_loc.dwo
+    .long 0x50          # Size in .debug_str_offsets.dwo
+    .long 0x60          # Size in .debug_macinfo.dwo
+    .long 0x70          # Size in .debug_macro.dwo

diff  --git a/llvm/test/DebugInfo/X86/dwp-v2-tu-index.s b/llvm/test/DebugInfo/X86/dwp-v2-tu-index.s
new file mode 100644
index 000000000000..302ac7ed5186
--- /dev/null
+++ b/llvm/test/DebugInfo/X86/dwp-v2-tu-index.s
@@ -0,0 +1,42 @@
+## The test checks that we can parse and dump a pre-standard TU index section.
+## See https://gcc.gnu.org/wiki/DebugFissionDWP for the proposal.
+
+# RUN: llvm-mc -triple x86_64-unknown-linux %s -filetype=obj -o - | \
+# RUN:   llvm-dwarfdump -debug-tu-index - | \
+# RUN:   FileCheck %s
+
+# CHECK:      .debug_tu_index contents:
+# CHECK-NEXT: version = 2 slots = 2
+# CHECK-EMPTY:
+# CHECK-NEXT: Index Signature          TYPES                    ABBREV                   LINE                     STR_OFFSETS
+# CHECK-NEXT: ----- ------------------ ------------------------ ------------------------ ------------------------ ------------------------
+# CHECK-NEXT:     1 0x1100001122222222 [0x00001000, 0x00001010) [0x00002000, 0x00002020) [0x00003000, 0x00003030) [0x00004000, 0x00004040)
+
+    .section .debug_tu_index, "", @progbits
+## Header:
+    .long 2             # Version
+    .long 4             # Section count
+    .long 1             # Unit count
+    .long 2             # Slot count
+## Hash Table of Signatures:
+    .quad 0x1100001122222222
+    .quad 0
+## Parallel Table of Indexes:
+    .long 1
+    .long 0
+## Table of Section Offsets:
+## Row 0:
+    .long 2             # DW_SECT_TYPES
+    .long 3             # DW_SECT_ABBREV
+    .long 4             # DW_SECT_LINE
+    .long 6             # DW_SECT_STR_OFFSETS
+## Row 1:
+    .long 0x1000        # Offset in .debug_types.dwo
+    .long 0x2000        # Offset in .debug_abbrev.dwo
+    .long 0x3000        # Offset in .debug_line.dwo
+    .long 0x4000        # Offset in .debug_str_offsets.dwo
+## Table of Section Sizes:
+    .long 0x10          # Size in .debug_types.dwo
+    .long 0x20          # Size in .debug_abbrev.dwo
+    .long 0x30          # Size in .debug_line.dwo
+    .long 0x40          # Size in .debug_str_offsets.dwo

diff  --git a/llvm/test/DebugInfo/X86/dwp-v5-cu-index.s b/llvm/test/DebugInfo/X86/dwp-v5-cu-index.s
new file mode 100644
index 000000000000..0cc1ee8e87dd
--- /dev/null
+++ b/llvm/test/DebugInfo/X86/dwp-v5-cu-index.s
@@ -0,0 +1,52 @@
+## The test checks that we can parse and dump a CU index section that is
+## compliant to the DWARFv5 standard.
+
+# RUN: llvm-mc -triple x86_64-unknown-linux %s -filetype=obj -o - | \
+# RUN:   llvm-dwarfdump -debug-cu-index - | \
+# RUN:   FileCheck %s
+
+# CHECK:      .debug_cu_index contents:
+# CHECK-NEXT: version = 5 slots = 2
+# CHECK-EMPTY:
+# CHECK-NEXT: Index Signature          INFO                     ABBREV                   LINE                     LOCLISTS                 STR_OFFSETS              MACRO                    RNGLISTS
+# CHECK-NEXT: ----- ------------------ ------------------------ ------------------------ ------------------------ ------------------------ ------------------------ ------------------------ ------------------------
+# CHECK-NEXT:     1 0x1100001122222222 [0x00001000, 0x00001010) [0x00002000, 0x00002020) [0x00003000, 0x00003030) [0x00004000, 0x00004040) [0x00005000, 0x00005050) [0x00006000, 0x00006060) [0x00007000, 0x00007070)
+
+    .section .debug_cu_index, "", @progbits
+## Header:
+    .short 5            # Version
+    .space 2            # Padding
+    .long 7             # Section count
+    .long 1             # Unit count
+    .long 2             # Slot count
+## Hash Table of Signatures:
+    .quad 0x1100001122222222
+    .quad 0
+## Parallel Table of Indexes:
+    .long 1
+    .long 0
+## Table of Section Offsets:
+## Row 0:
+    .long 1             # DW_SECT_INFO
+    .long 3             # DW_SECT_ABBREV
+    .long 4             # DW_SECT_LINE
+    .long 5             # DW_SECT_LOCLISTS
+    .long 6             # DW_SECT_STR_OFFSETS
+    .long 7             # DW_SECT_MACRO
+    .long 8             # DW_SECT_RNGLISTS
+## Row 1:
+    .long 0x1000        # Offset in .debug_info.dwo
+    .long 0x2000        # Offset in .debug_abbrev.dwo
+    .long 0x3000        # Offset in .debug_line.dwo
+    .long 0x4000        # Offset in .debug_loclists.dwo
+    .long 0x5000        # Offset in .debug_str_offsets.dwo
+    .long 0x6000        # Offset in .debug_macro.dwo
+    .long 0x7000        # Offset in .debug_rnglists.dwo
+## Table of Section Sizes:
+    .long 0x10          # Size in .debug_info.dwo
+    .long 0x20          # Size in .debug_abbrev.dwo
+    .long 0x30          # Size in .debug_line.dwo
+    .long 0x40          # Size in .debug_loclists.dwo
+    .long 0x50          # Size in .debug_str_offsets.dwo
+    .long 0x60          # Size in .debug_macro.dwo
+    .long 0x70          # Size in .debug_rnglists.dwo

diff  --git a/llvm/test/DebugInfo/X86/dwp-v5-tu-index.s b/llvm/test/DebugInfo/X86/dwp-v5-tu-index.s
new file mode 100644
index 000000000000..e050296cd410
--- /dev/null
+++ b/llvm/test/DebugInfo/X86/dwp-v5-tu-index.s
@@ -0,0 +1,43 @@
+## The test checks that we can parse and dump a TU index section that is
+## compliant to the DWARFv5 standard.
+
+# RUN: llvm-mc -triple x86_64-unknown-linux %s -filetype=obj -o - | \
+# RUN:   llvm-dwarfdump -debug-tu-index - | \
+# RUN:   FileCheck %s
+
+# CHECK:      .debug_tu_index contents:
+# CHECK-NEXT: version = 5 slots = 2
+# CHECK-EMPTY:
+# CHECK-NEXT: Index Signature          INFO                     ABBREV                   LINE                     STR_OFFSETS
+# CHECK-NEXT: ----- ------------------ ------------------------ ------------------------ ------------------------ ------------------------
+# CHECK-NEXT:     1 0x1100001122222222 [0x00001000, 0x00001010) [0x00002000, 0x00002020) [0x00003000, 0x00003030) [0x00004000, 0x00004040)
+
+    .section .debug_tu_index, "", @progbits
+## Header:
+    .short 5            # Version
+    .space 2            # Padding
+    .long 4             # Section count
+    .long 1             # Unit count
+    .long 2             # Slot count
+## Hash Table of Signatures:
+    .quad 0x1100001122222222
+    .quad 0
+## Parallel Table of Indexes:
+    .long 1
+    .long 0
+## Table of Section Offsets:
+## Row 0:
+    .long 1             # DW_SECT_INFO
+    .long 3             # DW_SECT_ABBREV
+    .long 4             # DW_SECT_LINE
+    .long 6             # DW_SECT_STR_OFFSETS
+## Row 1:
+    .long 0x1000        # Offset in .debug_info.dwo
+    .long 0x2000        # Offset in .debug_abbrev.dwo
+    .long 0x3000        # Offset in .debug_line.dwo
+    .long 0x4000        # Offset in .debug_str_offsets.dwo
+## Table of Section Sizes:
+    .long 0x10          # Size in .debug_info.dwo
+    .long 0x20          # Size in .debug_abbrev.dwo
+    .long 0x30          # Size in .debug_line.dwo
+    .long 0x40          # Size in .debug_str_offsets.dwo

diff  --git a/llvm/tools/llvm-dwp/llvm-dwp.cpp b/llvm/tools/llvm-dwp/llvm-dwp.cpp
index 571dc6241abf..18cd92fcb613 100644
--- a/llvm/tools/llvm-dwp/llvm-dwp.cpp
+++ b/llvm/tools/llvm-dwp/llvm-dwp.cpp
@@ -216,11 +216,12 @@ struct UnitIndexEntry {
   StringRef DWPName;
 };
 
-// Convert a section identifier into the index to use with
+// Convert an internal section identifier into the index to use with
 // UnitIndexEntry::Contributions.
 static unsigned getContributionIndex(DWARFSectionKind Kind) {
-  assert(Kind >= DW_SECT_INFO);
-  return Kind - DW_SECT_INFO;
+  // Assuming the pre-standard DWP format.
+  assert(serializeSectionKind(Kind, 2) >= DW_SECT_INFO);
+  return serializeSectionKind(Kind, 2) - DW_SECT_INFO;
 }
 
 // Convert a UnitIndexEntry::Contributions index to the corresponding on-disk


        


More information about the llvm-commits mailing list