[llvm] 595b168 - [llvm-dwp] Skip type unit debug info sections

David Blaikie via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 2 12:01:07 PDT 2021


Author: Kim-Anh Tran
Date: 2021-06-02T11:48:10-07:00
New Revision: 595b1683b79be089c3f72e7b3dcee4d1a9f6327b

URL: https://github.com/llvm/llvm-project/commit/595b1683b79be089c3f72e7b3dcee4d1a9f6327b
DIFF: https://github.com/llvm/llvm-project/commit/595b1683b79be089c3f72e7b3dcee4d1a9f6327b.diff

LOG: [llvm-dwp] Skip type unit debug info sections

This patch makes llvm-dwp skip debug info sections that may not be encoding a compile unit.
In DWARF5, debug info sections are also used for type units. As in preparation to support type units,
make llvm-dwp aware of other uses of debug info sections but skip them for now.

The patch first records all .debug_info sections, then goes through them one by one and records
the cu debug info section for writing the index unit, and copies that section to the final dwp output
info section. If it's not a compile unit, skip.

Reviewed By: dblaikie

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

Added: 
    llvm/test/tools/llvm-dwp/X86/cu_and_tu_info_section_v5.s
    llvm/test/tools/llvm-dwp/X86/invalid_tu_header_length.s
    llvm/test/tools/llvm-dwp/X86/multiple_debug_info_sections_in_dwp.s
    llvm/test/tools/llvm-dwp/X86/no_cu_found.s
    llvm/test/tools/llvm-dwp/X86/wrong-unit-type-info-v4.s

Modified: 
    llvm/test/tools/llvm-dwp/X86/invalid_cu_header_length.s
    llvm/tools/llvm-dwp/llvm-dwp.cpp

Removed: 
    llvm/test/tools/llvm-dwp/X86/wrong-unit-type-info-v5.s


################################################################################
diff  --git a/llvm/test/tools/llvm-dwp/X86/cu_and_tu_info_section_v5.s b/llvm/test/tools/llvm-dwp/X86/cu_and_tu_info_section_v5.s
new file mode 100644
index 000000000000..8a1051ba751f
--- /dev/null
+++ b/llvm/test/tools/llvm-dwp/X86/cu_and_tu_info_section_v5.s
@@ -0,0 +1,48 @@
+# This test checks if llvm-dwp can find the compilation unit if
+# both type and compile units are available in the debug info section (v5)
+
+# RUN: llvm-mc --triple=x86_64-unknown-linux --filetype=obj --split-dwarf-file=%t.dwo -dwarf-version=5 %s -o %t.o
+# RUN: llvm-dwp %t.dwo -o %t.dwp
+# RUN: llvm-dwarfdump -debug-info -debug-tu-index %t.dwp | FileCheck %s
+
+## Note: For this test we do not need to define the DIE for the structure type, as we only want to
+## have the info on the type and compile units.
+
+# CHECK-DAG: .debug_info.dwo contents
+# CHECK-NOT: Type Unit:
+# CHECK: 0x00000000: Compile Unit: length = 0x00000011, format = DWARF32, version = 0x0005, unit_type = DW_UT_split_compile, abbr_offset = 0x0000, addr_size = 0x08, DWO_id = {{.*}} (next unit at 0x00000015)
+    .section	.debug_info.dwo,"e", at progbits
+    .long	.Ldebug_info_dwo_end0-.Ldebug_info_dwo_start0 # Length of Unit
+.Ldebug_info_dwo_start0:
+    .short	5                               # DWARF version number
+    .byte	6                               # DWARF Unit Type (DW_UT_split_type)
+    .byte	8                               # Address Size (in bytes)
+    .long	0                               # Offset Into Abbrev. Section
+    .quad	5657452045627120676             # Type Signature
+    .long	25                              # Type DIE Offset
+    .byte	1                               # Abbrev [1] DW_TAG_type_unit
+    .byte	2                               # Abbrev [2] DW_TAG_structure_type
+    .byte	0                               # End Of Children Mark
+.Ldebug_info_dwo_end0:
+    .section	.debug_info.dwo,"e", at progbits
+    .long	.Ldebug_info_dwo_end1-.Ldebug_info_dwo_start1 # Length of Unit
+.Ldebug_info_dwo_start1:
+    .short	5                               # DWARF version number
+    .byte	5                               # DWARF Unit Type (DW_UT_split_compile)
+    .byte	8                               # Address Size (in bytes)
+    .long	0                               # Offset Into Abbrev. Section
+    .quad	-1506010254921578184
+    .byte	3                               # Abbrev [3] DW_TAG_compile_unit
+.Ldebug_info_dwo_end1:
+    .section	.debug_abbrev.dwo,"e", at progbits
+    .byte	1                               # Abbreviation Code
+    .byte	65                              # DW_TAG_type_unit
+    .byte	1                               # DW_CHILDREN_yes
+    .byte	0                               # EOM(1)
+    .byte	0                               # EOM(2)
+    .byte	3                               # Abbreviation Code
+    .byte	17                              # DW_TAG_compile_unit
+    .byte	0                               # DW_CHILDREN_no
+    .byte	0                               # EOM(1)
+    .byte	0                               # EOM(2)
+    .byte	0                               # EOM(3)

