LLVM 19.0.0git
DWARFAcceleratorTable.h
Go to the documentation of this file.
1//===- DWARFAcceleratorTable.h ----------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLVM_DEBUGINFO_DWARF_DWARFACCELERATORTABLE_H
10#define LLVM_DEBUGINFO_DWARF_DWARFACCELERATORTABLE_H
11
12#include "llvm/ADT/DenseSet.h"
18#include <cstdint>
19#include <utility>
20
21namespace llvm {
22
23class raw_ostream;
24class ScopedPrinter;
25
26/// The accelerator tables are designed to allow efficient random access
27/// (using a symbol name as a key) into debug info by providing an index of the
28/// debug info DIEs. This class implements the common functionality of Apple and
29/// DWARF 5 accelerator tables.
30/// TODO: Generalize the rest of the AppleAcceleratorTable interface and move it
31/// to this class.
33protected:
36
37public:
38 /// An abstract class representing a single entry in the accelerator tables.
39 class Entry {
40 protected:
42
43 Entry() = default;
44
45 // Make these protected so only (final) subclasses can be copied around.
46 Entry(const Entry &) = default;
47 Entry(Entry &&) = default;
48 Entry &operator=(const Entry &) = default;
49 Entry &operator=(Entry &&) = default;
50 ~Entry() = default;
51
52
53 public:
54 /// Returns the Offset of the Compilation Unit associated with this
55 /// Accelerator Entry or std::nullopt if the Compilation Unit offset is not
56 /// recorded in this Accelerator Entry.
57 virtual std::optional<uint64_t> getCUOffset() const = 0;
58
59 /// Returns the Offset of the Type Unit associated with this
60 /// Accelerator Entry or std::nullopt if the Type Unit offset is not
61 /// recorded in this Accelerator Entry.
62 virtual std::optional<uint64_t> getLocalTUOffset() const {
63 // Default return for accelerator tables that don't support type units.
64 return std::nullopt;
65 }
66
67 /// Returns the Tag of the Debug Info Entry associated with this
68 /// Accelerator Entry or std::nullopt if the Tag is not recorded in this
69 /// Accelerator Entry.
70 virtual std::optional<dwarf::Tag> getTag() const = 0;
71
72 /// Returns the raw values of fields in the Accelerator Entry. In general,
73 /// these can only be interpreted with the help of the metadata in the
74 /// owning Accelerator Table.
76 };
77
82
83 virtual Error extract() = 0;
84 virtual void dump(raw_ostream &OS) const = 0;
85
87 void operator=(const DWARFAcceleratorTable &) = delete;
88};
89
90/// This implements the Apple accelerator table format, a precursor of the
91/// DWARF 5 accelerator table format.
93 struct Header {
94 uint32_t Magic;
95 uint16_t Version;
96 uint16_t HashFunction;
97 uint32_t BucketCount;
98 uint32_t HashCount;
99 uint32_t HeaderDataLength;
100
101 void dump(ScopedPrinter &W) const;
102 };
103
104 struct HeaderData {
105 using AtomType = uint16_t;
106 using Form = dwarf::Form;
107
108 uint64_t DIEOffsetBase;
110
111 std::optional<uint64_t>
112 extractOffset(std::optional<DWARFFormValue> Value) const;
113 };
114
115 Header Hdr;
116 HeaderData HdrData;
118 uint32_t HashDataEntryLength;
119 bool IsValid = false;
120
121 /// Returns true if we should continue scanning for entries or false if we've
122 /// reached the last (sentinel) entry of encountered a parsing error.
123 bool dumpName(ScopedPrinter &W, SmallVectorImpl<DWARFFormValue> &AtomForms,
124 uint64_t *DataOffset) const;
125
126 /// Reads an uint32_t from the accelerator table at Offset, which is
127 /// incremented by the number of bytes read.
128 std::optional<uint32_t> readU32FromAccel(uint64_t &Offset,
129 bool UseRelocation = false) const;
130
131 /// Reads a StringRef from the string table at Offset.
132 std::optional<StringRef>
133 readStringFromStrSection(uint64_t StringSectionOffset) const;
134
135 /// Return the offset into the section where the Buckets begin.
136 uint64_t getBucketBase() const { return sizeof(Hdr) + Hdr.HeaderDataLength; }
137
138 /// Return the offset into the section where the I-th bucket is.
139 uint64_t getIthBucketBase(uint32_t I) const {
140 return getBucketBase() + I * 4;
141 }
142
143 /// Return the offset into the section where the hash list begins.
144 uint64_t getHashBase() const { return getBucketBase() + getNumBuckets() * 4; }
145
146 /// Return the offset into the section where the I-th hash is.
147 uint64_t getIthHashBase(uint32_t I) const { return getHashBase() + I * 4; }
148
149 /// Return the offset into the section where the offset list begins.
150 uint64_t getOffsetBase() const { return getHashBase() + getNumHashes() * 4; }
151
152 /// Return the offset into the section where the table entries begin.
153 uint64_t getEntriesBase() const {
154 return getOffsetBase() + getNumHashes() * 4;
155 }
156
157 /// Return the offset into the section where the I-th offset is.
158 uint64_t getIthOffsetBase(uint32_t I) const {
159 return getOffsetBase() + I * 4;
160 }
161
162 /// Returns the index of the bucket where a hypothetical Hash would be.
163 uint32_t hashToBucketIdx(uint32_t Hash) const {
164 return Hash % getNumBuckets();
165 }
166
167 /// Returns true iff a hypothetical Hash would be assigned to the BucketIdx-th
168 /// bucket.
169 bool wouldHashBeInBucket(uint32_t Hash, uint32_t BucketIdx) const {
170 return hashToBucketIdx(Hash) == BucketIdx;
171 }
172
173 /// Reads the contents of the I-th bucket, that is, the index in the hash list
174 /// where the hashes corresponding to this bucket begin.
175 std::optional<uint32_t> readIthBucket(uint32_t I) const {
176 uint64_t Offset = getIthBucketBase(I);
177 return readU32FromAccel(Offset);
178 }
179
180 /// Reads the I-th hash in the hash list.
181 std::optional<uint32_t> readIthHash(uint32_t I) const {
182 uint64_t Offset = getIthHashBase(I);
183 return readU32FromAccel(Offset);
184 }
185
186 /// Reads the I-th offset in the offset list.
187 std::optional<uint32_t> readIthOffset(uint32_t I) const {
188 uint64_t Offset = getIthOffsetBase(I);
189 return readU32FromAccel(Offset);
190 }
191
192 /// Reads a string offset from the accelerator table at Offset, which is
193 /// incremented by the number of bytes read.
194 std::optional<uint32_t> readStringOffsetAt(uint64_t &Offset) const {
195 return readU32FromAccel(Offset, /*UseRelocation*/ true);
196 }
197
198 /// Scans through all Hashes in the BucketIdx-th bucket, attempting to find
199 /// HashToFind. If it is found, its index in the list of hashes is returned.
200 std::optional<uint32_t> idxOfHashInBucket(uint32_t HashToFind,
201 uint32_t BucketIdx) const;
202
203public:
204 /// Apple-specific implementation of an Accelerator Entry.
205 class Entry final : public DWARFAcceleratorTable::Entry {
206 const AppleAcceleratorTable &Table;
207
208 Entry(const AppleAcceleratorTable &Table);
209 void extract(uint64_t *Offset);
210
211 public:
212 std::optional<uint64_t> getCUOffset() const override;
213
214 /// Returns the Section Offset of the Debug Info Entry associated with this
215 /// Accelerator Entry or std::nullopt if the DIE offset is not recorded in
216 /// this Accelerator Entry. The returned offset is relative to the start of
217 /// the Section containing the DIE.
218 std::optional<uint64_t> getDIESectionOffset() const;
219
220 std::optional<dwarf::Tag> getTag() const override;
221
222 /// Returns the value of the Atom in this Accelerator Entry, if the Entry
223 /// contains such Atom.
224 std::optional<DWARFFormValue> lookup(HeaderData::AtomType Atom) const;
225
227 friend class ValueIterator;
228 };
229
230 /// An iterator for Entries all having the same string as key.
232 : public iterator_facade_base<SameNameIterator, std::forward_iterator_tag,
233 Entry> {
234 Entry Current;
235 uint64_t Offset = 0;
236
237 public:
238 /// Construct a new iterator for the entries at \p DataOffset.
240 uint64_t DataOffset);
241
242 const Entry &operator*() {
243 uint64_t OffsetCopy = Offset;
244 Current.extract(&OffsetCopy);
245 return Current;
246 }
248 Offset += Current.Table.getHashDataEntryLength();
249 return *this;
250 }
251 friend bool operator==(const SameNameIterator &A,
252 const SameNameIterator &B) {
253 return A.Offset == B.Offset;
254 }
255 };
256
259 : BaseEntry(Table), StrOffset(0) {}
260
261 std::optional<StringRef> readName() const {
262 return BaseEntry.Table.readStringFromStrSection(StrOffset);
263 }
264
267 };
268
269 /// An iterator for all entries in the table.
271 : public iterator_facade_base<Iterator, std::forward_iterator_tag,
272 EntryWithName> {
273 constexpr static auto EndMarker = std::numeric_limits<uint64_t>::max();
274
275 EntryWithName Current;
276 uint64_t Offset = EndMarker;
277 uint32_t NumEntriesToCome = 0;
278
279 void setToEnd() { Offset = EndMarker; }
280 bool isEnd() const { return Offset == EndMarker; }
281 const AppleAcceleratorTable &getTable() const {
282 return Current.BaseEntry.Table;
283 }
284
285 /// Reads the next Entry in the table, populating `Current`.
286 /// If not possible (e.g. end of the section), becomes the end iterator.
287 void prepareNextEntryOrEnd();
288
289 /// Reads the next string pointer and the entry count for that string,
290 /// populating `NumEntriesToCome`.
291 /// If not possible (e.g. end of the section), becomes the end iterator.
292 /// Assumes `Offset` points to a string reference.
293 void prepareNextStringOrEnd();
294
295 public:
296 Iterator(const AppleAcceleratorTable &Table, bool SetEnd = false);
297
299 prepareNextEntryOrEnd();
300 return *this;
301 }
302 bool operator==(const Iterator &It) const { return Offset == It.Offset; }
303 const EntryWithName &operator*() const {
304 assert(!isEnd() && "dereferencing end iterator");
305 return Current;
306 }
307 };
308
312
313 Error extract() override;
314 uint32_t getNumBuckets() const;
315 uint32_t getNumHashes() const;
316 uint32_t getSizeHdr() const;
318
319 /// Returns the size of one HashData entry.
320 uint32_t getHashDataEntryLength() const { return HashDataEntryLength; }
321
322 /// Return the Atom description, which can be used to interpret the raw values
323 /// of the Accelerator Entries in this table.
325
326 /// Returns true iff `AtomTy` is one of the atoms available in Entries of this
327 /// table.
329 return is_contained(make_first_range(HdrData.Atoms), AtomTy);
330 }
331
332 bool validateForms();
333
334 /// Return information related to the DWARF DIE we're looking for when
335 /// performing a lookup by name.
336 ///
337 /// \param HashDataOffset an offset into the hash data table
338 /// \returns <DieOffset, DieTag>
339 /// DieOffset is the offset into the .debug_info section for the DIE
340 /// related to the input hash data offset.
341 /// DieTag is the tag of the DIE
342 std::pair<uint64_t, dwarf::Tag> readAtoms(uint64_t *HashDataOffset);
343 void dump(raw_ostream &OS) const override;
344
345 /// Look up all entries in the accelerator table matching \c Key.
347
348 /// Lookup all entries in the accelerator table.
349 auto entries() const {
350 return make_range(Iterator(*this), Iterator(*this, /*SetEnd*/ true));
351 }
352};
353
354/// .debug_names section consists of one or more units. Each unit starts with a
355/// header, which is followed by a list of compilation units, local and foreign
356/// type units.
357///
358/// These may be followed by an (optional) hash lookup table, which consists of
359/// an array of buckets and hashes similar to the apple tables above. The only
360/// difference is that the hashes array is 1-based, and consequently an empty
361/// bucket is denoted by 0 and not UINT32_MAX.
362///
363/// Next is the name table, which consists of an array of names and array of
364/// entry offsets. This is different from the apple tables, which store names
365/// next to the actual entries.
366///
367/// The structure of the entries is described by an abbreviations table, which
368/// comes after the name table. Unlike the apple tables, which have a uniform
369/// entry structure described in the header, each .debug_names entry may have
370/// different index attributes (DW_IDX_???) attached to it.
371///
372/// The last segment consists of a list of entries, which is a 0-terminated list
373/// referenced by the name table and interpreted with the help of the
374/// abbreviation table.
376public:
377 class NameIndex;
378 class NameIterator;
379 class ValueIterator;
380
381 /// DWARF v5 Name Index header.
382 struct Header {
394
396 void dump(ScopedPrinter &W) const;
397 };
398
399 /// Index attribute and its encoding.
403
405 : Index(Index), Form(Form) {}
406
407 friend bool operator==(const AttributeEncoding &LHS,
408 const AttributeEncoding &RHS) {
409 return LHS.Index == RHS.Index && LHS.Form == RHS.Form;
410 }
411 };
412
413 /// Abbreviation describing the encoding of Name Index entries.
414 struct Abbrev {
415 uint64_t AbbrevOffset; /// < Abbreviation offset in the .debug_names section
416 uint32_t Code; ///< Abbreviation code
417 dwarf::Tag Tag; ///< Dwarf Tag of the described entity.
418 std::vector<AttributeEncoding> Attributes; ///< List of index attributes.
419
421 std::vector<AttributeEncoding> Attributes)
424
425 void dump(ScopedPrinter &W) const;
426 };
427
428 /// DWARF v5-specific implementation of an Accelerator Entry.
429 class Entry final : public DWARFAcceleratorTable::Entry {
430 const NameIndex *NameIdx;
431 const Abbrev *Abbr;
432
433 Entry(const NameIndex &NameIdx, const Abbrev &Abbr);
434
435 public:
436 std::optional<uint64_t> getCUOffset() const override;
437 std::optional<uint64_t> getLocalTUOffset() const override;
438 std::optional<dwarf::Tag> getTag() const override { return tag(); }
439
440 /// Returns the Index into the Compilation Unit list of the owning Name
441 /// Index or std::nullopt if this Accelerator Entry does not have an
442 /// associated Compilation Unit. It is up to the user to verify that the
443 /// returned Index is valid in the owning NameIndex (or use getCUOffset(),
444 /// which will handle that check itself). Note that entries in NameIndexes
445 /// which index just a single Compilation Unit are implicitly associated
446 /// with that unit, so this function will return 0 even without an explicit
447 /// DW_IDX_compile_unit attribute, unless there is a DW_IDX_type_unit
448 /// attribute.
449 std::optional<uint64_t> getCUIndex() const;
450
451 /// Returns the Index into the Local Type Unit list of the owning Name
452 /// Index or std::nullopt if this Accelerator Entry does not have an
453 /// associated Type Unit. It is up to the user to verify that the
454 /// returned Index is valid in the owning NameIndex (or use
455 /// getLocalTUOffset(), which will handle that check itself).
456 std::optional<uint64_t> getLocalTUIndex() const;
457
458 /// .debug_names-specific getter, which always succeeds (DWARF v5 index
459 /// entries always have a tag).
460 dwarf::Tag tag() const { return Abbr->Tag; }
461
462 /// Returns the Offset of the DIE within the containing CU or TU.
463 std::optional<uint64_t> getDIEUnitOffset() const;
464
465 /// Returns true if this Entry has information about its parent DIE (i.e. if
466 /// it has an IDX_parent attribute)
467 bool hasParentInformation() const;
468
469 /// Returns the Entry corresponding to the parent of the DIE represented by
470 /// `this` Entry. If the parent is not in the table, nullopt is returned.
471 /// Precondition: hasParentInformation() == true.
472 /// An error is returned for ill-formed tables.
474
475 /// Return the Abbreviation that can be used to interpret the raw values of
476 /// this Accelerator Entry.
477 const Abbrev &getAbbrev() const { return *Abbr; }
478
479 /// Returns the value of the Index Attribute in this Accelerator Entry, if
480 /// the Entry contains such Attribute.
481 std::optional<DWARFFormValue> lookup(dwarf::Index Index) const;
482
483 void dump(ScopedPrinter &W) const;
484 void dumpParentIdx(ScopedPrinter &W, const DWARFFormValue &FormValue) const;
485
486 friend class NameIndex;
487 friend class ValueIterator;
488 };
489
490 /// Error returned by NameIndex::getEntry to report it has reached the end of
491 /// the entry list.
492 class SentinelError : public ErrorInfo<SentinelError> {
493 public:
494 static char ID;
495
496 void log(raw_ostream &OS) const override { OS << "Sentinel"; }
497 std::error_code convertToErrorCode() const override;
498 };
499
500private:
501 /// DenseMapInfo for struct Abbrev.
502 struct AbbrevMapInfo {
503 static Abbrev getEmptyKey();
504 static Abbrev getTombstoneKey();
505 static unsigned getHashValue(uint32_t Code) {
507 }
508 static unsigned getHashValue(const Abbrev &Abbr) {
509 return getHashValue(Abbr.Code);
510 }
511 static bool isEqual(uint32_t LHS, const Abbrev &RHS) {
512 return LHS == RHS.Code;
513 }
514 static bool isEqual(const Abbrev &LHS, const Abbrev &RHS) {
515 return LHS.Code == RHS.Code;
516 }
517 };
518
519public:
520 /// A single entry in the Name Table (DWARF v5 sect. 6.1.1.4.6) of the Name
521 /// Index.
523 DataExtractor StrData;
524
526 uint64_t StringOffset;
527 uint64_t EntryOffset;
528
529 public:
531 uint64_t StringOffset, uint64_t EntryOffset)
532 : StrData(StrData), Index(Index), StringOffset(StringOffset),
533 EntryOffset(EntryOffset) {}
534
535 /// Return the index of this name in the parent Name Index.
536 uint32_t getIndex() const { return Index; }
537
538 /// Returns the offset of the name of the described entities.
539 uint64_t getStringOffset() const { return StringOffset; }
540
541 /// Return the string referenced by this name table entry or nullptr if the
542 /// string offset is not valid.
543 const char *getString() const {
544 uint64_t Off = StringOffset;
545 return StrData.getCStr(&Off);
546 }
547
548 /// Compares the name of this entry against Target, returning true if they
549 /// are equal. This is more efficient in hot code paths that do not need the
550 /// length of the name.
552 // Note: this is not the name, but the rest of debug_str starting from
553 // name. This handles corrupt data (non-null terminated) without
554 // overrunning the buffer.
555 StringRef Data = StrData.getData().substr(StringOffset);
556 size_t TargetSize = Target.size();
557 return Data.size() > TargetSize && !Data[TargetSize] &&
558 strncmp(Data.data(), Target.data(), TargetSize) == 0;
559 }
560
561 /// Returns the offset of the first Entry in the list.
562 uint64_t getEntryOffset() const { return EntryOffset; }
563 };
564
565 /// Offsets for the start of various important tables from the start of the
566 /// section.
574 };
575
576 /// Represents a single accelerator table within the DWARF v5 .debug_names
577 /// section.
578 class NameIndex {
580 struct Header Hdr;
581 const DWARFDebugNames &Section;
582
583 // Base of the whole unit and of various important tables, as offsets from
584 // the start of the section.
585 uint64_t Base;
587
588 void dumpCUs(ScopedPrinter &W) const;
589 void dumpLocalTUs(ScopedPrinter &W) const;
590 void dumpForeignTUs(ScopedPrinter &W) const;
591 void dumpAbbreviations(ScopedPrinter &W) const;
592 bool dumpEntry(ScopedPrinter &W, uint64_t *Offset) const;
593 void dumpName(ScopedPrinter &W, const NameTableEntry &NTE,
594 std::optional<uint32_t> Hash) const;
595 void dumpBucket(ScopedPrinter &W, uint32_t Bucket) const;
596
597 Expected<AttributeEncoding> extractAttributeEncoding(uint64_t *Offset);
598
600 extractAttributeEncodings(uint64_t *Offset);
601
602 Expected<Abbrev> extractAbbrev(uint64_t *Offset);
603
604 public:
605 NameIndex(const DWARFDebugNames &Section, uint64_t Base)
606 : Section(Section), Base(Base) {}
607
608 /// Returns Hdr field
609 Header getHeader() const { return Hdr; }
610
611 /// Reads offset of compilation unit CU. CU is 0-based.
613 uint32_t getCUCount() const { return Hdr.CompUnitCount; }
614
615 /// Reads offset of local type unit TU, TU is 0-based.
617 uint32_t getLocalTUCount() const { return Hdr.LocalTypeUnitCount; }
618
619 /// Reads signature of foreign type unit TU. TU is 0-based.
621 uint32_t getForeignTUCount() const { return Hdr.ForeignTypeUnitCount; }
622
623 /// Reads an entry in the Bucket Array for the given Bucket. The returned
624 /// value is a (1-based) index into the Names, StringOffsets and
625 /// EntryOffsets arrays. The input Bucket index is 0-based.
627 uint32_t getBucketCount() const { return Hdr.BucketCount; }
628
629 /// Reads an entry in the Hash Array for the given Index. The input Index
630 /// is 1-based.
632
633 /// Reads an entry in the Name Table for the given Index. The Name Table
634 /// consists of two arrays -- String Offsets and Entry Offsets. The returned
635 /// offsets are relative to the starts of respective sections. Input Index
636 /// is 1-based.
638
639 uint32_t getNameCount() const { return Hdr.NameCount; }
640
642 return Abbrevs;
643 }
644
646
647 /// Returns the Entry at the relative `Offset` from the start of the Entry
648 /// pool.
650 auto OffsetFromSection = Offset + this->Offsets.EntriesBase;
651 return getEntry(&OffsetFromSection);
652 }
653
654 /// Look up all entries in this Name Index matching \c Key.
656
657 NameIterator begin() const { return NameIterator(this, 1); }
658 NameIterator end() const { return NameIterator(this, getNameCount() + 1); }
659
660 Error extract();
661 uint64_t getUnitOffset() const { return Base; }
663 return Base + dwarf::getUnitLengthFieldByteSize(Hdr.Format) +
664 Hdr.UnitLength;
665 }
666 void dump(ScopedPrinter &W) const;
667
668 friend class DWARFDebugNames;
669 };
670
672 public:
673 using iterator_category = std::input_iterator_tag;
675 using difference_type = std::ptrdiff_t;
678
679 private:
680 /// The Name Index we are currently iterating through. The implementation
681 /// relies on the fact that this can also be used as an iterator into the
682 /// "NameIndices" vector in the Accelerator section.
683 const NameIndex *CurrentIndex = nullptr;
684
685 /// Whether this is a local iterator (searches in CurrentIndex only) or not
686 /// (searches all name indices).
687 bool IsLocal;
688
689 std::optional<Entry> CurrentEntry;
690 uint64_t DataOffset = 0; ///< Offset into the section.
691 std::string Key; ///< The Key we are searching for.
692 std::optional<uint32_t> Hash; ///< Hash of Key, if it has been computed.
693
694 bool getEntryAtCurrentOffset();
695 std::optional<uint64_t> findEntryOffsetInCurrentIndex();
696 bool findInCurrentIndex();
697 void searchFromStartOfCurrentIndex();
698 void next();
699
700 /// Set the iterator to the "end" state.
701 void setEnd() { *this = ValueIterator(); }
702
703 public:
704 /// Create a "begin" iterator for looping over all entries in the
705 /// accelerator table matching Key. The iterator will run through all Name
706 /// Indexes in the section in sequence.
708
709 /// Create a "begin" iterator for looping over all entries in a specific
710 /// Name Index. Other indices in the section will not be visited.
711 ValueIterator(const NameIndex &NI, StringRef Key);
712
713 /// End marker.
714 ValueIterator() = default;
715
716 const Entry &operator*() const { return *CurrentEntry; }
718 next();
719 return *this;
720 }
722 ValueIterator I = *this;
723 next();
724 return I;
725 }
726
727 friend bool operator==(const ValueIterator &A, const ValueIterator &B) {
728 return A.CurrentIndex == B.CurrentIndex && A.DataOffset == B.DataOffset;
729 }
730 friend bool operator!=(const ValueIterator &A, const ValueIterator &B) {
731 return !(A == B);
732 }
733 };
734
736
737 /// The Name Index we are iterating through.
738 const NameIndex *CurrentIndex;
739
740 /// The current name in the Name Index.
741 uint32_t CurrentName;
742
743 void next() {
744 assert(CurrentName <= CurrentIndex->getNameCount());
745 ++CurrentName;
746 }
747
748 public:
749 using iterator_category = std::input_iterator_tag;
753 using reference = NameTableEntry; // We return entries by value.
754
755 /// Creates an iterator whose initial position is name CurrentName in
756 /// CurrentIndex.
757 NameIterator(const NameIndex *CurrentIndex, uint32_t CurrentName)
758 : CurrentIndex(CurrentIndex), CurrentName(CurrentName) {}
759
761 return CurrentIndex->getNameTableEntry(CurrentName);
762 }
764 next();
765 return *this;
766 }
768 NameIterator I = *this;
769 next();
770 return I;
771 }
772
773 friend bool operator==(const NameIterator &A, const NameIterator &B) {
774 return A.CurrentIndex == B.CurrentIndex && A.CurrentName == B.CurrentName;
775 }
776 friend bool operator!=(const NameIterator &A, const NameIterator &B) {
777 return !(A == B);
778 }
779 };
780
781private:
782 SmallVector<NameIndex, 0> NameIndices;
784
785public:
789
790 Error extract() override;
791 void dump(raw_ostream &OS) const override;
792
793 /// Look up all entries in the accelerator table matching \c Key.
795
797 const_iterator begin() const { return NameIndices.begin(); }
798 const_iterator end() const { return NameIndices.end(); }
799
800 /// Return the Name Index covering the compile unit at CUOffset, or nullptr if
801 /// there is no Name Index covering that unit.
802 const NameIndex *getCUNameIndex(uint64_t CUOffset);
803};
804
805/// Calculates the starting offsets for various sections within the
806/// .debug_names section.
807void findDebugNamesOffsets(DWARFDebugNames::DWARFDebugNamesOffsets &Offsets,
808 uint64_t HdrSize, const dwarf::DwarfFormat Format,
809 const DWARFDebugNames::Header &Hdr);
810
811/// If `Name` is the name of a templated function that includes template
812/// parameters, returns a substring of `Name` containing no template
813/// parameters.
814/// E.g.: StripTemplateParameters("foo<int>") = "foo".
815std::optional<StringRef> StripTemplateParameters(StringRef Name);
816
818 /// For "-[A(Category) method:]", this would be "method:"
820 /// For "-[A(Category) method:]", this would be "A(category)"
822 /// For "-[A(Category) method:]", this would be "A"
823 std::optional<StringRef> ClassNameNoCategory;
824 /// For "-[A(Category) method:]", this would be "A method:"
825 std::optional<std::string> MethodNameNoCategory;
826};
827
828/// If `Name` is the AT_name of a DIE which refers to an Objective-C selector,
829/// returns an instance of ObjCSelectorNames. The Selector and ClassName fields
830/// are guaranteed to be non-empty in the result.
831std::optional<ObjCSelectorNames> getObjCNamesIfSelector(StringRef Name);
832
833} // end namespace llvm
834
835#endif // LLVM_DEBUGINFO_DWARF_DWARFACCELERATORTABLE_H
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
This file defines the DenseSet and SmallDenseSet classes.
This file contains constants used for implementing Dwarf debug support.
std::string Name
#define I(x, y, z)
Definition: MD5.cpp:58
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
This file defines the SmallString class.
This file defines the SmallVector class.
Value * RHS
Value * LHS
This class holds an abstract representation of an Accelerator Table, consisting of a sequence of buck...
Definition: AccelTable.h:202
Apple-specific implementation of an Accelerator Entry.
std::optional< DWARFFormValue > lookup(HeaderData::AtomType Atom) const
Returns the value of the Atom in this Accelerator Entry, if the Entry contains such Atom.
std::optional< uint64_t > getDIESectionOffset() const
Returns the Section Offset of the Debug Info Entry associated with this Accelerator Entry or std::nul...
std::optional< dwarf::Tag > getTag() const override
Returns the Tag of the Debug Info Entry associated with this Accelerator Entry or std::nullopt if the...
std::optional< uint64_t > getCUOffset() const override
Returns the Offset of the Compilation Unit associated with this Accelerator Entry or std::nullopt if ...
An iterator for all entries in the table.
bool operator==(const Iterator &It) const
const EntryWithName & operator*() const
An iterator for Entries all having the same string as key.
friend bool operator==(const SameNameIterator &A, const SameNameIterator &B)
This implements the Apple accelerator table format, a precursor of the DWARF 5 accelerator table form...
iterator_range< SameNameIterator > equal_range(StringRef Key) const
Look up all entries in the accelerator table matching Key.
AppleAcceleratorTable(const DWARFDataExtractor &AccelSection, DataExtractor StringSection)
bool containsAtomType(HeaderData::AtomType AtomTy) const
Returns true iff AtomTy is one of the atoms available in Entries of this table.
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.
uint32_t getHashDataEntryLength() const
Returns the size of one HashData entry.
void dump(raw_ostream &OS) const override
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...
auto entries() const
Lookup all entries in the accelerator table.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
An abstract class representing a single entry in the accelerator tables.
Entry & operator=(Entry &&)=default
ArrayRef< DWARFFormValue > getValues() const
Returns the raw values of fields in the Accelerator Entry.
SmallVector< DWARFFormValue, 3 > Values
Entry(const Entry &)=default
virtual std::optional< uint64_t > getLocalTUOffset() const
Returns the Offset of the Type Unit associated with this Accelerator Entry or std::nullopt if the Typ...
Entry & operator=(const Entry &)=default
virtual std::optional< uint64_t > getCUOffset() const =0
Returns the Offset of the Compilation Unit associated with this Accelerator Entry or std::nullopt if ...
virtual std::optional< dwarf::Tag > getTag() const =0
Returns the Tag of the Debug Info Entry associated with this Accelerator Entry or std::nullopt if the...
The accelerator tables are designed to allow efficient random access (using a symbol name as a key) i...
DWARFAcceleratorTable(const DWARFDataExtractor &AccelSection, DataExtractor StringSection)
virtual Error extract()=0
virtual void dump(raw_ostream &OS) const =0
void operator=(const DWARFAcceleratorTable &)=delete
DWARFAcceleratorTable(const DWARFAcceleratorTable &)=delete
A DataExtractor (typically for an in-memory copy of an object-file section) plus a relocation map for...
DWARF v5-specific implementation of an Accelerator Entry.
std::optional< uint64_t > getLocalTUIndex() const
Returns the Index into the Local Type Unit list of the owning Name Index or std::nullopt if this Acce...
std::optional< uint64_t > getCUIndex() const
Returns the Index into the Compilation Unit list of the owning Name Index or std::nullopt if this Acc...
const Abbrev & getAbbrev() const
Return the Abbreviation that can be used to interpret the raw values of this Accelerator Entry.
std::optional< uint64_t > getCUOffset() const override
Returns the Offset of the Compilation Unit associated with this Accelerator Entry or std::nullopt if ...
std::optional< uint64_t > getDIEUnitOffset() const
Returns the Offset of the DIE within the containing CU or TU.
Expected< std::optional< DWARFDebugNames::Entry > > getParentDIEEntry() const
Returns the Entry corresponding to the parent of the DIE represented by this Entry.
dwarf::Tag tag() const
.debug_names-specific getter, which always succeeds (DWARF v5 index entries always have a tag).
bool hasParentInformation() const
Returns true if this Entry has information about its parent DIE (i.e.
std::optional< DWARFFormValue > lookup(dwarf::Index Index) const
Returns the value of the Index Attribute in this Accelerator Entry, if the Entry contains such Attrib...
std::optional< uint64_t > getLocalTUOffset() const override
Returns the Offset of the Type Unit associated with this Accelerator Entry or std::nullopt if the Typ...
std::optional< dwarf::Tag > getTag() const override
Returns the Tag of the Debug Info Entry associated with this Accelerator Entry or std::nullopt if the...
void dumpParentIdx(ScopedPrinter &W, const DWARFFormValue &FormValue) const
void dump(ScopedPrinter &W) const
Represents a single accelerator table within the DWARF v5 .debug_names section.
uint32_t getHashArrayEntry(uint32_t Index) const
Reads an entry in the Hash Array for the given Index.
uint64_t getLocalTUOffset(uint32_t TU) const
Reads offset of local type unit TU, TU is 0-based.
uint32_t getBucketArrayEntry(uint32_t Bucket) const
Reads an entry in the Bucket Array for the given Bucket.
void dump(ScopedPrinter &W) const
Header getHeader() const
Returns Hdr field.
iterator_range< ValueIterator > equal_range(StringRef Key) const
Look up all entries in this Name Index matching Key.
uint64_t getCUOffset(uint32_t CU) const
Reads offset of compilation unit CU. CU is 0-based.
Expected< Entry > getEntry(uint64_t *Offset) const
NameTableEntry getNameTableEntry(uint32_t Index) const
Reads an entry in the Name Table for the given Index.
NameIndex(const DWARFDebugNames &Section, uint64_t Base)
const DenseSet< Abbrev, AbbrevMapInfo > & getAbbrevs() const
uint64_t getForeignTUSignature(uint32_t TU) const
Reads signature of foreign type unit TU. TU is 0-based.
Expected< Entry > getEntryAtRelativeOffset(uint64_t Offset) const
Returns the Entry at the relative Offset from the start of the Entry pool.
friend bool operator==(const NameIterator &A, const NameIterator &B)
NameIterator(const NameIndex *CurrentIndex, uint32_t CurrentName)
Creates an iterator whose initial position is name CurrentName in CurrentIndex.
friend bool operator!=(const NameIterator &A, const NameIterator &B)
A single entry in the Name Table (DWARF v5 sect.
uint64_t getStringOffset() const
Returns the offset of the name of the described entities.
uint64_t getEntryOffset() const
Returns the offset of the first Entry in the list.
bool sameNameAs(StringRef Target) const
Compares the name of this entry against Target, returning true if they are equal.
NameTableEntry(const DataExtractor &StrData, uint32_t Index, uint64_t StringOffset, uint64_t EntryOffset)
const char * getString() const
Return the string referenced by this name table entry or nullptr if the string offset is not valid.
uint32_t getIndex() const
Return the index of this name in the parent Name Index.
Error returned by NameIndex::getEntry to report it has reached the end of the entry list.
void log(raw_ostream &OS) const override
Print an error message to an output stream.
std::error_code convertToErrorCode() const override
Convert this error to a std::error_code.
friend bool operator==(const ValueIterator &A, const ValueIterator &B)
friend bool operator!=(const ValueIterator &A, const ValueIterator &B)
ValueIterator()=default
End marker.
.debug_names section consists of one or more units.
const_iterator end() const
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...
const_iterator begin() const
DWARFDebugNames(const DWARFDataExtractor &AccelSection, DataExtractor StringSection)
iterator_range< ValueIterator > equal_range(StringRef Key) const
Look up all entries in the accelerator table matching Key.
void dump(raw_ostream &OS) const override
const char * getCStr(uint64_t *OffsetPtr, Error *Err=nullptr) const
Extract a C string from *offset_ptr.
StringRef getData() const
Get the data pointed to by this extractor.
Definition: DataExtractor.h:95
Implements a dense probed hash-table based set.
Definition: DenseSet.h:271
Base class for user error types.
Definition: Error.h:352
Lightweight error class with error context and mandatory checking.
Definition: Error.h:160
Tagged union holding either a T or a Error.
Definition: Error.h:474
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition: SmallString.h:26
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:586
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1209
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition: StringRef.h:567
Target - Wrapper for Target specific information.
LLVM Value Representation.
Definition: Value.h:74
CRTP base class which implements the entire standard iterator facade in terms of a minimal subset of ...
Definition: iterator.h:80
A range adaptor for a pair of iterators.
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
uint8_t getUnitLengthFieldByteSize(DwarfFormat Format)
Get the byte size of the unit length field depending on the DWARF format.
Definition: Dwarf.h:788
DwarfFormat
Constants that define the DWARF format as 32 or 64 bit.
Definition: Dwarf.h:91
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
@ Offset
Definition: DWP.cpp:456
bool isEqual(const GCNRPTracker::LiveRegSet &S1, const GCNRPTracker::LiveRegSet &S2)
void findDebugNamesOffsets(DWARFDebugNames::DWARFDebugNamesOffsets &Offsets, uint64_t HdrSize, const dwarf::DwarfFormat Format, const DWARFDebugNames::Header &Hdr)
Calculates the starting offsets for various sections within the .debug_names section.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
auto make_first_range(ContainerTy &&c)
Given a container of pairs, return a range over the first elements.
Definition: STLExtras.h:1431
std::optional< StringRef > StripTemplateParameters(StringRef Name)
If Name is the name of a templated function that includes template parameters, returns a substring of...
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1858
std::optional< ObjCSelectorNames > getObjCNamesIfSelector(StringRef Name)
If Name is the AT_name of a DIE which refers to an Objective-C selector, returns an instance of ObjCS...
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition: STLExtras.h:1888
Implement std::hash so that hash_code can be used in STL containers.
Definition: BitVector.h:858
EntryWithName(const AppleAcceleratorTable &Table)
std::optional< StringRef > readName() const
Abbreviation describing the encoding of Name Index entries.
void dump(ScopedPrinter &W) const
uint32_t Code
< Abbreviation offset in the .debug_names section
Abbrev(uint32_t Code, dwarf::Tag Tag, uint64_t AbbrevOffset, std::vector< AttributeEncoding > Attributes)
std::vector< AttributeEncoding > Attributes
List of index attributes.
dwarf::Tag Tag
Dwarf Tag of the described entity.
Index attribute and its encoding.
friend bool operator==(const AttributeEncoding &LHS, const AttributeEncoding &RHS)
constexpr AttributeEncoding(dwarf::Index Index, dwarf::Form Form)
Offsets for the start of various important tables from the start of the section.
DWARF v5 Name Index header.
void dump(ScopedPrinter &W) const
An information struct used to provide DenseMap with the various necessary components for a given valu...
Definition: DenseMapInfo.h:50
StringRef ClassName
For "-[A(Category) method:]", this would be "A(category)".
std::optional< std::string > MethodNameNoCategory
For "-[A(Category) method:]", this would be "A method:".
StringRef Selector
For "-[A(Category) method:]", this would be "method:".
std::optional< StringRef > ClassNameNoCategory
For "-[A(Category) method:]", this would be "A".
A helper struct providing information about the byte size of DW_FORM values that vary in size dependi...
Definition: Dwarf.h:762