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, Split Compilation, and Type Unit Headers (only in
81 // v5) as defined in Dwarf 5 specification, 7.5.1.2, 7.5.1.3 and Dwarf 4
82 // specification 7.5.1.1.
83 struct InfoSectionUnitHeader {
84   // unit_length field. Note that the type is uint64_t even in 32-bit dwarf.
85   uint64_t Length = 0;
86 
87   // version field.
88   uint16_t Version = 0;
89 
90   // unit_type field. Initialized only if Version >= 5.
91   uint8_t UnitType = 0;
92 
93   // address_size field.
94   uint8_t AddrSize = 0;
95 
96   // debug_abbrev_offset field. Note that the type is uint64_t even in 32-bit
97   // dwarf. It is assumed to be 0.
98   uint64_t DebugAbbrevOffset = 0;
99 
100   // dwo_id field. This resides in the header only if Version >= 5.
101   // In earlier versions, it is read from DW_AT_GNU_dwo_id.
102   Optional<uint64_t> Signature = None;
103 
104   // Derived from the length of Length field.
105   dwarf::DwarfFormat Format = dwarf::DwarfFormat::DWARF32;
106 
107   // The size of the Header in bytes. This is derived while parsing the header,
108   // and is stored as a convenience.
109   uint8_t HeaderSize = 0;
110 };
111 
112 // Parse and return the header of an info section compile/type unit.
113 static Expected<InfoSectionUnitHeader>
114 parseInfoSectionUnitHeader(StringRef Info) {
115   InfoSectionUnitHeader Header;
116   Error Err = Error::success();
117   uint64_t Offset = 0;
118   DWARFDataExtractor InfoData(Info, true, 0);
119   std::tie(Header.Length, Header.Format) =
120       InfoData.getInitialLength(&Offset, &Err);
121   if (Err)
122     return make_error<DWPError>("cannot parse compile unit length: " +
123                                 llvm::toString(std::move(Err)));
124 
125   if (!InfoData.isValidOffset(Offset + (Header.Length - 1))) {
126     return make_error<DWPError>(
127         "compile unit exceeds .debug_info section range: " +
128         utostr(Offset + Header.Length) + " >= " + utostr(InfoData.size()));
129   }
130 
131   Header.Version = InfoData.getU16(&Offset, &Err);
132   if (Err)
133     return make_error<DWPError>("cannot parse compile unit version: " +
134                                 llvm::toString(std::move(Err)));
135 
136   uint64_t MinHeaderLength;
137   if (Header.Version >= 5) {
138     // Size: Version (2), UnitType (1), AddrSize (1), DebugAbbrevOffset (4),
139     // Signature (8)
140     MinHeaderLength = 16;
141   } else {
142     // Size: Version (2), DebugAbbrevOffset (4), AddrSize (1)
143     MinHeaderLength = 7;
144   }
145   if (Header.Length < MinHeaderLength) {
146     return make_error<DWPError>("unit length is too small: expected at least " +
147                                 utostr(MinHeaderLength) + " got " +
148                                 utostr(Header.Length) + ".");
149   }
150   if (Header.Version >= 5) {
151     Header.UnitType = InfoData.getU8(&Offset);
152     Header.AddrSize = InfoData.getU8(&Offset);
153     Header.DebugAbbrevOffset = InfoData.getU32(&Offset);
154     Header.Signature = InfoData.getU64(&Offset);
155     if (Header.UnitType == dwarf::DW_UT_split_type) {
156       // Type offset.
157       MinHeaderLength += 4;
158       if (Header.Length < MinHeaderLength)
159         return make_error<DWPError>("type unit is missing type offset");
160       InfoData.getU32(&Offset);
161     }
162   } else {
163     // Note that, address_size and debug_abbrev_offset fields have switched
164     // places between dwarf version 4 and 5.
165     Header.DebugAbbrevOffset = InfoData.getU32(&Offset);
166     Header.AddrSize = InfoData.getU8(&Offset);
167   }
168 
169   Header.HeaderSize = Offset;
170   return Header;
171 }
172 
173 static void writeStringsAndOffsets(MCStreamer &Out, DWPStringPool &Strings,
174                                    MCSection *StrOffsetSection,
175                                    StringRef CurStrSection,
176                                    StringRef CurStrOffsetSection,
177                                    uint16_t Version) {
178   // Could possibly produce an error or warning if one of these was non-null but
179   // the other was null.
180   if (CurStrSection.empty() || CurStrOffsetSection.empty())
181     return;
182 
183   DenseMap<uint64_t, uint32_t> OffsetRemapping;
184 
185   DataExtractor Data(CurStrSection, true, 0);
186   uint64_t LocalOffset = 0;
187   uint64_t PrevOffset = 0;
188   while (const char *s = Data.getCStr(&LocalOffset)) {
189     OffsetRemapping[PrevOffset] =
190         Strings.getOffset(s, LocalOffset - PrevOffset);
191     PrevOffset = LocalOffset;
192   }
193 
194   Data = DataExtractor(CurStrOffsetSection, true, 0);
195 
196   Out.SwitchSection(StrOffsetSection);
197 
198   uint64_t HeaderSize = debugStrOffsetsHeaderSize(Data, Version);
199   uint64_t Offset = 0;
200   uint64_t Size = CurStrOffsetSection.size();
201   // FIXME: This can be caused by bad input and should be handled as such.
202   assert(HeaderSize <= Size && "StrOffsetSection size is less than its header");
203   // Copy the header to the output.
204   Out.emitBytes(Data.getBytes(&Offset, HeaderSize));
205   while (Offset < Size) {
206     auto OldOffset = Data.getU32(&Offset);
207     auto NewOffset = OffsetRemapping[OldOffset];
208     Out.emitIntValue(NewOffset, 4);
209   }
210 }
211 
212 static uint64_t getCUAbbrev(StringRef Abbrev, uint64_t AbbrCode) {
213   uint64_t Offset = 0;
214   DataExtractor AbbrevData(Abbrev, true, 0);
215   while (AbbrevData.getULEB128(&Offset) != AbbrCode) {
216     // Tag
217     AbbrevData.getULEB128(&Offset);
218     // DW_CHILDREN
219     AbbrevData.getU8(&Offset);
220     // Attributes
221     while (AbbrevData.getULEB128(&Offset) | AbbrevData.getULEB128(&Offset))
222       ;
223   }
224   return Offset;
225 }
226 
227 struct CompileUnitIdentifiers {
228   uint64_t Signature = 0;
229   const char *Name = "";
230   const char *DWOName = "";
231 };
232 
233 static Expected<const char *>
234 getIndexedString(dwarf::Form Form, DataExtractor InfoData, uint64_t &InfoOffset,
235                  StringRef StrOffsets, StringRef Str, uint16_t Version) {
236   if (Form == dwarf::DW_FORM_string)
237     return InfoData.getCStr(&InfoOffset);
238   uint64_t StrIndex;
239   switch (Form) {
240   case dwarf::DW_FORM_strx1:
241     StrIndex = InfoData.getU8(&InfoOffset);
242     break;
243   case dwarf::DW_FORM_strx2:
244     StrIndex = InfoData.getU16(&InfoOffset);
245     break;
246   case dwarf::DW_FORM_strx3:
247     StrIndex = InfoData.getU24(&InfoOffset);
248     break;
249   case dwarf::DW_FORM_strx4:
250     StrIndex = InfoData.getU32(&InfoOffset);
251     break;
252   case dwarf::DW_FORM_strx:
253   case dwarf::DW_FORM_GNU_str_index:
254     StrIndex = InfoData.getULEB128(&InfoOffset);
255     break;
256   default:
257     return make_error<DWPError>(
258         "string field must be encoded with one of the following: "
259         "DW_FORM_string, DW_FORM_strx, DW_FORM_strx1, DW_FORM_strx2, "
260         "DW_FORM_strx3, DW_FORM_strx4, or DW_FORM_GNU_str_index.");
261   }
262   DataExtractor StrOffsetsData(StrOffsets, true, 0);
263   uint64_t StrOffsetsOffset = 4 * StrIndex;
264   StrOffsetsOffset += debugStrOffsetsHeaderSize(StrOffsetsData, Version);
265 
266   uint64_t StrOffset = StrOffsetsData.getU32(&StrOffsetsOffset);
267   DataExtractor StrData(Str, true, 0);
268   return StrData.getCStr(&StrOffset);
269 }
270 
271 static Expected<CompileUnitIdentifiers>
272 getCUIdentifiers(InfoSectionUnitHeader &Header, StringRef Abbrev,
273                  StringRef Info, StringRef StrOffsets, StringRef Str) {
274   DataExtractor InfoData(Info, true, 0);
275   uint64_t Offset = Header.HeaderSize;
276   if (Header.Version >= 5 && Header.UnitType != dwarf::DW_UT_split_compile)
277     return make_error<DWPError>(
278         std::string("unit type DW_UT_split_compile type not found in "
279                     "debug_info header. Unexpected unit type 0x" +
280                     utostr(Header.UnitType) + " found"));
281 
282   CompileUnitIdentifiers ID;
283 
284   uint32_t AbbrCode = InfoData.getULEB128(&Offset);
285   DataExtractor AbbrevData(Abbrev, true, 0);
286   uint64_t AbbrevOffset = getCUAbbrev(Abbrev, AbbrCode);
287   auto Tag = static_cast<dwarf::Tag>(AbbrevData.getULEB128(&AbbrevOffset));
288   if (Tag != dwarf::DW_TAG_compile_unit)
289     return make_error<DWPError>("top level DIE is not a compile unit");
290   // DW_CHILDREN
291   AbbrevData.getU8(&AbbrevOffset);
292   uint32_t Name;
293   dwarf::Form Form;
294   while ((Name = AbbrevData.getULEB128(&AbbrevOffset)) |
295          (Form = static_cast<dwarf::Form>(AbbrevData.getULEB128(&AbbrevOffset))) &&
296          (Name != 0 || Form != 0)) {
297     switch (Name) {
298     case dwarf::DW_AT_name: {
299       Expected<const char *> EName = getIndexedString(
300           Form, InfoData, Offset, StrOffsets, Str, Header.Version);
301       if (!EName)
302         return EName.takeError();
303       ID.Name = *EName;
304       break;
305     }
306     case dwarf::DW_AT_GNU_dwo_name:
307     case dwarf::DW_AT_dwo_name: {
308       Expected<const char *> EName = getIndexedString(
309           Form, InfoData, Offset, StrOffsets, Str, Header.Version);
310       if (!EName)
311         return EName.takeError();
312       ID.DWOName = *EName;
313       break;
314     }
315     case dwarf::DW_AT_GNU_dwo_id:
316       Header.Signature = InfoData.getU64(&Offset);
317       break;
318     default:
319       DWARFFormValue::skipValue(
320           Form, InfoData, &Offset,
321           dwarf::FormParams({Header.Version, Header.AddrSize, Header.Format}));
322     }
323   }
324   if (!Header.Signature)
325     return make_error<DWPError>("compile unit missing dwo_id");
326   ID.Signature = *Header.Signature;
327   return ID;
328 }
329 
330 struct UnitIndexEntry {
331   DWARFUnitIndex::Entry::SectionContribution Contributions[8];
332   std::string Name;
333   std::string DWOName;
334   StringRef DWPName;
335 };
336 
337 static bool isSupportedSectionKind(DWARFSectionKind Kind) {
338   return Kind != DW_SECT_EXT_unknown;
339 }
340 
341 // Convert an internal section identifier into the index to use with
342 // UnitIndexEntry::Contributions.
343 static unsigned getContributionIndex(DWARFSectionKind Kind,
344                                      uint32_t IndexVersion) {
345   assert(serializeSectionKind(Kind, IndexVersion) >= DW_SECT_INFO);
346   return serializeSectionKind(Kind, IndexVersion) - DW_SECT_INFO;
347 }
348 
349 // Convert a UnitIndexEntry::Contributions index to the corresponding on-disk
350 // value of the section identifier.
351 static unsigned getOnDiskSectionId(unsigned Index) {
352   return Index + DW_SECT_INFO;
353 }
354 
355 static StringRef getSubsection(StringRef Section,
356                                const DWARFUnitIndex::Entry &Entry,
357                                DWARFSectionKind Kind) {
358   const auto *Off = Entry.getContribution(Kind);
359   if (!Off)
360     return StringRef();
361   return Section.substr(Off->Offset, Off->Length);
362 }
363 
364 static void
365 addAllTypesFromDWP(MCStreamer &Out,
366                    MapVector<uint64_t, UnitIndexEntry> &TypeIndexEntries,
367                    const DWARFUnitIndex &TUIndex, MCSection *OutputTypes,
368                    StringRef Types, const UnitIndexEntry &TUEntry,
369                    uint32_t &TypesOffset, unsigned TypesContributionIndex) {
370   Out.SwitchSection(OutputTypes);
371   for (const DWARFUnitIndex::Entry &E : TUIndex.getRows()) {
372     auto *I = E.getContributions();
373     if (!I)
374       continue;
375     auto P = TypeIndexEntries.insert(std::make_pair(E.getSignature(), TUEntry));
376     if (!P.second)
377       continue;
378     auto &Entry = P.first->second;
379     // Zero out the debug_info contribution
380     Entry.Contributions[0] = {};
381     for (auto Kind : TUIndex.getColumnKinds()) {
382       if (!isSupportedSectionKind(Kind))
383         continue;
384       auto &C =
385           Entry.Contributions[getContributionIndex(Kind, TUIndex.getVersion())];
386       C.Offset += I->Offset;
387       C.Length = I->Length;
388       ++I;
389     }
390     auto &C = Entry.Contributions[TypesContributionIndex];
391     Out.emitBytes(Types.substr(
392         C.Offset - TUEntry.Contributions[TypesContributionIndex].Offset,
393         C.Length));
394     C.Offset = TypesOffset;
395     TypesOffset += C.Length;
396   }
397 }
398 
399 static void addAllTypesFromTypesSection(
400     MCStreamer &Out, MapVector<uint64_t, UnitIndexEntry> &TypeIndexEntries,
401     MCSection *OutputTypes, const std::vector<StringRef> &TypesSections,
402     const UnitIndexEntry &CUEntry, uint32_t &TypesOffset) {
403   for (StringRef Types : TypesSections) {
404     Out.SwitchSection(OutputTypes);
405     uint64_t Offset = 0;
406     DataExtractor Data(Types, true, 0);
407     while (Data.isValidOffset(Offset)) {
408       UnitIndexEntry Entry = CUEntry;
409       // Zero out the debug_info contribution
410       Entry.Contributions[0] = {};
411       auto &C = Entry.Contributions[getContributionIndex(DW_SECT_EXT_TYPES, 2)];
412       C.Offset = TypesOffset;
413       auto PrevOffset = Offset;
414       // Length of the unit, including the 4 byte length field.
415       C.Length = Data.getU32(&Offset) + 4;
416 
417       Data.getU16(&Offset); // Version
418       Data.getU32(&Offset); // Abbrev offset
419       Data.getU8(&Offset);  // Address size
420       auto Signature = Data.getU64(&Offset);
421       Offset = PrevOffset + C.Length;
422 
423       auto P = TypeIndexEntries.insert(std::make_pair(Signature, Entry));
424       if (!P.second)
425         continue;
426 
427       Out.emitBytes(Types.substr(PrevOffset, C.Length));
428       TypesOffset += C.Length;
429     }
430   }
431 }
432 
433 static void
434 writeIndexTable(MCStreamer &Out, ArrayRef<unsigned> ContributionOffsets,
435                 const MapVector<uint64_t, UnitIndexEntry> &IndexEntries,
436                 uint32_t DWARFUnitIndex::Entry::SectionContribution::*Field) {
437   for (const auto &E : IndexEntries)
438     for (size_t i = 0; i != array_lengthof(E.second.Contributions); ++i)
439       if (ContributionOffsets[i])
440         Out.emitIntValue(E.second.Contributions[i].*Field, 4);
441 }
442 
443 static void writeIndex(MCStreamer &Out, MCSection *Section,
444                        ArrayRef<unsigned> ContributionOffsets,
445                        const MapVector<uint64_t, UnitIndexEntry> &IndexEntries,
446                        uint32_t IndexVersion) {
447   if (IndexEntries.empty())
448     return;
449 
450   unsigned Columns = 0;
451   for (auto &C : ContributionOffsets)
452     if (C)
453       ++Columns;
454 
455   std::vector<unsigned> Buckets(NextPowerOf2(3 * IndexEntries.size() / 2));
456   uint64_t Mask = Buckets.size() - 1;
457   size_t i = 0;
458   for (const auto &P : IndexEntries) {
459     auto S = P.first;
460     auto H = S & Mask;
461     auto HP = ((S >> 32) & Mask) | 1;
462     while (Buckets[H]) {
463       assert(S != IndexEntries.begin()[Buckets[H] - 1].first &&
464              "Duplicate unit");
465       H = (H + HP) & Mask;
466     }
467     Buckets[H] = i + 1;
468     ++i;
469   }
470 
471   Out.SwitchSection(Section);
472   Out.emitIntValue(IndexVersion, 4);        // Version
473   Out.emitIntValue(Columns, 4);             // Columns
474   Out.emitIntValue(IndexEntries.size(), 4); // Num Units
475   Out.emitIntValue(Buckets.size(), 4);      // Num Buckets
476 
477   // Write the signatures.
478   for (const auto &I : Buckets)
479     Out.emitIntValue(I ? IndexEntries.begin()[I - 1].first : 0, 8);
480 
481   // Write the indexes.
482   for (const auto &I : Buckets)
483     Out.emitIntValue(I, 4);
484 
485   // Write the column headers (which sections will appear in the table)
486   for (size_t i = 0; i != ContributionOffsets.size(); ++i)
487     if (ContributionOffsets[i])
488       Out.emitIntValue(getOnDiskSectionId(i), 4);
489 
490   // Write the offsets.
491   writeIndexTable(Out, ContributionOffsets, IndexEntries,
492                   &DWARFUnitIndex::Entry::SectionContribution::Offset);
493 
494   // Write the lengths.
495   writeIndexTable(Out, ContributionOffsets, IndexEntries,
496                   &DWARFUnitIndex::Entry::SectionContribution::Length);
497 }
498 
499 static std::string buildDWODescription(StringRef Name, StringRef DWPName,
500                                        StringRef DWOName) {
501   std::string Text = "\'";
502   Text += Name;
503   Text += '\'';
504   if (!DWPName.empty()) {
505     Text += " (from ";
506     if (!DWOName.empty()) {
507       Text += '\'';
508       Text += DWOName;
509       Text += "' in ";
510     }
511     Text += '\'';
512     Text += DWPName;
513     Text += "')";
514   }
515   return Text;
516 }
517 
518 static Error createError(StringRef Name, Error E) {
519   return make_error<DWPError>(
520       ("failure while decompressing compressed section: '" + Name + "', " +
521        llvm::toString(std::move(E)))
522           .str());
523 }
524 
525 static Error
526 handleCompressedSection(std::deque<SmallString<32>> &UncompressedSections,
527                         StringRef &Name, StringRef &Contents) {
528   if (!Decompressor::isGnuStyle(Name))
529     return Error::success();
530 
531   Expected<Decompressor> Dec =
532       Decompressor::create(Name, Contents, false /*IsLE*/, false /*Is64Bit*/);
533   if (!Dec)
534     return createError(Name, Dec.takeError());
535 
536   UncompressedSections.emplace_back();
537   if (Error E = Dec->resizeAndDecompress(UncompressedSections.back()))
538     return createError(Name, std::move(E));
539 
540   Name = Name.substr(2); // Drop ".z"
541   Contents = UncompressedSections.back();
542   return Error::success();
543 }
544 
545 static Error handleSection(
546     const StringMap<std::pair<MCSection *, DWARFSectionKind>> &KnownSections,
547     const MCSection *StrSection, const MCSection *StrOffsetSection,
548     const MCSection *TypesSection, const MCSection *CUIndexSection,
549     const MCSection *TUIndexSection, const MCSection *InfoSection,
550     const SectionRef &Section, MCStreamer &Out,
551     std::deque<SmallString<32>> &UncompressedSections,
552     uint32_t (&ContributionOffsets)[8], UnitIndexEntry &CurEntry,
553     StringRef &CurStrSection, StringRef &CurStrOffsetSection,
554     std::vector<StringRef> &CurTypesSection,
555     std::vector<StringRef> &CurInfoSection, StringRef &AbbrevSection,
556     StringRef &CurCUIndexSection, StringRef &CurTUIndexSection,
557     std::vector<std::pair<DWARFSectionKind, uint32_t>> &SectionLength) {
558   if (Section.isBSS())
559     return Error::success();
560 
561   if (Section.isVirtual())
562     return Error::success();
563 
564   Expected<StringRef> NameOrErr = Section.getName();
565   if (!NameOrErr)
566     return NameOrErr.takeError();
567   StringRef Name = *NameOrErr;
568 
569   Expected<StringRef> ContentsOrErr = Section.getContents();
570   if (!ContentsOrErr)
571     return ContentsOrErr.takeError();
572   StringRef Contents = *ContentsOrErr;
573 
574   if (auto Err = handleCompressedSection(UncompressedSections, Name, Contents))
575     return Err;
576 
577   Name = Name.substr(Name.find_first_not_of("._"));
578 
579   auto SectionPair = KnownSections.find(Name);
580   if (SectionPair == KnownSections.end())
581     return Error::success();
582 
583   if (DWARFSectionKind Kind = SectionPair->second.second) {
584     if (Kind != DW_SECT_EXT_TYPES && Kind != DW_SECT_INFO) {
585       SectionLength.push_back(std::make_pair(Kind, Contents.size()));
586     }
587 
588     if (Kind == DW_SECT_ABBREV) {
589       AbbrevSection = Contents;
590     }
591   }
592 
593   MCSection *OutSection = SectionPair->second.first;
594   if (OutSection == StrOffsetSection)
595     CurStrOffsetSection = Contents;
596   else if (OutSection == StrSection)
597     CurStrSection = Contents;
598   else if (OutSection == TypesSection)
599     CurTypesSection.push_back(Contents);
600   else if (OutSection == CUIndexSection)
601     CurCUIndexSection = Contents;
602   else if (OutSection == TUIndexSection)
603     CurTUIndexSection = Contents;
604   else if (OutSection == InfoSection)
605     CurInfoSection.push_back(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   MCSection *const InfoSection = MCOFI.getDwarfInfoDWOSection();
660   const StringMap<std::pair<MCSection *, DWARFSectionKind>> KnownSections = {
661       {"debug_info.dwo", {InfoSection, DW_SECT_INFO}},
662       {"debug_types.dwo", {MCOFI.getDwarfTypesDWOSection(), DW_SECT_EXT_TYPES}},
663       {"debug_str_offsets.dwo", {StrOffsetSection, DW_SECT_STR_OFFSETS}},
664       {"debug_str.dwo", {StrSection, static_cast<DWARFSectionKind>(0)}},
665       {"debug_loc.dwo", {MCOFI.getDwarfLocDWOSection(), DW_SECT_EXT_LOC}},
666       {"debug_line.dwo", {MCOFI.getDwarfLineDWOSection(), DW_SECT_LINE}},
667       {"debug_macro.dwo", {MCOFI.getDwarfMacroDWOSection(), DW_SECT_MACRO}},
668       {"debug_abbrev.dwo", {MCOFI.getDwarfAbbrevDWOSection(), DW_SECT_ABBREV}},
669       {"debug_loclists.dwo",
670        {MCOFI.getDwarfLoclistsDWOSection(), DW_SECT_LOCLISTS}},
671       {"debug_rnglists.dwo",
672        {MCOFI.getDwarfRnglistsDWOSection(), DW_SECT_RNGLISTS}},
673       {"debug_cu_index", {CUIndexSection, static_cast<DWARFSectionKind>(0)}},
674       {"debug_tu_index", {TUIndexSection, static_cast<DWARFSectionKind>(0)}}};
675 
676   MapVector<uint64_t, UnitIndexEntry> IndexEntries;
677   MapVector<uint64_t, UnitIndexEntry> TypeIndexEntries;
678 
679   uint32_t ContributionOffsets[8] = {};
680   uint16_t Version = 0;
681   uint32_t IndexVersion = 0;
682 
683   DWPStringPool Strings(Out, StrSection);
684 
685   SmallVector<OwningBinary<object::ObjectFile>, 128> Objects;
686   Objects.reserve(Inputs.size());
687 
688   std::deque<SmallString<32>> UncompressedSections;
689 
690   for (const auto &Input : Inputs) {
691     auto ErrOrObj = object::ObjectFile::createObjectFile(Input);
692     if (!ErrOrObj)
693       return ErrOrObj.takeError();
694 
695     auto &Obj = *ErrOrObj->getBinary();
696     Objects.push_back(std::move(*ErrOrObj));
697 
698     UnitIndexEntry CurEntry = {};
699 
700     StringRef CurStrSection;
701     StringRef CurStrOffsetSection;
702     std::vector<StringRef> CurTypesSection;
703     std::vector<StringRef> CurInfoSection;
704     StringRef AbbrevSection;
705     StringRef CurCUIndexSection;
706     StringRef CurTUIndexSection;
707 
708     // This maps each section contained in this file to its length.
709     // This information is later on used to calculate the contributions,
710     // i.e. offset and length, of each compile/type unit to a section.
711     std::vector<std::pair<DWARFSectionKind, uint32_t>> SectionLength;
712 
713     for (const auto &Section : Obj.sections())
714       if (auto Err = handleSection(
715               KnownSections, StrSection, StrOffsetSection, TypesSection,
716               CUIndexSection, TUIndexSection, InfoSection, Section, Out,
717               UncompressedSections, ContributionOffsets, CurEntry,
718               CurStrSection, CurStrOffsetSection, CurTypesSection,
719               CurInfoSection, AbbrevSection, CurCUIndexSection,
720               CurTUIndexSection, SectionLength))
721         return Err;
722 
723     if (CurInfoSection.empty())
724       continue;
725 
726     Expected<InfoSectionUnitHeader> HeaderOrErr =
727         parseInfoSectionUnitHeader(CurInfoSection.front());
728     if (!HeaderOrErr)
729       return HeaderOrErr.takeError();
730     InfoSectionUnitHeader &Header = *HeaderOrErr;
731 
732     if (Version == 0) {
733       Version = Header.Version;
734       IndexVersion = Version < 5 ? 2 : 5;
735     } else if (Version != Header.Version) {
736       return make_error<DWPError>("incompatible DWARF compile unit versions.");
737     }
738 
739     writeStringsAndOffsets(Out, Strings, StrOffsetSection, CurStrSection,
740                            CurStrOffsetSection, Header.Version);
741 
742     for (auto Pair : SectionLength) {
743       auto Index = getContributionIndex(Pair.first, IndexVersion);
744       CurEntry.Contributions[Index].Offset = ContributionOffsets[Index];
745       ContributionOffsets[Index] +=
746           (CurEntry.Contributions[Index].Length = Pair.second);
747     }
748 
749     uint32_t &InfoSectionOffset =
750         ContributionOffsets[getContributionIndex(DW_SECT_INFO, IndexVersion)];
751     if (CurCUIndexSection.empty()) {
752       bool FoundCUUnit = false;
753       Out.SwitchSection(InfoSection);
754       for (StringRef Info : CurInfoSection) {
755         uint64_t UnitOffset = 0;
756         while (Info.size() > UnitOffset) {
757           Expected<InfoSectionUnitHeader> HeaderOrError =
758               parseInfoSectionUnitHeader(Info.substr(UnitOffset, Info.size()));
759           if (!HeaderOrError)
760             return HeaderOrError.takeError();
761           InfoSectionUnitHeader &Header = *HeaderOrError;
762 
763           UnitIndexEntry Entry = CurEntry;
764           auto &C = Entry.Contributions[getContributionIndex(DW_SECT_INFO,
765                                                              IndexVersion)];
766           C.Offset = InfoSectionOffset;
767           C.Length = Header.Length + 4;
768           UnitOffset += C.Length;
769           if (Header.Version < 5 ||
770               Header.UnitType == dwarf::DW_UT_split_compile) {
771             Expected<CompileUnitIdentifiers> EID =
772                 getCUIdentifiers(Header, AbbrevSection,
773                                  Info.substr(UnitOffset - C.Length, C.Length),
774                                  CurStrOffsetSection, CurStrSection);
775 
776             if (!EID)
777               return createFileError(Input, EID.takeError());
778             const auto &ID = *EID;
779             auto P = IndexEntries.insert(std::make_pair(ID.Signature, Entry));
780             if (!P.second)
781               return buildDuplicateError(*P.first, ID, "");
782             P.first->second.Name = ID.Name;
783             P.first->second.DWOName = ID.DWOName;
784 
785             FoundCUUnit = true;
786           } else if (Header.UnitType == dwarf::DW_UT_split_type) {
787             auto P = TypeIndexEntries.insert(
788                 std::make_pair(Header.Signature.getValue(), Entry));
789             if (!P.second)
790               continue;
791           }
792           Out.emitBytes(Info.substr(UnitOffset - C.Length, C.Length));
793           InfoSectionOffset += C.Length;
794         }
795       }
796 
797       if (!FoundCUUnit)
798         return make_error<DWPError>("no compile unit found in file: " + Input);
799 
800       if (IndexVersion == 2) {
801         // Add types from the .debug_types section from DWARF < 5.
802         addAllTypesFromTypesSection(
803             Out, TypeIndexEntries, TypesSection, CurTypesSection, CurEntry,
804             ContributionOffsets[getContributionIndex(DW_SECT_EXT_TYPES, 2)]);
805       }
806       continue;
807     }
808 
809     if (CurInfoSection.size() != 1)
810       return make_error<DWPError>("expected exactly one occurrence of a debug "
811                                   "info section in a .dwp file");
812     StringRef DwpSingleInfoSection = CurInfoSection.front();
813 
814     DWARFUnitIndex CUIndex(DW_SECT_INFO);
815     DataExtractor CUIndexData(CurCUIndexSection, Obj.isLittleEndian(), 0);
816     if (!CUIndex.parse(CUIndexData))
817       return make_error<DWPError>("failed to parse cu_index");
818     if (CUIndex.getVersion() != IndexVersion)
819       return make_error<DWPError>("incompatible cu_index versions, found " +
820                                   utostr(CUIndex.getVersion()) +
821                                   " and expecting " + utostr(IndexVersion));
822 
823     Out.SwitchSection(InfoSection);
824     for (const DWARFUnitIndex::Entry &E : CUIndex.getRows()) {
825       auto *I = E.getContributions();
826       if (!I)
827         continue;
828       auto P = IndexEntries.insert(std::make_pair(E.getSignature(), CurEntry));
829       StringRef CUInfoSection =
830           getSubsection(DwpSingleInfoSection, E, DW_SECT_INFO);
831       Expected<InfoSectionUnitHeader> HeaderOrError =
832           parseInfoSectionUnitHeader(CUInfoSection);
833       if (!HeaderOrError)
834         return HeaderOrError.takeError();
835       InfoSectionUnitHeader &Header = *HeaderOrError;
836 
837       Expected<CompileUnitIdentifiers> EID = getCUIdentifiers(
838           Header, getSubsection(AbbrevSection, E, DW_SECT_ABBREV),
839           CUInfoSection,
840           getSubsection(CurStrOffsetSection, E, DW_SECT_STR_OFFSETS),
841           CurStrSection);
842       if (!EID)
843         return createFileError(Input, EID.takeError());
844       const auto &ID = *EID;
845       if (!P.second)
846         return buildDuplicateError(*P.first, ID, Input);
847       auto &NewEntry = P.first->second;
848       NewEntry.Name = ID.Name;
849       NewEntry.DWOName = ID.DWOName;
850       NewEntry.DWPName = Input;
851       for (auto Kind : CUIndex.getColumnKinds()) {
852         if (!isSupportedSectionKind(Kind))
853           continue;
854         auto &C =
855             NewEntry.Contributions[getContributionIndex(Kind, IndexVersion)];
856         C.Offset += I->Offset;
857         C.Length = I->Length;
858         ++I;
859       }
860       unsigned Index = getContributionIndex(DW_SECT_INFO, IndexVersion);
861       auto &C = NewEntry.Contributions[Index];
862       Out.emitBytes(CUInfoSection);
863       C.Offset = InfoSectionOffset;
864       InfoSectionOffset += C.Length;
865     }
866 
867     if (!CurTUIndexSection.empty()) {
868       llvm::DWARFSectionKind TUSectionKind;
869       MCSection *OutSection;
870       StringRef TypeInputSection;
871       // Write type units into debug info section for DWARFv5.
872       if (Version >= 5) {
873         TUSectionKind = DW_SECT_INFO;
874         OutSection = InfoSection;
875         TypeInputSection = DwpSingleInfoSection;
876       } else {
877         // Write type units into debug types section for DWARF < 5.
878         if (CurTypesSection.size() != 1)
879           return make_error<DWPError>(
880               "multiple type unit sections in .dwp file");
881 
882         TUSectionKind = DW_SECT_EXT_TYPES;
883         OutSection = TypesSection;
884         TypeInputSection = CurTypesSection.front();
885       }
886 
887       DWARFUnitIndex TUIndex(TUSectionKind);
888       DataExtractor TUIndexData(CurTUIndexSection, Obj.isLittleEndian(), 0);
889       if (!TUIndex.parse(TUIndexData))
890         return make_error<DWPError>("failed to parse tu_index");
891       if (TUIndex.getVersion() != IndexVersion)
892         return make_error<DWPError>("incompatible tu_index versions, found " +
893                                     utostr(TUIndex.getVersion()) +
894                                     " and expecting " + utostr(IndexVersion));
895 
896       unsigned TypesContributionIndex =
897           getContributionIndex(TUSectionKind, IndexVersion);
898       addAllTypesFromDWP(Out, TypeIndexEntries, TUIndex, OutSection,
899                          TypeInputSection, CurEntry,
900                          ContributionOffsets[TypesContributionIndex],
901                          TypesContributionIndex);
902     }
903   }
904 
905   if (Version < 5) {
906     // Lie about there being no info contributions so the TU index only includes
907     // the type unit contribution for DWARF < 5. In DWARFv5 the TU index has a
908     // contribution to the info section, so we do not want to lie about it.
909     ContributionOffsets[0] = 0;
910   }
911   writeIndex(Out, MCOFI.getDwarfTUIndexSection(), ContributionOffsets,
912              TypeIndexEntries, IndexVersion);
913 
914   if (Version < 5) {
915     // Lie about the type contribution for DWARF < 5. In DWARFv5 the type
916     // section does not exist, so no need to do anything about this.
917     ContributionOffsets[getContributionIndex(DW_SECT_EXT_TYPES, 2)] = 0;
918     // Unlie about the info contribution
919     ContributionOffsets[0] = 1;
920   }
921 
922   writeIndex(Out, MCOFI.getDwarfCUIndexSection(), ContributionOffsets,
923              IndexEntries, IndexVersion);
924 
925   return Error::success();
926 }
927 
928 static int error(const Twine &Error, const Twine &Context) {
929   errs() << Twine("while processing ") + Context + ":\n";
930   errs() << Twine("error: ") + Error + "\n";
931   return 1;
932 }
933 
934 static Expected<Triple> readTargetTriple(StringRef FileName) {
935   auto ErrOrObj = object::ObjectFile::createObjectFile(FileName);
936   if (!ErrOrObj)
937     return ErrOrObj.takeError();
938 
939   return ErrOrObj->getBinary()->makeTriple();
940 }
941 
942 int main(int argc, char **argv) {
943   InitLLVM X(argc, argv);
944 
945   cl::ParseCommandLineOptions(argc, argv, "merge split dwarf (.dwo) files\n");
946 
947   llvm::InitializeAllTargetInfos();
948   llvm::InitializeAllTargetMCs();
949   llvm::InitializeAllTargets();
950   llvm::InitializeAllAsmPrinters();
951 
952   std::vector<std::string> DWOFilenames = InputFiles;
953   for (const auto &ExecFilename : ExecFilenames) {
954     auto DWOs = getDWOFilenames(ExecFilename);
955     if (!DWOs) {
956       logAllUnhandledErrors(DWOs.takeError(), WithColor::error());
957       return 1;
958     }
959     DWOFilenames.insert(DWOFilenames.end(),
960                         std::make_move_iterator(DWOs->begin()),
961                         std::make_move_iterator(DWOs->end()));
962   }
963 
964   if (DWOFilenames.empty())
965     return 0;
966 
967   std::string ErrorStr;
968   StringRef Context = "dwarf streamer init";
969 
970   auto ErrOrTriple = readTargetTriple(DWOFilenames.front());
971   if (!ErrOrTriple) {
972     logAllUnhandledErrors(ErrOrTriple.takeError(), WithColor::error());
973     return 1;
974   }
975 
976   // Get the target.
977   const Target *TheTarget =
978       TargetRegistry::lookupTarget("", *ErrOrTriple, ErrorStr);
979   if (!TheTarget)
980     return error(ErrorStr, Context);
981   std::string TripleName = ErrOrTriple->getTriple();
982 
983   // Create all the MC Objects.
984   std::unique_ptr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TripleName));
985   if (!MRI)
986     return error(Twine("no register info for target ") + TripleName, Context);
987 
988   MCTargetOptions MCOptions = llvm::mc::InitMCTargetOptionsFromFlags();
989   std::unique_ptr<MCAsmInfo> MAI(
990       TheTarget->createMCAsmInfo(*MRI, TripleName, MCOptions));
991   if (!MAI)
992     return error("no asm info for target " + TripleName, Context);
993 
994   std::unique_ptr<MCSubtargetInfo> MSTI(
995       TheTarget->createMCSubtargetInfo(TripleName, "", ""));
996   if (!MSTI)
997     return error("no subtarget info for target " + TripleName, Context);
998 
999   MCContext MC(*ErrOrTriple, MAI.get(), MRI.get(), MSTI.get());
1000   std::unique_ptr<MCObjectFileInfo> MOFI(
1001       TheTarget->createMCObjectFileInfo(MC, /*PIC=*/false));
1002   MC.setObjectFileInfo(MOFI.get());
1003 
1004   MCTargetOptions Options;
1005   auto MAB = TheTarget->createMCAsmBackend(*MSTI, *MRI, Options);
1006   if (!MAB)
1007     return error("no asm backend for target " + TripleName, Context);
1008 
1009   std::unique_ptr<MCInstrInfo> MII(TheTarget->createMCInstrInfo());
1010   if (!MII)
1011     return error("no instr info info for target " + TripleName, Context);
1012 
1013   MCCodeEmitter *MCE = TheTarget->createMCCodeEmitter(*MII, *MRI, MC);
1014   if (!MCE)
1015     return error("no code emitter for target " + TripleName, Context);
1016 
1017   // Create the output file.
1018   std::error_code EC;
1019   ToolOutputFile OutFile(OutputFilename, EC, sys::fs::OF_None);
1020   Optional<buffer_ostream> BOS;
1021   raw_pwrite_stream *OS;
1022   if (EC)
1023     return error(Twine(OutputFilename) + ": " + EC.message(), Context);
1024   if (OutFile.os().supportsSeeking()) {
1025     OS = &OutFile.os();
1026   } else {
1027     BOS.emplace(OutFile.os());
1028     OS = BOS.getPointer();
1029   }
1030 
1031   std::unique_ptr<MCStreamer> MS(TheTarget->createMCObjectStreamer(
1032       *ErrOrTriple, MC, std::unique_ptr<MCAsmBackend>(MAB),
1033       MAB->createObjectWriter(*OS), std::unique_ptr<MCCodeEmitter>(MCE), *MSTI,
1034       MCOptions.MCRelaxAll, MCOptions.MCIncrementalLinkerCompatible,
1035       /*DWARFMustBeAtTheEnd*/ false));
1036   if (!MS)
1037     return error("no object streamer for target " + TripleName, Context);
1038 
1039   if (auto Err = write(*MS, DWOFilenames)) {
1040     logAllUnhandledErrors(std::move(Err), WithColor::error());
1041     return 1;
1042   }
1043 
1044   MS->Finish();
1045   OutFile.keep();
1046   return 0;
1047 }
1048