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