diff  --git a/llvm/test/tools/llvm-dwp/X86/invalid_cu_header_length.s b/llvm/test/tools/llvm-dwp/X86/invalid_cu_header_length.s
index 8f32822eebe6..ba0c0860dacd 100644
--- a/llvm/test/tools/llvm-dwp/X86/invalid_cu_header_length.s
+++ b/llvm/test/tools/llvm-dwp/X86/invalid_cu_header_length.s
@@ -4,5 +4,5 @@
 
 # CHECK: error: compile unit exceeds .debug_info section range: 20 >= 6
     .section	.debug_info.dwo,"e", at progbits
-	  .long	16      # Length of Unit
+    .long 16      # Length of Unit
     .short 5      # Version
\ No newline at end of file

diff  --git a/llvm/test/tools/llvm-dwp/X86/invalid_tu_header_length.s b/llvm/test/tools/llvm-dwp/X86/invalid_tu_header_length.s
new file mode 100644
index 000000000000..cef2ea3600cb
--- /dev/null
+++ b/llvm/test/tools/llvm-dwp/X86/invalid_tu_header_length.s
@@ -0,0 +1,15 @@
+# RUN: llvm-mc -triple x86_64-unknown-linux %s -filetype=obj -o %t.o \
+# RUN:         -split-dwarf-file=%t.dwo -dwarf-version=5
+# RUN: not llvm-dwp %t.dwo -o %t.dwp 2>&1 | FileCheck %s
+
+# CHECK: error: type unit is missing type offset
+    .section	.debug_info.dwo,"e", at progbits
+    .long	.Ldebug_info_dwo_end0-.Ldebug_info_dwo_start0 # Length of Unit
+.Ldebug_info_dwo_start0:
+    .short	5                               # DWARF version number
+    .byte	6                               # DWARF Unit Type (DW_UT_split_type)
+    .byte	8                               # Address Size (in bytes)
+    .long	0                               # Offset Into Abbrev. Section
+    .quad	5657452045627120676             # Type Signature
+.Ldebug_info_dwo_end0:
+

