1 //===-- llvm-dwp.cpp - Split DWARF merging tool for llvm ------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // A utility for merging DWARF 5 Split DWARF .dwo files into .dwp (DWARF
10 // package files).
11 //
12 //===----------------------------------------------------------------------===//
13 #include "DWPError.h"
14 #include "DWPStringPool.h"
15 #include "llvm/ADT/MapVector.h"
16 #include "llvm/ADT/Optional.h"
17 #include "llvm/ADT/STLExtras.h"
18 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
19 #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
20 #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
21 #include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
22 #include "llvm/MC/MCAsmBackend.h"
23 #include "llvm/MC/MCAsmInfo.h"
24 #include "llvm/MC/MCCodeEmitter.h"
25 #include "llvm/MC/MCContext.h"
26 #include "llvm/MC/MCInstrInfo.h"
27 #include "llvm/MC/MCObjectFileInfo.h"
28 #include "llvm/MC/MCObjectWriter.h"
29 #include "llvm/MC/MCRegisterInfo.h"
30 #include "llvm/MC/MCStreamer.h"
31 #include "llvm/MC/MCTargetOptionsCommandFlags.h"
32 #include "llvm/Object/Decompressor.h"
33 #include "llvm/Object/ObjectFile.h"
34 #include "llvm/Support/CommandLine.h"
35 #include "llvm/Support/DataExtractor.h"
36 #include "llvm/Support/Error.h"
37 #include "llvm/Support/FileSystem.h"
38 #include "llvm/Support/InitLLVM.h"
39 #include "llvm/Support/MathExtras.h"
40 #include "llvm/Support/MemoryBuffer.h"
41 #include "llvm/Support/Path.h"
42 #include "llvm/Support/TargetRegistry.h"
43 #include "llvm/Support/TargetSelect.h"
44 #include "llvm/Support/ToolOutputFile.h"
45 #include "llvm/Support/WithColor.h"
46 #include "llvm/Support/raw_ostream.h"
47 
48 using namespace llvm;
49 using namespace llvm::object;
50 
51 static mc::RegisterMCTargetOptionsFlags MCTargetOptionsFlags;
52 
53 cl::OptionCategory DwpCategory("Specific Options");
54 static cl::list<std::string> InputFiles(cl::Positional, cl::ZeroOrMore,
55                                         cl::desc("<input files>"),
56                                         cl::cat(DwpCategory));
57 
58 static cl::list<std::string> ExecFilenames(
59     "e", cl::ZeroOrMore,
60     cl::desc("Specify the executable/library files to get the list of *.dwo from"),
61     cl::value_desc("filename"), cl::cat(DwpCategory));
62 
63 static cl::opt<std::string> OutputFilename(cl::Required, "o",
64                                            cl::desc("Specify the output file."),
65                                            cl::value_desc("filename"),
66                                            cl::cat(DwpCategory));
67 
68 // Returns the size of debug_str_offsets section headers in bytes.
69 static uint64_t debugStrOffsetsHeaderSize(DataExtractor StrOffsetsData,
70                                           uint16_t DwarfVersion) {
71   if (DwarfVersion <= 4)
72     return 0; // There is no header before dwarf 5.
73   uint64_t Offset = 0;
74   uint64_t Length = StrOffsetsData.getU32(&Offset);
75   if (Length == llvm::dwarf::DW_LENGTH_DWARF64)
76     return 16; // unit length: 12 bytes, version: 2 bytes, padding: 2 bytes.
77   return 8;    // unit length: 4 bytes, version: 2 bytes, padding: 2 bytes.
78 }
79 
80 // Holds data for Skeleton and Split Compilation Unit Headers as defined in
81 // Dwarf 5 specification, 7.5.1.2 and Dwarf 4 specification 7.5.1.1.
82 struct CompileUnitHeader {
83   // unit_length field. Note that the type is uint64_t even in 32-bit dwarf.
84   uint64_t Length = 0;
85 
86   // version field.
87   uint16_t Version = 0;
88 
89   // unit_type field. Initialized only if Version >= 5.
90   uint8_t UnitType = 0;
91 
92   // address_size field.
93   uint8_t AddrSize = 0;
94 
95   // debug_abbrev_offset field. Note that the type is uint64_t even in 32-bit
96   // dwarf. It is assumed to be 0.
97   uint64_t DebugAbbrevOffset = 0;
98 
99   // dwo_id field. This resides in the header only if Version >= 5.
100   // In earlier versions, it is read from DW_AT_GNU_dwo_id.
101   Optional<uint64_t> Signature = None;
102 
103   // Derived from the length of Length field.
104   dwarf::DwarfFormat Format = dwarf::DwarfFormat::DWARF32;
105 
106   // The size of the Header in bytes. This is derived while parsing the header,
107   // and is stored as a convenience.
108   uint8_t HeaderSize = 0;
109 };
110 
111 // Parse and return the header of the compile unit.
112 static Expected<CompileUnitHeader> parseCompileUnitHeader(StringRef Info) {
113   CompileUnitHeader Header;
114   Error Err = Error::success();
115   uint64_t Offset = 0;
116   DWARFDataExtractor InfoData(Info, true, 0);
117   std::tie(Header.Length, Header.Format) =
118       InfoData.getInitialLength(&Offset, &Err);
119   if (Err)
120     return make_error<DWPError>("cannot parse compile unit length: " +
121                                 llvm::toString(std::move(Err)));
122 
123   if (!InfoData.isValidOffset(Offset + (Header.Length - 1))) {
124     return make_error<DWPError>(
125         "compile unit exceeds .debug_info section range: " +
126         utostr(Offset + Header.Length) + " >= " + utostr(InfoData.size()));
127   }
128 
129   Header.Version = InfoData.getU16(&Offset, &Err);
130   if (Err)
131     return make_error<DWPError>("cannot parse compile unit version: " +
132                                 llvm::toString(std::move(Err)));
133 
134   uint64_t MinHeaderLength;
135   if (Header.Version >= 5) {
136     // Size: Version (2), UnitType (1), AddrSize (1), DebugAbbrevOffset (4),
137     // Signature (8)
138     MinHeaderLength = 16;
139   } else {
140     // Size: Version (2), DebugAbbrevOffset (4), AddrSize (1)
141     MinHeaderLength = 7;
142   }
143   if (Header.Length < MinHeaderLength) {
144     return make_error<DWPError>(
145         "compile unit length is too small: expected at least " +
146         utostr(MinHeaderLength) + " got " + utostr(Header.Length) + ".");
147   }
148   if (Header.Version >= 5) {
149     Header.UnitType = InfoData.getU8(&Offset);
150     Header.AddrSize = InfoData.getU8(&Offset);
151     Header.DebugAbbrevOffset = InfoData.getU32(&Offset);
152     Header.Signature = InfoData.getU64(&Offset);
153   } else {
154     // Note that, address_size and debug_abbrev_offset fields have switched
155     // places between dwarf version 4 and 5.
156     Header.DebugAbbrevOffset = InfoData.getU32(&Offset);
157     Header.AddrSize = InfoData.getU8(&Offset);
158   }
159 
160   Header.HeaderSize = Offset;
161   return Header;
162 }
163 
164 static void writeStringsAndOffsets(MCStreamer &Out, DWPStringPool &Strings,
165                                    MCSection *StrOffsetSection,
166                                    StringRef CurStrSection,
167                                    StringRef CurStrOffsetSection,
168                                    const CompileUnitHeader &Header) {
169   // Could possibly produce an error or warning if one of these was non-null but
170   // the other was null.
171   if (CurStrSection.empty() || CurStrOffsetSection.empty())
172     return;
173 
174   DenseMap<uint64_t, uint32_t> OffsetRemapping;
175 
176   DataExtractor Data(CurStrSection, true, 0);
177   uint64_t LocalOffset = 0;
178   uint64_t PrevOffset = 0;
179   while (const char *s = Data.getCStr(&LocalOffset)) {
180     OffsetRemapping[PrevOffset] =
181         Strings.getOffset(s, LocalOffset - PrevOffset);
182     PrevOffset = LocalOffset;
183   }
184 
185   Data = DataExtractor(CurStrOffsetSection, true, 0);
186 
187   Out.SwitchSection(StrOffsetSection);
188 
189   uint64_t HeaderSize = debugStrOffsetsHeaderSize(Data, Header.Version);
190   uint64_t Offset = 0;
191   uint64_t Size = CurStrOffsetSection.size();
192   // FIXME: This can be caused by bad input and should be handled as such.
193   assert(HeaderSize <= Size && "StrOffsetSection size is less than its header");
194   // Copy the header to the output.
195   Out.emitBytes(Data.getBytes(&Offset, HeaderSize));
196   while (Offset < Size) {
197     auto OldOffset = Data.getU32(&Offset);
198     auto NewOffset = OffsetRemapping[OldOffset];
199     Out.emitIntValue(NewOffset, 4);
200   }
201 }
202 
203 static uint64_t getCUAbbrev(StringRef Abbrev, uint64_t AbbrCode) {
204   uint64_t Offset = 0;
205   DataExtractor AbbrevData(Abbrev, true, 0);
206   while (AbbrevData.getULEB128(&Offset) != AbbrCode) {
207     // Tag
208     AbbrevData.getULEB128(&Offset);
209     // DW_CHILDREN
210     AbbrevData.getU8(&Offset);
211     // Attributes
212     while (AbbrevData.getULEB128(&Offset) | AbbrevData.getULEB128(&Offset))
213       ;
214   }
215   return Offset;
216 }
217 
218 struct CompileUnitIdentifiers {
219   uint64_t Signature = 0;
220   const char *Name = "";
221   const char *DWOName = "";
222 };
223 
224 static Expected<const char *>
225 getIndexedString(dwarf::Form Form, DataExtractor InfoData, uint64_t &InfoOffset,
226                  StringRef StrOffsets, StringRef Str, uint16_t Version) {
227   if (Form == dwarf::DW_FORM_string)
228     return InfoData.getCStr(&InfoOffset);
229   uint64_t StrIndex;
230   switch (Form) {
231   case dwarf::DW_FORM_strx1:
232     StrIndex = InfoData.getU8(&InfoOffset);
233     break;
234   case dwarf::DW_FORM_strx2:
235     StrIndex = InfoData.getU16(&InfoOffset);
236     break;
237   case dwarf::DW_FORM_strx3:
238     StrIndex = InfoData.getU24(&InfoOffset);
239     break;
240   case dwarf::DW_FORM_strx4:
241     StrIndex = InfoData.getU32(&InfoOffset);
242     break;
243   case dwarf::DW_FORM_strx:
244   case dwarf::DW_FORM_GNU_str_index:
245     StrIndex = InfoData.getULEB128(&InfoOffset);
246     break;
247   default:
248     return make_error<DWPError>(
249         "string field must be encoded with one of the following: "
250         "DW_FORM_string, DW_FORM_strx, DW_FORM_strx1, DW_FORM_strx2, "
251         "DW_FORM_strx3, DW_FORM_strx4, or DW_FORM_GNU_str_index.");
252   }
253   DataExtractor StrOffsetsData(StrOffsets, true, 0);
254   uint64_t StrOffsetsOffset = 4 * StrIndex;
255   StrOffsetsOffset += debugStrOffsetsHeaderSize(StrOffsetsData, Version);
256 
257   uint64_t StrOffset = StrOffsetsData.getU32(&StrOffsetsOffset);
258   DataExtractor StrData(Str, true, 0);
259   return StrData.getCStr(&StrOffset);
260 }
261 
262 static Expected<CompileUnitIdentifiers> getCUIdentifiers(StringRef Abbrev,
263                                                          StringRef Info,
264                                                          StringRef StrOffsets,
265                                                          StringRef Str) {
266   Expected<CompileUnitHeader> HeaderOrError = parseCompileUnitHeader(Info);
267   if (!HeaderOrError)
268     return HeaderOrError.takeError();
269   CompileUnitHeader &Header = *HeaderOrError;
270   DataExtractor InfoData(Info, true, 0);
271   uint64_t Offset = Header.HeaderSize;
272   if (Header.Version >= 5 && Header.UnitType != dwarf::DW_UT_split_compile)
273     return make_error<DWPError>(
274         std::string("unit type DW_UT_split_compile type not found in "
275                     "debug_info header. Unexpected unit type 0x" +
276                     utostr(Header.UnitType) + " found"));
277 
278   CompileUnitIdentifiers ID;
279 
280   uint32_t AbbrCode = InfoData.getULEB128(&Offset);
281   DataExtractor AbbrevData(Abbrev, true, 0);
282   uint64_t AbbrevOffset = getCUAbbrev(Abbrev, AbbrCode);
283   auto Tag = static_cast<dwarf::Tag>(AbbrevData.getULEB128(&AbbrevOffset));
284   if (Tag != dwarf::DW_TAG_compile_unit)
285     return make_error<DWPError>("top level DIE is not a compile unit");
286   // DW_CHILDREN
287   AbbrevData.getU8(&AbbrevOffset);
288   uint32_t Name;
289   dwarf::Form Form;
290   while ((Name = AbbrevData.getULEB128(&AbbrevOffset)) |
291          (Form = static_cast<dwarf::Form>(AbbrevData.getULEB128(&AbbrevOffset))) &&
292          (Name != 0 || Form != 0)) {
293     switch (Name) {
294     case dwarf::DW_AT_name: {
295       Expected<const char *> EName = getIndexedString(
296           Form, InfoData, Offset, StrOffsets, Str, Header.Version);
297       if (!EName)
298         return EName.takeError();
299       ID.Name = *EName;
300       break;
301     }
302     case dwarf::DW_AT_GNU_dwo_name:
303     case dwarf::DW_AT_dwo_name: {
304       Expected<const char *> EName = getIndexedString(
305           Form, InfoData, Offset, StrOffsets, Str, Header.Version);
306       if (!EName)
307         return EName.takeError();
308       ID.DWOName = *EName;
309       break;
310     }
311     case dwarf::DW_AT_GNU_dwo_id:
312       Header.Signature = InfoData.getU64(&Offset);
313       break;
314     default:
315       DWARFFormValue::skipValue(
316           Form, InfoData, &Offset,
317           dwarf::FormParams({Header.Version, Header.AddrSize, Header.Format}));
318     }
319   }
320   if (!Header.Signature)
321     return make_error<DWPError>("compile unit missing dwo_id");
322   ID.Signature = *Header.Signature;
323   return ID;
324 }
325 
326 struct UnitIndexEntry {
327   DWARFUnitIndex::Entry::SectionContribution Contributions[8];
328   std::string Name;
329   std::string DWOName;
330   StringRef DWPName;
331 };
332 
333 static bool isSupportedSectionKind(DWARFSectionKind Kind) {
334   return Kind != DW_SECT_EXT_unknown;
335 }
336 
337 // Convert an internal section identifier into the index to use with
338 // UnitIndexEntry::Contributions.
339 static unsigned getContributionIndex(DWARFSectionKind Kind) {
340   // Assuming the pre-standard DWP format.
341   assert(serializeSectionKind(Kind, 2) >= DW_SECT_INFO);
342   return serializeSectionKind(Kind, 2) - DW_SECT_INFO;
343 }
344 
345 // Convert a UnitIndexEntry::Contributions index to the corresponding on-disk
346 // value of the section identifier.
347 static unsigned getOnDiskSectionId(unsigned Index) {
348   return Index + DW_SECT_INFO;
349 }
350 
351 static StringRef getSubsection(StringRef Section,
352                                const DWARFUnitIndex::Entry &Entry,
353                                DWARFSectionKind Kind) {
354   const auto *Off = Entry.getContribution(Kind);
355   if (!Off)
356     return StringRef();
357   return Section.substr(Off->Offset, Off->Length);
358 }
359 
360 static void addAllTypesFromDWP(
361     MCStreamer &Out, MapVector<uint64_t, UnitIndexEntry> &TypeIndexEntries,
362     const DWARFUnitIndex &TUIndex, MCSection *OutputTypes, StringRef Types,
363     const UnitIndexEntry &TUEntry, uint32_t &TypesOffset) {
364   Out.SwitchSection(OutputTypes);
365   for (const DWARFUnitIndex::Entry &E : TUIndex.getRows()) {
366     auto *I = E.getContributions();
367     if (!I)
368       continue;
369     auto P = TypeIndexEntries.insert(std::make_pair(E.getSignature(), TUEntry));
370     if (!P.second)
371       continue;
372     auto &Entry = P.first->second;
373     // Zero out the debug_info contribution
374     Entry.Contributions[0] = {};
375     for (auto Kind : TUIndex.getColumnKinds()) {
376       if (!isSupportedSectionKind(Kind))
377         continue;
378       auto &C = Entry.Contributions[getContributionIndex(Kind)];
379       C.Offset += I->Offset;
380       C.Length = I->Length;
381       ++I;
382     }
383     unsigned TypesIndex = getContributionIndex(DW_SECT_EXT_TYPES);
384     auto &C = Entry.Contributions[TypesIndex];
385     Out.emitBytes(Types.substr(
386         C.Offset - TUEntry.Contributions[TypesIndex].Offset, C.Length));
387     C.Offset = TypesOffset;
388     TypesOffset += C.Length;
389   }
390 }
391 
392 static void addAllTypes(MCStreamer &Out,
393                         MapVector<uint64_t, UnitIndexEntry> &TypeIndexEntries,
394                         MCSection *OutputTypes,
395                         const std::vector<StringRef> &TypesSections,
396                         const UnitIndexEntry &CUEntry, uint32_t &TypesOffset) {
397   for (StringRef Types : TypesSections) {
398     Out.SwitchSection(OutputTypes);
399     uint64_t Offset = 0;
400     DataExtractor Data(Types, true, 0);
401     while (Data.isValidOffset(Offset)) {
402       UnitIndexEntry Entry = CUEntry;
403       // Zero out the debug_info contribution
404       Entry.Contributions[0] = {};
405       auto &C = Entry.Contributions[getContributionIndex(DW_SECT_EXT_TYPES)];
406       C.Offset = TypesOffset;
407       auto PrevOffset = Offset;
408       // Length of the unit, including the 4 byte length field.
409       C.Length = Data.getU32(&Offset) + 4;
410 
411       Data.getU16(&Offset); // Version
412       Data.getU32(&Offset); // Abbrev offset
413       Data.getU8(&Offset);  // Address size
414       auto Signature = Data.getU64(&Offset);
415       Offset = PrevOffset + C.Length;
416 
417       auto P = TypeIndexEntries.insert(std::make_pair(Signature, Entry));
418       if (!P.second)
419         continue;
420 
421       Out.emitBytes(Types.substr(PrevOffset, C.Length));
422       TypesOffset += C.Length;
423     }
424   }
425 }
426 
427 static void
428 writeIndexTable(MCStreamer &Out, ArrayRef<unsigned> ContributionOffsets,
429                 const MapVector<uint64_t, UnitIndexEntry> &IndexEntries,
430                 uint32_t DWARFUnitIndex::Entry::SectionContribution::*Field) {
431   for (const auto &E : IndexEntries)
432     for (size_t i = 0; i != array_lengthof(E.second.Contributions); ++i)
433       if (ContributionOffsets[i])
434         Out.emitIntValue(E.second.Contributions[i].*Field, 4);
435 }
436 
437 static void
438 writeIndex(MCStreamer &Out, MCSection *Section,
439            ArrayRef<unsigned> ContributionOffsets,
440            const MapVector<uint64_t, UnitIndexEntry> &IndexEntries) {
441   if (IndexEntries.empty())
442     return;
443 
444   unsigned Columns = 0;
445   for (auto &C : ContributionOffsets)
446     if (C)
447       ++Columns;
448 
449   std::vector<unsigned> Buckets(NextPowerOf2(3 * IndexEntries.size() / 2));
450   uint64_t Mask = Buckets.size() - 1;
451   size_t i = 0;
452   for (const auto &P : IndexEntries) {
453     auto S = P.first;
454     auto H = S & Mask;
455     auto HP = ((S >> 32) & Mask) | 1;
456     while (Buckets[H]) {
457       assert(S != IndexEntries.begin()[Buckets[H] - 1].first &&
458              "Duplicate unit");
459       H = (H + HP) & Mask;
460     }
461     Buckets[H] = i + 1;
462     ++i;
463   }
464 
465   Out.SwitchSection(Section);
466   Out.emitIntValue(2, 4);                   // Version
467   Out.emitIntValue(Columns, 4);             // Columns
468   Out.emitIntValue(IndexEntries.size(), 4); // Num Units
469   Out.emitIntValue(Buckets.size(), 4);      // Num Buckets
470 
471   // Write the signatures.
472   for (const auto &I : Buckets)
473     Out.emitIntValue(I ? IndexEntries.begin()[I - 1].first : 0, 8);
474 
475   // Write the indexes.
476   for (const auto &I : Buckets)
477     Out.emitIntValue(I, 4);
478 
479   // Write the column headers (which sections will appear in the table)
480   for (size_t i = 0; i != ContributionOffsets.size(); ++i)
481     if (ContributionOffsets[i])
482       Out.emitIntValue(getOnDiskSectionId(i), 4);
483 
484   // Write the offsets.
485   writeIndexTable(Out, ContributionOffsets, IndexEntries,
486                   &DWARFUnitIndex::Entry::SectionContribution::Offset);
487 
488   // Write the lengths.
489   writeIndexTable(Out, ContributionOffsets, IndexEntries,
490                   &DWARFUnitIndex::Entry::SectionContribution::Length);
491 }
492 
493 static std::string buildDWODescription(StringRef Name, StringRef DWPName,
494                                        StringRef DWOName) {
495   std::string Text = "\'";
496   Text += Name;
497   Text += '\'';
498   if (!DWPName.empty()) {
499     Text += " (from ";
500     if (!DWOName.empty()) {
501       Text += '\'';
502       Text += DWOName;
503       Text += "' in ";
504     }
505     Text += '\'';
506     Text += DWPName;
507     Text += "')";
508   }
509   return Text;
510 }
511 
512 static Error createError(StringRef Name, Error E) {
513   return make_error<DWPError>(
514       ("failure while decompressing compressed section: '" + Name + "', " +
515        llvm::toString(std::move(E)))
516           .str());
517 }
518 
519 static Error
520 handleCompressedSection(std::deque<SmallString<32>> &UncompressedSections,
521                         StringRef &Name, StringRef &Contents) {
522   if (!Decompressor::isGnuStyle(Name))
523     return Error::success();
524 
525   Expected<Decompressor> Dec =
526       Decompressor::create(Name, Contents, false /*IsLE*/, false /*Is64Bit*/);
527   if (!Dec)
528     return createError(Name, Dec.takeError());
529 
530   UncompressedSections.emplace_back();
531   if (Error E = Dec->resizeAndDecompress(UncompressedSections.back()))
532     return createError(Name, std::move(E));
533 
534   Name = Name.substr(2); // Drop ".z"
535   Contents = UncompressedSections.back();
536   return Error::success();
537 }
538 
539 static Error handleSection(
540     const StringMap<std::pair<MCSection *, DWARFSectionKind>> &KnownSections,
541     const MCSection *StrSection, const MCSection *StrOffsetSection,
542     const MCSection *TypesSection, const MCSection *CUIndexSection,
543     const MCSection *TUIndexSection, const SectionRef &Section, MCStreamer &Out,
544     std::deque<SmallString<32>> &UncompressedSections,
545     uint32_t (&ContributionOffsets)[8], UnitIndexEntry &CurEntry,
546     StringRef &CurStrSection, StringRef &CurStrOffsetSection,
547     std::vector<StringRef> &CurTypesSection, StringRef &InfoSection,
548     StringRef &AbbrevSection, StringRef &CurCUIndexSection,
549     StringRef &CurTUIndexSection) {
550   if (Section.isBSS())
551     return Error::success();
552 
553   if (Section.isVirtual())
554     return Error::success();
555 
556   Expected<StringRef> NameOrErr = Section.getName();
557   if (!NameOrErr)
558     return NameOrErr.takeError();
559   StringRef Name = *NameOrErr;
560 
561   Expected<StringRef> ContentsOrErr = Section.getContents();
562   if (!ContentsOrErr)
563     return ContentsOrErr.takeError();
564   StringRef Contents = *ContentsOrErr;
565 
566   if (auto Err = handleCompressedSection(UncompressedSections, Name, Contents))
567     return Err;
568 
569   Name = Name.substr(Name.find_first_not_of("._"));
570 
571   auto SectionPair = KnownSections.find(Name);
572   if (SectionPair == KnownSections.end())
573     return Error::success();
574 
575   if (DWARFSectionKind Kind = SectionPair->second.second) {
576     auto Index = getContributionIndex(Kind);
577     if (Kind != DW_SECT_EXT_TYPES) {
578       CurEntry.Contributions[Index].Offset = ContributionOffsets[Index];
579       ContributionOffsets[Index] +=
580           (CurEntry.Contributions[Index].Length = Contents.size());
581     }
582 
583     switch (Kind) {
584     case DW_SECT_INFO:
585       InfoSection = Contents;
586       break;
587     case DW_SECT_ABBREV:
588       AbbrevSection = Contents;
589       break;
590     default:
591       break;
592     }
593   }
594 
595   MCSection *OutSection = SectionPair->second.first;
596   if (OutSection == StrOffsetSection)
597     CurStrOffsetSection = Contents;
598   else if (OutSection == StrSection)
599     CurStrSection = Contents;
600   else if (OutSection == TypesSection)
601     CurTypesSection.push_back(Contents);
602   else if (OutSection == CUIndexSection)
603     CurCUIndexSection = Contents;
604   else if (OutSection == TUIndexSection)
605     CurTUIndexSection = Contents;
606   else {
607     Out.SwitchSection(OutSection);
608     Out.emitBytes(Contents);
609   }
610   return Error::success();
611 }
612 
613 static Error
614 buildDuplicateError(const std::pair<uint64_t, UnitIndexEntry> &PrevE,
615                     const CompileUnitIdentifiers &ID, StringRef DWPName) {
616   return make_error<DWPError>(
617       std::string("duplicate DWO ID (") + utohexstr(PrevE.first) + ") in " +
618       buildDWODescription(PrevE.second.Name, PrevE.second.DWPName,
619                           PrevE.second.DWOName) +
620       " and " + buildDWODescription(ID.Name, DWPName, ID.DWOName));
621 }
622 
623 static Expected<SmallVector<std::string, 16>>
624 getDWOFilenames(StringRef ExecFilename) {
625   auto ErrOrObj = object::ObjectFile::createObjectFile(ExecFilename);
626   if (!ErrOrObj)
627     return ErrOrObj.takeError();
628 
629   const ObjectFile &Obj = *ErrOrObj.get().getBinary();
630   std::unique_ptr<DWARFContext> DWARFCtx = DWARFContext::create(Obj);
631 
632   SmallVector<std::string, 16> DWOPaths;
633   for (const auto &CU : DWARFCtx->compile_units()) {
634     const DWARFDie &Die = CU->getUnitDIE();
635     std::string DWOName = dwarf::toString(
636         Die.find({dwarf::DW_AT_dwo_name, dwarf::DW_AT_GNU_dwo_name}), "");
637     if (DWOName.empty())
638       continue;
639     std::string DWOCompDir =
640         dwarf::toString(Die.find(dwarf::DW_AT_comp_dir), "");
641     if (!DWOCompDir.empty()) {
642       SmallString<16> DWOPath(std::move(DWOName));
643       sys::fs::make_absolute(DWOCompDir, DWOPath);
644       DWOPaths.emplace_back(DWOPath.data(), DWOPath.size());
645     } else {
646       DWOPaths.push_back(std::move(DWOName));
647     }
648   }
649   return std::move(DWOPaths);
650 }
651 
652 static Error write(MCStreamer &Out, ArrayRef<std::string> Inputs) {
653   const auto &MCOFI = *Out.getContext().getObjectFileInfo();
654   MCSection *const StrSection = MCOFI.getDwarfStrDWOSection();
655   MCSection *const StrOffsetSection = MCOFI.getDwarfStrOffDWOSection();
656   MCSection *const TypesSection = MCOFI.getDwarfTypesDWOSection();
657   MCSection *const CUIndexSection = MCOFI.getDwarfCUIndexSection();
658   MCSection *const TUIndexSection = MCOFI.getDwarfTUIndexSection();
659   const StringMap<std::pair<MCSection *, DWARFSectionKind>> KnownSections = {
660       {"debug_info.dwo", {MCOFI.getDwarfInfoDWOSection(), DW_SECT_INFO}},
661       {"debug_types.dwo", {MCOFI.getDwarfTypesDWOSection(), DW_SECT_EXT_TYPES}},
662       {"debug_str_offsets.dwo", {StrOffsetSection, DW_SECT_STR_OFFSETS}},
663       {"debug_str.dwo", {StrSection, static_cast<DWARFSectionKind>(0)}},
664       {"debug_loc.dwo", {MCOFI.getDwarfLocDWOSection(), DW_SECT_EXT_LOC}},
665       {"debug_line.dwo", {MCOFI.getDwarfLineDWOSection(), DW_SECT_LINE}},
666       {"debug_abbrev.dwo", {MCOFI.getDwarfAbbrevDWOSection(), DW_SECT_ABBREV}},
667       {"debug_cu_index", {CUIndexSection, static_cast<DWARFSectionKind>(0)}},
668       {"debug_tu_index", {TUIndexSection, static_cast<DWARFSectionKind>(0)}}};
669 
670   MapVector<uint64_t, UnitIndexEntry> IndexEntries;
671   MapVector<uint64_t, UnitIndexEntry> TypeIndexEntries;
672 
673   uint32_t ContributionOffsets[8] = {};
674 
675   DWPStringPool Strings(Out, StrSection);
676 
677   SmallVector<OwningBinary<object::ObjectFile>, 128> Objects;
678   Objects.reserve(Inputs.size());
679 
680   std::deque<SmallString<32>> UncompressedSections;
681 
682   for (const auto &Input : Inputs) {
683     auto ErrOrObj = object::ObjectFile::createObjectFile(Input);
684     if (!ErrOrObj)
685       return ErrOrObj.takeError();
686 
687     auto &Obj = *ErrOrObj->getBinary();
688     Objects.push_back(std::move(*ErrOrObj));
689 
690     UnitIndexEntry CurEntry = {};
691 
692     StringRef CurStrSection;
693     StringRef CurStrOffsetSection;
694     std::vector<StringRef> CurTypesSection;
695     StringRef InfoSection;
696     StringRef AbbrevSection;
697     StringRef CurCUIndexSection;
698     StringRef CurTUIndexSection;
699 
700     for (const auto &Section : Obj.sections())
701       if (auto Err = handleSection(
702               KnownSections, StrSection, StrOffsetSection, TypesSection,
703               CUIndexSection, TUIndexSection, Section, Out,
704               UncompressedSections, ContributionOffsets, CurEntry,
705               CurStrSection, CurStrOffsetSection, CurTypesSection, InfoSection,
706               AbbrevSection, CurCUIndexSection, CurTUIndexSection))
707         return Err;
708 
709     if (InfoSection.empty())
710       continue;
711 
712     Expected<CompileUnitHeader> CompileUnitHeaderOrErr =
713         parseCompileUnitHeader(InfoSection);
714     if (!CompileUnitHeaderOrErr)
715       return CompileUnitHeaderOrErr.takeError();
716     CompileUnitHeader &CompileUnitHeader = *CompileUnitHeaderOrErr;
717 
718     writeStringsAndOffsets(Out, Strings, StrOffsetSection, CurStrSection,
719                            CurStrOffsetSection, CompileUnitHeader);
720 
721     if (CurCUIndexSection.empty()) {
722       Expected<CompileUnitIdentifiers> EID = getCUIdentifiers(
723           AbbrevSection, InfoSection, CurStrOffsetSection, CurStrSection);
724       if (!EID)
725         return createFileError(Input, EID.takeError());
726       const auto &ID = *EID;
727       auto P = IndexEntries.insert(std::make_pair(ID.Signature, CurEntry));
728       if (!P.second)
729         return buildDuplicateError(*P.first, ID, "");
730       P.first->second.Name = ID.Name;
731       P.first->second.DWOName = ID.DWOName;
732       addAllTypes(Out, TypeIndexEntries, TypesSection, CurTypesSection,
733                   CurEntry,
734                   ContributionOffsets[getContributionIndex(DW_SECT_EXT_TYPES)]);
735       continue;
736     }
737 
738     DWARFUnitIndex CUIndex(DW_SECT_INFO);
739     DataExtractor CUIndexData(CurCUIndexSection, Obj.isLittleEndian(), 0);
740     if (!CUIndex.parse(CUIndexData))
741       return make_error<DWPError>("failed to parse cu_index");
742     if (CUIndex.getVersion() != 2)
743       return make_error<DWPError>(
744           "unsupported cu_index version: " + utostr(CUIndex.getVersion()) +
745           " (only version 2 is supported)");
746 
747     for (const DWARFUnitIndex::Entry &E : CUIndex.getRows()) {
748       auto *I = E.getContributions();
749       if (!I)
750         continue;
751       auto P = IndexEntries.insert(std::make_pair(E.getSignature(), CurEntry));
752       Expected<CompileUnitIdentifiers> EID = getCUIdentifiers(
753           getSubsection(AbbrevSection, E, DW_SECT_ABBREV),
754           getSubsection(InfoSection, E, DW_SECT_INFO),
755           getSubsection(CurStrOffsetSection, E, DW_SECT_STR_OFFSETS),
756           CurStrSection);
757       if (!EID)
758         return createFileError(Input, EID.takeError());
759       const auto &ID = *EID;
760       if (!P.second)
761         return buildDuplicateError(*P.first, ID, Input);
762       auto &NewEntry = P.first->second;
763       NewEntry.Name = ID.Name;
764       NewEntry.DWOName = ID.DWOName;
765       NewEntry.DWPName = Input;
766       for (auto Kind : CUIndex.getColumnKinds()) {
767         if (!isSupportedSectionKind(Kind))
768           continue;
769         auto &C = NewEntry.Contributions[getContributionIndex(Kind)];
770         C.Offset += I->Offset;
771         C.Length = I->Length;
772         ++I;
773       }
774     }
775 
776     if (!CurTypesSection.empty()) {
777       if (CurTypesSection.size() != 1)
778         return make_error<DWPError>("multiple type unit sections in .dwp file");
779       DWARFUnitIndex TUIndex(DW_SECT_EXT_TYPES);
780       DataExtractor TUIndexData(CurTUIndexSection, Obj.isLittleEndian(), 0);
781       if (!TUIndex.parse(TUIndexData))
782         return make_error<DWPError>("failed to parse tu_index");
783       if (TUIndex.getVersion() != 2)
784         return make_error<DWPError>(
785             "unsupported tu_index version: " + utostr(TUIndex.getVersion()) +
786             " (only version 2 is supported)");
787 
788       addAllTypesFromDWP(
789           Out, TypeIndexEntries, TUIndex, TypesSection, CurTypesSection.front(),
790           CurEntry,
791           ContributionOffsets[getContributionIndex(DW_SECT_EXT_TYPES)]);
792     }
793   }
794 
795   // Lie about there being no info contributions so the TU index only includes
796   // the type unit contribution
797   ContributionOffsets[0] = 0;
798   writeIndex(Out, MCOFI.getDwarfTUIndexSection(), ContributionOffsets,
799              TypeIndexEntries);
800 
801   // Lie about the type contribution
802   ContributionOffsets[getContributionIndex(DW_SECT_EXT_TYPES)] = 0;
803   // Unlie about the info contribution
804   ContributionOffsets[0] = 1;
805 
806   writeIndex(Out, MCOFI.getDwarfCUIndexSection(), ContributionOffsets,
807              IndexEntries);
808 
809   return Error::success();
810 }
811 
812 static int error(const Twine &Error, const Twine &Context) {
813   errs() << Twine("while processing ") + Context + ":\n";
814   errs() << Twine("error: ") + Error + "\n";
815   return 1;
816 }
817 
818 static Expected<Triple> readTargetTriple(StringRef FileName) {
819   auto ErrOrObj = object::ObjectFile::createObjectFile(FileName);
820   if (!ErrOrObj)
821     return ErrOrObj.takeError();
822 
823   return ErrOrObj->getBinary()->makeTriple();
824 }
825 
826 int main(int argc, char **argv) {
827   InitLLVM X(argc, argv);
828 
829   cl::ParseCommandLineOptions(argc, argv, "merge split dwarf (.dwo) files\n");
830 
831   llvm::InitializeAllTargetInfos();
832   llvm::InitializeAllTargetMCs();
833   llvm::InitializeAllTargets();
834   llvm::InitializeAllAsmPrinters();
835 
836   std::vector<std::string> DWOFilenames = InputFiles;
837   for (const auto &ExecFilename : ExecFilenames) {
838     auto DWOs = getDWOFilenames(ExecFilename);
839     if (!DWOs) {
840       logAllUnhandledErrors(DWOs.takeError(), WithColor::error());
841       return 1;
842     }
843     DWOFilenames.insert(DWOFilenames.end(),
844                         std::make_move_iterator(DWOs->begin()),
845                         std::make_move_iterator(DWOs->end()));
846   }
847 
848   if (DWOFilenames.empty())
849     return 0;
850 
851   std::string ErrorStr;
852   StringRef Context = "dwarf streamer init";
853 
854   auto ErrOrTriple = readTargetTriple(DWOFilenames.front());
855   if (!ErrOrTriple) {
856     logAllUnhandledErrors(ErrOrTriple.takeError(), WithColor::error());
857     return 1;
858   }
859 
860   // Get the target.
861   const Target *TheTarget =
862       TargetRegistry::lookupTarget("", *ErrOrTriple, ErrorStr);
863   if (!TheTarget)
864     return error(ErrorStr, Context);
865   std::string TripleName = ErrOrTriple->getTriple();
866 
867   // Create all the MC Objects.
868   std::unique_ptr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TripleName));
869   if (!MRI)
870     return error(Twine("no register info for target ") + TripleName, Context);
871 
872   MCTargetOptions MCOptions = llvm::mc::InitMCTargetOptionsFromFlags();
873   std::unique_ptr<MCAsmInfo> MAI(
874       TheTarget->createMCAsmInfo(*MRI, TripleName, MCOptions));
875   if (!MAI)
876     return error("no asm info for target " + TripleName, Context);
877 
878   MCObjectFileInfo MOFI;
879   MCContext MC(MAI.get(), MRI.get(), &MOFI);
880   MOFI.InitMCObjectFileInfo(*ErrOrTriple, /*PIC*/ false, MC);
881 
882   std::unique_ptr<MCSubtargetInfo> MSTI(
883       TheTarget->createMCSubtargetInfo(TripleName, "", ""));
884   if (!MSTI)
885     return error("no subtarget info for target " + TripleName, Context);
886 
887   MCTargetOptions Options;
888   auto MAB = TheTarget->createMCAsmBackend(*MSTI, *MRI, Options);
889   if (!MAB)
890     return error("no asm backend for target " + TripleName, Context);
891 
892   std::unique_ptr<MCInstrInfo> MII(TheTarget->createMCInstrInfo());
893   if (!MII)
894     return error("no instr info info for target " + TripleName, Context);
895 
896   MCCodeEmitter *MCE = TheTarget->createMCCodeEmitter(*MII, *MRI, MC);
897   if (!MCE)
898     return error("no code emitter for target " + TripleName, Context);
899 
900   // Create the output file.
901   std::error_code EC;
902   ToolOutputFile OutFile(OutputFilename, EC, sys::fs::OF_None);
903   Optional<buffer_ostream> BOS;
904   raw_pwrite_stream *OS;
905   if (EC)
906     return error(Twine(OutputFilename) + ": " + EC.message(), Context);
907   if (OutFile.os().supportsSeeking()) {
908     OS = &OutFile.os();
909   } else {
910     BOS.emplace(OutFile.os());
911     OS = BOS.getPointer();
912   }
913 
914   std::unique_ptr<MCStreamer> MS(TheTarget->createMCObjectStreamer(
915       *ErrOrTriple, MC, std::unique_ptr<MCAsmBackend>(MAB),
916       MAB->createObjectWriter(*OS), std::unique_ptr<MCCodeEmitter>(MCE), *MSTI,
917       MCOptions.MCRelaxAll, MCOptions.MCIncrementalLinkerCompatible,
918       /*DWARFMustBeAtTheEnd*/ false));
919   if (!MS)
920     return error("no object streamer for target " + TripleName, Context);
921 
922   if (auto Err = write(*MS, DWOFilenames)) {
923     logAllUnhandledErrors(std::move(Err), WithColor::error());
924     return 1;
925   }
926 
927   MS->Finish();
928   OutFile.keep();
929   return 0;
930 }
931