LLVM  16.0.0git
DWARFAcceleratorTable.cpp
Go to the documentation of this file.
1 //===- DWARFAcceleratorTable.cpp ------------------------------------------===//
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 
10 
11 #include "llvm/ADT/SmallVector.h"
13 #include "llvm/Support/Compiler.h"
14 #include "llvm/Support/DJB.h"
15 #include "llvm/Support/Errc.h"
16 #include "llvm/Support/Format.h"
20 #include <cstddef>
21 #include <cstdint>
22 #include <utility>
23 
24 using namespace llvm;
25 
26 namespace {
27 struct Atom {
28  unsigned Value;
29 };
30 
31 static raw_ostream &operator<<(raw_ostream &OS, const Atom &A) {
32  StringRef Str = dwarf::AtomTypeString(A.Value);
33  if (!Str.empty())
34  return OS << Str;
35  return OS << "DW_ATOM_unknown_" << format("%x", A.Value);
36 }
37 } // namespace
38 
39 static Atom formatAtom(unsigned Atom) { return {Atom}; }
40 
42 
44  uint64_t Offset = 0;
45 
46  // Check that we can at least read the header.
47  if (!AccelSection.isValidOffset(offsetof(Header, HeaderDataLength) + 4))
49  "Section too small: cannot read header.");
50 
51  Hdr.Magic = AccelSection.getU32(&Offset);
52  Hdr.Version = AccelSection.getU16(&Offset);
53  Hdr.HashFunction = AccelSection.getU16(&Offset);
54  Hdr.BucketCount = AccelSection.getU32(&Offset);
55  Hdr.HashCount = AccelSection.getU32(&Offset);
56  Hdr.HeaderDataLength = AccelSection.getU32(&Offset);
57 
58  // Check that we can read all the hashes and offsets from the
59  // section (see SourceLevelDebugging.rst for the structure of the index).
60  // We need to substract one because we're checking for an *offset* which is
61  // equal to the size for an empty table and hence pointer after the section.
62  if (!AccelSection.isValidOffset(sizeof(Hdr) + Hdr.HeaderDataLength +
63  Hdr.BucketCount * 4 + Hdr.HashCount * 8 - 1))
64  return createStringError(
66  "Section too small: cannot read buckets and hashes.");
67 
68  HdrData.DIEOffsetBase = AccelSection.getU32(&Offset);
69  uint32_t NumAtoms = AccelSection.getU32(&Offset);
70 
71  for (unsigned i = 0; i < NumAtoms; ++i) {
72  uint16_t AtomType = AccelSection.getU16(&Offset);
73  auto AtomForm = static_cast<dwarf::Form>(AccelSection.getU16(&Offset));
74  HdrData.Atoms.push_back(std::make_pair(AtomType, AtomForm));
75  }
76 
77  IsValid = true;
78  return Error::success();
79 }
80 
81 uint32_t AppleAcceleratorTable::getNumBuckets() { return Hdr.BucketCount; }
82 uint32_t AppleAcceleratorTable::getNumHashes() { return Hdr.HashCount; }
85  return Hdr.HeaderDataLength;
86 }
87 
91  return HdrData.Atoms;
92 }
93 
95  for (auto Atom : getAtomsDesc()) {
96  DWARFFormValue FormValue(Atom.second);
97  switch (Atom.first) {
101  if ((!FormValue.isFormClass(DWARFFormValue::FC_Constant) &&
102  !FormValue.isFormClass(DWARFFormValue::FC_Flag)) ||
103  FormValue.getForm() == dwarf::DW_FORM_sdata)
104  return false;
105  break;
106  default:
107  break;
108  }
109  }
110  return true;
111 }
112 
113 std::pair<uint64_t, dwarf::Tag>
116  dwarf::Tag DieTag = dwarf::DW_TAG_null;
118 
119  for (auto Atom : getAtomsDesc()) {
120  DWARFFormValue FormValue(Atom.second);
121  FormValue.extractValue(AccelSection, HashDataOffset, FormParams);
122  switch (Atom.first) {
124  DieOffset = *FormValue.getAsUnsignedConstant();
125  break;
127  DieTag = (dwarf::Tag)*FormValue.getAsUnsignedConstant();
128  break;
129  default:
130  break;
131  }
132  }
133  return {DieOffset, DieTag};
134 }
135 
137  DictScope HeaderScope(W, "Header");
138  W.printHex("Magic", Magic);
139  W.printHex("Version", Version);
140  W.printHex("Hash function", HashFunction);
141  W.printNumber("Bucket count", BucketCount);
142  W.printNumber("Hashes count", HashCount);
143  W.printNumber("HeaderData length", HeaderDataLength);
144 }
145 
146 Optional<uint64_t> AppleAcceleratorTable::HeaderData::extractOffset(
148  if (!Value)
149  return None;
150 
151  switch (Value->getForm()) {
152  case dwarf::DW_FORM_ref1:
153  case dwarf::DW_FORM_ref2:
154  case dwarf::DW_FORM_ref4:
155  case dwarf::DW_FORM_ref8:
156  case dwarf::DW_FORM_ref_udata:
157  return Value->getRawUValue() + DIEOffsetBase;
158  default:
159  return Value->getAsSectionOffset();
160  }
161 }
162 
163 bool AppleAcceleratorTable::dumpName(ScopedPrinter &W,
165  uint64_t *DataOffset) const {
167  uint64_t NameOffset = *DataOffset;
168  if (!AccelSection.isValidOffsetForDataOfSize(*DataOffset, 4)) {
169  W.printString("Incorrectly terminated list.");
170  return false;
171  }
172  uint64_t StringOffset = AccelSection.getRelocatedValue(4, DataOffset);
173  if (!StringOffset)
174  return false; // End of list
175 
176  DictScope NameScope(W, ("Name@0x" + Twine::utohexstr(NameOffset)).str());
177  W.startLine() << format("String: 0x%08" PRIx64, StringOffset);
178  W.getOStream() << " \"" << StringSection.getCStr(&StringOffset) << "\"\n";
179 
180  unsigned NumData = AccelSection.getU32(DataOffset);
181  for (unsigned Data = 0; Data < NumData; ++Data) {
182  ListScope DataScope(W, ("Data " + Twine(Data)).str());
183  unsigned i = 0;
184  for (auto &Atom : AtomForms) {
185  W.startLine() << format("Atom[%d]: ", i);
186  if (Atom.extractValue(AccelSection, DataOffset, FormParams)) {
187  Atom.dump(W.getOStream());
188  if (Optional<uint64_t> Val = Atom.getAsUnsignedConstant()) {
189  StringRef Str = dwarf::AtomValueString(HdrData.Atoms[i].first, *Val);
190  if (!Str.empty())
191  W.getOStream() << " (" << Str << ")";
192  }
193  } else
194  W.getOStream() << "Error extracting the value";
195  W.getOStream() << "\n";
196  i++;
197  }
198  }
199  return true; // more entries follow
200 }
201 
203  if (!IsValid)
204  return;
205 
206  ScopedPrinter W(OS);
207 
208  Hdr.dump(W);
209 
210  W.printNumber("DIE offset base", HdrData.DIEOffsetBase);
211  W.printNumber("Number of atoms", uint64_t(HdrData.Atoms.size()));
213  {
214  ListScope AtomsScope(W, "Atoms");
215  unsigned i = 0;
216  for (const auto &Atom : HdrData.Atoms) {
217  DictScope AtomScope(W, ("Atom " + Twine(i++)).str());
218  W.startLine() << "Type: " << formatAtom(Atom.first) << '\n';
219  W.startLine() << "Form: " << formatv("{0}", Atom.second) << '\n';
220  AtomForms.push_back(DWARFFormValue(Atom.second));
221  }
222  }
223 
224  // Now go through the actual tables and dump them.
225  uint64_t Offset = sizeof(Hdr) + Hdr.HeaderDataLength;
226  uint64_t HashesBase = Offset + Hdr.BucketCount * 4;
227  uint64_t OffsetsBase = HashesBase + Hdr.HashCount * 4;
228 
229  for (unsigned Bucket = 0; Bucket < Hdr.BucketCount; ++Bucket) {
230  unsigned Index = AccelSection.getU32(&Offset);
231 
232  ListScope BucketScope(W, ("Bucket " + Twine(Bucket)).str());
233  if (Index == UINT32_MAX) {
234  W.printString("EMPTY");
235  continue;
236  }
237 
238  for (unsigned HashIdx = Index; HashIdx < Hdr.HashCount; ++HashIdx) {
239  uint64_t HashOffset = HashesBase + HashIdx*4;
240  uint64_t OffsetsOffset = OffsetsBase + HashIdx*4;
241  uint32_t Hash = AccelSection.getU32(&HashOffset);
242 
243  if (Hash % Hdr.BucketCount != Bucket)
244  break;
245 
246  uint64_t DataOffset = AccelSection.getU32(&OffsetsOffset);
247  ListScope HashScope(W, ("Hash 0x" + Twine::utohexstr(Hash)).str());
248  if (!AccelSection.isValidOffset(DataOffset)) {
249  W.printString("Invalid section offset");
250  continue;
251  }
252  while (dumpName(W, AtomForms, &DataOffset))
253  /*empty*/;
254  }
255  }
256 }
257 
258 AppleAcceleratorTable::Entry::Entry(
259  const AppleAcceleratorTable::HeaderData &HdrData)
260  : HdrData(&HdrData) {
261  Values.reserve(HdrData.Atoms.size());
262  for (const auto &Atom : HdrData.Atoms)
263  Values.push_back(DWARFFormValue(Atom.second));
264 }
265 
266 void AppleAcceleratorTable::Entry::extract(
267  const AppleAcceleratorTable &AccelTable, uint64_t *Offset) {
268 
269  dwarf::FormParams FormParams = {AccelTable.Hdr.Version, 0,
271  for (auto &Atom : Values)
272  Atom.extractValue(AccelTable.AccelSection, Offset, FormParams);
273 }
274 
277  assert(HdrData && "Dereferencing end iterator?");
278  assert(HdrData->Atoms.size() == Values.size());
279  for (auto Tuple : zip_first(HdrData->Atoms, Values)) {
280  if (std::get<0>(Tuple).first == Atom)
281  return std::get<1>(Tuple);
282  }
283  return None;
284 }
285 
287  return HdrData->extractOffset(lookup(dwarf::DW_ATOM_die_offset));
288 }
289 
291  return HdrData->extractOffset(lookup(dwarf::DW_ATOM_cu_offset));
292 }
293 
296  if (!Tag)
297  return None;
298  if (Optional<uint64_t> Value = Tag->getAsUnsignedConstant())
299  return dwarf::Tag(*Value);
300  return None;
301 }
302 
305  : AccelTable(&AccelTable), Current(AccelTable.HdrData), DataOffset(Offset) {
306  if (!AccelTable.AccelSection.isValidOffsetForDataOfSize(DataOffset, 4))
307  return;
308 
309  // Read the first entry.
310  NumData = AccelTable.AccelSection.getU32(&DataOffset);
311  Next();
312 }
313 
314 void AppleAcceleratorTable::ValueIterator::Next() {
315  assert(NumData > 0 && "attempted to increment iterator past the end");
316  auto &AccelSection = AccelTable->AccelSection;
317  if (Data >= NumData ||
318  !AccelSection.isValidOffsetForDataOfSize(DataOffset, 4)) {
319  NumData = 0;
320  DataOffset = 0;
321  return;
322  }
323  Current.extract(*AccelTable, &DataOffset);
324  ++Data;
325 }
326 
329  if (!IsValid)
331 
332  // Find the bucket.
333  unsigned HashValue = djbHash(Key);
334  unsigned Bucket = HashValue % Hdr.BucketCount;
335  uint64_t BucketBase = sizeof(Hdr) + Hdr.HeaderDataLength;
336  uint64_t HashesBase = BucketBase + Hdr.BucketCount * 4;
337  uint64_t OffsetsBase = HashesBase + Hdr.HashCount * 4;
338 
339  uint64_t BucketOffset = BucketBase + Bucket * 4;
340  unsigned Index = AccelSection.getU32(&BucketOffset);
341 
342  // Search through all hashes in the bucket.
343  for (unsigned HashIdx = Index; HashIdx < Hdr.HashCount; ++HashIdx) {
344  uint64_t HashOffset = HashesBase + HashIdx * 4;
345  uint64_t OffsetsOffset = OffsetsBase + HashIdx * 4;
346  uint32_t Hash = AccelSection.getU32(&HashOffset);
347 
348  if (Hash % Hdr.BucketCount != Bucket)
349  // We are already in the next bucket.
350  break;
351 
352  uint64_t DataOffset = AccelSection.getU32(&OffsetsOffset);
353  uint64_t StringOffset = AccelSection.getRelocatedValue(4, &DataOffset);
354  if (!StringOffset)
355  break;
356 
357  // Finally, compare the key.
358  if (Key == StringSection.getCStr(&StringOffset))
359  return make_range({*this, DataOffset}, ValueIterator());
360  }
362 }
363 
365  DictScope HeaderScope(W, "Header");
366  W.printHex("Length", UnitLength);
367  W.printString("Format", dwarf::FormatString(Format));
368  W.printNumber("Version", Version);
369  W.printNumber("CU count", CompUnitCount);
370  W.printNumber("Local TU count", LocalTypeUnitCount);
371  W.printNumber("Foreign TU count", ForeignTypeUnitCount);
372  W.printNumber("Bucket count", BucketCount);
373  W.printNumber("Name count", NameCount);
374  W.printHex("Abbreviations table size", AbbrevTableSize);
375  W.startLine() << "Augmentation: '" << AugmentationString << "'\n";
376 }
377 
379  uint64_t *Offset) {
380  auto HeaderError = [Offset = *Offset](Error E) {
382  "parsing .debug_names header at 0x%" PRIx64 ": %s",
383  Offset, toString(std::move(E)).c_str());
384  };
385 
386  DataExtractor::Cursor C(*Offset);
387  std::tie(UnitLength, Format) = AS.getInitialLength(C);
388 
389  Version = AS.getU16(C);
390  AS.skip(C, 2); // padding
391  CompUnitCount = AS.getU32(C);
392  LocalTypeUnitCount = AS.getU32(C);
393  ForeignTypeUnitCount = AS.getU32(C);
394  BucketCount = AS.getU32(C);
395  NameCount = AS.getU32(C);
396  AbbrevTableSize = AS.getU32(C);
397  AugmentationStringSize = alignTo(AS.getU32(C), 4);
398 
399  if (!C)
400  return HeaderError(C.takeError());
401 
402  if (!AS.isValidOffsetForDataOfSize(C.tell(), AugmentationStringSize))
404  "cannot read header augmentation"));
405  AugmentationString.resize(AugmentationStringSize);
406  AS.getU8(C, reinterpret_cast<uint8_t *>(AugmentationString.data()),
407  AugmentationStringSize);
408  *Offset = C.tell();
409  return C.takeError();
410 }
411 
413  DictScope AbbrevScope(W, ("Abbreviation 0x" + Twine::utohexstr(Code)).str());
414  W.startLine() << formatv("Tag: {0}\n", Tag);
415 
416  for (const auto &Attr : Attributes)
417  W.startLine() << formatv("{0}: {1}\n", Attr.Index, Attr.Form);
418 }
419 
421  return {dwarf::Index(0), dwarf::Form(0)};
422 }
423 
425  return AE == sentinelAttrEnc();
426 }
427 
429  return DWARFDebugNames::Abbrev(0, dwarf::Tag(0), {});
430 }
431 
432 static bool isSentinel(const DWARFDebugNames::Abbrev &Abbr) {
433  return Abbr.Code == 0;
434 }
435 
436 DWARFDebugNames::Abbrev DWARFDebugNames::AbbrevMapInfo::getEmptyKey() {
437  return sentinelAbbrev();
438 }
439 
440 DWARFDebugNames::Abbrev DWARFDebugNames::AbbrevMapInfo::getTombstoneKey() {
441  return DWARFDebugNames::Abbrev(~0, dwarf::Tag(0), {});
442 }
443 
445 DWARFDebugNames::NameIndex::extractAttributeEncoding(uint64_t *Offset) {
446  if (*Offset >= EntriesBase) {
448  "Incorrectly terminated abbreviation table.");
449  }
450 
451  uint32_t Index = Section.AccelSection.getULEB128(Offset);
452  uint32_t Form = Section.AccelSection.getULEB128(Offset);
453  return AttributeEncoding(dwarf::Index(Index), dwarf::Form(Form));
454 }
455 
457 DWARFDebugNames::NameIndex::extractAttributeEncodings(uint64_t *Offset) {
458  std::vector<AttributeEncoding> Result;
459  for (;;) {
460  auto AttrEncOr = extractAttributeEncoding(Offset);
461  if (!AttrEncOr)
462  return AttrEncOr.takeError();
463  if (isSentinel(*AttrEncOr))
464  return std::move(Result);
465 
466  Result.emplace_back(*AttrEncOr);
467  }
468 }
469 
471 DWARFDebugNames::NameIndex::extractAbbrev(uint64_t *Offset) {
472  if (*Offset >= EntriesBase) {
474  "Incorrectly terminated abbreviation table.");
475  }
476 
477  uint32_t Code = Section.AccelSection.getULEB128(Offset);
478  if (Code == 0)
479  return sentinelAbbrev();
480 
481  uint32_t Tag = Section.AccelSection.getULEB128(Offset);
482  auto AttrEncOr = extractAttributeEncodings(Offset);
483  if (!AttrEncOr)
484  return AttrEncOr.takeError();
485  return Abbrev(Code, dwarf::Tag(Tag), std::move(*AttrEncOr));
486 }
487 
489  const DWARFDataExtractor &AS = Section.AccelSection;
490  uint64_t Offset = Base;
491  if (Error E = Hdr.extract(AS, &Offset))
492  return E;
493 
494  const unsigned SectionOffsetSize = dwarf::getDwarfOffsetByteSize(Hdr.Format);
495  CUsBase = Offset;
496  Offset += Hdr.CompUnitCount * SectionOffsetSize;
497  Offset += Hdr.LocalTypeUnitCount * SectionOffsetSize;
498  Offset += Hdr.ForeignTypeUnitCount * 8;
499  BucketsBase = Offset;
500  Offset += Hdr.BucketCount * 4;
501  HashesBase = Offset;
502  if (Hdr.BucketCount > 0)
503  Offset += Hdr.NameCount * 4;
504  StringOffsetsBase = Offset;
505  Offset += Hdr.NameCount * SectionOffsetSize;
506  EntryOffsetsBase = Offset;
507  Offset += Hdr.NameCount * SectionOffsetSize;
508 
509  if (!AS.isValidOffsetForDataOfSize(Offset, Hdr.AbbrevTableSize))
511  "Section too small: cannot read abbreviations.");
512 
513  EntriesBase = Offset + Hdr.AbbrevTableSize;
514 
515  for (;;) {
516  auto AbbrevOr = extractAbbrev(&Offset);
517  if (!AbbrevOr)
518  return AbbrevOr.takeError();
519  if (isSentinel(*AbbrevOr))
520  return Error::success();
521 
522  if (!Abbrevs.insert(std::move(*AbbrevOr)).second)
524  "Duplicate abbreviation code.");
525  }
526 }
527 
528 DWARFDebugNames::Entry::Entry(const NameIndex &NameIdx, const Abbrev &Abbr)
529  : NameIdx(&NameIdx), Abbr(&Abbr) {
530  // This merely creates form values. It is up to the caller
531  // (NameIndex::getEntry) to populate them.
532  Values.reserve(Abbr.Attributes.size());
533  for (const auto &Attr : Abbr.Attributes)
534  Values.emplace_back(Attr.Form);
535 }
536 
539  assert(Abbr->Attributes.size() == Values.size());
540  for (auto Tuple : zip_first(Abbr->Attributes, Values)) {
541  if (std::get<0>(Tuple).Index == Index)
542  return std::get<1>(Tuple);
543  }
544  return None;
545 }
546 
548  if (Optional<DWARFFormValue> Off = lookup(dwarf::DW_IDX_die_offset))
549  return Off->getAsReferenceUVal();
550  return None;
551 }
552 
554  if (Optional<DWARFFormValue> Off = lookup(dwarf::DW_IDX_compile_unit))
555  return Off->getAsUnsignedConstant();
556  // In a per-CU index, the entries without a DW_IDX_compile_unit attribute
557  // implicitly refer to the single CU.
558  if (NameIdx->getCUCount() == 1)
559  return 0;
560  return None;
561 }
562 
564  Optional<uint64_t> Index = getCUIndex();
565  if (!Index || *Index >= NameIdx->getCUCount())
566  return None;
567  return NameIdx->getCUOffset(*Index);
568 }
569 
571  W.printHex("Abbrev", Abbr->Code);
572  W.startLine() << formatv("Tag: {0}\n", Abbr->Tag);
573  assert(Abbr->Attributes.size() == Values.size());
574  for (auto Tuple : zip_first(Abbr->Attributes, Values)) {
575  W.startLine() << formatv("{0}: ", std::get<0>(Tuple).Index);
576  std::get<1>(Tuple).dump(W.getOStream());
577  W.getOStream() << '\n';
578  }
579 }
580 
583  return inconvertibleErrorCode();
584 }
585 
587  assert(CU < Hdr.CompUnitCount);
588  const unsigned SectionOffsetSize = dwarf::getDwarfOffsetByteSize(Hdr.Format);
589  uint64_t Offset = CUsBase + SectionOffsetSize * CU;
590  return Section.AccelSection.getRelocatedValue(SectionOffsetSize, &Offset);
591 }
592 
594  assert(TU < Hdr.LocalTypeUnitCount);
595  const unsigned SectionOffsetSize = dwarf::getDwarfOffsetByteSize(Hdr.Format);
596  uint64_t Offset = CUsBase + SectionOffsetSize * (Hdr.CompUnitCount + TU);
597  return Section.AccelSection.getRelocatedValue(SectionOffsetSize, &Offset);
598 }
599 
601  assert(TU < Hdr.ForeignTypeUnitCount);
602  const unsigned SectionOffsetSize = dwarf::getDwarfOffsetByteSize(Hdr.Format);
603  uint64_t Offset =
604  CUsBase +
605  SectionOffsetSize * (Hdr.CompUnitCount + Hdr.LocalTypeUnitCount) + 8 * TU;
606  return Section.AccelSection.getU64(&Offset);
607 }
608 
611  const DWARFDataExtractor &AS = Section.AccelSection;
612  if (!AS.isValidOffset(*Offset))
614  "Incorrectly terminated entry list.");
615 
616  uint32_t AbbrevCode = AS.getULEB128(Offset);
617  if (AbbrevCode == 0)
618  return make_error<SentinelError>();
619 
620  const auto AbbrevIt = Abbrevs.find_as(AbbrevCode);
621  if (AbbrevIt == Abbrevs.end())
622  return createStringError(errc::invalid_argument, "Invalid abbreviation.");
623 
624  Entry E(*this, *AbbrevIt);
625 
626  dwarf::FormParams FormParams = {Hdr.Version, 0, Hdr.Format};
627  for (auto &Value : E.Values) {
628  if (!Value.extractValue(AS, Offset, FormParams))
630  "Error extracting index attribute values.");
631  }
632  return std::move(E);
633 }
634 
637  assert(0 < Index && Index <= Hdr.NameCount);
638  const unsigned SectionOffsetSize = dwarf::getDwarfOffsetByteSize(Hdr.Format);
639  uint64_t StringOffsetOffset =
640  StringOffsetsBase + SectionOffsetSize * (Index - 1);
641  uint64_t EntryOffsetOffset =
642  EntryOffsetsBase + SectionOffsetSize * (Index - 1);
643  const DWARFDataExtractor &AS = Section.AccelSection;
644 
645  uint64_t StringOffset =
646  AS.getRelocatedValue(SectionOffsetSize, &StringOffsetOffset);
647  uint64_t EntryOffset = AS.getUnsigned(&EntryOffsetOffset, SectionOffsetSize);
648  EntryOffset += EntriesBase;
649  return {Section.StringSection, Index, StringOffset, EntryOffset};
650 }
651 
652 uint32_t
654  assert(Bucket < Hdr.BucketCount);
655  uint64_t BucketOffset = BucketsBase + 4 * Bucket;
656  return Section.AccelSection.getU32(&BucketOffset);
657 }
658 
660  assert(0 < Index && Index <= Hdr.NameCount);
661  uint64_t HashOffset = HashesBase + 4 * (Index - 1);
662  return Section.AccelSection.getU32(&HashOffset);
663 }
664 
665 // Returns true if we should continue scanning for entries, false if this is the
666 // last (sentinel) entry). In case of a parsing error we also return false, as
667 // it's not possible to recover this entry list (but the other lists may still
668 // parse OK).
669 bool DWARFDebugNames::NameIndex::dumpEntry(ScopedPrinter &W,
670  uint64_t *Offset) const {
671  uint64_t EntryId = *Offset;
672  auto EntryOr = getEntry(Offset);
673  if (!EntryOr) {
674  handleAllErrors(EntryOr.takeError(), [](const SentinelError &) {},
675  [&W](const ErrorInfoBase &EI) { EI.log(W.startLine()); });
676  return false;
677  }
678 
679  DictScope EntryScope(W, ("Entry @ 0x" + Twine::utohexstr(EntryId)).str());
680  EntryOr->dump(W);
681  return true;
682 }
683 
684 void DWARFDebugNames::NameIndex::dumpName(ScopedPrinter &W,
685  const NameTableEntry &NTE,
686  Optional<uint32_t> Hash) const {
687  DictScope NameScope(W, ("Name " + Twine(NTE.getIndex())).str());
688  if (Hash)
689  W.printHex("Hash", *Hash);
690 
691  W.startLine() << format("String: 0x%08" PRIx64, NTE.getStringOffset());
692  W.getOStream() << " \"" << NTE.getString() << "\"\n";
693 
694  uint64_t EntryOffset = NTE.getEntryOffset();
695  while (dumpEntry(W, &EntryOffset))
696  /*empty*/;
697 }
698 
699 void DWARFDebugNames::NameIndex::dumpCUs(ScopedPrinter &W) const {
700  ListScope CUScope(W, "Compilation Unit offsets");
701  for (uint32_t CU = 0; CU < Hdr.CompUnitCount; ++CU)
702  W.startLine() << format("CU[%u]: 0x%08" PRIx64 "\n", CU, getCUOffset(CU));
703 }
704 
705 void DWARFDebugNames::NameIndex::dumpLocalTUs(ScopedPrinter &W) const {
706  if (Hdr.LocalTypeUnitCount == 0)
707  return;
708 
709  ListScope TUScope(W, "Local Type Unit offsets");
710  for (uint32_t TU = 0; TU < Hdr.LocalTypeUnitCount; ++TU)
711  W.startLine() << format("LocalTU[%u]: 0x%08" PRIx64 "\n", TU,
712  getLocalTUOffset(TU));
713 }
714 
715 void DWARFDebugNames::NameIndex::dumpForeignTUs(ScopedPrinter &W) const {
716  if (Hdr.ForeignTypeUnitCount == 0)
717  return;
718 
719  ListScope TUScope(W, "Foreign Type Unit signatures");
720  for (uint32_t TU = 0; TU < Hdr.ForeignTypeUnitCount; ++TU) {
721  W.startLine() << format("ForeignTU[%u]: 0x%016" PRIx64 "\n", TU,
722  getForeignTUSignature(TU));
723  }
724 }
725 
726 void DWARFDebugNames::NameIndex::dumpAbbreviations(ScopedPrinter &W) const {
727  ListScope AbbrevsScope(W, "Abbreviations");
728  for (const auto &Abbr : Abbrevs)
729  Abbr.dump(W);
730 }
731 
732 void DWARFDebugNames::NameIndex::dumpBucket(ScopedPrinter &W,
733  uint32_t Bucket) const {
734  ListScope BucketScope(W, ("Bucket " + Twine(Bucket)).str());
735  uint32_t Index = getBucketArrayEntry(Bucket);
736  if (Index == 0) {
737  W.printString("EMPTY");
738  return;
739  }
740  if (Index > Hdr.NameCount) {
741  W.printString("Name index is invalid");
742  return;
743  }
744 
745  for (; Index <= Hdr.NameCount; ++Index) {
746  uint32_t Hash = getHashArrayEntry(Index);
747  if (Hash % Hdr.BucketCount != Bucket)
748  break;
749 
750  dumpName(W, getNameTableEntry(Index), Hash);
751  }
752 }
753 
755  DictScope UnitScope(W, ("Name Index @ 0x" + Twine::utohexstr(Base)).str());
756  Hdr.dump(W);
757  dumpCUs(W);
758  dumpLocalTUs(W);
759  dumpForeignTUs(W);
760  dumpAbbreviations(W);
761 
762  if (Hdr.BucketCount > 0) {
763  for (uint32_t Bucket = 0; Bucket < Hdr.BucketCount; ++Bucket)
764  dumpBucket(W, Bucket);
765  return;
766  }
767 
768  W.startLine() << "Hash table not present\n";
769  for (const NameTableEntry &NTE : *this)
770  dumpName(W, NTE, None);
771 }
772 
774  uint64_t Offset = 0;
775  while (AccelSection.isValidOffset(Offset)) {
776  NameIndex Next(*this, Offset);
777  if (Error E = Next.extract())
778  return E;
779  Offset = Next.getNextUnitOffset();
780  NameIndices.push_back(std::move(Next));
781  }
782  return Error::success();
783 }
784 
787  return make_range(ValueIterator(*this, Key), ValueIterator());
788 }
789 
791  ScopedPrinter W(OS);
792  for (const NameIndex &NI : NameIndices)
793  NI.dump(W);
794 }
795 
797 DWARFDebugNames::ValueIterator::findEntryOffsetInCurrentIndex() {
798  const Header &Hdr = CurrentIndex->Hdr;
799  if (Hdr.BucketCount == 0) {
800  // No Hash Table, We need to search through all names in the Name Index.
801  for (const NameTableEntry &NTE : *CurrentIndex) {
802  if (NTE.getString() == Key)
803  return NTE.getEntryOffset();
804  }
805  return None;
806  }
807 
808  // The Name Index has a Hash Table, so use that to speed up the search.
809  // Compute the Key Hash, if it has not been done already.
810  if (!Hash)
811  Hash = caseFoldingDjbHash(Key);
812  uint32_t Bucket = *Hash % Hdr.BucketCount;
813  uint32_t Index = CurrentIndex->getBucketArrayEntry(Bucket);
814  if (Index == 0)
815  return None; // Empty bucket
816 
817  for (; Index <= Hdr.NameCount; ++Index) {
818  uint32_t Hash = CurrentIndex->getHashArrayEntry(Index);
819  if (Hash % Hdr.BucketCount != Bucket)
820  return None; // End of bucket
821 
822  NameTableEntry NTE = CurrentIndex->getNameTableEntry(Index);
823  if (NTE.getString() == Key)
824  return NTE.getEntryOffset();
825  }
826  return None;
827 }
828 
829 bool DWARFDebugNames::ValueIterator::getEntryAtCurrentOffset() {
830  auto EntryOr = CurrentIndex->getEntry(&DataOffset);
831  if (!EntryOr) {
832  consumeError(EntryOr.takeError());
833  return false;
834  }
835  CurrentEntry = std::move(*EntryOr);
836  return true;
837 }
838 
839 bool DWARFDebugNames::ValueIterator::findInCurrentIndex() {
840  Optional<uint64_t> Offset = findEntryOffsetInCurrentIndex();
841  if (!Offset)
842  return false;
843  DataOffset = *Offset;
844  return getEntryAtCurrentOffset();
845 }
846 
847 void DWARFDebugNames::ValueIterator::searchFromStartOfCurrentIndex() {
848  for (const NameIndex *End = CurrentIndex->Section.NameIndices.end();
849  CurrentIndex != End; ++CurrentIndex) {
850  if (findInCurrentIndex())
851  return;
852  }
853  setEnd();
854 }
855 
856 void DWARFDebugNames::ValueIterator::next() {
857  assert(CurrentIndex && "Incrementing an end() iterator?");
858 
859  // First try the next entry in the current Index.
860  if (getEntryAtCurrentOffset())
861  return;
862 
863  // If we're a local iterator or we have reached the last Index, we're done.
864  if (IsLocal || CurrentIndex == &CurrentIndex->Section.NameIndices.back()) {
865  setEnd();
866  return;
867  }
868 
869  // Otherwise, try the next index.
870  ++CurrentIndex;
871  searchFromStartOfCurrentIndex();
872 }
873 
875  StringRef Key)
876  : CurrentIndex(AccelTable.NameIndices.begin()), IsLocal(false),
877  Key(std::string(Key)) {
878  searchFromStartOfCurrentIndex();
879 }
880 
883  : CurrentIndex(&NI), IsLocal(true), Key(std::string(Key)) {
884  if (!findInCurrentIndex())
885  setEnd();
886 }
887 
890  if (NameIndices.empty())
892  return make_range(ValueIterator(*this, Key), ValueIterator());
893 }
894 
897  if (CUToNameIndex.size() == 0 && NameIndices.size() > 0) {
898  for (const auto &NI : *this) {
899  for (uint32_t CU = 0; CU < NI.getCUCount(); ++CU)
900  CUToNameIndex.try_emplace(NI.getCUOffset(CU), &NI);
901  }
902  }
903  return CUToNameIndex.lookup(CUOffset);
904 }
i
i
Definition: README.txt:29
llvm::alignTo
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition: Alignment.h:156
llvm::errc::invalid_argument
@ invalid_argument
llvm::DWARFDebugNames::ValueIterator::ValueIterator
ValueIterator()=default
End marker.
LLVM_DUMP_METHOD
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
Definition: Compiler.h:492
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
llvm::make_range
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
Definition: iterator_range.h:53
llvm::DWARFDebugNames::Header::dump
void dump(ScopedPrinter &W) const
Definition: DWARFAcceleratorTable.cpp:364
DJB.h
DWARFAcceleratorTable.h
llvm::dwarf::DW_ATOM_die_offset
@ DW_ATOM_die_offset
Marker as the end of a list of atoms.
Definition: Dwarf.h:509
llvm::AppleAcceleratorTable::dump
void dump(raw_ostream &OS) const override
Definition: DWARFAcceleratorTable.cpp:202
offsetof
#define offsetof(TYPE, MEMBER)
Definition: AMDHSAKernelDescriptor.h:23
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::tgtok::Code
@ Code
Definition: TGLexer.h:50
llvm::RISCVFenceField::W
@ W
Definition: RISCVBaseInfo.h:266
llvm::dwarf::Form
Form
Definition: Dwarf.h:132
llvm::Error::success
static ErrorSuccess success()
Create a success value.
Definition: Error.h:329
llvm::DWARFFormValue::FC_Constant
@ FC_Constant
Definition: DWARFFormValue.h:34
llvm::AppleAcceleratorTable::Entry::getTag
Optional< dwarf::Tag > getTag() const override
Returns the Tag of the Debug Info Entry associated with this Accelerator Entry or None if the Tag is ...
Definition: DWARFAcceleratorTable.cpp:294
llvm::DWARFDebugNames::ValueIterator
Definition: DWARFAcceleratorTable.h:476
llvm::DWARFFormValue::getAsUnsignedConstant
Optional< uint64_t > getAsUnsignedConstant() const
Definition: DWARFFormValue.cpp:728
Errc.h
true
basic Basic Alias true
Definition: BasicAliasAnalysis.cpp:1793
llvm::DWARFDebugNames::NameIndex::getNextUnitOffset
uint64_t getNextUnitOffset() const
Definition: DWARFAcceleratorTable.h:467
llvm::DWARFDebugNames::begin
const_iterator begin() const
Definition: DWARFAcceleratorTable.h:602
llvm::DWARFAcceleratorTable::Entry::Values
SmallVector< DWARFFormValue, 3 > Values
Definition: DWARFAcceleratorTable.h:40
llvm::DWARFDebugNames::NameTableEntry
A single entry in the Name Table (DWARF v5 sect.
Definition: DWARFAcceleratorTable.h:356
llvm::Optional< uint64_t >
llvm::dump
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
Definition: SparseBitVector.h:877
llvm::Expected
Tagged union holding either a T or a Error.
Definition: APFloat.h:41
llvm::AccelTable
This class holds an abstract representation of an Accelerator Table, consisting of a sequence of buck...
Definition: AccelTable.h:195
llvm::DWARFDebugNames::NameIndex::extract
Error extract()
Definition: DWARFAcceleratorTable.cpp:488
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::ListScope
Definition: ScopedPrinter.h:828
llvm::dwarf::Tag
Tag
Definition: Dwarf.h:105
Format.h
llvm::DWARFDebugNames::Header::extract
Error extract(const DWARFDataExtractor &AS, uint64_t *Offset)
Definition: DWARFAcceleratorTable.cpp:378
isSentinel
static bool isSentinel(const DWARFDebugNames::AttributeEncoding &AE)
Definition: DWARFAcceleratorTable.cpp:424
llvm::DWARFDebugNames::extract
Error extract() override
Definition: DWARFAcceleratorTable.cpp:773
llvm::zip_first
detail::zippy< detail::zip_first, T, U, Args... > zip_first(T &&t, U &&u, Args &&... args)
zip iterator that, for the sake of efficiency, assumes the first iteratee to be the shortest.
Definition: STLExtras.h:884
llvm::DataExtractor::skip
void skip(Cursor &C, uint64_t Length) const
Advance the Cursor position by the given number of bytes.
Definition: DataExtractor.cpp:228
llvm::DWARFDebugNames::Abbrev
Abbreviation describing the encoding of Name Index entries.
Definition: DWARFAcceleratorTable.h:270
llvm::consumeError
void consumeError(Error Err)
Consume a Error without doing anything.
Definition: Error.h:1042
llvm::Data
@ Data
Definition: SIMachineScheduler.h:55
llvm::DWARFAcceleratorTable::Entry::Entry
Entry()=default
llvm::DWARFDebugNames::AttributeEncoding
Index attribute and its encoding.
Definition: DWARFAcceleratorTable.h:256
llvm::DWARFDebugNames::Entry::getCUIndex
Optional< uint64_t > getCUIndex() const
Returns the Index into the Compilation Unit list of the owning Name Index or None if this Accelerator...
Definition: DWARFAcceleratorTable.cpp:553
llvm::DWARFDebugNames::NameIndex::getBucketArrayEntry
uint32_t getBucketArrayEntry(uint32_t Bucket) const
Reads an entry in the Bucket Array for the given Bucket.
Definition: DWARFAcceleratorTable.cpp:653
llvm::ARMBuildAttrs::Section
@ Section
Legacy Tags.
Definition: ARMBuildAttributes.h:82
llvm::dwarf::AtomTypeString
StringRef AtomTypeString(unsigned Atom)
Definition: Dwarf.cpp:587
llvm::dwarf::DW_INVALID_OFFSET
const uint32_t DW_INVALID_OFFSET
Identifier of an invalid DIE offset in the .debug_info section.
Definition: Dwarf.h:103
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::formatv
auto formatv(const char *Fmt, Ts &&... Vals) -> formatv_object< decltype(std::make_tuple(detail::build_format_adapter(std::forward< Ts >(Vals))...))>
Definition: FormatVariadic.h:251
llvm::AppleAcceleratorTable::getHeaderDataLength
uint32_t getHeaderDataLength()
Definition: DWARFAcceleratorTable.cpp:84
llvm::AppleAcceleratorTable::getNumBuckets
uint32_t getNumBuckets()
Definition: DWARFAcceleratorTable.cpp:81
llvm::AppleAcceleratorTable::getSizeHdr
uint32_t getSizeHdr()
Definition: DWARFAcceleratorTable.cpp:83
llvm::DWARFDataExtractor::getRelocatedValue
uint64_t getRelocatedValue(uint32_t Size, uint64_t *Off, uint64_t *SectionIndex=nullptr, Error *Err=nullptr) const
Extracts a value and applies a relocation to the result if one exists for the given offset.
Definition: DWARFDataExtractor.cpp:48
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
llvm::dwarf::DW_ATOM_die_tag
@ DW_ATOM_die_tag
Definition: Dwarf.h:512
C
(vector float) vec_cmpeq(*A, *B) C
Definition: README_ALTIVEC.txt:86
llvm::ARM_PROC::A
@ A
Definition: ARMBaseInfo.h:34
llvm::DWARFDebugNames::NameIndex
Represents a single accelerator table within the DWARF v5 .debug_names section.
Definition: DWARFAcceleratorTable.h:388
llvm::AppleAcceleratorTable::ValueIterator::ValueIterator
ValueIterator()=default
End marker.
llvm::DWARFDebugNames::NameIndex::getEntry
Expected< Entry > getEntry(uint64_t *Offset) const
Definition: DWARFAcceleratorTable.cpp:610
llvm::dwarf::DW_ATOM_cu_offset
@ DW_ATOM_cu_offset
Definition: Dwarf.h:510
llvm::AppleAcceleratorTable::validateForms
bool validateForms()
Definition: DWARFAcceleratorTable.cpp:94
llvm::ms_demangle::QualifierMangleMode::Result
@ Result
llvm::DWARFDebugNames::NameIndex::getHashArrayEntry
uint32_t getHashArrayEntry(uint32_t Index) const
Reads an entry in the Hash Array for the given Index.
Definition: DWARFAcceleratorTable.cpp:659
llvm::DWARFDebugNames::NameIndex::equal_range
iterator_range< ValueIterator > equal_range(StringRef Key) const
Look up all entries in this Name Index matching Key.
Definition: DWARFAcceleratorTable.cpp:786
llvm::AMDGPU::PALMD::Key
Key
PAL metadata keys.
Definition: AMDGPUMetadata.h:486
false
Definition: StackSlotColoring.cpp:141
llvm::dwarf::Index
Index
Definition: Dwarf.h:472
llvm::DWARFDebugNames::Abbrev::Tag
dwarf::Tag Tag
Dwarf Tag of the described entity.
Definition: DWARFAcceleratorTable.h:272
llvm::dwarf::FormatString
StringRef FormatString(DwarfFormat Format)
Definition: Dwarf.cpp:790
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
llvm::operator<<
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
Definition: APFixedPoint.h:291
llvm::DWARFFormValue
Definition: DWARFFormValue.h:28
llvm::IndexedInstrProf::Version
const uint64_t Version
Definition: InstrProf.h:1056
FormatVariadic.h
llvm::ErrorInfoBase
Base class for error info classes.
Definition: Error.h:46
llvm::AppleAcceleratorTable::getAtomsDesc
ArrayRef< std::pair< HeaderData::AtomType, HeaderData::Form > > getAtomsDesc()
Return the Atom description, which can be used to interpret the raw values of the Accelerator Entries...
Definition: DWARFAcceleratorTable.cpp:90
llvm::DWARFAcceleratorTable::AccelSection
DWARFDataExtractor AccelSection
Definition: DWARFAcceleratorTable.h:33
llvm::AppleAcceleratorTable::readAtoms
std::pair< uint64_t, dwarf::Tag > readAtoms(uint64_t *HashDataOffset)
Return information related to the DWARF DIE we're looking for when performing a lookup by name.
Definition: DWARFAcceleratorTable.cpp:114
llvm::errc::illegal_byte_sequence
@ illegal_byte_sequence
sentinelAbbrev
static DWARFDebugNames::Abbrev sentinelAbbrev()
Definition: DWARFAcceleratorTable.cpp:428
llvm::Twine::utohexstr
static Twine utohexstr(const uint64_t &Val)
Definition: Twine.h:404
llvm::AMDGPU::Hwreg::Offset
Offset
Definition: SIDefines.h:416
Index
uint32_t Index
Definition: ELFObjHandler.cpp:83
uint64_t
llvm::DataExtractor::isValidOffsetForDataOfSize
bool isValidOffsetForDataOfSize(uint64_t offset, uint64_t length) const
Test the availability of length bytes of data from offset.
Definition: DataExtractor.h:672
llvm::DWARFDebugNames::getCUNameIndex
const NameIndex * getCUNameIndex(uint64_t CUOffset)
Return the Name Index covering the compile unit at CUOffset, or nullptr if there is no Name Index cov...
Definition: DWARFAcceleratorTable.cpp:896
llvm::caseFoldingDjbHash
uint32_t caseFoldingDjbHash(StringRef Buffer, uint32_t H=5381)
Computes the Bernstein hash after folding the input according to the Dwarf 5 standard case folding ru...
Definition: DJB.cpp:71
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
formatAtom
static Atom formatAtom(unsigned Atom)
Definition: DWARFAcceleratorTable.cpp:39
llvm::DWARFDebugNames::NameIndex::getForeignTUSignature
uint64_t getForeignTUSignature(uint32_t TU) const
Reads signature of foreign type unit TU. TU is 0-based.
Definition: DWARFAcceleratorTable.cpp:600
Attributes
AMDGPU Kernel Attributes
Definition: AMDGPULowerKernelAttributes.cpp:347
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
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::DWARFDebugNames::SentinelError
Error returned by NameIndex::getEntry to report it has reached the end of the entry list.
Definition: DWARFAcceleratorTable.h:326
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::DWARFFormValue::FC_Flag
@ FC_Flag
Definition: DWARFFormValue.h:36
llvm::DWARFDebugNames::NameIndex::getLocalTUOffset
uint64_t getLocalTUOffset(uint32_t TU) const
Reads offset of local type unit TU, TU is 0-based.
Definition: DWARFAcceleratorTable.cpp:593
llvm::DataExtractor::Cursor
A class representing a position in a DataExtractor, as well as any error encountered during extractio...
Definition: DataExtractor.h:54
llvm::DWARFDebugNames::equal_range
iterator_range< ValueIterator > equal_range(StringRef Key) const
Look up all entries in the accelerator table matching Key.
Definition: DWARFAcceleratorTable.cpp:889
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::DictScope
Definition: ScopedPrinter.h:809
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::DWARFAcceleratorTable::StringSection
DataExtractor StringSection
Definition: DWARFAcceleratorTable.h:34
llvm::ArrayRef
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: APInt.h:32
llvm::DWARFDebugNames::SentinelError::ID
static char ID
Definition: DWARFAcceleratorTable.h:328
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
Dwarf.h
llvm::msf::Magic
static const char Magic[]
Definition: MSFCommon.h:23
uint32_t
Compiler.h
llvm::dwarf::AtomValueString
StringRef AtomValueString(uint16_t Atom, unsigned Val)
Returns the symbolic string representing Val when used as a value for atom Atom.
Definition: Dwarf.cpp:672
llvm::AppleAcceleratorTable::getNumHashes
uint32_t getNumHashes()
Definition: DWARFAcceleratorTable.cpp:82
llvm::AppleAcceleratorTable
This implements the Apple accelerator table format, a precursor of the DWARF 5 accelerator table form...
Definition: DWARFAcceleratorTable.h:83
llvm::format
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Definition: Format.h:124
llvm::AppleAcceleratorTable::ValueIterator
Definition: DWARFAcceleratorTable.h:143
llvm::DWARFDebugNames::NameIndex::dump
void dump(ScopedPrinter &W) const
Definition: DWARFAcceleratorTable.cpp:754
for
this could be done in SelectionDAGISel along with other special for
Definition: README.txt:104
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
llvm::DWARFDebugNames::Entry::getDIEUnitOffset
Optional< uint64_t > getDIEUnitOffset() const
Returns the Offset of the DIE within the containing CU or TU.
Definition: DWARFAcceleratorTable.cpp:547
llvm::DWARFDebugNames::Entry
DWARF v5-specific implementation of an Accelerator Entry.
Definition: DWARFAcceleratorTable.h:283
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
sentinelAttrEnc
static constexpr DWARFDebugNames::AttributeEncoding sentinelAttrEnc()
Definition: DWARFAcceleratorTable.cpp:420
llvm::createStringError
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition: Error.h:1238
std
Definition: BitVector.h:851
llvm::AppleAcceleratorTable::equal_range
iterator_range< ValueIterator > equal_range(StringRef Key) const
Look up all entries in the accelerator table matching Key.
Definition: DWARFAcceleratorTable.cpp:328
llvm::inconvertibleErrorCode
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Definition: Error.cpp:79
llvm::None
constexpr std::nullopt_t None
Definition: None.h:27
uint16_t
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::c_str
SmallVectorImpl< T >::const_pointer c_str(SmallVectorImpl< T > &str)
Definition: WindowsSupport.h:193
llvm::DWARFDebugNames::dump
void dump(raw_ostream &OS) const override
Definition: DWARFAcceleratorTable.cpp:790
llvm::ScopedPrinter
Definition: ScopedPrinter.h:100
llvm::errc::io_error
@ io_error
llvm::TargetStackID::Value
Value
Definition: TargetFrameLowering.h:27
llvm::DWARFDebugNames::Abbrev::Code
uint32_t Code
Abbreviation code.
Definition: DWARFAcceleratorTable.h:271
llvm::DWARFDebugNames::SentinelError::convertToErrorCode
std::error_code convertToErrorCode() const override
Convert this error to a std::error_code.
Definition: DWARFAcceleratorTable.cpp:582
llvm::AppleAcceleratorTable::Entry::getCUOffset
Optional< uint64_t > getCUOffset() const override
Returns the Offset of the Compilation Unit associated with this Accelerator Entry or None if the Comp...
Definition: DWARFAcceleratorTable.cpp:290
llvm::DWARFFormValue::extractValue
bool extractValue(const DWARFDataExtractor &Data, uint64_t *OffsetPtr, dwarf::FormParams FormParams, const DWARFContext *Context=nullptr, const DWARFUnit *Unit=nullptr)
Extracts a value in Data at offset *OffsetPtr.
Definition: DWARFFormValue.cpp:248
llvm::dwarf::FormParams::Version
uint16_t Version
Definition: Dwarf.h:654
SmallVector.h
lookup
static bool lookup(const GsymReader &GR, DataExtractor &Data, uint64_t &Offset, uint64_t BaseAddr, uint64_t Addr, SourceLocations &SrcLocs, llvm::Error &Err)
A Lookup helper functions.
Definition: InlineInfo.cpp:108
llvm::DWARFDebugNames::NameIndex::getNameTableEntry
NameTableEntry getNameTableEntry(uint32_t Index) const
Reads an entry in the Name Table for the given Index.
Definition: DWARFAcceleratorTable.cpp:636
llvm::DWARFDebugNames::Entry::lookup
Optional< DWARFFormValue > lookup(dwarf::Index Index) const
Returns the value of the Index Attribute in this Accelerator Entry, if the Entry contains such Attrib...
Definition: DWARFAcceleratorTable.cpp:538
llvm::DWARFFormValue::isFormClass
bool isFormClass(FormClass FC) const
Definition: DWARFFormValue.cpp:216
llvm::DWARFDebugNames::Abbrev::dump
void dump(ScopedPrinter &W) const
Definition: DWARFAcceleratorTable.cpp:412
llvm::DWARFFormValue::getForm
dwarf::Form getForm() const
Definition: DWARFFormValue.h:79
llvm::iterator_range
A range adaptor for a pair of iterators.
Definition: iterator_range.h:30
llvm::AppleAcceleratorTable::Entry::lookup
Optional< DWARFFormValue > lookup(HeaderData::AtomType Atom) const
Returns the value of the Atom in this Accelerator Entry, if the Entry contains such Atom.
Definition: DWARFAcceleratorTable.cpp:276
llvm::DWARFDebugNames::Entry::getCUOffset
Optional< uint64_t > getCUOffset() const override
Returns the Offset of the Compilation Unit associated with this Accelerator Entry or None if the Comp...
Definition: DWARFAcceleratorTable.cpp:563
llvm::SmallVectorImpl
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:42
llvm::AppleAcceleratorTable::extract
Error extract() override
Definition: DWARFAcceleratorTable.cpp:43
llvm::DWARFDebugNames::Abbrev::Attributes
std::vector< AttributeEncoding > Attributes
List of index attributes.
Definition: DWARFAcceleratorTable.h:273
llvm::dwarf::DW_ATOM_type_flags
@ DW_ATOM_type_flags
Definition: Dwarf.h:513
llvm::DWARFAcceleratorTable::~DWARFAcceleratorTable
virtual ~DWARFAcceleratorTable()
llvm::DWARFDebugNames
.debug_names section consists of one or more units.
Definition: DWARFAcceleratorTable.h:231
llvm::djbHash
uint32_t djbHash(StringRef Buffer, uint32_t H=5381)
The Bernstein hash function used by the DWARF accelerator tables.
Definition: DJB.h:21
llvm::DWARFDebugNames::Entry::dump
void dump(ScopedPrinter &W) const
Definition: DWARFAcceleratorTable.cpp:570
llvm::DWARFDebugNames::NameIndex::getCUCount
uint32_t getCUCount() const
Definition: DWARFAcceleratorTable.h:425
raw_ostream.h
llvm::dwarf::getDwarfOffsetByteSize
uint8_t getDwarfOffsetByteSize(DwarfFormat Format)
The size of a reference determined by the DWARF 32/64-bit format.
Definition: Dwarf.h:640
llvm::DWARFDebugNames::NameIndex::getCUOffset
uint64_t getCUOffset(uint32_t CU) const
Reads offset of compilation unit CU. CU is 0-based.
Definition: DWARFAcceleratorTable.cpp:586
llvm::AppleAcceleratorTable::Entry::getDIESectionOffset
Optional< uint64_t > getDIESectionOffset() const
Returns the Section Offset of the Debug Info Entry associated with this Accelerator Entry or None if ...
Definition: DWARFAcceleratorTable.cpp:286
CU
Definition: AArch64AsmBackend.cpp:504
llvm::handleAllErrors
void handleAllErrors(Error E, HandlerTs &&... Handlers)
Behaves the same as handleErrors, except that by contract all errors must be handled by the given han...
Definition: Error.h:965
llvm::Value
LLVM Value Representation.
Definition: Value.h:74
llvm::dwarf::DWARF32
@ DWARF32
Definition: Dwarf.h:93
llvm::sampleprof::Base
@ Base
Definition: Discriminator.h:58
SpecialSubKind::string
@ string
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
ScopedPrinter.h