diff  --git a/llvm/test/tools/llvm-dwp/X86/multiple_debug_info_sections_in_dwp.s b/llvm/test/tools/llvm-dwp/X86/multiple_debug_info_sections_in_dwp.s
new file mode 100644
index 000000000000..7819f8115280
--- /dev/null
+++ b/llvm/test/tools/llvm-dwp/X86/multiple_debug_info_sections_in_dwp.s
@@ -0,0 +1,24 @@
+# RUN: llvm-mc -triple x86_64-unknown-linux %s -filetype=obj -o %t.dwp
+# RUN: not llvm-dwp %t.dwp -o /dev/null 2>&1 | FileCheck %s
+
+## Note: To reach the test point, we need to use comdat groups, to have multiple
+## .debug_info sections. One comdat group needs to have one complete unit header,
+## the second one may be completely empty. 
+## Furthermore, the .debug_cu_index also does not need to be complete.
+
+# CHECK: error: expected exactly one occurrence of a debug info section in a .dwp file
+    .section	.debug_info.dwo,"G", at progbits,0xFDFDFDFD,comdat
+    .long	.Ldebug_info_dwo_end1-.Ldebug_info_dwo_start1 # Length of Unit
+.Ldebug_info_dwo_start1:
+    .short	5                               # DWARF version number
+    .byte	5                               # DWARF Unit Type (DW_UT_split_compile)
+    .byte	8                               # Address Size (in bytes)
+    .long	0                               # Offset Into Abbrev. Section
+    .quad	-1506010254921578184
+    .byte	1                               # Abbrev [1] DW_TAG_compile_unit
+.Ldebug_info_dwo_end1:
+.section	.debug_info.dwo,"G", at progbits,0xDFDFDFDF,comdat
+    .long	0                               # Length of Unit
+  .section .debug_cu_index, "", @progbits
+## Incomplete Header:
+    .long 2                         # Version

diff  --git a/llvm/test/tools/llvm-dwp/X86/wrong-unit-type-info-v5.s b/llvm/test/tools/llvm-dwp/X86/no_cu_found.s
similarity index 89%
rename from llvm/test/tools/llvm-dwp/X86/wrong-unit-type-info-v5.s
rename to llvm/test/tools/llvm-dwp/X86/no_cu_found.s
index fbcdc36da054..015919294ad9 100644
--- a/llvm/test/tools/llvm-dwp/X86/wrong-unit-type-info-v5.s
+++ b/llvm/test/tools/llvm-dwp/X86/no_cu_found.s
@@ -1,12 +1,12 @@
 # RUN: llvm-mc --triple=x86_64-unknown-linux --filetype=obj --split-dwarf-file=%t.dwo -dwarf-version=5 %s -o %t.o
 # RUN: not llvm-dwp %t.dwo -o /dev/null 2>&1 | FileCheck %s
 
-# CHECK: error: {{.*}}: unit type DW_UT_split_compile type not found in debug_info header. Unexpected unit type 0x12 found
+# CHECK: error: no compile unit found in file: {{.*}}no_cu_found.s
 	.section	.debug_info.dwo,"e", at progbits
 	.long	.Ldebug_info_dwo_end0-.Ldebug_info_dwo_start0 # Length of Unit
 .Ldebug_info_dwo_start0:
 	.short	5                      # DWARF version number
-	.byte	12                       # DWARF Unit Type
+	.byte	12                       # DWARF Unit Type (DW_TAG_string_type, wrong type)
 	.byte	8                       # Address Size (in bytes)
 	.long	0                       # Offset Into Abbrev. Section
 	.quad	-1173350285159172090

diff  --git a/llvm/test/tools/llvm-dwp/X86/wrong-unit-type-info-v4.s b/llvm/test/tools/llvm-dwp/X86/wrong-unit-type-info-v4.s
new file mode 100644
index 000000000000..d8feb310d61a
--- /dev/null
+++ b/llvm/test/tools/llvm-dwp/X86/wrong-unit-type-info-v4.s
@@ -0,0 +1,15 @@
+# RUN: llvm-mc -triple x86_64-unknown-linux %s -filetype=obj -o %t.dwp
+# RUN: not llvm-dwp %t.dwp -o %t 2>&1 | FileCheck %s
+
+# CHECK: error: {{.*}}: top level DIE is not a compile unit
+  .section	.debug_info.dwo,"e", at progbits
+  .long	.Ldebug_info_dwo_end0-.Ldebug_info_dwo_start0 # Length of Unit
+.Ldebug_info_dwo_start0:
+  .short	4                               # DWARF version number
+  .long	0                               # Offset Into Abbrev. Section
+  .byte	8                               # Address Size (in bytes)
+  .byte	1                               # Abbrev [1] 0xb:0x1 DW_TAG_string_type
+.Ldebug_info_dwo_end0:
+  .section	.debug_abbrev.dwo,"e", at progbits
+  .byte	1                               # Abbreviation Code
+  .byte	18                              # DW_TAG_string_type

