xref: /llvm-project/llvm/lib/DWP/DWP.cpp (revision 699cd9ac1dc305b2f0ee6e70939a3dddccc2add4)
1f8c65155SAlexander Yermolovich //===-- llvm-dwp.cpp - Split DWARF merging tool for llvm ------------------===//
2f8c65155SAlexander Yermolovich //
3f8c65155SAlexander Yermolovich // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4f8c65155SAlexander Yermolovich // See https://llvm.org/LICENSE.txt for license information.
5f8c65155SAlexander Yermolovich // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6f8c65155SAlexander Yermolovich //
7f8c65155SAlexander Yermolovich //===----------------------------------------------------------------------===//
8f8c65155SAlexander Yermolovich //
9f8c65155SAlexander Yermolovich // A utility for merging DWARF 5 Split DWARF .dwo files into .dwp (DWARF
10f8c65155SAlexander Yermolovich // package files).
11f8c65155SAlexander Yermolovich //
12f8c65155SAlexander Yermolovich //===----------------------------------------------------------------------===//
13f8c65155SAlexander Yermolovich #include "llvm/DWP/DWP.h"
1453a483ceSzhuna #include "llvm/ADT/Twine.h"
15f8c65155SAlexander Yermolovich #include "llvm/DWP/DWPError.h"
16f8c65155SAlexander Yermolovich #include "llvm/MC/MCContext.h"
17f8c65155SAlexander Yermolovich #include "llvm/MC/MCObjectFileInfo.h"
18f8c65155SAlexander Yermolovich #include "llvm/MC/MCTargetOptionsCommandFlags.h"
19f8c65155SAlexander Yermolovich #include "llvm/Object/Decompressor.h"
20141c9d77SFangrui Song #include "llvm/Object/ELFObjectFile.h"
2153a483ceSzhuna #include "llvm/Support/CommandLine.h"
22e72c195fSserge-sans-paille #include "llvm/Support/MemoryBuffer.h"
23f8df8114SAlexander Yermolovich #include <limits>
24f8c65155SAlexander Yermolovich 
25f8c65155SAlexander Yermolovich using namespace llvm;
26f8c65155SAlexander Yermolovich using namespace llvm::object;
27f8c65155SAlexander Yermolovich 
28f8c65155SAlexander Yermolovich static mc::RegisterMCTargetOptionsFlags MCTargetOptionsFlags;
29f8c65155SAlexander Yermolovich 
30f8c65155SAlexander Yermolovich // Returns the size of debug_str_offsets section headers in bytes.
debugStrOffsetsHeaderSize(DataExtractor StrOffsetsData,uint16_t DwarfVersion)31f8c65155SAlexander Yermolovich static uint64_t debugStrOffsetsHeaderSize(DataExtractor StrOffsetsData,
32f8c65155SAlexander Yermolovich                                           uint16_t DwarfVersion) {
33f8c65155SAlexander Yermolovich   if (DwarfVersion <= 4)
34f8c65155SAlexander Yermolovich     return 0; // There is no header before dwarf 5.
35f8c65155SAlexander Yermolovich   uint64_t Offset = 0;
36f8c65155SAlexander Yermolovich   uint64_t Length = StrOffsetsData.getU32(&Offset);
37f8c65155SAlexander Yermolovich   if (Length == llvm::dwarf::DW_LENGTH_DWARF64)
38f8c65155SAlexander Yermolovich     return 16; // unit length: 12 bytes, version: 2 bytes, padding: 2 bytes.
39f8c65155SAlexander Yermolovich   return 8;    // unit length: 4 bytes, version: 2 bytes, padding: 2 bytes.
40f8c65155SAlexander Yermolovich }
41f8c65155SAlexander Yermolovich 
getCUAbbrev(StringRef Abbrev,uint64_t AbbrCode)42f8c65155SAlexander Yermolovich static uint64_t getCUAbbrev(StringRef Abbrev, uint64_t AbbrCode) {
43f8c65155SAlexander Yermolovich   uint64_t Offset = 0;
44f8c65155SAlexander Yermolovich   DataExtractor AbbrevData(Abbrev, true, 0);
45f8c65155SAlexander Yermolovich   while (AbbrevData.getULEB128(&Offset) != AbbrCode) {
46f8c65155SAlexander Yermolovich     // Tag
47f8c65155SAlexander Yermolovich     AbbrevData.getULEB128(&Offset);
48f8c65155SAlexander Yermolovich     // DW_CHILDREN
49f8c65155SAlexander Yermolovich     AbbrevData.getU8(&Offset);
50f8c65155SAlexander Yermolovich     // Attributes
51f8c65155SAlexander Yermolovich     while (AbbrevData.getULEB128(&Offset) | AbbrevData.getULEB128(&Offset))
52f8c65155SAlexander Yermolovich       ;
53f8c65155SAlexander Yermolovich   }
54f8c65155SAlexander Yermolovich   return Offset;
55f8c65155SAlexander Yermolovich }
56f8c65155SAlexander Yermolovich 
57f8c65155SAlexander Yermolovich static Expected<const char *>
getIndexedString(dwarf::Form Form,DataExtractor InfoData,uint64_t & InfoOffset,StringRef StrOffsets,StringRef Str,uint16_t Version)58f8c65155SAlexander Yermolovich getIndexedString(dwarf::Form Form, DataExtractor InfoData, uint64_t &InfoOffset,
59f8c65155SAlexander Yermolovich                  StringRef StrOffsets, StringRef Str, uint16_t Version) {
60f8c65155SAlexander Yermolovich   if (Form == dwarf::DW_FORM_string)
61f8c65155SAlexander Yermolovich     return InfoData.getCStr(&InfoOffset);
62f8c65155SAlexander Yermolovich   uint64_t StrIndex;
63f8c65155SAlexander Yermolovich   switch (Form) {
64f8c65155SAlexander Yermolovich   case dwarf::DW_FORM_strx1:
65f8c65155SAlexander Yermolovich     StrIndex = InfoData.getU8(&InfoOffset);
66f8c65155SAlexander Yermolovich     break;
67f8c65155SAlexander Yermolovich   case dwarf::DW_FORM_strx2:
68f8c65155SAlexander Yermolovich     StrIndex = InfoData.getU16(&InfoOffset);
69f8c65155SAlexander Yermolovich     break;
70f8c65155SAlexander Yermolovich   case dwarf::DW_FORM_strx3:
71f8c65155SAlexander Yermolovich     StrIndex = InfoData.getU24(&InfoOffset);
72f8c65155SAlexander Yermolovich     break;
73f8c65155SAlexander Yermolovich   case dwarf::DW_FORM_strx4:
74f8c65155SAlexander Yermolovich     StrIndex = InfoData.getU32(&InfoOffset);
75f8c65155SAlexander Yermolovich     break;
76f8c65155SAlexander Yermolovich   case dwarf::DW_FORM_strx:
77f8c65155SAlexander Yermolovich   case dwarf::DW_FORM_GNU_str_index:
78f8c65155SAlexander Yermolovich     StrIndex = InfoData.getULEB128(&InfoOffset);
79f8c65155SAlexander Yermolovich     break;
80f8c65155SAlexander Yermolovich   default:
81f8c65155SAlexander Yermolovich     return make_error<DWPError>(
82f8c65155SAlexander Yermolovich         "string field must be encoded with one of the following: "
83f8c65155SAlexander Yermolovich         "DW_FORM_string, DW_FORM_strx, DW_FORM_strx1, DW_FORM_strx2, "
84f8c65155SAlexander Yermolovich         "DW_FORM_strx3, DW_FORM_strx4, or DW_FORM_GNU_str_index.");
85f8c65155SAlexander Yermolovich   }
86f8c65155SAlexander Yermolovich   DataExtractor StrOffsetsData(StrOffsets, true, 0);
87f8c65155SAlexander Yermolovich   uint64_t StrOffsetsOffset = 4 * StrIndex;
88f8c65155SAlexander Yermolovich   StrOffsetsOffset += debugStrOffsetsHeaderSize(StrOffsetsData, Version);
89f8c65155SAlexander Yermolovich 
90f8c65155SAlexander Yermolovich   uint64_t StrOffset = StrOffsetsData.getU32(&StrOffsetsOffset);
91f8c65155SAlexander Yermolovich   DataExtractor StrData(Str, true, 0);
92f8c65155SAlexander Yermolovich   return StrData.getCStr(&StrOffset);
93f8c65155SAlexander Yermolovich }
94f8c65155SAlexander Yermolovich 
95f8c65155SAlexander Yermolovich static Expected<CompileUnitIdentifiers>
getCUIdentifiers(InfoSectionUnitHeader & Header,StringRef Abbrev,StringRef Info,StringRef StrOffsets,StringRef Str)96f8c65155SAlexander Yermolovich getCUIdentifiers(InfoSectionUnitHeader &Header, StringRef Abbrev,
97f8c65155SAlexander Yermolovich                  StringRef Info, StringRef StrOffsets, StringRef Str) {
98f8c65155SAlexander Yermolovich   DataExtractor InfoData(Info, true, 0);
99f8c65155SAlexander Yermolovich   uint64_t Offset = Header.HeaderSize;
100f8c65155SAlexander Yermolovich   if (Header.Version >= 5 && Header.UnitType != dwarf::DW_UT_split_compile)
101f8c65155SAlexander Yermolovich     return make_error<DWPError>(
102f8c65155SAlexander Yermolovich         std::string("unit type DW_UT_split_compile type not found in "
103f8c65155SAlexander Yermolovich                     "debug_info header. Unexpected unit type 0x" +
104f8c65155SAlexander Yermolovich                     utostr(Header.UnitType) + " found"));
105f8c65155SAlexander Yermolovich 
106f8c65155SAlexander Yermolovich   CompileUnitIdentifiers ID;
107f8c65155SAlexander Yermolovich 
108f8c65155SAlexander Yermolovich   uint32_t AbbrCode = InfoData.getULEB128(&Offset);
109f8c65155SAlexander Yermolovich   DataExtractor AbbrevData(Abbrev, true, 0);
110f8c65155SAlexander Yermolovich   uint64_t AbbrevOffset = getCUAbbrev(Abbrev, AbbrCode);
111f8c65155SAlexander Yermolovich   auto Tag = static_cast<dwarf::Tag>(AbbrevData.getULEB128(&AbbrevOffset));
112f8c65155SAlexander Yermolovich   if (Tag != dwarf::DW_TAG_compile_unit)
113f8c65155SAlexander Yermolovich     return make_error<DWPError>("top level DIE is not a compile unit");
114f8c65155SAlexander Yermolovich   // DW_CHILDREN
115f8c65155SAlexander Yermolovich   AbbrevData.getU8(&AbbrevOffset);
116f8c65155SAlexander Yermolovich   uint32_t Name;
117f8c65155SAlexander Yermolovich   dwarf::Form Form;
118f8c65155SAlexander Yermolovich   while ((Name = AbbrevData.getULEB128(&AbbrevOffset)) |
119f8c65155SAlexander Yermolovich              (Form = static_cast<dwarf::Form>(
120f8c65155SAlexander Yermolovich                   AbbrevData.getULEB128(&AbbrevOffset))) &&
121f8c65155SAlexander Yermolovich          (Name != 0 || Form != 0)) {
122f8c65155SAlexander Yermolovich     switch (Name) {
123f8c65155SAlexander Yermolovich     case dwarf::DW_AT_name: {
124f8c65155SAlexander Yermolovich       Expected<const char *> EName = getIndexedString(
125f8c65155SAlexander Yermolovich           Form, InfoData, Offset, StrOffsets, Str, Header.Version);
126f8c65155SAlexander Yermolovich       if (!EName)
127f8c65155SAlexander Yermolovich         return EName.takeError();
128f8c65155SAlexander Yermolovich       ID.Name = *EName;
129f8c65155SAlexander Yermolovich       break;
130f8c65155SAlexander Yermolovich     }
131f8c65155SAlexander Yermolovich     case dwarf::DW_AT_GNU_dwo_name:
132f8c65155SAlexander Yermolovich     case dwarf::DW_AT_dwo_name: {
133f8c65155SAlexander Yermolovich       Expected<const char *> EName = getIndexedString(
134f8c65155SAlexander Yermolovich           Form, InfoData, Offset, StrOffsets, Str, Header.Version);
135f8c65155SAlexander Yermolovich       if (!EName)
136f8c65155SAlexander Yermolovich         return EName.takeError();
137f8c65155SAlexander Yermolovich       ID.DWOName = *EName;
138f8c65155SAlexander Yermolovich       break;
139f8c65155SAlexander Yermolovich     }
140f8c65155SAlexander Yermolovich     case dwarf::DW_AT_GNU_dwo_id:
141f8c65155SAlexander Yermolovich       Header.Signature = InfoData.getU64(&Offset);
142f8c65155SAlexander Yermolovich       break;
143f8c65155SAlexander Yermolovich     default:
144f8c65155SAlexander Yermolovich       DWARFFormValue::skipValue(
145f8c65155SAlexander Yermolovich           Form, InfoData, &Offset,
146f8c65155SAlexander Yermolovich           dwarf::FormParams({Header.Version, Header.AddrSize, Header.Format}));
147f8c65155SAlexander Yermolovich     }
148f8c65155SAlexander Yermolovich   }
149f8c65155SAlexander Yermolovich   if (!Header.Signature)
150f8c65155SAlexander Yermolovich     return make_error<DWPError>("compile unit missing dwo_id");
151f8c65155SAlexander Yermolovich   ID.Signature = *Header.Signature;
152f8c65155SAlexander Yermolovich   return ID;
153f8c65155SAlexander Yermolovich }
154f8c65155SAlexander Yermolovich 
isSupportedSectionKind(DWARFSectionKind Kind)155f8c65155SAlexander Yermolovich static bool isSupportedSectionKind(DWARFSectionKind Kind) {
156f8c65155SAlexander Yermolovich   return Kind != DW_SECT_EXT_unknown;
157f8c65155SAlexander Yermolovich }
158f8c65155SAlexander Yermolovich 
159f8c65155SAlexander Yermolovich namespace llvm {
160f8c65155SAlexander Yermolovich // Convert an internal section identifier into the index to use with
161f8c65155SAlexander Yermolovich // UnitIndexEntry::Contributions.
getContributionIndex(DWARFSectionKind Kind,uint32_t IndexVersion)162f8c65155SAlexander Yermolovich unsigned getContributionIndex(DWARFSectionKind Kind, uint32_t IndexVersion) {
163f8c65155SAlexander Yermolovich   assert(serializeSectionKind(Kind, IndexVersion) >= DW_SECT_INFO);
164f8c65155SAlexander Yermolovich   return serializeSectionKind(Kind, IndexVersion) - DW_SECT_INFO;
165f8c65155SAlexander Yermolovich }
166f8c65155SAlexander Yermolovich } // namespace llvm
167f8c65155SAlexander Yermolovich 
168f8c65155SAlexander Yermolovich // Convert a UnitIndexEntry::Contributions index to the corresponding on-disk
169f8c65155SAlexander Yermolovich // value of the section identifier.
getOnDiskSectionId(unsigned Index)170f8c65155SAlexander Yermolovich static unsigned getOnDiskSectionId(unsigned Index) {
171f8c65155SAlexander Yermolovich   return Index + DW_SECT_INFO;
172f8c65155SAlexander Yermolovich }
173f8c65155SAlexander Yermolovich 
getSubsection(StringRef Section,const DWARFUnitIndex::Entry & Entry,DWARFSectionKind Kind)174f8c65155SAlexander Yermolovich static StringRef getSubsection(StringRef Section,
175f8c65155SAlexander Yermolovich                                const DWARFUnitIndex::Entry &Entry,
176f8c65155SAlexander Yermolovich                                DWARFSectionKind Kind) {
177f8c65155SAlexander Yermolovich   const auto *Off = Entry.getContribution(Kind);
178f8c65155SAlexander Yermolovich   if (!Off)
179f8c65155SAlexander Yermolovich     return StringRef();
1807fc79340SAlexander Yermolovich   return Section.substr(Off->getOffset(), Off->getLength());
181f8c65155SAlexander Yermolovich }
182f8c65155SAlexander Yermolovich 
sectionOverflowErrorOrWarning(uint32_t PrevOffset,uint32_t OverflowedOffset,StringRef SectionName,OnCuIndexOverflow OverflowOptValue,bool & AnySectionOverflow)18353a483ceSzhuna static Error sectionOverflowErrorOrWarning(uint32_t PrevOffset,
18453a483ceSzhuna                                            uint32_t OverflowedOffset,
18553a483ceSzhuna                                            StringRef SectionName,
1864c44dcffSJinjie Huang                                            OnCuIndexOverflow OverflowOptValue,
1874c44dcffSJinjie Huang                                            bool &AnySectionOverflow) {
18853a483ceSzhuna   std::string Msg =
18953a483ceSzhuna       (SectionName +
19053a483ceSzhuna        Twine(" Section Contribution Offset overflow 4G. Previous Offset ") +
19153a483ceSzhuna        Twine(PrevOffset) + Twine(", After overflow offset ") +
19253a483ceSzhuna        Twine(OverflowedOffset) + Twine("."))
19353a483ceSzhuna           .str();
1944c44dcffSJinjie Huang   if (OverflowOptValue == OnCuIndexOverflow::Continue) {
1954c44dcffSJinjie Huang     WithColor::defaultWarningHandler(make_error<DWPError>(Msg));
1964c44dcffSJinjie Huang     return Error::success();
1974c44dcffSJinjie Huang   } else if (OverflowOptValue == OnCuIndexOverflow::SoftStop) {
1984c44dcffSJinjie Huang     AnySectionOverflow = true;
19953a483ceSzhuna     WithColor::defaultWarningHandler(make_error<DWPError>(Msg));
20053a483ceSzhuna     return Error::success();
20153a483ceSzhuna   }
20253a483ceSzhuna   return make_error<DWPError>(Msg);
20353a483ceSzhuna }
20453a483ceSzhuna 
addAllTypesFromDWP(MCStreamer & Out,MapVector<uint64_t,UnitIndexEntry> & TypeIndexEntries,const DWARFUnitIndex & TUIndex,MCSection * OutputTypes,StringRef Types,const UnitIndexEntry & TUEntry,uint32_t & TypesOffset,unsigned TypesContributionIndex,OnCuIndexOverflow OverflowOptValue,bool & AnySectionOverflow)20553a483ceSzhuna static Error addAllTypesFromDWP(
20653a483ceSzhuna     MCStreamer &Out, MapVector<uint64_t, UnitIndexEntry> &TypeIndexEntries,
20753a483ceSzhuna     const DWARFUnitIndex &TUIndex, MCSection *OutputTypes, StringRef Types,
20853a483ceSzhuna     const UnitIndexEntry &TUEntry, uint32_t &TypesOffset,
2094c44dcffSJinjie Huang     unsigned TypesContributionIndex, OnCuIndexOverflow OverflowOptValue,
2104c44dcffSJinjie Huang     bool &AnySectionOverflow) {
211adf4142fSFangrui Song   Out.switchSection(OutputTypes);
212f8c65155SAlexander Yermolovich   for (const DWARFUnitIndex::Entry &E : TUIndex.getRows()) {
213f8c65155SAlexander Yermolovich     auto *I = E.getContributions();
214f8c65155SAlexander Yermolovich     if (!I)
215f8c65155SAlexander Yermolovich       continue;
216f8c65155SAlexander Yermolovich     auto P = TypeIndexEntries.insert(std::make_pair(E.getSignature(), TUEntry));
217f8c65155SAlexander Yermolovich     if (!P.second)
218f8c65155SAlexander Yermolovich       continue;
219f8c65155SAlexander Yermolovich     auto &Entry = P.first->second;
220f8c65155SAlexander Yermolovich     // Zero out the debug_info contribution
221f8c65155SAlexander Yermolovich     Entry.Contributions[0] = {};
222f8c65155SAlexander Yermolovich     for (auto Kind : TUIndex.getColumnKinds()) {
223f8c65155SAlexander Yermolovich       if (!isSupportedSectionKind(Kind))
224f8c65155SAlexander Yermolovich         continue;
225f8c65155SAlexander Yermolovich       auto &C =
226f8c65155SAlexander Yermolovich           Entry.Contributions[getContributionIndex(Kind, TUIndex.getVersion())];
2277fc79340SAlexander Yermolovich       C.setOffset(C.getOffset() + I->getOffset());
2287fc79340SAlexander Yermolovich       C.setLength(I->getLength());
229f8c65155SAlexander Yermolovich       ++I;
230f8c65155SAlexander Yermolovich     }
231f8c65155SAlexander Yermolovich     auto &C = Entry.Contributions[TypesContributionIndex];
232f8c65155SAlexander Yermolovich     Out.emitBytes(Types.substr(
2337fc79340SAlexander Yermolovich         C.getOffset() -
2347fc79340SAlexander Yermolovich             TUEntry.Contributions[TypesContributionIndex].getOffset(),
2357fc79340SAlexander Yermolovich         C.getLength()));
2367fc79340SAlexander Yermolovich     C.setOffset(TypesOffset);
23753a483ceSzhuna     uint32_t OldOffset = TypesOffset;
23853a483ceSzhuna     static_assert(sizeof(OldOffset) == sizeof(TypesOffset));
2397fc79340SAlexander Yermolovich     TypesOffset += C.getLength();
24053a483ceSzhuna     if (OldOffset > TypesOffset) {
2414c44dcffSJinjie Huang       if (Error Err = sectionOverflowErrorOrWarning(OldOffset, TypesOffset,
2424c44dcffSJinjie Huang                                                     "Types", OverflowOptValue,
2434c44dcffSJinjie Huang                                                     AnySectionOverflow))
24453a483ceSzhuna         return Err;
2454c44dcffSJinjie Huang       if (AnySectionOverflow) {
2464c44dcffSJinjie Huang         TypesOffset = OldOffset;
2474c44dcffSJinjie Huang         return Error::success();
2484c44dcffSJinjie Huang       }
249f8c65155SAlexander Yermolovich     }
250f8c65155SAlexander Yermolovich   }
25153a483ceSzhuna   return Error::success();
25253a483ceSzhuna }
253f8c65155SAlexander Yermolovich 
addAllTypesFromTypesSection(MCStreamer & Out,MapVector<uint64_t,UnitIndexEntry> & TypeIndexEntries,MCSection * OutputTypes,const std::vector<StringRef> & TypesSections,const UnitIndexEntry & CUEntry,uint32_t & TypesOffset,OnCuIndexOverflow OverflowOptValue,bool & AnySectionOverflow)25453a483ceSzhuna static Error addAllTypesFromTypesSection(
255f8c65155SAlexander Yermolovich     MCStreamer &Out, MapVector<uint64_t, UnitIndexEntry> &TypeIndexEntries,
256f8c65155SAlexander Yermolovich     MCSection *OutputTypes, const std::vector<StringRef> &TypesSections,
25753a483ceSzhuna     const UnitIndexEntry &CUEntry, uint32_t &TypesOffset,
2584c44dcffSJinjie Huang     OnCuIndexOverflow OverflowOptValue, bool &AnySectionOverflow) {
259f8c65155SAlexander Yermolovich   for (StringRef Types : TypesSections) {
260adf4142fSFangrui Song     Out.switchSection(OutputTypes);
261f8c65155SAlexander Yermolovich     uint64_t Offset = 0;
262f8c65155SAlexander Yermolovich     DataExtractor Data(Types, true, 0);
263f8c65155SAlexander Yermolovich     while (Data.isValidOffset(Offset)) {
264f8c65155SAlexander Yermolovich       UnitIndexEntry Entry = CUEntry;
265f8c65155SAlexander Yermolovich       // Zero out the debug_info contribution
266f8c65155SAlexander Yermolovich       Entry.Contributions[0] = {};
267f8c65155SAlexander Yermolovich       auto &C = Entry.Contributions[getContributionIndex(DW_SECT_EXT_TYPES, 2)];
2687fc79340SAlexander Yermolovich       C.setOffset(TypesOffset);
269f8c65155SAlexander Yermolovich       auto PrevOffset = Offset;
270f8c65155SAlexander Yermolovich       // Length of the unit, including the 4 byte length field.
2717fc79340SAlexander Yermolovich       C.setLength(Data.getU32(&Offset) + 4);
272f8c65155SAlexander Yermolovich 
273f8c65155SAlexander Yermolovich       Data.getU16(&Offset); // Version
274f8c65155SAlexander Yermolovich       Data.getU32(&Offset); // Abbrev offset
275f8c65155SAlexander Yermolovich       Data.getU8(&Offset);  // Address size
276f8c65155SAlexander Yermolovich       auto Signature = Data.getU64(&Offset);
2777fc79340SAlexander Yermolovich       Offset = PrevOffset + C.getLength32();
278f8c65155SAlexander Yermolovich 
279f8c65155SAlexander Yermolovich       auto P = TypeIndexEntries.insert(std::make_pair(Signature, Entry));
280f8c65155SAlexander Yermolovich       if (!P.second)
281f8c65155SAlexander Yermolovich         continue;
282f8c65155SAlexander Yermolovich 
2837fc79340SAlexander Yermolovich       Out.emitBytes(Types.substr(PrevOffset, C.getLength32()));
28453a483ceSzhuna       uint32_t OldOffset = TypesOffset;
2857fc79340SAlexander Yermolovich       TypesOffset += C.getLength32();
28653a483ceSzhuna       if (OldOffset > TypesOffset) {
2874c44dcffSJinjie Huang         if (Error Err = sectionOverflowErrorOrWarning(OldOffset, TypesOffset,
2884c44dcffSJinjie Huang                                                       "Types", OverflowOptValue,
2894c44dcffSJinjie Huang                                                       AnySectionOverflow))
29053a483ceSzhuna           return Err;
2914c44dcffSJinjie Huang         if (AnySectionOverflow) {
2924c44dcffSJinjie Huang           TypesOffset = OldOffset;
2934c44dcffSJinjie Huang           return Error::success();
2944c44dcffSJinjie Huang         }
295f8c65155SAlexander Yermolovich       }
296f8c65155SAlexander Yermolovich     }
297f8c65155SAlexander Yermolovich   }
29853a483ceSzhuna   return Error::success();
29953a483ceSzhuna }
300f8c65155SAlexander Yermolovich 
buildDWODescription(StringRef Name,StringRef DWPName,StringRef DWOName)301f8c65155SAlexander Yermolovich static std::string buildDWODescription(StringRef Name, StringRef DWPName,
302f8c65155SAlexander Yermolovich                                        StringRef DWOName) {
303f8c65155SAlexander Yermolovich   std::string Text = "\'";
304f8c65155SAlexander Yermolovich   Text += Name;
305f8c65155SAlexander Yermolovich   Text += '\'';
3066139626dSDavid Blaikie   bool HasDWO = !DWOName.empty();
3076139626dSDavid Blaikie   bool HasDWP = !DWPName.empty();
3086139626dSDavid Blaikie   if (HasDWO || HasDWP) {
309f8c65155SAlexander Yermolovich     Text += " (from ";
3106139626dSDavid Blaikie     if (HasDWO) {
311f8c65155SAlexander Yermolovich       Text += '\'';
312f8c65155SAlexander Yermolovich       Text += DWOName;
3136139626dSDavid Blaikie       Text += '\'';
314f8c65155SAlexander Yermolovich     }
3156139626dSDavid Blaikie     if (HasDWO && HasDWP)
3166139626dSDavid Blaikie       Text += " in ";
3176139626dSDavid Blaikie     if (!DWPName.empty()) {
318f8c65155SAlexander Yermolovich       Text += '\'';
319f8c65155SAlexander Yermolovich       Text += DWPName;
3206139626dSDavid Blaikie       Text += '\'';
3216139626dSDavid Blaikie     }
3226139626dSDavid Blaikie     Text += ")";
323f8c65155SAlexander Yermolovich   }
324f8c65155SAlexander Yermolovich   return Text;
325f8c65155SAlexander Yermolovich }
326f8c65155SAlexander Yermolovich 
createError(StringRef Name,Error E)327f8c65155SAlexander Yermolovich static Error createError(StringRef Name, Error E) {
328f8c65155SAlexander Yermolovich   return make_error<DWPError>(
329f8c65155SAlexander Yermolovich       ("failure while decompressing compressed section: '" + Name + "', " +
330f8c65155SAlexander Yermolovich        llvm::toString(std::move(E)))
331f8c65155SAlexander Yermolovich           .str());
332f8c65155SAlexander Yermolovich }
333f8c65155SAlexander Yermolovich 
334f8c65155SAlexander Yermolovich static Error
handleCompressedSection(std::deque<SmallString<32>> & UncompressedSections,SectionRef Sec,StringRef Name,StringRef & Contents)335f8c65155SAlexander Yermolovich handleCompressedSection(std::deque<SmallString<32>> &UncompressedSections,
336141c9d77SFangrui Song                         SectionRef Sec, StringRef Name, StringRef &Contents) {
337141c9d77SFangrui Song   auto *Obj = dyn_cast<ELFObjectFileBase>(Sec.getObject());
338141c9d77SFangrui Song   if (!Obj ||
339141c9d77SFangrui Song       !(static_cast<ELFSectionRef>(Sec).getFlags() & ELF::SHF_COMPRESSED))
340f8c65155SAlexander Yermolovich     return Error::success();
341141c9d77SFangrui Song   bool IsLE = isa<object::ELF32LEObjectFile>(Obj) ||
342141c9d77SFangrui Song               isa<object::ELF64LEObjectFile>(Obj);
343141c9d77SFangrui Song   bool Is64 = isa<object::ELF64LEObjectFile>(Obj) ||
344141c9d77SFangrui Song               isa<object::ELF64BEObjectFile>(Obj);
345141c9d77SFangrui Song   Expected<Decompressor> Dec = Decompressor::create(Name, Contents, IsLE, Is64);
346f8c65155SAlexander Yermolovich   if (!Dec)
347f8c65155SAlexander Yermolovich     return createError(Name, Dec.takeError());
348f8c65155SAlexander Yermolovich 
349f8c65155SAlexander Yermolovich   UncompressedSections.emplace_back();
350f8c65155SAlexander Yermolovich   if (Error E = Dec->resizeAndDecompress(UncompressedSections.back()))
351f8c65155SAlexander Yermolovich     return createError(Name, std::move(E));
352f8c65155SAlexander Yermolovich 
353f8c65155SAlexander Yermolovich   Contents = UncompressedSections.back();
354f8c65155SAlexander Yermolovich   return Error::success();
355f8c65155SAlexander Yermolovich }
356f8c65155SAlexander Yermolovich 
357f8c65155SAlexander Yermolovich namespace llvm {
358f8c65155SAlexander Yermolovich // Parse and return the header of an info section compile/type unit.
parseInfoSectionUnitHeader(StringRef Info)359f8c65155SAlexander Yermolovich Expected<InfoSectionUnitHeader> parseInfoSectionUnitHeader(StringRef Info) {
360f8c65155SAlexander Yermolovich   InfoSectionUnitHeader Header;
361f8c65155SAlexander Yermolovich   Error Err = Error::success();
362f8c65155SAlexander Yermolovich   uint64_t Offset = 0;
363f8c65155SAlexander Yermolovich   DWARFDataExtractor InfoData(Info, true, 0);
364f8c65155SAlexander Yermolovich   std::tie(Header.Length, Header.Format) =
365f8c65155SAlexander Yermolovich       InfoData.getInitialLength(&Offset, &Err);
366f8c65155SAlexander Yermolovich   if (Err)
367f8c65155SAlexander Yermolovich     return make_error<DWPError>("cannot parse compile unit length: " +
368f8c65155SAlexander Yermolovich                                 llvm::toString(std::move(Err)));
369f8c65155SAlexander Yermolovich 
370f8c65155SAlexander Yermolovich   if (!InfoData.isValidOffset(Offset + (Header.Length - 1))) {
371f8c65155SAlexander Yermolovich     return make_error<DWPError>(
372f8c65155SAlexander Yermolovich         "compile unit exceeds .debug_info section range: " +
373f8c65155SAlexander Yermolovich         utostr(Offset + Header.Length) + " >= " + utostr(InfoData.size()));
374f8c65155SAlexander Yermolovich   }
375f8c65155SAlexander Yermolovich 
376f8c65155SAlexander Yermolovich   Header.Version = InfoData.getU16(&Offset, &Err);
377f8c65155SAlexander Yermolovich   if (Err)
378f8c65155SAlexander Yermolovich     return make_error<DWPError>("cannot parse compile unit version: " +
379f8c65155SAlexander Yermolovich                                 llvm::toString(std::move(Err)));
380f8c65155SAlexander Yermolovich 
381f8c65155SAlexander Yermolovich   uint64_t MinHeaderLength;
382f8c65155SAlexander Yermolovich   if (Header.Version >= 5) {
383f8c65155SAlexander Yermolovich     // Size: Version (2), UnitType (1), AddrSize (1), DebugAbbrevOffset (4),
384f8c65155SAlexander Yermolovich     // Signature (8)
385f8c65155SAlexander Yermolovich     MinHeaderLength = 16;
386f8c65155SAlexander Yermolovich   } else {
387f8c65155SAlexander Yermolovich     // Size: Version (2), DebugAbbrevOffset (4), AddrSize (1)
388f8c65155SAlexander Yermolovich     MinHeaderLength = 7;
389f8c65155SAlexander Yermolovich   }
390f8c65155SAlexander Yermolovich   if (Header.Length < MinHeaderLength) {
391f8c65155SAlexander Yermolovich     return make_error<DWPError>("unit length is too small: expected at least " +
392f8c65155SAlexander Yermolovich                                 utostr(MinHeaderLength) + " got " +
393f8c65155SAlexander Yermolovich                                 utostr(Header.Length) + ".");
394f8c65155SAlexander Yermolovich   }
395f8c65155SAlexander Yermolovich   if (Header.Version >= 5) {
396f8c65155SAlexander Yermolovich     Header.UnitType = InfoData.getU8(&Offset);
397f8c65155SAlexander Yermolovich     Header.AddrSize = InfoData.getU8(&Offset);
398f8c65155SAlexander Yermolovich     Header.DebugAbbrevOffset = InfoData.getU32(&Offset);
399f8c65155SAlexander Yermolovich     Header.Signature = InfoData.getU64(&Offset);
400f8c65155SAlexander Yermolovich     if (Header.UnitType == dwarf::DW_UT_split_type) {
401f8c65155SAlexander Yermolovich       // Type offset.
402f8c65155SAlexander Yermolovich       MinHeaderLength += 4;
403f8c65155SAlexander Yermolovich       if (Header.Length < MinHeaderLength)
404f8c65155SAlexander Yermolovich         return make_error<DWPError>("type unit is missing type offset");
405f8c65155SAlexander Yermolovich       InfoData.getU32(&Offset);
406f8c65155SAlexander Yermolovich     }
407f8c65155SAlexander Yermolovich   } else {
408f8c65155SAlexander Yermolovich     // Note that, address_size and debug_abbrev_offset fields have switched
409f8c65155SAlexander Yermolovich     // places between dwarf version 4 and 5.
410f8c65155SAlexander Yermolovich     Header.DebugAbbrevOffset = InfoData.getU32(&Offset);
411f8c65155SAlexander Yermolovich     Header.AddrSize = InfoData.getU8(&Offset);
412f8c65155SAlexander Yermolovich   }
413f8c65155SAlexander Yermolovich 
414f8c65155SAlexander Yermolovich   Header.HeaderSize = Offset;
415f8c65155SAlexander Yermolovich   return Header;
416f8c65155SAlexander Yermolovich }
417f8c65155SAlexander Yermolovich 
writeNewOffsetsTo(MCStreamer & Out,DataExtractor & Data,DenseMap<uint64_t,uint32_t> & OffsetRemapping,uint64_t & Offset,uint64_t & Size)418*699cd9acSMorten larsen static void writeNewOffsetsTo(MCStreamer &Out, DataExtractor &Data,
419*699cd9acSMorten larsen                               DenseMap<uint64_t, uint32_t> &OffsetRemapping,
420*699cd9acSMorten larsen                               uint64_t &Offset, uint64_t &Size) {
421*699cd9acSMorten larsen 
422*699cd9acSMorten larsen   while (Offset < Size) {
423*699cd9acSMorten larsen     auto OldOffset = Data.getU32(&Offset);
424*699cd9acSMorten larsen     auto NewOffset = OffsetRemapping[OldOffset];
425*699cd9acSMorten larsen     Out.emitIntValue(NewOffset, 4);
426*699cd9acSMorten larsen   }
427*699cd9acSMorten larsen }
428*699cd9acSMorten larsen 
writeStringsAndOffsets(MCStreamer & Out,DWPStringPool & Strings,MCSection * StrOffsetSection,StringRef CurStrSection,StringRef CurStrOffsetSection,uint16_t Version)429f8c65155SAlexander Yermolovich void writeStringsAndOffsets(MCStreamer &Out, DWPStringPool &Strings,
430f8c65155SAlexander Yermolovich                             MCSection *StrOffsetSection,
431f8c65155SAlexander Yermolovich                             StringRef CurStrSection,
432f8c65155SAlexander Yermolovich                             StringRef CurStrOffsetSection, uint16_t Version) {
433f8c65155SAlexander Yermolovich   // Could possibly produce an error or warning if one of these was non-null but
434f8c65155SAlexander Yermolovich   // the other was null.
435f8c65155SAlexander Yermolovich   if (CurStrSection.empty() || CurStrOffsetSection.empty())
436f8c65155SAlexander Yermolovich     return;
437f8c65155SAlexander Yermolovich 
438f8c65155SAlexander Yermolovich   DenseMap<uint64_t, uint32_t> OffsetRemapping;
439f8c65155SAlexander Yermolovich 
440f8c65155SAlexander Yermolovich   DataExtractor Data(CurStrSection, true, 0);
441f8c65155SAlexander Yermolovich   uint64_t LocalOffset = 0;
442f8c65155SAlexander Yermolovich   uint64_t PrevOffset = 0;
443f8c65155SAlexander Yermolovich   while (const char *S = Data.getCStr(&LocalOffset)) {
444f8c65155SAlexander Yermolovich     OffsetRemapping[PrevOffset] =
445f8c65155SAlexander Yermolovich         Strings.getOffset(S, LocalOffset - PrevOffset);
446f8c65155SAlexander Yermolovich     PrevOffset = LocalOffset;
447f8c65155SAlexander Yermolovich   }
448f8c65155SAlexander Yermolovich 
449f8c65155SAlexander Yermolovich   Data = DataExtractor(CurStrOffsetSection, true, 0);
450f8c65155SAlexander Yermolovich 
451adf4142fSFangrui Song   Out.switchSection(StrOffsetSection);
452f8c65155SAlexander Yermolovich 
453f8c65155SAlexander Yermolovich   uint64_t Offset = 0;
454f8c65155SAlexander Yermolovich   uint64_t Size = CurStrOffsetSection.size();
455*699cd9acSMorten larsen   if (Version > 4) {
456f8c65155SAlexander Yermolovich     while (Offset < Size) {
457*699cd9acSMorten larsen       uint64_t HeaderSize = debugStrOffsetsHeaderSize(Data, Version);
458*699cd9acSMorten larsen       assert(HeaderSize <= Size - Offset &&
459*699cd9acSMorten larsen              "StrOffsetSection size is less than its header");
460*699cd9acSMorten larsen 
461*699cd9acSMorten larsen       uint64_t ContributionEnd = 0;
462*699cd9acSMorten larsen       uint64_t ContributionSize = 0;
463*699cd9acSMorten larsen       uint64_t HeaderLengthOffset = Offset;
464*699cd9acSMorten larsen       if (HeaderSize == 8) {
465*699cd9acSMorten larsen         ContributionSize = Data.getU32(&HeaderLengthOffset);
466*699cd9acSMorten larsen       } else if (HeaderSize == 16) {
467*699cd9acSMorten larsen         HeaderLengthOffset += 4; // skip the dwarf64 marker
468*699cd9acSMorten larsen         ContributionSize = Data.getU64(&HeaderLengthOffset);
469*699cd9acSMorten larsen       }
470*699cd9acSMorten larsen       ContributionEnd = ContributionSize + HeaderLengthOffset;
471*699cd9acSMorten larsen       Out.emitBytes(Data.getBytes(&Offset, HeaderSize));
472*699cd9acSMorten larsen       writeNewOffsetsTo(Out, Data, OffsetRemapping, Offset, ContributionEnd);
473*699cd9acSMorten larsen     }
474*699cd9acSMorten larsen 
475*699cd9acSMorten larsen   } else {
476*699cd9acSMorten larsen     writeNewOffsetsTo(Out, Data, OffsetRemapping, Offset, Size);
477f8c65155SAlexander Yermolovich   }
478f8c65155SAlexander Yermolovich }
479f8c65155SAlexander Yermolovich 
4807fc79340SAlexander Yermolovich enum AccessField { Offset, Length };
writeIndexTable(MCStreamer & Out,ArrayRef<unsigned> ContributionOffsets,const MapVector<uint64_t,UnitIndexEntry> & IndexEntries,const AccessField & Field)4817fc79340SAlexander Yermolovich void writeIndexTable(MCStreamer &Out, ArrayRef<unsigned> ContributionOffsets,
482f8c65155SAlexander Yermolovich                      const MapVector<uint64_t, UnitIndexEntry> &IndexEntries,
4837fc79340SAlexander Yermolovich                      const AccessField &Field) {
484f8c65155SAlexander Yermolovich   for (const auto &E : IndexEntries)
4855e96cea1SJoe Loser     for (size_t I = 0; I != std::size(E.second.Contributions); ++I)
486f8c65155SAlexander Yermolovich       if (ContributionOffsets[I])
4877fc79340SAlexander Yermolovich         Out.emitIntValue((Field == AccessField::Offset
4887fc79340SAlexander Yermolovich                               ? E.second.Contributions[I].getOffset32()
4897fc79340SAlexander Yermolovich                               : E.second.Contributions[I].getLength32()),
4907fc79340SAlexander Yermolovich                          4);
491f8c65155SAlexander Yermolovich }
492f8c65155SAlexander Yermolovich 
writeIndex(MCStreamer & Out,MCSection * Section,ArrayRef<unsigned> ContributionOffsets,const MapVector<uint64_t,UnitIndexEntry> & IndexEntries,uint32_t IndexVersion)493f8c65155SAlexander Yermolovich void writeIndex(MCStreamer &Out, MCSection *Section,
494f8c65155SAlexander Yermolovich                 ArrayRef<unsigned> ContributionOffsets,
495f8c65155SAlexander Yermolovich                 const MapVector<uint64_t, UnitIndexEntry> &IndexEntries,
496f8c65155SAlexander Yermolovich                 uint32_t IndexVersion) {
497f8c65155SAlexander Yermolovich   if (IndexEntries.empty())
498f8c65155SAlexander Yermolovich     return;
499f8c65155SAlexander Yermolovich 
500f8c65155SAlexander Yermolovich   unsigned Columns = 0;
501f8c65155SAlexander Yermolovich   for (auto &C : ContributionOffsets)
502f8c65155SAlexander Yermolovich     if (C)
503f8c65155SAlexander Yermolovich       ++Columns;
504f8c65155SAlexander Yermolovich 
505f8c65155SAlexander Yermolovich   std::vector<unsigned> Buckets(NextPowerOf2(3 * IndexEntries.size() / 2));
506f8c65155SAlexander Yermolovich   uint64_t Mask = Buckets.size() - 1;
507f8c65155SAlexander Yermolovich   size_t I = 0;
508f8c65155SAlexander Yermolovich   for (const auto &P : IndexEntries) {
509f8c65155SAlexander Yermolovich     auto S = P.first;
510f8c65155SAlexander Yermolovich     auto H = S & Mask;
511f8c65155SAlexander Yermolovich     auto HP = ((S >> 32) & Mask) | 1;
512f8c65155SAlexander Yermolovich     while (Buckets[H]) {
513f8c65155SAlexander Yermolovich       assert(S != IndexEntries.begin()[Buckets[H] - 1].first &&
514f8c65155SAlexander Yermolovich              "Duplicate unit");
515f8c65155SAlexander Yermolovich       H = (H + HP) & Mask;
516f8c65155SAlexander Yermolovich     }
517f8c65155SAlexander Yermolovich     Buckets[H] = I + 1;
518f8c65155SAlexander Yermolovich     ++I;
519f8c65155SAlexander Yermolovich   }
520f8c65155SAlexander Yermolovich 
521adf4142fSFangrui Song   Out.switchSection(Section);
522f8c65155SAlexander Yermolovich   Out.emitIntValue(IndexVersion, 4);        // Version
523f8c65155SAlexander Yermolovich   Out.emitIntValue(Columns, 4);             // Columns
524f8c65155SAlexander Yermolovich   Out.emitIntValue(IndexEntries.size(), 4); // Num Units
525f8c65155SAlexander Yermolovich   Out.emitIntValue(Buckets.size(), 4);      // Num Buckets
526f8c65155SAlexander Yermolovich 
527f8c65155SAlexander Yermolovich   // Write the signatures.
528f8c65155SAlexander Yermolovich   for (const auto &I : Buckets)
529f8c65155SAlexander Yermolovich     Out.emitIntValue(I ? IndexEntries.begin()[I - 1].first : 0, 8);
530f8c65155SAlexander Yermolovich 
531f8c65155SAlexander Yermolovich   // Write the indexes.
532f8c65155SAlexander Yermolovich   for (const auto &I : Buckets)
533f8c65155SAlexander Yermolovich     Out.emitIntValue(I, 4);
534f8c65155SAlexander Yermolovich 
535f8c65155SAlexander Yermolovich   // Write the column headers (which sections will appear in the table)
536f8c65155SAlexander Yermolovich   for (size_t I = 0; I != ContributionOffsets.size(); ++I)
537f8c65155SAlexander Yermolovich     if (ContributionOffsets[I])
538f8c65155SAlexander Yermolovich       Out.emitIntValue(getOnDiskSectionId(I), 4);
539f8c65155SAlexander Yermolovich 
540f8c65155SAlexander Yermolovich   // Write the offsets.
5417fc79340SAlexander Yermolovich   writeIndexTable(Out, ContributionOffsets, IndexEntries, AccessField::Offset);
542f8c65155SAlexander Yermolovich 
543f8c65155SAlexander Yermolovich   // Write the lengths.
5447fc79340SAlexander Yermolovich   writeIndexTable(Out, ContributionOffsets, IndexEntries, AccessField::Length);
545f8c65155SAlexander Yermolovich }
546f8c65155SAlexander Yermolovich 
buildDuplicateError(const std::pair<uint64_t,UnitIndexEntry> & PrevE,const CompileUnitIdentifiers & ID,StringRef DWPName)547f8c65155SAlexander Yermolovich Error buildDuplicateError(const std::pair<uint64_t, UnitIndexEntry> &PrevE,
548f8c65155SAlexander Yermolovich                           const CompileUnitIdentifiers &ID, StringRef DWPName) {
549f8c65155SAlexander Yermolovich   return make_error<DWPError>(
550f8c65155SAlexander Yermolovich       std::string("duplicate DWO ID (") + utohexstr(PrevE.first) + ") in " +
551f8c65155SAlexander Yermolovich       buildDWODescription(PrevE.second.Name, PrevE.second.DWPName,
552f8c65155SAlexander Yermolovich                           PrevE.second.DWOName) +
553f8c65155SAlexander Yermolovich       " and " + buildDWODescription(ID.Name, DWPName, ID.DWOName));
554f8c65155SAlexander Yermolovich }
555f8c65155SAlexander Yermolovich 
handleSection(const StringMap<std::pair<MCSection *,DWARFSectionKind>> & KnownSections,const MCSection * StrSection,const MCSection * StrOffsetSection,const MCSection * TypesSection,const MCSection * CUIndexSection,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,std::vector<StringRef> & CurInfoSection,StringRef & AbbrevSection,StringRef & CurCUIndexSection,StringRef & CurTUIndexSection,std::vector<std::pair<DWARFSectionKind,uint32_t>> & SectionLength)556f8c65155SAlexander Yermolovich Error handleSection(
557f8c65155SAlexander Yermolovich     const StringMap<std::pair<MCSection *, DWARFSectionKind>> &KnownSections,
558f8c65155SAlexander Yermolovich     const MCSection *StrSection, const MCSection *StrOffsetSection,
559f8c65155SAlexander Yermolovich     const MCSection *TypesSection, const MCSection *CUIndexSection,
560f8c65155SAlexander Yermolovich     const MCSection *TUIndexSection, const MCSection *InfoSection,
561f8c65155SAlexander Yermolovich     const SectionRef &Section, MCStreamer &Out,
562f8c65155SAlexander Yermolovich     std::deque<SmallString<32>> &UncompressedSections,
563f8c65155SAlexander Yermolovich     uint32_t (&ContributionOffsets)[8], UnitIndexEntry &CurEntry,
564f8c65155SAlexander Yermolovich     StringRef &CurStrSection, StringRef &CurStrOffsetSection,
565f8c65155SAlexander Yermolovich     std::vector<StringRef> &CurTypesSection,
566f8c65155SAlexander Yermolovich     std::vector<StringRef> &CurInfoSection, StringRef &AbbrevSection,
567f8c65155SAlexander Yermolovich     StringRef &CurCUIndexSection, StringRef &CurTUIndexSection,
568f8c65155SAlexander Yermolovich     std::vector<std::pair<DWARFSectionKind, uint32_t>> &SectionLength) {
569f8c65155SAlexander Yermolovich   if (Section.isBSS())
570f8c65155SAlexander Yermolovich     return Error::success();
571f8c65155SAlexander Yermolovich 
572f8c65155SAlexander Yermolovich   if (Section.isVirtual())
573f8c65155SAlexander Yermolovich     return Error::success();
574f8c65155SAlexander Yermolovich 
575f8c65155SAlexander Yermolovich   Expected<StringRef> NameOrErr = Section.getName();
576f8c65155SAlexander Yermolovich   if (!NameOrErr)
577f8c65155SAlexander Yermolovich     return NameOrErr.takeError();
578f8c65155SAlexander Yermolovich   StringRef Name = *NameOrErr;
579f8c65155SAlexander Yermolovich 
580f8c65155SAlexander Yermolovich   Expected<StringRef> ContentsOrErr = Section.getContents();
581f8c65155SAlexander Yermolovich   if (!ContentsOrErr)
582f8c65155SAlexander Yermolovich     return ContentsOrErr.takeError();
583f8c65155SAlexander Yermolovich   StringRef Contents = *ContentsOrErr;
584f8c65155SAlexander Yermolovich 
585141c9d77SFangrui Song   if (auto Err = handleCompressedSection(UncompressedSections, Section, Name,
586141c9d77SFangrui Song                                          Contents))
587f8c65155SAlexander Yermolovich     return Err;
588f8c65155SAlexander Yermolovich 
589f8c65155SAlexander Yermolovich   Name = Name.substr(Name.find_first_not_of("._"));
590f8c65155SAlexander Yermolovich 
591f8c65155SAlexander Yermolovich   auto SectionPair = KnownSections.find(Name);
592f8c65155SAlexander Yermolovich   if (SectionPair == KnownSections.end())
593f8c65155SAlexander Yermolovich     return Error::success();
594f8c65155SAlexander Yermolovich 
595f8c65155SAlexander Yermolovich   if (DWARFSectionKind Kind = SectionPair->second.second) {
596f8c65155SAlexander Yermolovich     if (Kind != DW_SECT_EXT_TYPES && Kind != DW_SECT_INFO) {
597f8c65155SAlexander Yermolovich       SectionLength.push_back(std::make_pair(Kind, Contents.size()));
598f8c65155SAlexander Yermolovich     }
599f8c65155SAlexander Yermolovich 
600f8c65155SAlexander Yermolovich     if (Kind == DW_SECT_ABBREV) {
601f8c65155SAlexander Yermolovich       AbbrevSection = Contents;
602f8c65155SAlexander Yermolovich     }
603f8c65155SAlexander Yermolovich   }
604f8c65155SAlexander Yermolovich 
605f8c65155SAlexander Yermolovich   MCSection *OutSection = SectionPair->second.first;
606f8c65155SAlexander Yermolovich   if (OutSection == StrOffsetSection)
607f8c65155SAlexander Yermolovich     CurStrOffsetSection = Contents;
608f8c65155SAlexander Yermolovich   else if (OutSection == StrSection)
609f8c65155SAlexander Yermolovich     CurStrSection = Contents;
610f8c65155SAlexander Yermolovich   else if (OutSection == TypesSection)
611f8c65155SAlexander Yermolovich     CurTypesSection.push_back(Contents);
612f8c65155SAlexander Yermolovich   else if (OutSection == CUIndexSection)
613f8c65155SAlexander Yermolovich     CurCUIndexSection = Contents;
614f8c65155SAlexander Yermolovich   else if (OutSection == TUIndexSection)
615f8c65155SAlexander Yermolovich     CurTUIndexSection = Contents;
616f8c65155SAlexander Yermolovich   else if (OutSection == InfoSection)
617f8c65155SAlexander Yermolovich     CurInfoSection.push_back(Contents);
618f8c65155SAlexander Yermolovich   else {
619adf4142fSFangrui Song     Out.switchSection(OutSection);
620f8c65155SAlexander Yermolovich     Out.emitBytes(Contents);
621f8c65155SAlexander Yermolovich   }
622f8c65155SAlexander Yermolovich   return Error::success();
623f8c65155SAlexander Yermolovich }
624f8c65155SAlexander Yermolovich 
write(MCStreamer & Out,ArrayRef<std::string> Inputs,OnCuIndexOverflow OverflowOptValue)62553a483ceSzhuna Error write(MCStreamer &Out, ArrayRef<std::string> Inputs,
6264c44dcffSJinjie Huang             OnCuIndexOverflow OverflowOptValue) {
627f8c65155SAlexander Yermolovich   const auto &MCOFI = *Out.getContext().getObjectFileInfo();
628f8c65155SAlexander Yermolovich   MCSection *const StrSection = MCOFI.getDwarfStrDWOSection();
629f8c65155SAlexander Yermolovich   MCSection *const StrOffsetSection = MCOFI.getDwarfStrOffDWOSection();
630f8c65155SAlexander Yermolovich   MCSection *const TypesSection = MCOFI.getDwarfTypesDWOSection();
631f8c65155SAlexander Yermolovich   MCSection *const CUIndexSection = MCOFI.getDwarfCUIndexSection();
632f8c65155SAlexander Yermolovich   MCSection *const TUIndexSection = MCOFI.getDwarfTUIndexSection();
633f8c65155SAlexander Yermolovich   MCSection *const InfoSection = MCOFI.getDwarfInfoDWOSection();
634f8c65155SAlexander Yermolovich   const StringMap<std::pair<MCSection *, DWARFSectionKind>> KnownSections = {
635f8c65155SAlexander Yermolovich       {"debug_info.dwo", {InfoSection, DW_SECT_INFO}},
636f8c65155SAlexander Yermolovich       {"debug_types.dwo", {MCOFI.getDwarfTypesDWOSection(), DW_SECT_EXT_TYPES}},
637f8c65155SAlexander Yermolovich       {"debug_str_offsets.dwo", {StrOffsetSection, DW_SECT_STR_OFFSETS}},
638f8c65155SAlexander Yermolovich       {"debug_str.dwo", {StrSection, static_cast<DWARFSectionKind>(0)}},
639f8c65155SAlexander Yermolovich       {"debug_loc.dwo", {MCOFI.getDwarfLocDWOSection(), DW_SECT_EXT_LOC}},
640f8c65155SAlexander Yermolovich       {"debug_line.dwo", {MCOFI.getDwarfLineDWOSection(), DW_SECT_LINE}},
641f8c65155SAlexander Yermolovich       {"debug_macro.dwo", {MCOFI.getDwarfMacroDWOSection(), DW_SECT_MACRO}},
642f8c65155SAlexander Yermolovich       {"debug_abbrev.dwo", {MCOFI.getDwarfAbbrevDWOSection(), DW_SECT_ABBREV}},
643f8c65155SAlexander Yermolovich       {"debug_loclists.dwo",
644f8c65155SAlexander Yermolovich        {MCOFI.getDwarfLoclistsDWOSection(), DW_SECT_LOCLISTS}},
645f8c65155SAlexander Yermolovich       {"debug_rnglists.dwo",
646f8c65155SAlexander Yermolovich        {MCOFI.getDwarfRnglistsDWOSection(), DW_SECT_RNGLISTS}},
647f8c65155SAlexander Yermolovich       {"debug_cu_index", {CUIndexSection, static_cast<DWARFSectionKind>(0)}},
648f8c65155SAlexander Yermolovich       {"debug_tu_index", {TUIndexSection, static_cast<DWARFSectionKind>(0)}}};
649f8c65155SAlexander Yermolovich 
650f8c65155SAlexander Yermolovich   MapVector<uint64_t, UnitIndexEntry> IndexEntries;
651f8c65155SAlexander Yermolovich   MapVector<uint64_t, UnitIndexEntry> TypeIndexEntries;
652f8c65155SAlexander Yermolovich 
653f8c65155SAlexander Yermolovich   uint32_t ContributionOffsets[8] = {};
654f8c65155SAlexander Yermolovich   uint16_t Version = 0;
655f8c65155SAlexander Yermolovich   uint32_t IndexVersion = 0;
6564c44dcffSJinjie Huang   bool AnySectionOverflow = false;
657f8c65155SAlexander Yermolovich 
658f8c65155SAlexander Yermolovich   DWPStringPool Strings(Out, StrSection);
659f8c65155SAlexander Yermolovich 
660f8c65155SAlexander Yermolovich   SmallVector<OwningBinary<object::ObjectFile>, 128> Objects;
661f8c65155SAlexander Yermolovich   Objects.reserve(Inputs.size());
662f8c65155SAlexander Yermolovich 
663f8c65155SAlexander Yermolovich   std::deque<SmallString<32>> UncompressedSections;
664f8c65155SAlexander Yermolovich 
665f8c65155SAlexander Yermolovich   for (const auto &Input : Inputs) {
666f8c65155SAlexander Yermolovich     auto ErrOrObj = object::ObjectFile::createObjectFile(Input);
667734843ebSZhang Qing Shan     if (!ErrOrObj) {
668734843ebSZhang Qing Shan       return handleErrors(ErrOrObj.takeError(),
669734843ebSZhang Qing Shan                           [&](std::unique_ptr<ECError> EC) -> Error {
670734843ebSZhang Qing Shan                             return createFileError(Input, Error(std::move(EC)));
671734843ebSZhang Qing Shan                           });
672734843ebSZhang Qing Shan     }
673f8c65155SAlexander Yermolovich 
674f8c65155SAlexander Yermolovich     auto &Obj = *ErrOrObj->getBinary();
675f8c65155SAlexander Yermolovich     Objects.push_back(std::move(*ErrOrObj));
676f8c65155SAlexander Yermolovich 
677f8c65155SAlexander Yermolovich     UnitIndexEntry CurEntry = {};
678f8c65155SAlexander Yermolovich 
679f8c65155SAlexander Yermolovich     StringRef CurStrSection;
680f8c65155SAlexander Yermolovich     StringRef CurStrOffsetSection;
681f8c65155SAlexander Yermolovich     std::vector<StringRef> CurTypesSection;
682f8c65155SAlexander Yermolovich     std::vector<StringRef> CurInfoSection;
683f8c65155SAlexander Yermolovich     StringRef AbbrevSection;
684f8c65155SAlexander Yermolovich     StringRef CurCUIndexSection;
685f8c65155SAlexander Yermolovich     StringRef CurTUIndexSection;
686f8c65155SAlexander Yermolovich 
687f8c65155SAlexander Yermolovich     // This maps each section contained in this file to its length.
688f8c65155SAlexander Yermolovich     // This information is later on used to calculate the contributions,
689f8c65155SAlexander Yermolovich     // i.e. offset and length, of each compile/type unit to a section.
690f8c65155SAlexander Yermolovich     std::vector<std::pair<DWARFSectionKind, uint32_t>> SectionLength;
691f8c65155SAlexander Yermolovich 
692f8c65155SAlexander Yermolovich     for (const auto &Section : Obj.sections())
693f8c65155SAlexander Yermolovich       if (auto Err = handleSection(
694f8c65155SAlexander Yermolovich               KnownSections, StrSection, StrOffsetSection, TypesSection,
695f8c65155SAlexander Yermolovich               CUIndexSection, TUIndexSection, InfoSection, Section, Out,
696f8c65155SAlexander Yermolovich               UncompressedSections, ContributionOffsets, CurEntry,
697f8c65155SAlexander Yermolovich               CurStrSection, CurStrOffsetSection, CurTypesSection,
698f8c65155SAlexander Yermolovich               CurInfoSection, AbbrevSection, CurCUIndexSection,
699f8c65155SAlexander Yermolovich               CurTUIndexSection, SectionLength))
700f8c65155SAlexander Yermolovich         return Err;
701f8c65155SAlexander Yermolovich 
702f8c65155SAlexander Yermolovich     if (CurInfoSection.empty())
703f8c65155SAlexander Yermolovich       continue;
704f8c65155SAlexander Yermolovich 
705f8c65155SAlexander Yermolovich     Expected<InfoSectionUnitHeader> HeaderOrErr =
706f8c65155SAlexander Yermolovich         parseInfoSectionUnitHeader(CurInfoSection.front());
707f8c65155SAlexander Yermolovich     if (!HeaderOrErr)
708f8c65155SAlexander Yermolovich       return HeaderOrErr.takeError();
709f8c65155SAlexander Yermolovich     InfoSectionUnitHeader &Header = *HeaderOrErr;
710f8c65155SAlexander Yermolovich 
711f8c65155SAlexander Yermolovich     if (Version == 0) {
712f8c65155SAlexander Yermolovich       Version = Header.Version;
713f8c65155SAlexander Yermolovich       IndexVersion = Version < 5 ? 2 : 5;
714f8c65155SAlexander Yermolovich     } else if (Version != Header.Version) {
715f8c65155SAlexander Yermolovich       return make_error<DWPError>("incompatible DWARF compile unit versions.");
716f8c65155SAlexander Yermolovich     }
717f8c65155SAlexander Yermolovich 
718f8c65155SAlexander Yermolovich     writeStringsAndOffsets(Out, Strings, StrOffsetSection, CurStrSection,
719f8c65155SAlexander Yermolovich                            CurStrOffsetSection, Header.Version);
720f8c65155SAlexander Yermolovich 
721f8c65155SAlexander Yermolovich     for (auto Pair : SectionLength) {
722f8c65155SAlexander Yermolovich       auto Index = getContributionIndex(Pair.first, IndexVersion);
7237fc79340SAlexander Yermolovich       CurEntry.Contributions[Index].setOffset(ContributionOffsets[Index]);
7247fc79340SAlexander Yermolovich       CurEntry.Contributions[Index].setLength(Pair.second);
72553a483ceSzhuna       uint32_t OldOffset = ContributionOffsets[Index];
7267fc79340SAlexander Yermolovich       ContributionOffsets[Index] += CurEntry.Contributions[Index].getLength32();
72753a483ceSzhuna       if (OldOffset > ContributionOffsets[Index]) {
72853a483ceSzhuna         uint32_t SectionIndex = 0;
72953a483ceSzhuna         for (auto &Section : Obj.sections()) {
73053a483ceSzhuna           if (SectionIndex == Index) {
7314c44dcffSJinjie Huang             if (Error Err = sectionOverflowErrorOrWarning(
73253a483ceSzhuna                     OldOffset, ContributionOffsets[Index], *Section.getName(),
7334c44dcffSJinjie Huang                     OverflowOptValue, AnySectionOverflow))
7344c44dcffSJinjie Huang               return Err;
73553a483ceSzhuna           }
73653a483ceSzhuna           ++SectionIndex;
73753a483ceSzhuna         }
7384c44dcffSJinjie Huang         if (AnySectionOverflow)
7394c44dcffSJinjie Huang           break;
74053a483ceSzhuna       }
741f8c65155SAlexander Yermolovich     }
742f8c65155SAlexander Yermolovich 
743f8c65155SAlexander Yermolovich     uint32_t &InfoSectionOffset =
744f8c65155SAlexander Yermolovich         ContributionOffsets[getContributionIndex(DW_SECT_INFO, IndexVersion)];
745f8c65155SAlexander Yermolovich     if (CurCUIndexSection.empty()) {
746f8c65155SAlexander Yermolovich       bool FoundCUUnit = false;
747adf4142fSFangrui Song       Out.switchSection(InfoSection);
748f8c65155SAlexander Yermolovich       for (StringRef Info : CurInfoSection) {
749f8c65155SAlexander Yermolovich         uint64_t UnitOffset = 0;
750f8c65155SAlexander Yermolovich         while (Info.size() > UnitOffset) {
751f8c65155SAlexander Yermolovich           Expected<InfoSectionUnitHeader> HeaderOrError =
752f8c65155SAlexander Yermolovich               parseInfoSectionUnitHeader(Info.substr(UnitOffset, Info.size()));
753f8c65155SAlexander Yermolovich           if (!HeaderOrError)
754f8c65155SAlexander Yermolovich             return HeaderOrError.takeError();
755f8c65155SAlexander Yermolovich           InfoSectionUnitHeader &Header = *HeaderOrError;
756f8c65155SAlexander Yermolovich 
757f8c65155SAlexander Yermolovich           UnitIndexEntry Entry = CurEntry;
758f8c65155SAlexander Yermolovich           auto &C = Entry.Contributions[getContributionIndex(DW_SECT_INFO,
759f8c65155SAlexander Yermolovich                                                              IndexVersion)];
7607fc79340SAlexander Yermolovich           C.setOffset(InfoSectionOffset);
7617fc79340SAlexander Yermolovich           C.setLength(Header.Length + 4);
762f8df8114SAlexander Yermolovich 
763f8df8114SAlexander Yermolovich           if (std::numeric_limits<uint32_t>::max() - InfoSectionOffset <
76453a483ceSzhuna               C.getLength32()) {
76553a483ceSzhuna             if (Error Err = sectionOverflowErrorOrWarning(
76653a483ceSzhuna                     InfoSectionOffset, InfoSectionOffset + C.getLength32(),
7674c44dcffSJinjie Huang                     "debug_info", OverflowOptValue, AnySectionOverflow))
76853a483ceSzhuna               return Err;
7694c44dcffSJinjie Huang             if (AnySectionOverflow) {
7704c44dcffSJinjie Huang               if (Header.Version < 5 ||
7714c44dcffSJinjie Huang                   Header.UnitType == dwarf::DW_UT_split_compile)
7724c44dcffSJinjie Huang                 FoundCUUnit = true;
7734c44dcffSJinjie Huang               break;
7744c44dcffSJinjie Huang             }
77553a483ceSzhuna           }
776f8df8114SAlexander Yermolovich 
7777fc79340SAlexander Yermolovich           UnitOffset += C.getLength32();
778f8c65155SAlexander Yermolovich           if (Header.Version < 5 ||
779f8c65155SAlexander Yermolovich               Header.UnitType == dwarf::DW_UT_split_compile) {
7807fc79340SAlexander Yermolovich             Expected<CompileUnitIdentifiers> EID = getCUIdentifiers(
7817fc79340SAlexander Yermolovich                 Header, AbbrevSection,
7827fc79340SAlexander Yermolovich                 Info.substr(UnitOffset - C.getLength32(), C.getLength32()),
783f8c65155SAlexander Yermolovich                 CurStrOffsetSection, CurStrSection);
784f8c65155SAlexander Yermolovich 
785f8c65155SAlexander Yermolovich             if (!EID)
786f8c65155SAlexander Yermolovich               return createFileError(Input, EID.takeError());
787f8c65155SAlexander Yermolovich             const auto &ID = *EID;
788f8c65155SAlexander Yermolovich             auto P = IndexEntries.insert(std::make_pair(ID.Signature, Entry));
789f8c65155SAlexander Yermolovich             if (!P.second)
790f8c65155SAlexander Yermolovich               return buildDuplicateError(*P.first, ID, "");
791f8c65155SAlexander Yermolovich             P.first->second.Name = ID.Name;
792f8c65155SAlexander Yermolovich             P.first->second.DWOName = ID.DWOName;
793f8c65155SAlexander Yermolovich 
794f8c65155SAlexander Yermolovich             FoundCUUnit = true;
795f8c65155SAlexander Yermolovich           } else if (Header.UnitType == dwarf::DW_UT_split_type) {
796f8c65155SAlexander Yermolovich             auto P = TypeIndexEntries.insert(
7977a47ee51SKazu Hirata                 std::make_pair(*Header.Signature, Entry));
798f8c65155SAlexander Yermolovich             if (!P.second)
799f8c65155SAlexander Yermolovich               continue;
800f8c65155SAlexander Yermolovich           }
8017fc79340SAlexander Yermolovich           Out.emitBytes(
8027fc79340SAlexander Yermolovich               Info.substr(UnitOffset - C.getLength32(), C.getLength32()));
8037fc79340SAlexander Yermolovich           InfoSectionOffset += C.getLength32();
804f8c65155SAlexander Yermolovich         }
8054c44dcffSJinjie Huang         if (AnySectionOverflow)
8064c44dcffSJinjie Huang           break;
807f8c65155SAlexander Yermolovich       }
808f8c65155SAlexander Yermolovich 
809f8c65155SAlexander Yermolovich       if (!FoundCUUnit)
810f8c65155SAlexander Yermolovich         return make_error<DWPError>("no compile unit found in file: " + Input);
811f8c65155SAlexander Yermolovich 
812f8c65155SAlexander Yermolovich       if (IndexVersion == 2) {
813f8c65155SAlexander Yermolovich         // Add types from the .debug_types section from DWARF < 5.
81453a483ceSzhuna         if (Error Err = addAllTypesFromTypesSection(
815f8c65155SAlexander Yermolovich                 Out, TypeIndexEntries, TypesSection, CurTypesSection, CurEntry,
81653a483ceSzhuna                 ContributionOffsets[getContributionIndex(DW_SECT_EXT_TYPES, 2)],
8174c44dcffSJinjie Huang                 OverflowOptValue, AnySectionOverflow))
81853a483ceSzhuna           return Err;
819f8c65155SAlexander Yermolovich       }
8204c44dcffSJinjie Huang       if (AnySectionOverflow)
8214c44dcffSJinjie Huang         break;
822f8c65155SAlexander Yermolovich       continue;
823f8c65155SAlexander Yermolovich     }
824f8c65155SAlexander Yermolovich 
825f8c65155SAlexander Yermolovich     if (CurInfoSection.size() != 1)
826f8c65155SAlexander Yermolovich       return make_error<DWPError>("expected exactly one occurrence of a debug "
827f8c65155SAlexander Yermolovich                                   "info section in a .dwp file");
828f8c65155SAlexander Yermolovich     StringRef DwpSingleInfoSection = CurInfoSection.front();
829f8c65155SAlexander Yermolovich 
830f8c65155SAlexander Yermolovich     DWARFUnitIndex CUIndex(DW_SECT_INFO);
831f8c65155SAlexander Yermolovich     DataExtractor CUIndexData(CurCUIndexSection, Obj.isLittleEndian(), 0);
832f8c65155SAlexander Yermolovich     if (!CUIndex.parse(CUIndexData))
833f8c65155SAlexander Yermolovich       return make_error<DWPError>("failed to parse cu_index");
834f8c65155SAlexander Yermolovich     if (CUIndex.getVersion() != IndexVersion)
835f8c65155SAlexander Yermolovich       return make_error<DWPError>("incompatible cu_index versions, found " +
836f8c65155SAlexander Yermolovich                                   utostr(CUIndex.getVersion()) +
837f8c65155SAlexander Yermolovich                                   " and expecting " + utostr(IndexVersion));
838f8c65155SAlexander Yermolovich 
839adf4142fSFangrui Song     Out.switchSection(InfoSection);
840f8c65155SAlexander Yermolovich     for (const DWARFUnitIndex::Entry &E : CUIndex.getRows()) {
841f8c65155SAlexander Yermolovich       auto *I = E.getContributions();
842f8c65155SAlexander Yermolovich       if (!I)
843f8c65155SAlexander Yermolovich         continue;
844f8c65155SAlexander Yermolovich       auto P = IndexEntries.insert(std::make_pair(E.getSignature(), CurEntry));
845f8c65155SAlexander Yermolovich       StringRef CUInfoSection =
846f8c65155SAlexander Yermolovich           getSubsection(DwpSingleInfoSection, E, DW_SECT_INFO);
847f8c65155SAlexander Yermolovich       Expected<InfoSectionUnitHeader> HeaderOrError =
848f8c65155SAlexander Yermolovich           parseInfoSectionUnitHeader(CUInfoSection);
849f8c65155SAlexander Yermolovich       if (!HeaderOrError)
850f8c65155SAlexander Yermolovich         return HeaderOrError.takeError();
851f8c65155SAlexander Yermolovich       InfoSectionUnitHeader &Header = *HeaderOrError;
852f8c65155SAlexander Yermolovich 
853f8c65155SAlexander Yermolovich       Expected<CompileUnitIdentifiers> EID = getCUIdentifiers(
854f8c65155SAlexander Yermolovich           Header, getSubsection(AbbrevSection, E, DW_SECT_ABBREV),
855f8c65155SAlexander Yermolovich           CUInfoSection,
856f8c65155SAlexander Yermolovich           getSubsection(CurStrOffsetSection, E, DW_SECT_STR_OFFSETS),
857f8c65155SAlexander Yermolovich           CurStrSection);
858f8c65155SAlexander Yermolovich       if (!EID)
859f8c65155SAlexander Yermolovich         return createFileError(Input, EID.takeError());
860f8c65155SAlexander Yermolovich       const auto &ID = *EID;
861f8c65155SAlexander Yermolovich       if (!P.second)
862f8c65155SAlexander Yermolovich         return buildDuplicateError(*P.first, ID, Input);
863f8c65155SAlexander Yermolovich       auto &NewEntry = P.first->second;
864f8c65155SAlexander Yermolovich       NewEntry.Name = ID.Name;
865f8c65155SAlexander Yermolovich       NewEntry.DWOName = ID.DWOName;
866f8c65155SAlexander Yermolovich       NewEntry.DWPName = Input;
867f8c65155SAlexander Yermolovich       for (auto Kind : CUIndex.getColumnKinds()) {
868f8c65155SAlexander Yermolovich         if (!isSupportedSectionKind(Kind))
869f8c65155SAlexander Yermolovich           continue;
870f8c65155SAlexander Yermolovich         auto &C =
871f8c65155SAlexander Yermolovich             NewEntry.Contributions[getContributionIndex(Kind, IndexVersion)];
8727fc79340SAlexander Yermolovich         C.setOffset(C.getOffset() + I->getOffset());
8737fc79340SAlexander Yermolovich         C.setLength(I->getLength());
874f8c65155SAlexander Yermolovich         ++I;
875f8c65155SAlexander Yermolovich       }
876f8c65155SAlexander Yermolovich       unsigned Index = getContributionIndex(DW_SECT_INFO, IndexVersion);
877f8c65155SAlexander Yermolovich       auto &C = NewEntry.Contributions[Index];
878f8c65155SAlexander Yermolovich       Out.emitBytes(CUInfoSection);
8797fc79340SAlexander Yermolovich       C.setOffset(InfoSectionOffset);
8807fc79340SAlexander Yermolovich       InfoSectionOffset += C.getLength32();
881f8c65155SAlexander Yermolovich     }
882f8c65155SAlexander Yermolovich 
883f8c65155SAlexander Yermolovich     if (!CurTUIndexSection.empty()) {
884f8c65155SAlexander Yermolovich       llvm::DWARFSectionKind TUSectionKind;
885f8c65155SAlexander Yermolovich       MCSection *OutSection;
886f8c65155SAlexander Yermolovich       StringRef TypeInputSection;
887f8c65155SAlexander Yermolovich       // Write type units into debug info section for DWARFv5.
888f8c65155SAlexander Yermolovich       if (Version >= 5) {
889f8c65155SAlexander Yermolovich         TUSectionKind = DW_SECT_INFO;
890f8c65155SAlexander Yermolovich         OutSection = InfoSection;
891f8c65155SAlexander Yermolovich         TypeInputSection = DwpSingleInfoSection;
892f8c65155SAlexander Yermolovich       } else {
893f8c65155SAlexander Yermolovich         // Write type units into debug types section for DWARF < 5.
894f8c65155SAlexander Yermolovich         if (CurTypesSection.size() != 1)
895f8c65155SAlexander Yermolovich           return make_error<DWPError>(
896f8c65155SAlexander Yermolovich               "multiple type unit sections in .dwp file");
897f8c65155SAlexander Yermolovich 
898f8c65155SAlexander Yermolovich         TUSectionKind = DW_SECT_EXT_TYPES;
899f8c65155SAlexander Yermolovich         OutSection = TypesSection;
900f8c65155SAlexander Yermolovich         TypeInputSection = CurTypesSection.front();
901f8c65155SAlexander Yermolovich       }
902f8c65155SAlexander Yermolovich 
903f8c65155SAlexander Yermolovich       DWARFUnitIndex TUIndex(TUSectionKind);
904f8c65155SAlexander Yermolovich       DataExtractor TUIndexData(CurTUIndexSection, Obj.isLittleEndian(), 0);
905f8c65155SAlexander Yermolovich       if (!TUIndex.parse(TUIndexData))
906f8c65155SAlexander Yermolovich         return make_error<DWPError>("failed to parse tu_index");
907f8c65155SAlexander Yermolovich       if (TUIndex.getVersion() != IndexVersion)
908f8c65155SAlexander Yermolovich         return make_error<DWPError>("incompatible tu_index versions, found " +
909f8c65155SAlexander Yermolovich                                     utostr(TUIndex.getVersion()) +
910f8c65155SAlexander Yermolovich                                     " and expecting " + utostr(IndexVersion));
911f8c65155SAlexander Yermolovich 
912f8c65155SAlexander Yermolovich       unsigned TypesContributionIndex =
913f8c65155SAlexander Yermolovich           getContributionIndex(TUSectionKind, IndexVersion);
91453a483ceSzhuna       if (Error Err = addAllTypesFromDWP(
91553a483ceSzhuna               Out, TypeIndexEntries, TUIndex, OutSection, TypeInputSection,
91653a483ceSzhuna               CurEntry, ContributionOffsets[TypesContributionIndex],
9174c44dcffSJinjie Huang               TypesContributionIndex, OverflowOptValue, AnySectionOverflow))
91853a483ceSzhuna         return Err;
919f8c65155SAlexander Yermolovich     }
9204c44dcffSJinjie Huang     if (AnySectionOverflow)
9214c44dcffSJinjie Huang       break;
922f8c65155SAlexander Yermolovich   }
923f8c65155SAlexander Yermolovich 
924f8c65155SAlexander Yermolovich   if (Version < 5) {
925f8c65155SAlexander Yermolovich     // Lie about there being no info contributions so the TU index only includes
926f8c65155SAlexander Yermolovich     // the type unit contribution for DWARF < 5. In DWARFv5 the TU index has a
927f8c65155SAlexander Yermolovich     // contribution to the info section, so we do not want to lie about it.
928f8c65155SAlexander Yermolovich     ContributionOffsets[0] = 0;
929f8c65155SAlexander Yermolovich   }
930f8c65155SAlexander Yermolovich   writeIndex(Out, MCOFI.getDwarfTUIndexSection(), ContributionOffsets,
931f8c65155SAlexander Yermolovich              TypeIndexEntries, IndexVersion);
932f8c65155SAlexander Yermolovich 
933f8c65155SAlexander Yermolovich   if (Version < 5) {
934f8c65155SAlexander Yermolovich     // Lie about the type contribution for DWARF < 5. In DWARFv5 the type
935f8c65155SAlexander Yermolovich     // section does not exist, so no need to do anything about this.
936f8c65155SAlexander Yermolovich     ContributionOffsets[getContributionIndex(DW_SECT_EXT_TYPES, 2)] = 0;
937f8c65155SAlexander Yermolovich     // Unlie about the info contribution
938f8c65155SAlexander Yermolovich     ContributionOffsets[0] = 1;
939f8c65155SAlexander Yermolovich   }
940f8c65155SAlexander Yermolovich 
941f8c65155SAlexander Yermolovich   writeIndex(Out, MCOFI.getDwarfCUIndexSection(), ContributionOffsets,
942f8c65155SAlexander Yermolovich              IndexEntries, IndexVersion);
943f8c65155SAlexander Yermolovich 
944f8c65155SAlexander Yermolovich   return Error::success();
945f8c65155SAlexander Yermolovich }
946f8c65155SAlexander Yermolovich } // namespace llvm
947