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;
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 into the Local Type Unit list of the owning Name
472 /// Index or std::nullopt if this Accelerator Entry does not have an
473 /// associated Type Unit. It is up to the user to verify that the
474 /// returned Index is valid in the owning NameIndex (or use
475 /// getLocalTUOffset(), which will handle that check itself).
476 std::optional<uint64_t> getLocalTUIndex() const;
477
478 /// .debug_names-specific getter, which always succeeds (DWARF v5 index
479 /// entries always have a tag).
480 dwarf::Tag tag() const { return Abbr->Tag; }
481
482 /// Returns the Offset of the DIE within the containing CU or TU.
483 std::optional<uint64_t> getDIEUnitOffset() const;
484
485 /// Returns true if this Entry has information about its parent DIE (i.e. if
486 /// it has an IDX_parent attribute)
487 bool hasParentInformation() const;
488
489 /// Returns the Entry corresponding to the parent of the DIE represented by
490 /// `this` Entry. If the parent is not in the table, nullopt is returned.
491 /// Precondition: hasParentInformation() == true.
492 /// An error is returned for ill-formed tables.
494
495 /// Return the Abbreviation that can be used to interpret the raw values of
496 /// this Accelerator Entry.
497 const Abbrev &getAbbrev() const { return *Abbr; }
498
499 /// Returns the value of the Index Attribute in this Accelerator Entry, if
500 /// the Entry contains such Attribute.
501 std::optional<DWARFFormValue> lookup(dwarf::Index Index) const;
502
503 void dump(ScopedPrinter &W) const;
504 void dumpParentIdx(ScopedPrinter &W, const DWARFFormValue &FormValue) const;
505
506 friend class NameIndex;
507 friend class ValueIterator;
508 };
509
510 /// Error returned by NameIndex::getEntry to report it has reached the end of
511 /// the entry list.
512 class SentinelError : public ErrorInfo<SentinelError> {
513 public:
514 static char ID;
515
516 void log(raw_ostream &OS) const override { OS << "Sentinel"; }
517 std::error_code convertToErrorCode() const override;
518 };
519
520private:
521 /// DenseMapInfo for struct Abbrev.
522 struct AbbrevMapInfo {
523 static Abbrev getEmptyKey();
524 static Abbrev getTombstoneKey();
525 static unsigned getHashValue(uint32_t Code) {
527 }
528 static unsigned getHashValue(const Abbrev &Abbr) {
529 return getHashValue(Abbr.Code);
530 }
531 static bool isEqual(uint32_t LHS, const Abbrev &RHS) {
532 return LHS == RHS.Code;
533 }
534 static bool isEqual(const Abbrev &LHS, const Abbrev &RHS) {
535 return LHS.Code == RHS.Code;
536 }
537 };
538
539public:
540 /// A single entry in the Name Table (DWARF v5 sect. 6.1.1.4.6) of the Name
541 /// Index.
543 DataExtractor StrData;
544
546 uint64_t StringOffset;
547 uint64_t EntryOffset;
548
549 public:
551 uint64_t StringOffset, uint64_t EntryOffset)
552 : StrData(StrData), Index(Index), StringOffset(StringOffset),
553 EntryOffset(EntryOffset) {}
554
555 /// Return the index of this name in the parent Name Index.
556 uint32_t getIndex() const { return Index; }
557
558 /// Returns the offset of the name of the described entities.
559 uint64_t getStringOffset() const { return StringOffset; }
560
561 /// Return the string referenced by this name table entry or nullptr if the
562 /// string offset is not valid.
563 const char *getString() const {
564 uint64_t Off = StringOffset;
565 return StrData.getCStr(&Off);
566 }
567
568 /// Compares the name of this entry against Target, returning true if they
569 /// are equal. This is more efficient in hot code paths that do not need the
570 /// length of the name.
572 // Note: this is not the name, but the rest of debug_str starting from
573 // name. This handles corrupt data (non-null terminated) without
574 // overrunning the buffer.
575 StringRef Data = StrData.getData().substr(StringOffset);
576 size_t TargetSize = Target.size();
577 return Data.size() > TargetSize && !Data[TargetSize] &&
578 strncmp(Data.data(), Target.data(), TargetSize) == 0;
579 }
580
581 /// Returns the offset of the first Entry in the list.
582 uint64_t getEntryOffset() const { return EntryOffset; }
583 };
584
585 /// Offsets for the start of various important tables from the start of the
586 /// section.
594 };
595
596 /// Represents a single accelerator table within the DWARF v5 .debug_names
597 /// section.
598 class NameIndex {
600 struct Header Hdr;
601 const DWARFDebugNames &Section;
602
603 // Base of the whole unit and of various important tables, as offsets from
604 // the start of the section.
605 uint64_t Base;
607
608 void dumpCUs(ScopedPrinter &W) const;
609 void dumpLocalTUs(ScopedPrinter &W) const;
610 void dumpForeignTUs(ScopedPrinter &W) const;
611 void dumpAbbreviations(ScopedPrinter &W) const;
612 bool dumpEntry(ScopedPrinter &W, uint64_t *Offset) const;
613 void dumpName(ScopedPrinter &W, const NameTableEntry &NTE,
614 std::optional<uint32_t> Hash) const;
615 void dumpBucket(ScopedPrinter &W, uint32_t Bucket) const;
616
617 Expected<AttributeEncoding> extractAttributeEncoding(uint64_t *Offset);
618
620 extractAttributeEncodings(uint64_t *Offset);
621
622 Expected<Abbrev> extractAbbrev(uint64_t *Offset);
623
624 public:
625 NameIndex(const DWARFDebugNames &Section, uint64_t Base)
626 : Section(Section), Base(Base) {}
627
628 /// Returns Hdr field
629 Header getHeader() const { return Hdr; }
630
631 /// Returns Offsets field
632 DWARFDebugNamesOffsets getOffsets() const { return Offsets; }
633
634 /// Reads offset of compilation unit CU. CU is 0-based.
636 uint32_t getCUCount() const { return Hdr.CompUnitCount; }
637
638 /// Reads offset of local type unit TU, TU is 0-based.
640 uint32_t getLocalTUCount() const { return Hdr.LocalTypeUnitCount; }
641
642 /// Reads signature of foreign type unit TU. TU is 0-based.
644 uint32_t getForeignTUCount() const { return Hdr.ForeignTypeUnitCount; }
645
646 /// Reads an entry in the Bucket Array for the given Bucket. The returned
647 /// value is a (1-based) index into the Names, StringOffsets and
648 /// EntryOffsets arrays. The input Bucket index is 0-based.
650 uint32_t getBucketCount() const { return Hdr.BucketCount; }
651
652 /// Reads an entry in the Hash Array for the given Index. The input Index
653 /// is 1-based.
655
656 /// Reads an entry in the Name Table for the given Index. The Name Table
657 /// consists of two arrays -- String Offsets and Entry Offsets. The returned
658 /// offsets are relative to the starts of respective sections. Input Index
659 /// is 1-based.
661
662 uint32_t getNameCount() const { return Hdr.NameCount; }
663
665 return Abbrevs;
666 }
667
669
670 /// Returns the Entry at the relative `Offset` from the start of the Entry
671 /// pool.
673 auto OffsetFromSection = Offset + this->Offsets.EntriesBase;
674 return getEntry(&OffsetFromSection);
675 }
676
677 /// Look up all entries in this Name Index matching \c Key.
679
680 NameIterator begin() const { return NameIterator(this, 1); }
681 NameIterator end() const { return NameIterator(this, getNameCount() + 1); }
682
683 Error extract();
684 uint64_t getUnitOffset() const { return Base; }
686 return Base + dwarf::getUnitLengthFieldByteSize(Hdr.Format) +
687 Hdr.UnitLength;
688 }
689 void dump(ScopedPrinter &W) const;
690
691 friend class DWARFDebugNames;
692 };
693
695 public:
696 using iterator_category = std::input_iterator_tag;
698 using difference_type = std::ptrdiff_t;
701
702 private:
703 /// The Name Index we are currently iterating through. The implementation
704 /// relies on the fact that this can also be used as an iterator into the
705 /// "NameIndices" vector in the Accelerator section.
706 const NameIndex *CurrentIndex = nullptr;
707
708 /// Whether this is a local iterator (searches in CurrentIndex only) or not
709 /// (searches all name indices).
710 bool IsLocal;
711
712 std::optional<Entry> CurrentEntry;
713 uint64_t DataOffset = 0; ///< Offset into the section.
714 std::string Key; ///< The Key we are searching for.
715 std::optional<uint32_t> Hash; ///< Hash of Key, if it has been computed.
716
717 bool getEntryAtCurrentOffset();
718 std::optional<uint64_t> findEntryOffsetInCurrentIndex();
719 bool findInCurrentIndex();
720 void searchFromStartOfCurrentIndex();
721 void next();
722
723 /// Set the iterator to the "end" state.
724 void setEnd() { *this = ValueIterator(); }
725
726 public:
727 /// Create a "begin" iterator for looping over all entries in the
728 /// accelerator table matching Key. The iterator will run through all Name
729 /// Indexes in the section in sequence.
731
732 /// Create a "begin" iterator for looping over all entries in a specific
733 /// Name Index. Other indices in the section will not be visited.
734 ValueIterator(const NameIndex &NI, StringRef Key);
735
736 /// End marker.
737 ValueIterator() = default;
738
739 const Entry &operator*() const { return *CurrentEntry; }
741 next();
742 return *this;
743 }
745 ValueIterator I = *this;
746 next();
747 return I;
748 }
749
750 friend bool operator==(const ValueIterator &A, const ValueIterator &B) {
751 return A.CurrentIndex == B.CurrentIndex && A.DataOffset == B.DataOffset;
752 }
753 friend bool operator!=(const ValueIterator &A, const ValueIterator &B) {
754 return !(A == B);
755 }
756 };
757
759
760 /// The Name Index we are iterating through.
761 const NameIndex *CurrentIndex;
762
763 /// The current name in the Name Index.
764 uint32_t CurrentName;
765
766 void next() {
767 assert(CurrentName <= CurrentIndex->getNameCount());
768 ++CurrentName;
769 }
770
771 public:
772 using iterator_category = std::input_iterator_tag;
776 using reference = NameTableEntry; // We return entries by value.
777
778 /// Creates an iterator whose initial position is name CurrentName in
779 /// CurrentIndex.
780 NameIterator(const NameIndex *CurrentIndex, uint32_t CurrentName)
781 : CurrentIndex(CurrentIndex), CurrentName(CurrentName) {}
782
784 return CurrentIndex->getNameTableEntry(CurrentName);
785 }
787 next();
788 return *this;
789 }
791 NameIterator I = *this;
792 next();
793 return I;
794 }
795
796 friend bool operator==(const NameIterator &A, const NameIterator &B) {
797 return A.CurrentIndex == B.CurrentIndex && A.CurrentName == B.CurrentName;
798 }
799 friend bool operator!=(const NameIterator &A, const NameIterator &B) {
800 return !(A == B);
801 }
802 };
803
804private:
805 SmallVector<NameIndex, 0> NameIndices;
807
808public:
812
813 Error extract() override;
814 void dump(raw_ostream &OS) const override;
815
816 /// Look up all entries in the accelerator table matching \c Key.
818
820 const_iterator begin() const { return NameIndices.begin(); }
821 const_iterator end() const { return NameIndices.end(); }
822
823 /// Return the Name Index covering the compile unit at CUOffset, or nullptr if
824 /// there is no Name Index covering that unit.
825 const NameIndex *getCUNameIndex(uint64_t CUOffset);
826};
827
828/// Calculates the starting offsets for various sections within the
829/// .debug_names section.
830namespace dwarf {
831DWARFDebugNames::DWARFDebugNamesOffsets
832findDebugNamesOffsets(uint64_t EndOfHeaderOffset,
833 const DWARFDebugNames::Header &Hdr);
834}
835
836/// If `Name` is the name of a templated function that includes template
837/// parameters, returns a substring of `Name` containing no template
838/// parameters.
839/// E.g.: StripTemplateParameters("foo<int>") = "foo".
840std::optional<StringRef> StripTemplateParameters(StringRef Name);
841
843 /// For "-[A(Category) method:]", this would be "method:"
845 /// For "-[A(Category) method:]", this would be "A(category)"
847 /// For "-[A(Category) method:]", this would be "A"
848 std::optional<StringRef> ClassNameNoCategory;
849 /// For "-[A(Category) method:]", this would be "A method:"
850 std::optional<std::string> MethodNameNoCategory;
851};
852
853/// If `Name` is the AT_name of a DIE which refers to an Objective-C selector,
854/// returns an instance of ObjCSelectorNames. The Selector and ClassName fields
855/// are guaranteed to be non-empty in the result.
856std::optional<ObjCSelectorNames> getObjCNamesIfSelector(StringRef Name);
857
858} // end namespace llvm
859
860#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
const MachineOperand & RHS
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
This file defines the SmallString class.
This file defines the SmallVector class.
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 > 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 > 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< 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 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: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: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: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:568
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:1103
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:1422
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:1856
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:1886
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:1077