LLVM 20.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 type signature of the Type Unit associated with this
68 /// Accelerator Entry or std::nullopt if the Type Unit offset is not
69 /// recorded in this Accelerator Entry.
70 virtual std::optional<uint64_t> getForeignTUTypeSignature() const {
71 // Default return for accelerator tables that don't support type units.
72 return std::nullopt;
73 }
74
75 /// Returns the Tag of the Debug Info Entry associated with this
76 /// Accelerator Entry or std::nullopt if the Tag is not recorded in this
77 /// Accelerator Entry.
78 virtual std::optional<dwarf::Tag> getTag() const = 0;
79
80 /// Returns the raw values of fields in the Accelerator Entry. In general,
81 /// these can only be interpreted with the help of the metadata in the
82 /// owning Accelerator Table.
84 };
85
90
91 virtual Error extract() = 0;
92 virtual void dump(raw_ostream &OS) const = 0;
93
95 void operator=(const DWARFAcceleratorTable &) = delete;
96};
97
98/// This implements the Apple accelerator table format, a precursor of the
99/// DWARF 5 accelerator table format.
101 struct Header {
102 uint32_t Magic;
103 uint16_t Version;
104 uint16_t HashFunction;
105 uint32_t BucketCount;
106 uint32_t HashCount;
107 uint32_t HeaderDataLength;
108
109 void dump(ScopedPrinter &W) const;
110 };
111
112 struct HeaderData {
113 using AtomType = uint16_t;
114 using Form = dwarf::Form;
115
116 uint64_t DIEOffsetBase;
118
119 std::optional<uint64_t>
120 extractOffset(std::optional<DWARFFormValue> Value) const;
121 };
122
123 Header Hdr;
124 HeaderData HdrData;
125 dwarf::FormParams FormParams;
126 uint32_t HashDataEntryLength;
127 bool IsValid = false;
128
129 /// Returns true if we should continue scanning for entries or false if we've
130 /// reached the last (sentinel) entry of encountered a parsing error.
131 bool dumpName(ScopedPrinter &W, SmallVectorImpl<DWARFFormValue> &AtomForms,
132 uint64_t *DataOffset) const;
133
134 /// Reads an uint32_t from the accelerator table at Offset, which is
135 /// incremented by the number of bytes read.
136 std::optional<uint32_t> readU32FromAccel(uint64_t &Offset,
137 bool UseRelocation = false) const;
138
139 /// Reads a StringRef from the string table at Offset.
140 std::optional<StringRef>
141 readStringFromStrSection(uint64_t StringSectionOffset) const;
142
143 /// Return the offset into the section where the Buckets begin.
144 uint64_t getBucketBase() const { return sizeof(Hdr) + Hdr.HeaderDataLength; }
145
146 /// Return the offset into the section where the I-th bucket is.
147 uint64_t getIthBucketBase(uint32_t I) const {
148 return getBucketBase() + I * 4;
149 }
150
151 /// Return the offset into the section where the hash list begins.
152 uint64_t getHashBase() const { return getBucketBase() + getNumBuckets() * 4; }
153
154 /// Return the offset into the section where the I-th hash is.
155 uint64_t getIthHashBase(uint32_t I) const { return getHashBase() + I * 4; }
156
157 /// Return the offset into the section where the offset list begins.
158 uint64_t getOffsetBase() const { return getHashBase() + getNumHashes() * 4; }
159
160 /// Return the offset into the section where the table entries begin.
161 uint64_t getEntriesBase() const {
162 return getOffsetBase() + getNumHashes() * 4;
163 }
164
165 /// Return the offset into the section where the I-th offset is.
166 uint64_t getIthOffsetBase(uint32_t I) const {
167 return getOffsetBase() + I * 4;
168 }
169
170 /// Returns the index of the bucket where a hypothetical Hash would be.
171 uint32_t hashToBucketIdx(uint32_t Hash) const {
172 return Hash % getNumBuckets();
173 }
174
175 /// Returns true iff a hypothetical Hash would be assigned to the BucketIdx-th
176 /// bucket.
177 bool wouldHashBeInBucket(uint32_t Hash, uint32_t BucketIdx) const {
178 return hashToBucketIdx(Hash) == BucketIdx;
179 }
180
181 /// Reads the contents of the I-th bucket, that is, the index in the hash list
182 /// where the hashes corresponding to this bucket begin.
183 std::optional<uint32_t> readIthBucket(uint32_t I) const {
184 uint64_t Offset = getIthBucketBase(I);
185 return readU32FromAccel(Offset);
186 }
187
188 /// Reads the I-th hash in the hash list.
189 std::optional<uint32_t> readIthHash(uint32_t I) const {
190 uint64_t Offset = getIthHashBase(I);
191 return readU32FromAccel(Offset);
192 }
193
194 /// Reads the I-th offset in the offset list.
195 std::optional<uint32_t> readIthOffset(uint32_t I) const {
196 uint64_t Offset = getIthOffsetBase(I);
197 return readU32FromAccel(Offset);
198 }
199
200 /// Reads a string offset from the accelerator table at Offset, which is
201 /// incremented by the number of bytes read.
202 std::optional<uint32_t> readStringOffsetAt(uint64_t &Offset) const {
203 return readU32FromAccel(Offset, /*UseRelocation*/ true);
204 }
205
206 /// Scans through all Hashes in the BucketIdx-th bucket, attempting to find
207 /// HashToFind. If it is found, its index in the list of hashes is returned.
208 std::optional<uint32_t> idxOfHashInBucket(uint32_t HashToFind,
209 uint32_t BucketIdx) const;
210
211public:
212 /// Apple-specific implementation of an Accelerator Entry.
213 class Entry final : public DWARFAcceleratorTable::Entry {
214 const AppleAcceleratorTable &Table;
215
216 Entry(const AppleAcceleratorTable &Table);
217 void extract(uint64_t *Offset);
218
219 public:
220 std::optional<uint64_t> getCUOffset() const override;
221
222 /// Returns the Section Offset of the Debug Info Entry associated with this
223 /// Accelerator Entry or std::nullopt if the DIE offset is not recorded in
224 /// this Accelerator Entry. The returned offset is relative to the start of
225 /// the Section containing the DIE.
226 std::optional<uint64_t> getDIESectionOffset() const;
227
228 std::optional<dwarf::Tag> getTag() const override;
229
230 /// Returns the value of the Atom in this Accelerator Entry, if the Entry
231 /// contains such Atom.
232 std::optional<DWARFFormValue> lookup(HeaderData::AtomType Atom) const;
233
235 friend class ValueIterator;
236 };
237
238 /// An iterator for Entries all having the same string as key.
240 : public iterator_facade_base<SameNameIterator, std::forward_iterator_tag,
241 Entry> {
242 Entry Current;
243 uint64_t Offset = 0;
244
245 public:
246 /// Construct a new iterator for the entries at \p DataOffset.
248 uint64_t DataOffset);
249
250 const Entry &operator*() {
251 uint64_t OffsetCopy = Offset;
252 Current.extract(&OffsetCopy);
253 return Current;
254 }
256 Offset += Current.Table.getHashDataEntryLength();
257 return *this;
258 }
259 friend bool operator==(const SameNameIterator &A,
260 const SameNameIterator &B) {
261 return A.Offset == B.Offset;
262 }
263 };
264
267 : BaseEntry(Table), StrOffset(0) {}
268
269 std::optional<StringRef> readName() const {
270 return BaseEntry.Table.readStringFromStrSection(StrOffset);
271 }
272
275 };
276
277 /// An iterator for all entries in the table.
279 : public iterator_facade_base<Iterator, std::forward_iterator_tag,
280 EntryWithName> {
281 constexpr static auto EndMarker = std::numeric_limits<uint64_t>::max();
282
283 EntryWithName Current;
284 uint64_t Offset = EndMarker;
285 uint32_t NumEntriesToCome = 0;
286
287 void setToEnd() { Offset = EndMarker; }
288 bool isEnd() const { return Offset == EndMarker; }
289 const AppleAcceleratorTable &getTable() const {
290 return Current.BaseEntry.Table;
291 }
292
293 /// Reads the next Entry in the table, populating `Current`.
294 /// If not possible (e.g. end of the section), becomes the end iterator.
295 void prepareNextEntryOrEnd();
296
297 /// Reads the next string pointer and the entry count for that string,
298 /// populating `NumEntriesToCome`.
299 /// If not possible (e.g. end of the section), becomes the end iterator.
300 /// Assumes `Offset` points to a string reference.
301 void prepareNextStringOrEnd();
302
303 public:
304 Iterator(const AppleAcceleratorTable &Table, bool SetEnd = false);
305
307 prepareNextEntryOrEnd();
308 return *this;
309 }
310 bool operator==(const Iterator &It) const { return Offset == It.Offset; }
311 const EntryWithName &operator*() const {
312 assert(!isEnd() && "dereferencing end iterator");
313 return Current;
314 }
315 };
316
320
321 Error extract() override;
322 uint32_t getNumBuckets() const;
323 uint32_t getNumHashes() const;
324 uint32_t getSizeHdr() const;
326
327 /// Returns the size of one HashData entry.
328 uint32_t getHashDataEntryLength() const { return HashDataEntryLength; }
329
330 /// Return the Atom description, which can be used to interpret the raw values
331 /// of the Accelerator Entries in this table.
333
334 /// Returns true iff `AtomTy` is one of the atoms available in Entries of this
335 /// table.
337 return is_contained(make_first_range(HdrData.Atoms), AtomTy);
338 }
339
340 bool validateForms();
341
342 /// Return information related to the DWARF DIE we're looking for when
343 /// performing a lookup by name.
344 ///
345 /// \param HashDataOffset an offset into the hash data table
346 /// \returns <DieOffset, DieTag>
347 /// DieOffset is the offset into the .debug_info section for the DIE
348 /// related to the input hash data offset.
349 /// DieTag is the tag of the DIE
350 std::pair<uint64_t, dwarf::Tag> readAtoms(uint64_t *HashDataOffset);
351 void dump(raw_ostream &OS) const override;
352
353 /// Look up all entries in the accelerator table matching \c Key.
355
356 /// Lookup all entries in the accelerator table.
357 auto entries() const {
358 return make_range(Iterator(*this), Iterator(*this, /*SetEnd*/ true));
359 }
360};
361
362/// .debug_names section consists of one or more units. Each unit starts with a
363/// header, which is followed by a list of compilation units, local and foreign
364/// type units.
365///
366/// These may be followed by an (optional) hash lookup table, which consists of
367/// an array of buckets and hashes similar to the apple tables above. The only
368/// difference is that the hashes array is 1-based, and consequently an empty
369/// bucket is denoted by 0 and not UINT32_MAX.
370///
371/// Next is the name table, which consists of an array of names and array of
372/// entry offsets. This is different from the apple tables, which store names
373/// next to the actual entries.
374///
375/// The structure of the entries is described by an abbreviations table, which
376/// comes after the name table. Unlike the apple tables, which have a uniform
377/// entry structure described in the header, each .debug_names entry may have
378/// different index attributes (DW_IDX_???) attached to it.
379///
380/// The last segment consists of a list of entries, which is a 0-terminated list
381/// referenced by the name table and interpreted with the help of the
382/// abbreviation table.
384public:
385 class NameIndex;
386 class NameIterator;
387 class ValueIterator;
388
389 /// DWARF v5 Name Index header.
390 struct Header {
402
404 void dump(ScopedPrinter &W) const;
405 };
406
407 /// Index attribute and its encoding.
411
413 : Index(Index), Form(Form) {}
414
415 friend bool operator==(const AttributeEncoding &LHS,
416 const AttributeEncoding &RHS) {
417 return LHS.Index == RHS.Index && LHS.Form == RHS.Form;
418 }
419 };
420
421 /// Abbreviation describing the encoding of Name Index entries.
422 struct Abbrev {
423 uint64_t AbbrevOffset; /// < Abbreviation offset in the .debug_names section
424 uint32_t Code; ///< Abbreviation code
425 dwarf::Tag Tag; ///< Dwarf Tag of the described entity.
426 std::vector<AttributeEncoding> Attributes; ///< List of index attributes.
427
429 std::vector<AttributeEncoding> Attributes)
432
433 void dump(ScopedPrinter &W) const;
434 };
435
436 /// DWARF v5-specific implementation of an Accelerator Entry.
437 class Entry final : public DWARFAcceleratorTable::Entry {
438 const NameIndex *NameIdx;
439 const Abbrev *Abbr;
440
441 Entry(const NameIndex &NameIdx, const Abbrev &Abbr);
442
443 public:
444 const NameIndex *getNameIndex() const { return NameIdx; }
445 std::optional<uint64_t> getCUOffset() const override;
446 std::optional<uint64_t> getLocalTUOffset() const override;
447 std::optional<uint64_t> getForeignTUTypeSignature() const override;
448 std::optional<dwarf::Tag> getTag() const override { return tag(); }
449
450 // Special function that will return the related CU offset needed type
451 // units. This gets used to find the .dwo file that originated the entries
452 // for a given type unit.
453 std::optional<uint64_t> getRelatedCUOffset() const;
454
455 /// Returns the Index into the Compilation Unit list of the owning Name
456 /// Index or std::nullopt if this Accelerator Entry does not have an
457 /// associated Compilation Unit. It is up to the user to verify that the
458 /// returned Index is valid in the owning NameIndex (or use getCUOffset(),
459 /// which will handle that check itself). Note that entries in NameIndexes
460 /// which index just a single Compilation Unit are implicitly associated
461 /// with that unit, so this function will return 0 even without an explicit
462 /// DW_IDX_compile_unit attribute, unless there is a DW_IDX_type_unit
463 /// attribute.
464 std::optional<uint64_t> getCUIndex() const;
465
466 /// Similar functionality to getCUIndex() but without the DW_IDX_type_unit
467 /// restriction. This allows us to get the associated a compilation unit
468 /// index for an entry that is a type unit.
469 std::optional<uint64_t> getRelatedCUIndex() const;
470
471 /// Returns the index of the Type Unit of the owning
472 /// Name
473 /// Index or std::nullopt if this Accelerator Entry does not have an
474 /// associated Type Unit. It is up to the user to verify that the
475 /// returned Index is a valid index in the owning NameIndex (or use
476 /// getLocalTUOffset(), which will handle that check itself).
477 std::optional<uint64_t> getTUIndex() const;
478
479 /// .debug_names-specific getter, which always succeeds (DWARF v5 index
480 /// entries always have a tag).
481 dwarf::Tag tag() const { return Abbr->Tag; }
482
483 /// Returns the Offset of the DIE within the containing CU or TU.
484 std::optional<uint64_t> getDIEUnitOffset() const;
485
486 /// Returns true if this Entry has information about its parent DIE (i.e. if
487 /// it has an IDX_parent attribute)
488 bool hasParentInformation() const;
489
490 /// Returns the Entry corresponding to the parent of the DIE represented by
491 /// `this` Entry. If the parent is not in the table, nullopt is returned.
492 /// Precondition: hasParentInformation() == true.
493 /// An error is returned for ill-formed tables.
495
496 /// Return the Abbreviation that can be used to interpret the raw values of
497 /// this Accelerator Entry.
498 const Abbrev &getAbbrev() const { return *Abbr; }
499
500 /// Returns the value of the Index Attribute in this Accelerator Entry, if
501 /// the Entry contains such Attribute.
502 std::optional<DWARFFormValue> lookup(dwarf::Index Index) const;
503
504 void dump(ScopedPrinter &W) const;
505 void dumpParentIdx(ScopedPrinter &W, const DWARFFormValue &FormValue) const;
506
507 friend class NameIndex;
508 friend class ValueIterator;
509 };
510
511 /// Error returned by NameIndex::getEntry to report it has reached the end of
512 /// the entry list.
513 class SentinelError : public ErrorInfo<SentinelError> {
514 public:
515 static char ID;
516
517 void log(raw_ostream &OS) const override { OS << "Sentinel"; }
518 std::error_code convertToErrorCode() const override;
519 };
520
521private:
522 /// DenseMapInfo for struct Abbrev.
523 struct AbbrevMapInfo {
524 static Abbrev getEmptyKey();
525 static Abbrev getTombstoneKey();
526 static unsigned getHashValue(uint32_t Code) {
528 }
529 static unsigned getHashValue(const Abbrev &Abbr) {
530 return getHashValue(Abbr.Code);
531 }
532 static bool isEqual(uint32_t LHS, const Abbrev &RHS) {
533 return LHS == RHS.Code;
534 }
535 static bool isEqual(const Abbrev &LHS, const Abbrev &RHS) {
536 return LHS.Code == RHS.Code;
537 }
538 };
539
540public:
541 /// A single entry in the Name Table (DWARF v5 sect. 6.1.1.4.6) of the Name
542 /// Index.
544 DataExtractor StrData;
545
546 uint32_t Index;
547 uint64_t StringOffset;
548 uint64_t EntryOffset;
549
550 public:
551 NameTableEntry(const DataExtractor &StrData, uint32_t Index,
552 uint64_t StringOffset, uint64_t EntryOffset)
553 : StrData(StrData), Index(Index), StringOffset(StringOffset),
554 EntryOffset(EntryOffset) {}
555
556 /// Return the index of this name in the parent Name Index.
557 uint32_t getIndex() const { return Index; }
558
559 /// Returns the offset of the name of the described entities.
560 uint64_t getStringOffset() const { return StringOffset; }
561
562 /// Return the string referenced by this name table entry or nullptr if the
563 /// string offset is not valid.
564 const char *getString() const {
565 uint64_t Off = StringOffset;
566 return StrData.getCStr(&Off);
567 }
568
569 /// Compares the name of this entry against Target, returning true if they
570 /// are equal. This is more efficient in hot code paths that do not need the
571 /// length of the name.
573 // Note: this is not the name, but the rest of debug_str starting from
574 // name. This handles corrupt data (non-null terminated) without
575 // overrunning the buffer.
576 StringRef Data = StrData.getData().substr(StringOffset);
577 size_t TargetSize = Target.size();
578 return Data.size() > TargetSize && !Data[TargetSize] &&
579 strncmp(Data.data(), Target.data(), TargetSize) == 0;
580 }
581
582 /// Returns the offset of the first Entry in the list.
583 uint64_t getEntryOffset() const { return EntryOffset; }
584 };
585
586 /// Offsets for the start of various important tables from the start of the
587 /// section.
595 };
596
597 /// Represents a single accelerator table within the DWARF v5 .debug_names
598 /// section.
599 class NameIndex {
601 struct Header Hdr;
602 const DWARFDebugNames &Section;
603
604 // Base of the whole unit and of various important tables, as offsets from
605 // the start of the section.
606 uint64_t Base;
608
609 void dumpCUs(ScopedPrinter &W) const;
610 void dumpLocalTUs(ScopedPrinter &W) const;
611 void dumpForeignTUs(ScopedPrinter &W) const;
612 void dumpAbbreviations(ScopedPrinter &W) const;
613 bool dumpEntry(ScopedPrinter &W, uint64_t *Offset) const;
614 void dumpName(ScopedPrinter &W, const NameTableEntry &NTE,
615 std::optional<uint32_t> Hash) const;
616 void dumpBucket(ScopedPrinter &W, uint32_t Bucket) const;
617
618 Expected<AttributeEncoding> extractAttributeEncoding(uint64_t *Offset);
619
621 extractAttributeEncodings(uint64_t *Offset);
622
623 Expected<Abbrev> extractAbbrev(uint64_t *Offset);
624
625 public:
626 NameIndex(const DWARFDebugNames &Section, uint64_t Base)
627 : Section(Section), Base(Base) {}
628
629 /// Returns Hdr field
630 Header getHeader() const { return Hdr; }
631
632 /// Returns Offsets field
633 DWARFDebugNamesOffsets getOffsets() const { return Offsets; }
634
635 /// Reads offset of compilation unit CU. CU is 0-based.
637 uint32_t getCUCount() const { return Hdr.CompUnitCount; }
638
639 /// Reads offset of local type unit TU, TU is 0-based.
641 uint32_t getLocalTUCount() const { return Hdr.LocalTypeUnitCount; }
642
643 /// Reads signature of foreign type unit TU. TU is 0-based.
645 uint32_t getForeignTUCount() const { return Hdr.ForeignTypeUnitCount; }
646
647 /// Reads an entry in the Bucket Array for the given Bucket. The returned
648 /// value is a (1-based) index into the Names, StringOffsets and
649 /// EntryOffsets arrays. The input Bucket index is 0-based.
651 uint32_t getBucketCount() const { return Hdr.BucketCount; }
652
653 /// Reads an entry in the Hash Array for the given Index. The input Index
654 /// is 1-based.
656
657 /// Reads an entry in the Name Table for the given Index. The Name Table
658 /// consists of two arrays -- String Offsets and Entry Offsets. The returned
659 /// offsets are relative to the starts of respective sections. Input Index
660 /// is 1-based.
662
663 uint32_t getNameCount() const { return Hdr.NameCount; }
664
666 return Abbrevs;
667 }
668
670
671 /// Returns the Entry at the relative `Offset` from the start of the Entry
672 /// pool.
674 auto OffsetFromSection = Offset + this->Offsets.EntriesBase;
675 return getEntry(&OffsetFromSection);
676 }
677
678 /// Look up all entries in this Name Index matching \c Key.
680
681 NameIterator begin() const { return NameIterator(this, 1); }
682 NameIterator end() const { return NameIterator(this, getNameCount() + 1); }
683
684 Error extract();
685 uint64_t getUnitOffset() const { return Base; }
687 return Base + dwarf::getUnitLengthFieldByteSize(Hdr.Format) +
688 Hdr.UnitLength;
689 }
690 void dump(ScopedPrinter &W) const;
691
692 friend class DWARFDebugNames;
693 };
694
696 public:
697 using iterator_category = std::input_iterator_tag;
699 using difference_type = std::ptrdiff_t;
702
703 private:
704 /// The Name Index we are currently iterating through. The implementation
705 /// relies on the fact that this can also be used as an iterator into the
706 /// "NameIndices" vector in the Accelerator section.
707 const NameIndex *CurrentIndex = nullptr;
708
709 /// Whether this is a local iterator (searches in CurrentIndex only) or not
710 /// (searches all name indices).
711 bool IsLocal;
712
713 std::optional<Entry> CurrentEntry;
714 uint64_t DataOffset = 0; ///< Offset into the section.
715 std::string Key; ///< The Key we are searching for.
716 std::optional<uint32_t> Hash; ///< Hash of Key, if it has been computed.
717
718 bool getEntryAtCurrentOffset();
719 std::optional<uint64_t> findEntryOffsetInCurrentIndex();
720 bool findInCurrentIndex();
721 void searchFromStartOfCurrentIndex();
722 void next();
723
724 /// Set the iterator to the "end" state.
725 void setEnd() { *this = ValueIterator(); }
726
727 public:
728 /// Create a "begin" iterator for looping over all entries in the
729 /// accelerator table matching Key. The iterator will run through all Name
730 /// Indexes in the section in sequence.
732
733 /// Create a "begin" iterator for looping over all entries in a specific
734 /// Name Index. Other indices in the section will not be visited.
735 ValueIterator(const NameIndex &NI, StringRef Key);
736
737 /// End marker.
738 ValueIterator() = default;
739
740 const Entry &operator*() const { return *CurrentEntry; }
742 next();
743 return *this;
744 }
746 ValueIterator I = *this;
747 next();
748 return I;
749 }
750
751 friend bool operator==(const ValueIterator &A, const ValueIterator &B) {
752 return A.CurrentIndex == B.CurrentIndex && A.DataOffset == B.DataOffset;
753 }
754 friend bool operator!=(const ValueIterator &A, const ValueIterator &B) {
755 return !(A == B);
756 }
757 };
758
760
761 /// The Name Index we are iterating through.
762 const NameIndex *CurrentIndex;
763
764 /// The current name in the Name Index.
765 uint32_t CurrentName;
766
767 void next() {
768 assert(CurrentName <= CurrentIndex->getNameCount());
769 ++CurrentName;
770 }
771
772 public:
773 using iterator_category = std::input_iterator_tag;
777 using reference = NameTableEntry; // We return entries by value.
778
779 /// Creates an iterator whose initial position is name CurrentName in
780 /// CurrentIndex.
781 NameIterator(const NameIndex *CurrentIndex, uint32_t CurrentName)
782 : CurrentIndex(CurrentIndex), CurrentName(CurrentName) {}
783
785 return CurrentIndex->getNameTableEntry(CurrentName);
786 }
788 next();
789 return *this;
790 }
792 NameIterator I = *this;
793 next();
794 return I;
795 }
796
797 friend bool operator==(const NameIterator &A, const NameIterator &B) {
798 return A.CurrentIndex == B.CurrentIndex && A.CurrentName == B.CurrentName;
799 }
800 friend bool operator!=(const NameIterator &A, const NameIterator &B) {
801 return !(A == B);
802 }
803 };
804
805private:
806 SmallVector<NameIndex, 0> NameIndices;
807 DenseMap<uint64_t, const NameIndex *> UnitOffsetToNameIndex;
808
809public:
813
814 Error extract() override;
815 void dump(raw_ostream &OS) const override;
816
817 /// Look up all entries in the accelerator table matching \c Key.
819
821 const_iterator begin() const { return NameIndices.begin(); }
822 const_iterator end() const { return NameIndices.end(); }
823
824 /// Return the Name Index covering the compile unit or local type unit at
825 /// UnitOffset, or nullptr if there is no Name Index covering that unit.
826 const NameIndex *getCUOrTUNameIndex(uint64_t UnitOffset);
827};
828
829/// Calculates the starting offsets for various sections within the
830/// .debug_names section.
831namespace dwarf {
832DWARFDebugNames::DWARFDebugNamesOffsets
833findDebugNamesOffsets(uint64_t EndOfHeaderOffset,
834 const DWARFDebugNames::Header &Hdr);
835}
836
837/// If `Name` is the name of a templated function that includes template
838/// parameters, returns a substring of `Name` containing no template
839/// parameters.
840/// E.g.: StripTemplateParameters("foo<int>") = "foo".
841std::optional<StringRef> StripTemplateParameters(StringRef Name);
842
844 /// For "-[A(Category) method:]", this would be "method:"
846 /// For "-[A(Category) method:]", this would be "A(category)"
848 /// For "-[A(Category) method:]", this would be "A"
849 std::optional<StringRef> ClassNameNoCategory;
850 /// For "-[A(Category) method:]", this would be "A method:"
851 std::optional<std::string> MethodNameNoCategory;
852};
853
854/// If `Name` is the AT_name of a DIE which refers to an Objective-C selector,
855/// returns an instance of ObjCSelectorNames. The Selector and ClassName fields
856/// are guaranteed to be non-empty in the result.
857std::optional<ObjCSelectorNames> getObjCNamesIfSelector(StringRef Name);
858
859} // end namespace llvm
860
861#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
uint32_t Index
#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 > getForeignTUTypeSignature() const
Returns the type signature of the Type Unit associated with this Accelerator Entry or std::nullopt if...
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 > getForeignTUTypeSignature() const override
Returns the type signature of the Type Unit associated with this Accelerator Entry or std::nullopt if...
std::optional< uint64_t > getRelatedCUIndex() const
Similar functionality to getCUIndex() but without the DW_IDX_type_unit restriction.
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...
std::optional< uint64_t > getRelatedCUOffset() const
const Abbrev & getAbbrev() const
Return the Abbreviation that can be used to interpret the raw values of this Accelerator Entry.
const NameIndex * getNameIndex() const
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< uint64_t > getTUIndex() const
Returns the index of the Type Unit of the owning Name Index or std::nullopt if this Accelerator Entry...
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.
DWARFDebugNamesOffsets getOffsets() const
Returns Offsets field.
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_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.
const NameIndex * getCUOrTUNameIndex(uint64_t UnitOffset)
Return the Name Index covering the compile unit or local type unit at UnitOffset, or nullptr if there...
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:278
Base class for user error types.
Definition: Error.h:355
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:481
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:573
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1196
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:51
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition: StringRef.h:571
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:1110
DWARFDebugNames::DWARFDebugNamesOffsets findDebugNamesOffsets(uint64_t EndOfHeaderOffset, const DWARFDebugNames::Header &Hdr)
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:480
bool isEqual(const GCNRPTracker::LiveRegSet &S1, const GCNRPTracker::LiveRegSet &S2)
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:1439
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:1873
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:1903
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:52
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:1084