diff  --git a/llvm/tools/llvm-dwp/llvm-dwp.cpp b/llvm/tools/llvm-dwp/llvm-dwp.cpp
index c7cb1fc23a40..926df64f4e37 100644
--- a/llvm/tools/llvm-dwp/llvm-dwp.cpp
+++ b/llvm/tools/llvm-dwp/llvm-dwp.cpp
@@ -77,9 +77,10 @@ static uint64_t debugStrOffsetsHeaderSize(DataExtractor StrOffsetsData,
   return 8;    // unit length: 4 bytes, version: 2 bytes, padding: 2 bytes.
 }
 
-// Holds data for Skeleton and Split Compilation Unit Headers as defined in
-// Dwarf 5 specification, 7.5.1.2 and Dwarf 4 specification 7.5.1.1.
-struct CompileUnitHeader {
+// Holds data for Skeleton, Split Compilation, and Type Unit Headers (only in
+// v5) as defined in Dwarf 5 specification, 7.5.1.2, 7.5.1.3 and Dwarf 4
+// specification 7.5.1.1.
+struct InfoSectionUnitHeader {
   // unit_length field. Note that the type is uint64_t even in 32-bit dwarf.
   uint64_t Length = 0;
 
@@ -108,9 +109,10 @@ struct CompileUnitHeader {
   uint8_t HeaderSize = 0;
 };
 
-// Parse and return the header of the compile unit.
-static Expected<CompileUnitHeader> parseCompileUnitHeader(StringRef Info) {
-  CompileUnitHeader Header;
+// Parse and return the header of an info section compile/type unit.
+static Expected<InfoSectionUnitHeader>
+parseInfoSectionUnitHeader(StringRef Info) {
+  InfoSectionUnitHeader Header;
   Error Err = Error::success();
   uint64_t Offset = 0;
   DWARFDataExtractor InfoData(Info, true, 0);
@@ -141,15 +143,22 @@ static Expected<CompileUnitHeader> parseCompileUnitHeader(StringRef Info) {
     MinHeaderLength = 7;
   }
   if (Header.Length < MinHeaderLength) {
-    return make_error<DWPError>(
-        "compile unit length is too small: expected at least " +
-        utostr(MinHeaderLength) + " got " + utostr(Header.Length) + ".");
+    return make_error<DWPError>("unit length is too small: expected at least " +
+                                utostr(MinHeaderLength) + " got " +
+                                utostr(Header.Length) + ".");
   }
   if (Header.Version >= 5) {
     Header.UnitType = InfoData.getU8(&Offset);
     Header.AddrSize = InfoData.getU8(&Offset);
     Header.DebugAbbrevOffset = InfoData.getU32(&Offset);
     Header.Signature = InfoData.getU64(&Offset);
+    if (Header.UnitType == dwarf::DW_UT_split_type) {
+      // Type offset.
+      MinHeaderLength += 4;
+      if (Header.Length < MinHeaderLength)
+        return make_error<DWPError>("type unit is missing type offset");
+      InfoData.getU32(&Offset);
+    }
   } else {
     // Note that, address_size and debug_abbrev_offset fields have switched
     // places between dwarf version 4 and 5.
@@ -165,7 +174,7 @@ static void writeStringsAndOffsets(MCStreamer &Out, DWPStringPool &Strings,
                                    MCSection *StrOffsetSection,
                                    StringRef CurStrSection,
                                    StringRef CurStrOffsetSection,
-                                   const CompileUnitHeader &Header) {
+                                   const InfoSectionUnitHeader &Header) {
   // Could possibly produce an error or warning if one of these was non-null but
   // the other was null.
   if (CurStrSection.empty() || CurStrOffsetSection.empty())
@@ -259,14 +268,9 @@ getIndexedString(dwarf::Form Form, DataExtractor InfoData, uint64_t &InfoOffset,
   return StrData.getCStr(&StrOffset);
 }
 
-static Expected<CompileUnitIdentifiers> getCUIdentifiers(StringRef Abbrev,
-                                                         StringRef Info,
-                                                         StringRef StrOffsets,
-                                                         StringRef Str) {
-  Expected<CompileUnitHeader> HeaderOrError = parseCompileUnitHeader(Info);
-  if (!HeaderOrError)
-    return HeaderOrError.takeError();
-  CompileUnitHeader &Header = *HeaderOrError;
+static Expected<CompileUnitIdentifiers>
+getCUIdentifiers(InfoSectionUnitHeader &Header, StringRef Abbrev,
+                 StringRef Info, StringRef StrOffsets, StringRef Str) {
   DataExtractor InfoData(Info, true, 0);
   uint64_t Offset = Header.HeaderSize;
   if (Header.Version >= 5 && Header.UnitType != dwarf::DW_UT_split_compile)
@@ -540,13 +544,14 @@ static Error handleSection(
     const StringMap<std::pair<MCSection *, DWARFSectionKind>> &KnownSections,
     const MCSection *StrSection, const MCSection *StrOffsetSection,
     const MCSection *TypesSection, const MCSection *CUIndexSection,
-    const MCSection *TUIndexSection, const SectionRef &Section, MCStreamer &Out,
+    const MCSection *TUIndexSection, const MCSection *InfoSection,
+    const SectionRef &Section, MCStreamer &Out,
     std::deque<SmallString<32>> &UncompressedSections,
     uint32_t (&ContributionOffsets)[8], UnitIndexEntry &CurEntry,
     StringRef &CurStrSection, StringRef &CurStrOffsetSection,
-    std::vector<StringRef> &CurTypesSection, StringRef &InfoSection,
-    StringRef &AbbrevSection, StringRef &CurCUIndexSection,
-    StringRef &CurTUIndexSection) {
+    std::vector<StringRef> &CurTypesSection,
+    std::vector<StringRef> &CurInfoSection, StringRef &AbbrevSection,
+    StringRef &CurCUIndexSection, StringRef &CurTUIndexSection) {
   if (Section.isBSS())
     return Error::success();
 
@@ -574,21 +579,14 @@ static Error handleSection(
 
   if (DWARFSectionKind Kind = SectionPair->second.second) {
     auto Index = getContributionIndex(Kind);
-    if (Kind != DW_SECT_EXT_TYPES) {
+    if (Kind != DW_SECT_EXT_TYPES && Kind != DW_SECT_INFO) {
       CurEntry.Contributions[Index].Offset = ContributionOffsets[Index];
       ContributionOffsets[Index] +=
           (CurEntry.Contributions[Index].Length = Contents.size());
     }
 
-    switch (Kind) {
-    case DW_SECT_INFO:
-      InfoSection = Contents;
-      break;
-    case DW_SECT_ABBREV:
+    if (Kind == DW_SECT_ABBREV) {
       AbbrevSection = Contents;
-      break;
-    default:
-      break;
     }
   }
 
@@ -603,6 +601,8 @@ static Error handleSection(
     CurCUIndexSection = Contents;
   else if (OutSection == TUIndexSection)
     CurTUIndexSection = Contents;
+  else if (OutSection == InfoSection)
+    CurInfoSection.push_back(Contents);
   else {
     Out.SwitchSection(OutSection);
     Out.emitBytes(Contents);
@@ -656,8 +656,9 @@ static Error write(MCStreamer &Out, ArrayRef<std::string> Inputs) {
   MCSection *const TypesSection = MCOFI.getDwarfTypesDWOSection();
   MCSection *const CUIndexSection = MCOFI.getDwarfCUIndexSection();
   MCSection *const TUIndexSection = MCOFI.getDwarfTUIndexSection();
+  MCSection *const InfoSection = MCOFI.getDwarfInfoDWOSection();
   const StringMap<std::pair<MCSection *, DWARFSectionKind>> KnownSections = {
-      {"debug_info.dwo", {MCOFI.getDwarfInfoDWOSection(), DW_SECT_INFO}},
+      {"debug_info.dwo", {InfoSection, DW_SECT_INFO}},
       {"debug_types.dwo", {MCOFI.getDwarfTypesDWOSection(), DW_SECT_EXT_TYPES}},
       {"debug_str_offsets.dwo", {StrOffsetSection, DW_SECT_STR_OFFSETS}},
       {"debug_str.dwo", {StrSection, static_cast<DWARFSectionKind>(0)}},
@@ -692,7 +693,7 @@ static Error write(MCStreamer &Out, ArrayRef<std::string> Inputs) {
     StringRef CurStrSection;
     StringRef CurStrOffsetSection;
     std::vector<StringRef> CurTypesSection;
-    StringRef InfoSection;
+    std::vector<StringRef> CurInfoSection;
     StringRef AbbrevSection;
     StringRef CurCUIndexSection;
     StringRef CurTUIndexSection;
@@ -700,41 +701,86 @@ static Error write(MCStreamer &Out, ArrayRef<std::string> Inputs) {
     for (const auto &Section : Obj.sections())
       if (auto Err = handleSection(
               KnownSections, StrSection, StrOffsetSection, TypesSection,
-              CUIndexSection, TUIndexSection, Section, Out,
+              CUIndexSection, TUIndexSection, InfoSection, Section, Out,
               UncompressedSections, ContributionOffsets, CurEntry,
-              CurStrSection, CurStrOffsetSection, CurTypesSection, InfoSection,
-              AbbrevSection, CurCUIndexSection, CurTUIndexSection))
+              CurStrSection, CurStrOffsetSection, CurTypesSection,
+              CurInfoSection, AbbrevSection, CurCUIndexSection,
+              CurTUIndexSection))
         return Err;
 
-    if (InfoSection.empty())
+    if (CurInfoSection.empty())
       continue;
 
-    Expected<CompileUnitHeader> CompileUnitHeaderOrErr =
-        parseCompileUnitHeader(InfoSection);
-    if (!CompileUnitHeaderOrErr)
-      return CompileUnitHeaderOrErr.takeError();
-    CompileUnitHeader &CompileUnitHeader = *CompileUnitHeaderOrErr;
+    Expected<InfoSectionUnitHeader> HeaderOrErr =
+        parseInfoSectionUnitHeader(CurInfoSection.front());
+    if (!HeaderOrErr)
+      return HeaderOrErr.takeError();
+    InfoSectionUnitHeader &Header = *HeaderOrErr;
 
     writeStringsAndOffsets(Out, Strings, StrOffsetSection, CurStrSection,
-                           CurStrOffsetSection, CompileUnitHeader);
+                           CurStrOffsetSection, Header);
 
+    uint32_t &InfoSectionOffset =
+        ContributionOffsets[getContributionIndex(DW_SECT_INFO)];
     if (CurCUIndexSection.empty()) {
-      Expected<CompileUnitIdentifiers> EID = getCUIdentifiers(
-          AbbrevSection, InfoSection, CurStrOffsetSection, CurStrSection);
-      if (!EID)
-        return createFileError(Input, EID.takeError());
-      const auto &ID = *EID;
-      auto P = IndexEntries.insert(std::make_pair(ID.Signature, CurEntry));
-      if (!P.second)
-        return buildDuplicateError(*P.first, ID, "");
-      P.first->second.Name = ID.Name;
-      P.first->second.DWOName = ID.DWOName;
+      bool FoundCUUnit = false;
+      Out.SwitchSection(InfoSection);
+      for (StringRef Info : CurInfoSection) {
+        if (FoundCUUnit)
+          break;
+        uint64_t UnitOffset = 0;
+        while (Info.size() > UnitOffset) {
+          Expected<InfoSectionUnitHeader> HeaderOrError =
+              parseInfoSectionUnitHeader(Info.substr(UnitOffset, Info.size()));
+          if (!HeaderOrError)
+            return HeaderOrError.takeError();
+          InfoSectionUnitHeader &Header = *HeaderOrError;
+
+          UnitIndexEntry Entry = CurEntry;
+          auto &C = Entry.Contributions[getContributionIndex(DW_SECT_INFO)];
+          C.Offset = InfoSectionOffset;
+          C.Length = Header.Length + 4;
+
+          if (Header.Version < 5 ||
+              Header.UnitType == dwarf::DW_UT_split_compile) {
+            Expected<CompileUnitIdentifiers> EID = getCUIdentifiers(
+                Header, AbbrevSection, Info.substr(UnitOffset, C.Length),
+                CurStrOffsetSection, CurStrSection);
+
+            if (!EID)
+              return createFileError(Input, EID.takeError());
+            const auto &ID = *EID;
+            auto P = IndexEntries.insert(std::make_pair(ID.Signature, Entry));
+            if (!P.second)
+              return buildDuplicateError(*P.first, ID, "");
+            P.first->second.Name = ID.Name;
+            P.first->second.DWOName = ID.DWOName;
+
+            Out.emitBytes(Info.substr(UnitOffset, C.Length));
+            InfoSectionOffset += C.Length;
+            FoundCUUnit = true;
+            break;
+          }
+          UnitOffset += Header.Length + 4;
+        }
+      }
+
+      if (!FoundCUUnit)
+        return make_error<DWPError>("no compile unit found in file: " + Input);
+
+      // Add types from the .debug_types section from DWARF < 5.
       addAllTypes(Out, TypeIndexEntries, TypesSection, CurTypesSection,
                   CurEntry,
                   ContributionOffsets[getContributionIndex(DW_SECT_EXT_TYPES)]);
+
       continue;
     }
 
+    if (CurInfoSection.size() != 1)
+      return make_error<DWPError>("expected exactly one occurrence of a debug "
+                                  "info section in a .dwp file");
+    StringRef DwpSingleInfoSection = CurInfoSection.front();
+
     DWARFUnitIndex CUIndex(DW_SECT_INFO);
     DataExtractor CUIndexData(CurCUIndexSection, Obj.isLittleEndian(), 0);
     if (!CUIndex.parse(CUIndexData))
@@ -744,14 +790,23 @@ static Error write(MCStreamer &Out, ArrayRef<std::string> Inputs) {
           "unsupported cu_index version: " + utostr(CUIndex.getVersion()) +
           " (only version 2 is supported)");
 
+    Out.SwitchSection(InfoSection);
     for (const DWARFUnitIndex::Entry &E : CUIndex.getRows()) {
       auto *I = E.getContributions();
       if (!I)
         continue;
       auto P = IndexEntries.insert(std::make_pair(E.getSignature(), CurEntry));
+      StringRef CUInfoSection =
+          getSubsection(DwpSingleInfoSection, E, DW_SECT_INFO);
+      Expected<InfoSectionUnitHeader> HeaderOrError =
+          parseInfoSectionUnitHeader(CUInfoSection);
+      if (!HeaderOrError)
+        return HeaderOrError.takeError();
+      InfoSectionUnitHeader &Header = *HeaderOrError;
+
       Expected<CompileUnitIdentifiers> EID = getCUIdentifiers(
-          getSubsection(AbbrevSection, E, DW_SECT_ABBREV),
-          getSubsection(InfoSection, E, DW_SECT_INFO),
+          Header, getSubsection(AbbrevSection, E, DW_SECT_ABBREV),
+          CUInfoSection,
           getSubsection(CurStrOffsetSection, E, DW_SECT_STR_OFFSETS),
           CurStrSection);
       if (!EID)
@@ -771,6 +826,11 @@ static Error write(MCStreamer &Out, ArrayRef<std::string> Inputs) {
         C.Length = I->Length;
         ++I;
       }
+      unsigned Index = getContributionIndex(DW_SECT_INFO);
+      auto &C = NewEntry.Contributions[Index];
+      Out.emitBytes(CUInfoSection);
+      C.Offset = InfoSectionOffset;
+      InfoSectionOffset += C.Length;
     }
 
     if (!CurTypesSection.empty()) {


        


More information about the llvm-commits mailing list