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