LLVM  16.0.0git
DWP.cpp
Go to the documentation of this file.
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 "llvm/DWP/DWP.h"
14 #include "llvm/DWP/DWPError.h"
15 #include "llvm/MC/MCContext.h"
21 #include <limits>
22 
23 using namespace llvm;
24 using namespace llvm::object;
25 
27 
28 // Returns the size of debug_str_offsets section headers in bytes.
30  uint16_t DwarfVersion) {
31  if (DwarfVersion <= 4)
32  return 0; // There is no header before dwarf 5.
33  uint64_t Offset = 0;
34  uint64_t Length = StrOffsetsData.getU32(&Offset);
35  if (Length == llvm::dwarf::DW_LENGTH_DWARF64)
36  return 16; // unit length: 12 bytes, version: 2 bytes, padding: 2 bytes.
37  return 8; // unit length: 4 bytes, version: 2 bytes, padding: 2 bytes.
38 }
39 
40 static uint64_t getCUAbbrev(StringRef Abbrev, uint64_t AbbrCode) {
41  uint64_t Offset = 0;
42  DataExtractor AbbrevData(Abbrev, true, 0);
43  while (AbbrevData.getULEB128(&Offset) != AbbrCode) {
44  // Tag
45  AbbrevData.getULEB128(&Offset);
46  // DW_CHILDREN
47  AbbrevData.getU8(&Offset);
48  // Attributes
49  while (AbbrevData.getULEB128(&Offset) | AbbrevData.getULEB128(&Offset))
50  ;
51  }
52  return Offset;
53 }
54 
57  StringRef StrOffsets, StringRef Str, uint16_t Version) {
58  if (Form == dwarf::DW_FORM_string)
59  return InfoData.getCStr(&InfoOffset);
60  uint64_t StrIndex;
61  switch (Form) {
62  case dwarf::DW_FORM_strx1:
63  StrIndex = InfoData.getU8(&InfoOffset);
64  break;
65  case dwarf::DW_FORM_strx2:
66  StrIndex = InfoData.getU16(&InfoOffset);
67  break;
68  case dwarf::DW_FORM_strx3:
69  StrIndex = InfoData.getU24(&InfoOffset);
70  break;
71  case dwarf::DW_FORM_strx4:
72  StrIndex = InfoData.getU32(&InfoOffset);
73  break;
74  case dwarf::DW_FORM_strx:
75  case dwarf::DW_FORM_GNU_str_index:
76  StrIndex = InfoData.getULEB128(&InfoOffset);
77  break;
78  default:
79  return make_error<DWPError>(
80  "string field must be encoded with one of the following: "
81  "DW_FORM_string, DW_FORM_strx, DW_FORM_strx1, DW_FORM_strx2, "
82  "DW_FORM_strx3, DW_FORM_strx4, or DW_FORM_GNU_str_index.");
83  }
84  DataExtractor StrOffsetsData(StrOffsets, true, 0);
85  uint64_t StrOffsetsOffset = 4 * StrIndex;
86  StrOffsetsOffset += debugStrOffsetsHeaderSize(StrOffsetsData, Version);
87 
88  uint64_t StrOffset = StrOffsetsData.getU32(&StrOffsetsOffset);
89  DataExtractor StrData(Str, true, 0);
90  return StrData.getCStr(&StrOffset);
91 }
92 
95  StringRef Info, StringRef StrOffsets, StringRef Str) {
96  DataExtractor InfoData(Info, true, 0);
97  uint64_t Offset = Header.HeaderSize;
98  if (Header.Version >= 5 && Header.UnitType != dwarf::DW_UT_split_compile)
99  return make_error<DWPError>(
100  std::string("unit type DW_UT_split_compile type not found in "
101  "debug_info header. Unexpected unit type 0x" +
102  utostr(Header.UnitType) + " found"));
103 
105 
106  uint32_t AbbrCode = InfoData.getULEB128(&Offset);
107  DataExtractor AbbrevData(Abbrev, true, 0);
108  uint64_t AbbrevOffset = getCUAbbrev(Abbrev, AbbrCode);
109  auto Tag = static_cast<dwarf::Tag>(AbbrevData.getULEB128(&AbbrevOffset));
110  if (Tag != dwarf::DW_TAG_compile_unit)
111  return make_error<DWPError>("top level DIE is not a compile unit");
112  // DW_CHILDREN
113  AbbrevData.getU8(&AbbrevOffset);
114  uint32_t Name;
116  while ((Name = AbbrevData.getULEB128(&AbbrevOffset)) |
117  (Form = static_cast<dwarf::Form>(
118  AbbrevData.getULEB128(&AbbrevOffset))) &&
119  (Name != 0 || Form != 0)) {
120  switch (Name) {
121  case dwarf::DW_AT_name: {
123  Form, InfoData, Offset, StrOffsets, Str, Header.Version);
124  if (!EName)
125  return EName.takeError();
126  ID.Name = *EName;
127  break;
128  }
129  case dwarf::DW_AT_GNU_dwo_name:
130  case dwarf::DW_AT_dwo_name: {
132  Form, InfoData, Offset, StrOffsets, Str, Header.Version);
133  if (!EName)
134  return EName.takeError();
135  ID.DWOName = *EName;
136  break;
137  }
138  case dwarf::DW_AT_GNU_dwo_id:
139  Header.Signature = InfoData.getU64(&Offset);
140  break;
141  default:
143  Form, InfoData, &Offset,
144  dwarf::FormParams({Header.Version, Header.AddrSize, Header.Format}));
145  }
146  }
147  if (!Header.Signature)
148  return make_error<DWPError>("compile unit missing dwo_id");
149  ID.Signature = *Header.Signature;
150  return ID;
151 }
152 
154  return Kind != DW_SECT_EXT_unknown;
155 }
156 
157 namespace llvm {
158 // Convert an internal section identifier into the index to use with
159 // UnitIndexEntry::Contributions.
161  assert(serializeSectionKind(Kind, IndexVersion) >= DW_SECT_INFO);
162  return serializeSectionKind(Kind, IndexVersion) - DW_SECT_INFO;
163 }
164 } // namespace llvm
165 
166 // Convert a UnitIndexEntry::Contributions index to the corresponding on-disk
167 // value of the section identifier.
168 static unsigned getOnDiskSectionId(unsigned Index) {
169  return Index + DW_SECT_INFO;
170 }
171 
173  const DWARFUnitIndex::Entry &Entry,
175  const auto *Off = Entry.getContribution(Kind);
176  if (!Off)
177  return StringRef();
178  return Section.substr(Off->Offset, Off->Length);
179 }
180 
181 static void
183  MapVector<uint64_t, UnitIndexEntry> &TypeIndexEntries,
184  const DWARFUnitIndex &TUIndex, MCSection *OutputTypes,
185  StringRef Types, const UnitIndexEntry &TUEntry,
186  uint32_t &TypesOffset, unsigned TypesContributionIndex) {
187  Out.switchSection(OutputTypes);
188  for (const DWARFUnitIndex::Entry &E : TUIndex.getRows()) {
189  auto *I = E.getContributions();
190  if (!I)
191  continue;
192  auto P = TypeIndexEntries.insert(std::make_pair(E.getSignature(), TUEntry));
193  if (!P.second)
194  continue;
195  auto &Entry = P.first->second;
196  // Zero out the debug_info contribution
197  Entry.Contributions[0] = {};
198  for (auto Kind : TUIndex.getColumnKinds()) {
200  continue;
201  auto &C =
202  Entry.Contributions[getContributionIndex(Kind, TUIndex.getVersion())];
203  C.Offset += I->Offset;
204  C.Length = I->Length;
205  ++I;
206  }
207  auto &C = Entry.Contributions[TypesContributionIndex];
208  Out.emitBytes(Types.substr(
209  C.Offset - TUEntry.Contributions[TypesContributionIndex].Offset,
210  C.Length));
211  C.Offset = TypesOffset;
212  TypesOffset += C.Length;
213  }
214 }
215 
217  MCStreamer &Out, MapVector<uint64_t, UnitIndexEntry> &TypeIndexEntries,
218  MCSection *OutputTypes, const std::vector<StringRef> &TypesSections,
219  const UnitIndexEntry &CUEntry, uint32_t &TypesOffset) {
220  for (StringRef Types : TypesSections) {
221  Out.switchSection(OutputTypes);
222  uint64_t Offset = 0;
223  DataExtractor Data(Types, true, 0);
224  while (Data.isValidOffset(Offset)) {
225  UnitIndexEntry Entry = CUEntry;
226  // Zero out the debug_info contribution
227  Entry.Contributions[0] = {};
228  auto &C = Entry.Contributions[getContributionIndex(DW_SECT_EXT_TYPES, 2)];
229  C.Offset = TypesOffset;
230  auto PrevOffset = Offset;
231  // Length of the unit, including the 4 byte length field.
232  C.Length = Data.getU32(&Offset) + 4;
233 
234  Data.getU16(&Offset); // Version
235  Data.getU32(&Offset); // Abbrev offset
236  Data.getU8(&Offset); // Address size
237  auto Signature = Data.getU64(&Offset);
238  Offset = PrevOffset + C.Length;
239 
240  auto P = TypeIndexEntries.insert(std::make_pair(Signature, Entry));
241  if (!P.second)
242  continue;
243 
244  Out.emitBytes(Types.substr(PrevOffset, C.Length));
245  TypesOffset += C.Length;
246  }
247  }
248 }
249 
250 static std::string buildDWODescription(StringRef Name, StringRef DWPName,
251  StringRef DWOName) {
252  std::string Text = "\'";
253  Text += Name;
254  Text += '\'';
255  bool HasDWO = !DWOName.empty();
256  bool HasDWP = !DWPName.empty();
257  if (HasDWO || HasDWP) {
258  Text += " (from ";
259  if (HasDWO) {
260  Text += '\'';
261  Text += DWOName;
262  Text += '\'';
263  }
264  if (HasDWO && HasDWP)
265  Text += " in ";
266  if (!DWPName.empty()) {
267  Text += '\'';
268  Text += DWPName;
269  Text += '\'';
270  }
271  Text += ")";
272  }
273  return Text;
274 }
275 
277  return make_error<DWPError>(
278  ("failure while decompressing compressed section: '" + Name + "', " +
280  .str());
281 }
282 
283 static Error
284 handleCompressedSection(std::deque<SmallString<32>> &UncompressedSections,
285  SectionRef Sec, StringRef Name, StringRef &Contents) {
286  auto *Obj = dyn_cast<ELFObjectFileBase>(Sec.getObject());
287  if (!Obj ||
288  !(static_cast<ELFSectionRef>(Sec).getFlags() & ELF::SHF_COMPRESSED))
289  return Error::success();
290  bool IsLE = isa<object::ELF32LEObjectFile>(Obj) ||
291  isa<object::ELF64LEObjectFile>(Obj);
292  bool Is64 = isa<object::ELF64LEObjectFile>(Obj) ||
293  isa<object::ELF64BEObjectFile>(Obj);
294  Expected<Decompressor> Dec = Decompressor::create(Name, Contents, IsLE, Is64);
295  if (!Dec)
296  return createError(Name, Dec.takeError());
297 
298  UncompressedSections.emplace_back();
299  if (Error E = Dec->resizeAndDecompress(UncompressedSections.back()))
300  return createError(Name, std::move(E));
301 
302  Contents = UncompressedSections.back();
303  return Error::success();
304 }
305 
306 namespace llvm {
307 // Parse and return the header of an info section compile/type unit.
309  InfoSectionUnitHeader Header;
310  Error Err = Error::success();
311  uint64_t Offset = 0;
312  DWARFDataExtractor InfoData(Info, true, 0);
313  std::tie(Header.Length, Header.Format) =
314  InfoData.getInitialLength(&Offset, &Err);
315  if (Err)
316  return make_error<DWPError>("cannot parse compile unit length: " +
317  llvm::toString(std::move(Err)));
318 
319  if (!InfoData.isValidOffset(Offset + (Header.Length - 1))) {
320  return make_error<DWPError>(
321  "compile unit exceeds .debug_info section range: " +
322  utostr(Offset + Header.Length) + " >= " + utostr(InfoData.size()));
323  }
324 
325  Header.Version = InfoData.getU16(&Offset, &Err);
326  if (Err)
327  return make_error<DWPError>("cannot parse compile unit version: " +
328  llvm::toString(std::move(Err)));
329 
330  uint64_t MinHeaderLength;
331  if (Header.Version >= 5) {
332  // Size: Version (2), UnitType (1), AddrSize (1), DebugAbbrevOffset (4),
333  // Signature (8)
334  MinHeaderLength = 16;
335  } else {
336  // Size: Version (2), DebugAbbrevOffset (4), AddrSize (1)
337  MinHeaderLength = 7;
338  }
339  if (Header.Length < MinHeaderLength) {
340  return make_error<DWPError>("unit length is too small: expected at least " +
341  utostr(MinHeaderLength) + " got " +
342  utostr(Header.Length) + ".");
343  }
344  if (Header.Version >= 5) {
345  Header.UnitType = InfoData.getU8(&Offset);
346  Header.AddrSize = InfoData.getU8(&Offset);
347  Header.DebugAbbrevOffset = InfoData.getU32(&Offset);
348  Header.Signature = InfoData.getU64(&Offset);
349  if (Header.UnitType == dwarf::DW_UT_split_type) {
350  // Type offset.
351  MinHeaderLength += 4;
352  if (Header.Length < MinHeaderLength)
353  return make_error<DWPError>("type unit is missing type offset");
354  InfoData.getU32(&Offset);
355  }
356  } else {
357  // Note that, address_size and debug_abbrev_offset fields have switched
358  // places between dwarf version 4 and 5.
359  Header.DebugAbbrevOffset = InfoData.getU32(&Offset);
360  Header.AddrSize = InfoData.getU8(&Offset);
361  }
362 
363  Header.HeaderSize = Offset;
364  return Header;
365 }
366 
368  MCSection *StrOffsetSection,
369  StringRef CurStrSection,
370  StringRef CurStrOffsetSection, uint16_t Version) {
371  // Could possibly produce an error or warning if one of these was non-null but
372  // the other was null.
373  if (CurStrSection.empty() || CurStrOffsetSection.empty())
374  return;
375 
376  DenseMap<uint64_t, uint32_t> OffsetRemapping;
377 
378  DataExtractor Data(CurStrSection, true, 0);
379  uint64_t LocalOffset = 0;
380  uint64_t PrevOffset = 0;
381  while (const char *S = Data.getCStr(&LocalOffset)) {
382  OffsetRemapping[PrevOffset] =
383  Strings.getOffset(S, LocalOffset - PrevOffset);
384  PrevOffset = LocalOffset;
385  }
386 
387  Data = DataExtractor(CurStrOffsetSection, true, 0);
388 
389  Out.switchSection(StrOffsetSection);
390 
392  uint64_t Offset = 0;
393  uint64_t Size = CurStrOffsetSection.size();
394  // FIXME: This can be caused by bad input and should be handled as such.
395  assert(HeaderSize <= Size && "StrOffsetSection size is less than its header");
396  // Copy the header to the output.
397  Out.emitBytes(Data.getBytes(&Offset, HeaderSize));
398  while (Offset < Size) {
399  auto OldOffset = Data.getU32(&Offset);
400  auto NewOffset = OffsetRemapping[OldOffset];
401  Out.emitIntValue(NewOffset, 4);
402  }
403 }
404 
406  MCStreamer &Out, ArrayRef<unsigned> ContributionOffsets,
407  const MapVector<uint64_t, UnitIndexEntry> &IndexEntries,
409  for (const auto &E : IndexEntries)
410  for (size_t I = 0; I != std::size(E.second.Contributions); ++I)
411  if (ContributionOffsets[I])
412  Out.emitIntValue(E.second.Contributions[I].*Field, 4);
413 }
414 
415 void writeIndex(MCStreamer &Out, MCSection *Section,
416  ArrayRef<unsigned> ContributionOffsets,
417  const MapVector<uint64_t, UnitIndexEntry> &IndexEntries,
418  uint32_t IndexVersion) {
419  if (IndexEntries.empty())
420  return;
421 
422  unsigned Columns = 0;
423  for (auto &C : ContributionOffsets)
424  if (C)
425  ++Columns;
426 
427  std::vector<unsigned> Buckets(NextPowerOf2(3 * IndexEntries.size() / 2));
428  uint64_t Mask = Buckets.size() - 1;
429  size_t I = 0;
430  for (const auto &P : IndexEntries) {
431  auto S = P.first;
432  auto H = S & Mask;
433  auto HP = ((S >> 32) & Mask) | 1;
434  while (Buckets[H]) {
435  assert(S != IndexEntries.begin()[Buckets[H] - 1].first &&
436  "Duplicate unit");
437  H = (H + HP) & Mask;
438  }
439  Buckets[H] = I + 1;
440  ++I;
441  }
442 
443  Out.switchSection(Section);
444  Out.emitIntValue(IndexVersion, 4); // Version
445  Out.emitIntValue(Columns, 4); // Columns
446  Out.emitIntValue(IndexEntries.size(), 4); // Num Units
447  Out.emitIntValue(Buckets.size(), 4); // Num Buckets
448 
449  // Write the signatures.
450  for (const auto &I : Buckets)
451  Out.emitIntValue(I ? IndexEntries.begin()[I - 1].first : 0, 8);
452 
453  // Write the indexes.
454  for (const auto &I : Buckets)
455  Out.emitIntValue(I, 4);
456 
457  // Write the column headers (which sections will appear in the table)
458  for (size_t I = 0; I != ContributionOffsets.size(); ++I)
459  if (ContributionOffsets[I])
461 
462  // Write the offsets.
463  writeIndexTable(Out, ContributionOffsets, IndexEntries,
465 
466  // Write the lengths.
467  writeIndexTable(Out, ContributionOffsets, IndexEntries,
469 }
470 
471 Error buildDuplicateError(const std::pair<uint64_t, UnitIndexEntry> &PrevE,
472  const CompileUnitIdentifiers &ID, StringRef DWPName) {
473  return make_error<DWPError>(
474  std::string("duplicate DWO ID (") + utohexstr(PrevE.first) + ") in " +
475  buildDWODescription(PrevE.second.Name, PrevE.second.DWPName,
476  PrevE.second.DWOName) +
477  " and " + buildDWODescription(ID.Name, DWPName, ID.DWOName));
478 }
479 
481  const StringMap<std::pair<MCSection *, DWARFSectionKind>> &KnownSections,
482  const MCSection *StrSection, const MCSection *StrOffsetSection,
483  const MCSection *TypesSection, const MCSection *CUIndexSection,
484  const MCSection *TUIndexSection, const MCSection *InfoSection,
485  const SectionRef &Section, MCStreamer &Out,
486  std::deque<SmallString<32>> &UncompressedSections,
487  uint32_t (&ContributionOffsets)[8], UnitIndexEntry &CurEntry,
488  StringRef &CurStrSection, StringRef &CurStrOffsetSection,
489  std::vector<StringRef> &CurTypesSection,
490  std::vector<StringRef> &CurInfoSection, StringRef &AbbrevSection,
491  StringRef &CurCUIndexSection, StringRef &CurTUIndexSection,
492  std::vector<std::pair<DWARFSectionKind, uint32_t>> &SectionLength) {
493  if (Section.isBSS())
494  return Error::success();
495 
496  if (Section.isVirtual())
497  return Error::success();
498 
499  Expected<StringRef> NameOrErr = Section.getName();
500  if (!NameOrErr)
501  return NameOrErr.takeError();
502  StringRef Name = *NameOrErr;
503 
504  Expected<StringRef> ContentsOrErr = Section.getContents();
505  if (!ContentsOrErr)
506  return ContentsOrErr.takeError();
507  StringRef Contents = *ContentsOrErr;
508 
509  if (auto Err = handleCompressedSection(UncompressedSections, Section, Name,
510  Contents))
511  return Err;
512 
513  Name = Name.substr(Name.find_first_not_of("._"));
514 
515  auto SectionPair = KnownSections.find(Name);
516  if (SectionPair == KnownSections.end())
517  return Error::success();
518 
519  if (DWARFSectionKind Kind = SectionPair->second.second) {
520  if (Kind != DW_SECT_EXT_TYPES && Kind != DW_SECT_INFO) {
521  SectionLength.push_back(std::make_pair(Kind, Contents.size()));
522  }
523 
524  if (Kind == DW_SECT_ABBREV) {
525  AbbrevSection = Contents;
526  }
527  }
528 
529  MCSection *OutSection = SectionPair->second.first;
530  if (OutSection == StrOffsetSection)
531  CurStrOffsetSection = Contents;
532  else if (OutSection == StrSection)
533  CurStrSection = Contents;
534  else if (OutSection == TypesSection)
535  CurTypesSection.push_back(Contents);
536  else if (OutSection == CUIndexSection)
537  CurCUIndexSection = Contents;
538  else if (OutSection == TUIndexSection)
539  CurTUIndexSection = Contents;
540  else if (OutSection == InfoSection)
541  CurInfoSection.push_back(Contents);
542  else {
543  Out.switchSection(OutSection);
544  Out.emitBytes(Contents);
545  }
546  return Error::success();
547 }
548 
550  const auto &MCOFI = *Out.getContext().getObjectFileInfo();
551  MCSection *const StrSection = MCOFI.getDwarfStrDWOSection();
552  MCSection *const StrOffsetSection = MCOFI.getDwarfStrOffDWOSection();
553  MCSection *const TypesSection = MCOFI.getDwarfTypesDWOSection();
554  MCSection *const CUIndexSection = MCOFI.getDwarfCUIndexSection();
555  MCSection *const TUIndexSection = MCOFI.getDwarfTUIndexSection();
556  MCSection *const InfoSection = MCOFI.getDwarfInfoDWOSection();
558  {"debug_info.dwo", {InfoSection, DW_SECT_INFO}},
559  {"debug_types.dwo", {MCOFI.getDwarfTypesDWOSection(), DW_SECT_EXT_TYPES}},
560  {"debug_str_offsets.dwo", {StrOffsetSection, DW_SECT_STR_OFFSETS}},
561  {"debug_str.dwo", {StrSection, static_cast<DWARFSectionKind>(0)}},
562  {"debug_loc.dwo", {MCOFI.getDwarfLocDWOSection(), DW_SECT_EXT_LOC}},
563  {"debug_line.dwo", {MCOFI.getDwarfLineDWOSection(), DW_SECT_LINE}},
564  {"debug_macro.dwo", {MCOFI.getDwarfMacroDWOSection(), DW_SECT_MACRO}},
565  {"debug_abbrev.dwo", {MCOFI.getDwarfAbbrevDWOSection(), DW_SECT_ABBREV}},
566  {"debug_loclists.dwo",
567  {MCOFI.getDwarfLoclistsDWOSection(), DW_SECT_LOCLISTS}},
568  {"debug_rnglists.dwo",
569  {MCOFI.getDwarfRnglistsDWOSection(), DW_SECT_RNGLISTS}},
570  {"debug_cu_index", {CUIndexSection, static_cast<DWARFSectionKind>(0)}},
571  {"debug_tu_index", {TUIndexSection, static_cast<DWARFSectionKind>(0)}}};
572 
574  MapVector<uint64_t, UnitIndexEntry> TypeIndexEntries;
575 
576  uint32_t ContributionOffsets[8] = {};
577  uint16_t Version = 0;
578  uint32_t IndexVersion = 0;
579 
580  DWPStringPool Strings(Out, StrSection);
581 
583  Objects.reserve(Inputs.size());
584 
585  std::deque<SmallString<32>> UncompressedSections;
586 
587  for (const auto &Input : Inputs) {
588  auto ErrOrObj = object::ObjectFile::createObjectFile(Input);
589  if (!ErrOrObj) {
590  return handleErrors(ErrOrObj.takeError(),
591  [&](std::unique_ptr<ECError> EC) -> Error {
592  return createFileError(Input, Error(std::move(EC)));
593  });
594  }
595 
596  auto &Obj = *ErrOrObj->getBinary();
597  Objects.push_back(std::move(*ErrOrObj));
598 
599  UnitIndexEntry CurEntry = {};
600 
601  StringRef CurStrSection;
602  StringRef CurStrOffsetSection;
603  std::vector<StringRef> CurTypesSection;
604  std::vector<StringRef> CurInfoSection;
605  StringRef AbbrevSection;
606  StringRef CurCUIndexSection;
607  StringRef CurTUIndexSection;
608 
609  // This maps each section contained in this file to its length.
610  // This information is later on used to calculate the contributions,
611  // i.e. offset and length, of each compile/type unit to a section.
612  std::vector<std::pair<DWARFSectionKind, uint32_t>> SectionLength;
613 
614  for (const auto &Section : Obj.sections())
615  if (auto Err = handleSection(
616  KnownSections, StrSection, StrOffsetSection, TypesSection,
617  CUIndexSection, TUIndexSection, InfoSection, Section, Out,
618  UncompressedSections, ContributionOffsets, CurEntry,
619  CurStrSection, CurStrOffsetSection, CurTypesSection,
620  CurInfoSection, AbbrevSection, CurCUIndexSection,
621  CurTUIndexSection, SectionLength))
622  return Err;
623 
624  if (CurInfoSection.empty())
625  continue;
626 
627  Expected<InfoSectionUnitHeader> HeaderOrErr =
628  parseInfoSectionUnitHeader(CurInfoSection.front());
629  if (!HeaderOrErr)
630  return HeaderOrErr.takeError();
631  InfoSectionUnitHeader &Header = *HeaderOrErr;
632 
633  if (Version == 0) {
634  Version = Header.Version;
635  IndexVersion = Version < 5 ? 2 : 5;
636  } else if (Version != Header.Version) {
637  return make_error<DWPError>("incompatible DWARF compile unit versions.");
638  }
639 
640  writeStringsAndOffsets(Out, Strings, StrOffsetSection, CurStrSection,
641  CurStrOffsetSection, Header.Version);
642 
643  for (auto Pair : SectionLength) {
644  auto Index = getContributionIndex(Pair.first, IndexVersion);
645  CurEntry.Contributions[Index].Offset = ContributionOffsets[Index];
646  ContributionOffsets[Index] +=
647  (CurEntry.Contributions[Index].Length = Pair.second);
648  }
649 
650  uint32_t &InfoSectionOffset =
651  ContributionOffsets[getContributionIndex(DW_SECT_INFO, IndexVersion)];
652  if (CurCUIndexSection.empty()) {
653  bool FoundCUUnit = false;
654  Out.switchSection(InfoSection);
655  for (StringRef Info : CurInfoSection) {
656  uint64_t UnitOffset = 0;
657  while (Info.size() > UnitOffset) {
658  Expected<InfoSectionUnitHeader> HeaderOrError =
659  parseInfoSectionUnitHeader(Info.substr(UnitOffset, Info.size()));
660  if (!HeaderOrError)
661  return HeaderOrError.takeError();
662  InfoSectionUnitHeader &Header = *HeaderOrError;
663 
664  UnitIndexEntry Entry = CurEntry;
665  auto &C = Entry.Contributions[getContributionIndex(DW_SECT_INFO,
666  IndexVersion)];
667  C.Offset = InfoSectionOffset;
668  C.Length = Header.Length + 4;
669 
670  if (std::numeric_limits<uint32_t>::max() - InfoSectionOffset <
671  C.Length)
672  return make_error<DWPError>(
673  "debug information section offset is greater than 4GB");
674 
675  UnitOffset += C.Length;
676  if (Header.Version < 5 ||
677  Header.UnitType == dwarf::DW_UT_split_compile) {
679  getCUIdentifiers(Header, AbbrevSection,
680  Info.substr(UnitOffset - C.Length, C.Length),
681  CurStrOffsetSection, CurStrSection);
682 
683  if (!EID)
684  return createFileError(Input, EID.takeError());
685  const auto &ID = *EID;
686  auto P = IndexEntries.insert(std::make_pair(ID.Signature, Entry));
687  if (!P.second)
688  return buildDuplicateError(*P.first, ID, "");
689  P.first->second.Name = ID.Name;
690  P.first->second.DWOName = ID.DWOName;
691 
692  FoundCUUnit = true;
693  } else if (Header.UnitType == dwarf::DW_UT_split_type) {
694  auto P = TypeIndexEntries.insert(
695  std::make_pair(*Header.Signature, Entry));
696  if (!P.second)
697  continue;
698  }
699  Out.emitBytes(Info.substr(UnitOffset - C.Length, C.Length));
700  InfoSectionOffset += C.Length;
701  }
702  }
703 
704  if (!FoundCUUnit)
705  return make_error<DWPError>("no compile unit found in file: " + Input);
706 
707  if (IndexVersion == 2) {
708  // Add types from the .debug_types section from DWARF < 5.
710  Out, TypeIndexEntries, TypesSection, CurTypesSection, CurEntry,
711  ContributionOffsets[getContributionIndex(DW_SECT_EXT_TYPES, 2)]);
712  }
713  continue;
714  }
715 
716  if (CurInfoSection.size() != 1)
717  return make_error<DWPError>("expected exactly one occurrence of a debug "
718  "info section in a .dwp file");
719  StringRef DwpSingleInfoSection = CurInfoSection.front();
720 
721  DWARFUnitIndex CUIndex(DW_SECT_INFO);
722  DataExtractor CUIndexData(CurCUIndexSection, Obj.isLittleEndian(), 0);
723  if (!CUIndex.parse(CUIndexData))
724  return make_error<DWPError>("failed to parse cu_index");
725  if (CUIndex.getVersion() != IndexVersion)
726  return make_error<DWPError>("incompatible cu_index versions, found " +
727  utostr(CUIndex.getVersion()) +
728  " and expecting " + utostr(IndexVersion));
729 
730  Out.switchSection(InfoSection);
731  for (const DWARFUnitIndex::Entry &E : CUIndex.getRows()) {
732  auto *I = E.getContributions();
733  if (!I)
734  continue;
735  auto P = IndexEntries.insert(std::make_pair(E.getSignature(), CurEntry));
736  StringRef CUInfoSection =
737  getSubsection(DwpSingleInfoSection, E, DW_SECT_INFO);
738  Expected<InfoSectionUnitHeader> HeaderOrError =
739  parseInfoSectionUnitHeader(CUInfoSection);
740  if (!HeaderOrError)
741  return HeaderOrError.takeError();
742  InfoSectionUnitHeader &Header = *HeaderOrError;
743 
745  Header, getSubsection(AbbrevSection, E, DW_SECT_ABBREV),
746  CUInfoSection,
747  getSubsection(CurStrOffsetSection, E, DW_SECT_STR_OFFSETS),
748  CurStrSection);
749  if (!EID)
750  return createFileError(Input, EID.takeError());
751  const auto &ID = *EID;
752  if (!P.second)
753  return buildDuplicateError(*P.first, ID, Input);
754  auto &NewEntry = P.first->second;
755  NewEntry.Name = ID.Name;
756  NewEntry.DWOName = ID.DWOName;
757  NewEntry.DWPName = Input;
758  for (auto Kind : CUIndex.getColumnKinds()) {
760  continue;
761  auto &C =
762  NewEntry.Contributions[getContributionIndex(Kind, IndexVersion)];
763  C.Offset += I->Offset;
764  C.Length = I->Length;
765  ++I;
766  }
767  unsigned Index = getContributionIndex(DW_SECT_INFO, IndexVersion);
768  auto &C = NewEntry.Contributions[Index];
769  Out.emitBytes(CUInfoSection);
770  C.Offset = InfoSectionOffset;
771  InfoSectionOffset += C.Length;
772  }
773 
774  if (!CurTUIndexSection.empty()) {
775  llvm::DWARFSectionKind TUSectionKind;
776  MCSection *OutSection;
777  StringRef TypeInputSection;
778  // Write type units into debug info section for DWARFv5.
779  if (Version >= 5) {
780  TUSectionKind = DW_SECT_INFO;
781  OutSection = InfoSection;
782  TypeInputSection = DwpSingleInfoSection;
783  } else {
784  // Write type units into debug types section for DWARF < 5.
785  if (CurTypesSection.size() != 1)
786  return make_error<DWPError>(
787  "multiple type unit sections in .dwp file");
788 
789  TUSectionKind = DW_SECT_EXT_TYPES;
790  OutSection = TypesSection;
791  TypeInputSection = CurTypesSection.front();
792  }
793 
794  DWARFUnitIndex TUIndex(TUSectionKind);
795  DataExtractor TUIndexData(CurTUIndexSection, Obj.isLittleEndian(), 0);
796  if (!TUIndex.parse(TUIndexData))
797  return make_error<DWPError>("failed to parse tu_index");
798  if (TUIndex.getVersion() != IndexVersion)
799  return make_error<DWPError>("incompatible tu_index versions, found " +
800  utostr(TUIndex.getVersion()) +
801  " and expecting " + utostr(IndexVersion));
802 
803  unsigned TypesContributionIndex =
804  getContributionIndex(TUSectionKind, IndexVersion);
805  addAllTypesFromDWP(Out, TypeIndexEntries, TUIndex, OutSection,
806  TypeInputSection, CurEntry,
807  ContributionOffsets[TypesContributionIndex],
808  TypesContributionIndex);
809  }
810  }
811 
812  if (Version < 5) {
813  // Lie about there being no info contributions so the TU index only includes
814  // the type unit contribution for DWARF < 5. In DWARFv5 the TU index has a
815  // contribution to the info section, so we do not want to lie about it.
816  ContributionOffsets[0] = 0;
817  }
818  writeIndex(Out, MCOFI.getDwarfTUIndexSection(), ContributionOffsets,
819  TypeIndexEntries, IndexVersion);
820 
821  if (Version < 5) {
822  // Lie about the type contribution for DWARF < 5. In DWARFv5 the type
823  // section does not exist, so no need to do anything about this.
824  ContributionOffsets[getContributionIndex(DW_SECT_EXT_TYPES, 2)] = 0;
825  // Unlie about the info contribution
826  ContributionOffsets[0] = 1;
827  }
828 
829  writeIndex(Out, MCOFI.getDwarfCUIndexSection(), ContributionOffsets,
830  IndexEntries, IndexVersion);
831 
832  return Error::success();
833 }
834 } // namespace llvm
MemoryBuffer.h
llvm::MCContext::getObjectFileInfo
const MCObjectFileInfo * getObjectFileInfo() const
Definition: MCContext.h:451
getCUAbbrev
static uint64_t getCUAbbrev(StringRef Abbrev, uint64_t AbbrCode)
Definition: DWP.cpp:40
llvm::object::Kind
Kind
Definition: COFFModuleDefinition.cpp:31
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
llvm::handleErrors
Error handleErrors(Error E, HandlerTs &&... Hs)
Pass the ErrorInfo(s) contained in E to their respective handlers.
Definition: Error.h:942
llvm::handleSection
Error handleSection(const StringMap< std::pair< MCSection *, DWARFSectionKind >> &KnownSections, const MCSection *StrSection, const MCSection *StrOffsetSection, const MCSection *TypesSection, const MCSection *CUIndexSection, const MCSection *TUIndexSection, const MCSection *InfoSection, const object::SectionRef &Section, MCStreamer &Out, std::deque< SmallString< 32 >> &UncompressedSections, uint32_t(&ContributionOffsets)[8], UnitIndexEntry &CurEntry, StringRef &CurStrSection, StringRef &CurStrOffsetSection, std::vector< StringRef > &CurTypesSection, std::vector< StringRef > &CurInfoSection, StringRef &AbbrevSection, StringRef &CurCUIndexSection, StringRef &CurTUIndexSection, std::vector< std::pair< DWARFSectionKind, uint32_t >> &SectionLength)
Definition: DWP.cpp:480
llvm::StringRef::front
char front() const
front - Get the first character in the string.
Definition: StringRef.h:140
P
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from P
Definition: README-SSE.txt:411
llvm::write
Error write(MCStreamer &Out, ArrayRef< std::string > Inputs)
Definition: DWP.cpp:549
llvm::writeIndexTable
void writeIndexTable(MCStreamer &Out, ArrayRef< unsigned > ContributionOffsets, const MapVector< uint64_t, UnitIndexEntry > &IndexEntries, uint32_t DWARFUnitIndex::Entry::SectionContribution::*Field)
Definition: DWP.cpp:405
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1199
llvm::DWARFUnitIndex::Entry::SectionContribution
Definition: DWARFUnitIndex.h:113
handleCompressedSection
static Error handleCompressedSection(std::deque< SmallString< 32 >> &UncompressedSections, SectionRef Sec, StringRef Name, StringRef &Contents)
Definition: DWP.cpp:284
MCTargetOptionsFlags
static mc::RegisterMCTargetOptionsFlags MCTargetOptionsFlags
Definition: DWP.cpp:26
getSubsection
static StringRef getSubsection(StringRef Section, const DWARFUnitIndex::Entry &Entry, DWARFSectionKind Kind)
Definition: DWP.cpp:172
llvm::dwarf::Form
Form
Definition: Dwarf.h:132
llvm::DW_SECT_EXT_unknown
@ DW_SECT_EXT_unknown
Denotes a value read from an index section that does not correspond to any of the supported standards...
Definition: DWARFUnitIndex.h:59
llvm::Error::success
static ErrorSuccess success()
Create a success value.
Definition: Error.h:329
llvm::DWPStringPool
Definition: DWPStringPool.h:10
MCTargetOptionsCommandFlags.h
llvm::dwarf::DW_LENGTH_DWARF64
@ DW_LENGTH_DWARF64
Indicator of 64-bit DWARF format.
Definition: Dwarf.h:57
MCObjectFileInfo.h
llvm::DWARFUnitIndex::Entry
Definition: DWARFUnitIndex.h:111
llvm::MapVector
This class implements a map that also provides access to all stored values in a deterministic order.
Definition: MapVector.h:37
llvm::object::ELFSectionRef
Definition: ELFObjectFile.h:114
llvm::max
Expected< ExpressionValue > max(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
Definition: FileCheck.cpp:337
llvm::Expected
Tagged union holding either a T or a Error.
Definition: APFloat.h:41
llvm::DataExtractor::getU64
uint64_t getU64(uint64_t *offset_ptr, Error *Err=nullptr) const
Extract a uint64_t value from *offset_ptr.
Definition: DataExtractor.cpp:116
llvm::DWARFDataExtractor
A DataExtractor (typically for an in-memory copy of an object-file section) plus a relocation map for...
Definition: DWARFDataExtractor.h:21
llvm::dwarf::Tag
Tag
Definition: Dwarf.h:105
llvm::ELF::SHF_COMPRESSED
@ SHF_COMPRESSED
Definition: ELF.h:1096
llvm::Data
@ Data
Definition: SIMachineScheduler.h:55
llvm::BitmaskEnumDetail::Mask
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
Definition: BitmaskEnum.h:80
llvm::serializeSectionKind
uint32_t serializeSectionKind(DWARFSectionKind Kind, unsigned IndexVersion)
Convert the internal value for a section kind to an on-disk value.
Definition: DWARFUnitIndex.cpp:42
llvm::MCStreamer
Streaming machine code generation interface.
Definition: MCStreamer.h:212
llvm::DataExtractor::getULEB128
uint64_t getULEB128(uint64_t *offset_ptr, llvm::Error *Err=nullptr) const
Extract a unsigned LEB128 value from *offset_ptr.
Definition: DataExtractor.cpp:220
llvm::object
Definition: DWARFDebugLoc.h:25
llvm::createFileError
Error createFileError(const Twine &F, Error E)
Concatenate a source file path and/or name with an Error.
Definition: Error.h:1319
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
C
(vector float) vec_cmpeq(*A, *B) C
Definition: README_ALTIVEC.txt:86
debugStrOffsetsHeaderSize
static uint64_t debugStrOffsetsHeaderSize(DataExtractor StrOffsetsData, uint16_t DwarfVersion)
Definition: DWP.cpp:29
MCContext.h
llvm::DWARFSectionKind
DWARFSectionKind
The enum of section identifiers to be used in internal interfaces.
Definition: DWARFUnitIndex.h:56
llvm::writeIndex
void writeIndex(MCStreamer &Out, MCSection *Section, ArrayRef< unsigned > ContributionOffsets, const MapVector< uint64_t, UnitIndexEntry > &IndexEntries, uint32_t IndexVersion)
Definition: DWP.cpp:415
getCUIdentifiers
static Expected< CompileUnitIdentifiers > getCUIdentifiers(InfoSectionUnitHeader &Header, StringRef Abbrev, StringRef Info, StringRef StrOffsets, StringRef Str)
Definition: DWP.cpp:94
llvm::DWARFUnitIndex
Definition: DWARFUnitIndex.h:99
llvm::MCStreamer::switchSection
virtual void switchSection(MCSection *Section, const MCExpr *Subsection=nullptr)
Set the current section where code is being emitted to Section.
Definition: MCStreamer.cpp:1234
llvm::NextPowerOf2
constexpr uint64_t NextPowerOf2(uint64_t A)
Returns the next power of two (in 64-bits) that is strictly greater than A.
Definition: MathExtras.h:611
llvm::dwarf::Index
Index
Definition: Dwarf.h:472
llvm::DWARFUnitIndex::parse
bool parse(DataExtractor IndexData)
Definition: DWARFUnitIndex.cpp:119
getIndexedString
static Expected< const char * > getIndexedString(dwarf::Form Form, DataExtractor InfoData, uint64_t &InfoOffset, StringRef StrOffsets, StringRef Str, uint16_t Version)
Definition: DWP.cpp:56
llvm::DW_SECT_EXT_TYPES
@ DW_SECT_EXT_TYPES
Definition: DWARFUnitIndex.h:62
llvm::BTF::HeaderSize
@ HeaderSize
Definition: BTF.h:60
isSupportedSectionKind
static bool isSupportedSectionKind(DWARFSectionKind Kind)
Definition: DWP.cpp:153
llvm::IndexedInstrProf::Version
const uint64_t Version
Definition: InstrProf.h:1056
Info
Analysis containing CSE Info
Definition: CSEInfo.cpp:27
llvm::CallingConv::ID
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
llvm::StringMap
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Definition: StringMap.h:110
llvm::SmallString< 32 >
llvm::DWARFFormValue::skipValue
bool skipValue(DataExtractor DebugInfoData, uint64_t *OffsetPtr, const dwarf::FormParams Params) const
Skip a form's value in DebugInfoData at the offset specified by OffsetPtr.
Definition: DWARFFormValue.h:147
llvm::object::SectionRef
This is a value type class that represents a single section in the list of sections in the object fil...
Definition: ObjectFile.h:80
llvm::DataExtractor::size
size_t size() const
Return the number of bytes in the underlying buffer.
Definition: DataExtractor.h:688
llvm::StringRef::empty
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:134
llvm::UnitIndexEntry::Contributions
DWARFUnitIndex::Entry::SectionContribution Contributions[8]
Definition: DWP.h:19
Index
uint32_t Index
Definition: ELFObjHandler.cpp:83
uint64_t
llvm::DW_SECT_EXT_LOC
@ DW_SECT_EXT_LOC
Definition: DWARFUnitIndex.h:63
move
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Definition: README.txt:546
llvm::object::Decompressor::create
static Expected< Decompressor > create(StringRef Name, StringRef Data, bool IsLE, bool Is64Bit)
Create decompressor object.
Definition: Decompressor.cpp:20
llvm::DenseMap
Definition: DenseMap.h:714
llvm::getContributionIndex
unsigned getContributionIndex(DWARFSectionKind Kind, uint32_t IndexVersion)
Definition: DWP.cpp:160
I
#define I(x, y, z)
Definition: MD5.cpp:58
llvm::InfoSectionUnitHeader
Definition: DWP.h:28
size
i< reg-> size
Definition: README.txt:166
llvm::dwarf::FormParams
A helper struct providing information about the byte size of DW_FORM values that vary in size dependi...
Definition: Dwarf.h:653
llvm::DataExtractor::isValidOffset
bool isValidOffset(uint64_t offset) const
Test the validity of offset.
Definition: DataExtractor.h:665
llvm::object::ObjectFile::createObjectFile
static Expected< OwningBinary< ObjectFile > > createObjectFile(StringRef ObjectPath)
Definition: ObjectFile.cpp:194
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::DWARFDataExtractor::getInitialLength
std::pair< uint64_t, dwarf::DwarfFormat > getInitialLength(uint64_t *Off, Error *Err=nullptr) const
Extracts the DWARF "initial length" field, which can either be a 32-bit value smaller than 0xfffffff0...
Definition: DWARFDataExtractor.cpp:17
llvm::DWARFUnitIndex::Entry::SectionContribution::Length
uint32_t Length
Definition: DWARFUnitIndex.h:115
llvm::MCStreamer::emitIntValue
virtual void emitIntValue(uint64_t Value, unsigned Size)
Special case of EmitValue that avoids the client having to pass in a MCExpr for constant integers.
Definition: MCStreamer.cpp:134
DWP.h
buildDWODescription
static std::string buildDWODescription(StringRef Name, StringRef DWPName, StringRef DWOName)
Definition: DWP.cpp:250
llvm::DataExtractor::getU32
uint32_t getU32(uint64_t *offset_ptr, Error *Err=nullptr) const
Extract a uint32_t value from *offset_ptr.
Definition: DataExtractor.cpp:107
llvm::parseInfoSectionUnitHeader
Expected< InfoSectionUnitHeader > parseInfoSectionUnitHeader(StringRef Info)
Definition: DWP.cpp:308
llvm::DataExtractor::getCStr
const char * getCStr(uint64_t *OffsetPtr, Error *Err=nullptr) const
Extract a C string from *offset_ptr.
Definition: DataExtractor.h:129
llvm::ArrayRef< unsigned >
llvm::MapVector::insert
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition: MapVector.h:118
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
DWPError.h
uint32_t
llvm::MCSection
Instances of this class represent a uniqued identifier for a section in the current translation unit.
Definition: MCSection.h:39
S
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
Definition: README.txt:210
llvm::DataExtractor::getU24
uint32_t getU24(uint64_t *OffsetPtr, Error *Err=nullptr) const
Extract a 24-bit unsigned value from *offset_ptr and return it in a uint32_t.
Definition: DataExtractor.cpp:101
llvm::DataExtractor::getU8
uint8_t getU8(uint64_t *offset_ptr, Error *Err=nullptr) const
Extract a uint8_t value from *offset_ptr.
Definition: DataExtractor.cpp:79
Decompressor.h
ELFObjectFile.h
llvm::StringRef::size
constexpr size_t size() const
size - Get the string size.
Definition: StringRef.h:137
llvm::mc::RegisterMCTargetOptionsFlags
Create this object with static storage to register mc-related command line options.
Definition: MCTargetOptionsCommandFlags.h:54
llvm::MapVector::empty
bool empty() const
Definition: MapVector.h:80
H
#define H(x, y, z)
Definition: MD5.cpp:57
uint16_t
getFlags
static uint32_t getFlags(const Symbol *Sym)
Definition: TapiFile.cpp:27
llvm::toString
const char * toString(DWARFSectionKind Kind)
Definition: DWARFUnitIndex.h:67
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:155
llvm::MapVector::size
size_type size() const
Definition: MapVector.h:61
llvm::DWARFUnitIndex::getColumnKinds
ArrayRef< DWARFSectionKind > getColumnKinds() const
Definition: DWARFUnitIndex.h:166
addAllTypesFromDWP
static void addAllTypesFromDWP(MCStreamer &Out, MapVector< uint64_t, UnitIndexEntry > &TypeIndexEntries, const DWARFUnitIndex &TUIndex, MCSection *OutputTypes, StringRef Types, const UnitIndexEntry &TUEntry, uint32_t &TypesOffset, unsigned TypesContributionIndex)
Definition: DWP.cpp:182
llvm::DWARFUnitIndex::Entry::SectionContribution::Offset
uint32_t Offset
Definition: DWARFUnitIndex.h:114
llvm::Expected::takeError
Error takeError()
Take ownership of the stored error.
Definition: Error.h:596
llvm::DWARFUnitIndex::getRows
ArrayRef< Entry > getRows() const
Definition: DWARFUnitIndex.h:170
llvm::DataExtractor
Definition: DataExtractor.h:41
llvm::MCStreamer::getContext
MCContext & getContext() const
Definition: MCStreamer.h:293
llvm::DWARFUnitIndex::getVersion
uint32_t getVersion() const
Definition: DWARFUnitIndex.h:161
llvm::writeStringsAndOffsets
void writeStringsAndOffsets(MCStreamer &Out, DWPStringPool &Strings, MCSection *StrOffsetSection, StringRef CurStrSection, StringRef CurStrOffsetSection, uint16_t Version)
Definition: DWP.cpp:367
llvm::ArrayRef::size
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:164
llvm::StringRef::back
char back() const
back - Get the last character in the string.
Definition: StringRef.h:146
llvm::MCStreamer::emitBytes
virtual void emitBytes(StringRef Data)
Emit the bytes in Data into the output.
Definition: MCStreamer.cpp:1212
llvm::object::createError
Error createError(const Twine &Err)
Definition: Error.h:84
llvm::UnitIndexEntry
Definition: DWP.h:18
getOnDiskSectionId
static unsigned getOnDiskSectionId(unsigned Index)
Definition: DWP.cpp:168
llvm::OptimizedStructLayoutField
A field in a structure.
Definition: OptimizedStructLayout.h:45
llvm::SmallVectorImpl::reserve
void reserve(size_type N)
Definition: SmallVector.h:667
llvm::object::SectionRef::getObject
const ObjectFile * getObject() const
Definition: ObjectFile.h:542
addAllTypesFromTypesSection
static void addAllTypesFromTypesSection(MCStreamer &Out, MapVector< uint64_t, UnitIndexEntry > &TypeIndexEntries, MCSection *OutputTypes, const std::vector< StringRef > &TypesSections, const UnitIndexEntry &CUEntry, uint32_t &TypesOffset)
Definition: DWP.cpp:216
llvm::CompileUnitIdentifiers
Definition: DWP.h:57
llvm::DataExtractor::getU16
uint16_t getU16(uint64_t *offset_ptr, Error *Err=nullptr) const
Extract a uint16_t value from *offset_ptr.
Definition: DataExtractor.cpp:92
llvm::buildDuplicateError
Error buildDuplicateError(const std::pair< uint64_t, UnitIndexEntry > &PrevE, const CompileUnitIdentifiers &ID, StringRef DWPName)
Definition: DWP.cpp:471