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
48using namespace llvm;
49using namespace llvm::object;
50
51static mc::RegisterMCTargetOptionsFlags MCTargetOptionsFlags;
52
53cl::OptionCategory DwpCategory("Specific Options");
54static cl::list<std::string> InputFiles(cl::Positional, cl::ZeroOrMore,
55                                        cl::desc("<input files>"),
56                                        cl::cat(DwpCategory));
57
58static 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
63static 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.
69static 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.
82struct 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.
112static 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
164static 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
203static 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
218struct CompileUnitIdentifiers {
219  uint64_t Signature = 0;
220  const char *Name = "";
221  const char *DWOName = "";
222};
223
224static Expected<const char *>
225getIndexedString(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
262static 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
326struct UnitIndexEntry {
327  DWARFUnitIndex::Entry::SectionContribution Contributions[8];
328  std::string Name;
329  std::string DWOName;
330  StringRef DWPName;
331};
332
333static 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.
339static 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.
347static unsigned getOnDiskSectionId(unsigned Index) {
348  return Index + DW_SECT_INFO;
349}
350
351static 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
360static 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
392static 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
427static void
428writeIndexTable(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
437static void
438writeIndex(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
493static 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
512static 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
519static Error
520handleCompressedSection(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
539static 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
613static Error
614buildDuplicateError(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
623static Expected<SmallVector<std::string, 16>>
624getDWOFilenames(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
652static 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
812static 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
818static 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
826int 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  std::unique_ptr<MCSubtargetInfo> MSTI(
879      TheTarget->createMCSubtargetInfo(TripleName, "", ""));
880  if (!MSTI)
881    return error("no subtarget info for target " + TripleName, Context);
882
883  MCContext MC(*ErrOrTriple, MAI.get(), MRI.get(), MSTI.get());
884  std::unique_ptr<MCObjectFileInfo> MOFI(
885      TheTarget->createMCObjectFileInfo(MC, /*PIC=*/false));
886  MC.setObjectFileInfo(MOFI.get());
887
888  MCTargetOptions Options;
889  auto MAB = TheTarget->createMCAsmBackend(*MSTI, *MRI, Options);
890  if (!MAB)
891    return error("no asm backend for target " + TripleName, Context);
892
893  std::unique_ptr<MCInstrInfo> MII(TheTarget->createMCInstrInfo());
894  if (!MII)
895    return error("no instr info info for target " + TripleName, Context);
896
897  MCCodeEmitter *MCE = TheTarget->createMCCodeEmitter(*MII, *MRI, MC);
898  if (!MCE)
899    return error("no code emitter for target " + TripleName, Context);
900
901  // Create the output file.
902  std::error_code EC;
903  ToolOutputFile OutFile(OutputFilename, EC, sys::fs::OF_None);
904  Optional<buffer_ostream> BOS;
905  raw_pwrite_stream *OS;
906  if (EC)
907    return error(Twine(OutputFilename) + ": " + EC.message(), Context);
908  if (OutFile.os().supportsSeeking()) {
909    OS = &OutFile.os();
910  } else {
911    BOS.emplace(OutFile.os());
912    OS = BOS.getPointer();
913  }
914
915  std::unique_ptr<MCStreamer> MS(TheTarget->createMCObjectStreamer(
916      *ErrOrTriple, MC, std::unique_ptr<MCAsmBackend>(MAB),
917      MAB->createObjectWriter(*OS), std::unique_ptr<MCCodeEmitter>(MCE), *MSTI,
918      MCOptions.MCRelaxAll, MCOptions.MCIncrementalLinkerCompatible,
919      /*DWARFMustBeAtTheEnd*/ false));
920  if (!MS)
921    return error("no object streamer for target " + TripleName, Context);
922
923  if (auto Err = write(*MS, DWOFilenames)) {
924    logAllUnhandledErrors(std::move(Err), WithColor::error());
925    return 1;
926  }
927
928  MS->Finish();
929  OutFile.keep();
930  return 0;
931}
932