[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
This commit is contained in:
Kim-Anh Tran 2021-06-02 11:48:02 -07:00 committed by David Blaikie
parent 70804f2a2f
commit 595b1683b7
7 changed files with 220 additions and 58 deletions

View File

@ -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",@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",@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",@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)

View File

@ -4,5 +4,5 @@
# CHECK: error: compile unit exceeds .debug_info section range: 20 >= 6 # CHECK: error: compile unit exceeds .debug_info section range: 20 >= 6
.section .debug_info.dwo,"e",@progbits .section .debug_info.dwo,"e",@progbits
.long 16 # Length of Unit .long 16 # Length of Unit
.short 5 # Version .short 5 # Version

View File

@ -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",@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:

View File

@ -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",@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",@progbits,0xDFDFDFDF,comdat
.long 0 # Length of Unit
.section .debug_cu_index, "", @progbits
## Incomplete Header:
.long 2 # Version

View File

@ -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: 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 # 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",@progbits .section .debug_info.dwo,"e",@progbits
.long .Ldebug_info_dwo_end0-.Ldebug_info_dwo_start0 # Length of Unit .long .Ldebug_info_dwo_end0-.Ldebug_info_dwo_start0 # Length of Unit
.Ldebug_info_dwo_start0: .Ldebug_info_dwo_start0:
.short 5 # DWARF version number .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) .byte 8 # Address Size (in bytes)
.long 0 # Offset Into Abbrev. Section .long 0 # Offset Into Abbrev. Section
.quad -1173350285159172090 .quad -1173350285159172090

View File

@ -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",@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",@progbits
.byte 1 # Abbreviation Code
.byte 18 # DW_TAG_string_type

View File

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