LLVM 22.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"
19#include <cstdint>
20#include <utility>
21
22namespace llvm {
23
24class raw_ostream;
25class ScopedPrinter;
26
27/// The accelerator tables are designed to allow efficient random access
28/// (using a symbol name as a key) into debug info by providing an index of the
29/// debug info DIEs. This class implements the common functionality of Apple and
30/// DWARF 5 accelerator tables.
31/// TODO: Generalize the rest of the AppleAcceleratorTable interface and move it
32/// to this class.
34protected:
37
38public:
39 /// An abstract class representing a single entry in the accelerator tables.
40 class Entry {
41 protected:
43
44 Entry() = default;
45
46 // Make these protected so only (final) subclasses can be copied around.
47 Entry(const Entry &) = default;
48 Entry(Entry &&) = default;
49 Entry &operator=(const Entry &) = default;
50 Entry &operator=(Entry &&) = default;
51 ~Entry() = default;
52
53
54 public:
55 /// Returns the Offset of the Compilation Unit associated with this
56 /// Accelerator Entry or std::nullopt if the Compilation Unit offset is not
57 /// recorded in this Accelerator Entry.
58 virtual std::optional<uint64_t> getCUOffset() const = 0;
59
60 /// Returns the Offset of the Type Unit associated with this
61 /// Accelerator Entry or std::nullopt if the Type Unit offset is not
62 /// recorded in this Accelerator Entry.
63 virtual std::optional<uint64_t> getLocalTUOffset() const {
64 // Default return for accelerator tables that don't support type units.
65 return std::nullopt;
66 }
67
68 /// Returns the type signature of the Type Unit associated with this
69 /// Accelerator Entry or std::nullopt if the Type Unit offset is not
70 /// recorded in this Accelerator Entry.
71 virtual std::optional<uint64_t> getForeignTUTypeSignature() const {
72 // Default return for accelerator tables that don't support type units.
73 return std::nullopt;
74 }
75
76 /// Returns the Tag of the Debug Info Entry associated with this
77 /// Accelerator Entry or std::nullopt if the Tag is not recorded in this
78 /// Accelerator Entry.
79 virtual std::optional<dwarf::Tag> getTag() const = 0;
80
81 /// Returns the raw values of fields in the Accelerator Entry. In general,
82 /// these can only be interpreted with the help of the metadata in the
83 /// owning Accelerator Table.
85 };
86
91
92 virtual Error extract() = 0;
93 virtual void dump(raw_ostream &OS) const = 0;
94
96 void operator=(const DWARFAcceleratorTable &) = delete;
97};
98
99/// This implements the Apple accelerator table format, a precursor of the
100/// DWARF 5 accelerator table format.
102 struct Header {
103 uint32_t Magic;
105 uint16_t HashFunction;
106 uint32_t BucketCount;
107 uint32_t HashCount;
108 uint32_t HeaderDataLength;
109
110 LLVM_ABI void dump(ScopedPrinter &W) const;
111 };
112
113 struct HeaderData {
114 using AtomType = uint16_t;
115 using Form = dwarf::Form;
116
117 uint64_t DIEOffsetBase;
119
120 LLVM_ABI std::optional<uint64_t>
121 extractOffset(std::optional<DWARFFormValue> Value) const;
122 };
123
124 Header Hdr;
125 HeaderData HdrData;
126 dwarf::FormParams FormParams;
127 uint32_t HashDataEntryLength;
128 bool IsValid = false;
129
130 /// Returns true if we should continue scanning for entries or false if we've
131 /// reached the last (sentinel) entry of encountered a parsing error.
132 bool dumpName(ScopedPrinter &W, SmallVectorImpl<DWARFFormValue> &AtomForms,
133 uint64_t *DataOffset) const;
134
135 /// Reads an uint32_t from the accelerator table at Offset, which is
136 /// incremented by the number of bytes read.
137 std::optional<uint32_t> readU32FromAccel(uint64_t &Offset,
138 bool UseRelocation = false) const;
139
140 /// Reads a StringRef from the string table at Offset.
141 std::optional<StringRef>
142 readStringFromStrSection(uint64_t StringSectionOffset) const;
143
144 /// Return the offset into the section where the Buckets begin.
145 uint64_t getBucketBase() const { return sizeof(Hdr) + Hdr.HeaderDataLength; }
146
147 /// Return the offset into the section where the I-th bucket is.
148 uint64_t getIthBucketBase(uint32_t I) const {
149 return getBucketBase() + I * 4;
150 }
151
152 /// Return the offset into the section where the hash list begins.
153 uint64_t getHashBase() const { return getBucketBase() + getNumBuckets() * 4; }
154
155 /// Return the offset into the section where the I-th hash is.
156 std::optional<uint64_t> getIthHashBase(uint32_t I) const {
157 if (I < Hdr.HashCount)
158 return getHashBase() + I * 4;
159 return std::nullopt;
160 }
161
162 /// Return the offset into the section where the offset list begins.
163 uint64_t getOffsetBase() const { return getHashBase() + getNumHashes() * 4; }
164
165 /// Return the offset into the section where the table entries begin.
166 uint64_t getEntriesBase() const {
167 return getOffsetBase() + getNumHashes() * 4;
168 }
169
170 /// Return the offset into the section where the I-th offset is.
171 std::optional<uint64_t> getIthOffsetBase(uint32_t I) const {
172 if (I < Hdr.HashCount)
173 return getOffsetBase() + I * 4;
174 return std::nullopt;
175 }
176
177 /// Returns the index of the bucket where a hypothetical Hash would be.
178 uint32_t hashToBucketIdx(uint32_t Hash) const {
179 return Hash % getNumBuckets();
180 }
181
182 /// Returns true iff a hypothetical Hash would be assigned to the BucketIdx-th
183 /// bucket.
184 bool wouldHashBeInBucket(uint32_t Hash, uint32_t BucketIdx) const {
185 return hashToBucketIdx(Hash) == BucketIdx;
186 }
187
188 /// Reads the contents of the I-th bucket, that is, the index in the hash list
189 /// where the hashes corresponding to this bucket begin.
190 std::optional<uint32_t> readIthBucket(uint32_t I) const {
191 uint64_t Offset = getIthBucketBase(I);
192 return readU32FromAccel(Offset);
193 }
194
195 /// Reads the I-th hash in the hash list.
196 std::optional<uint32_t> readIthHash(uint32_t I) const {
197 std::optional<uint64_t> OptOffset = getIthHashBase(I);
198 if (OptOffset)
199 return readU32FromAccel(*OptOffset);
200 return std::nullopt;
201 }
202
203 /// Reads the I-th offset in the offset list.
204 std::optional<uint32_t> readIthOffset(uint32_t I) const {
205 std::optional<uint64_t> OptOffset = getIthOffsetBase(I);
206 if (OptOffset)
207 return readU32FromAccel(*OptOffset);
208 return std::nullopt;
209 }
210
211 /// Reads a string offset from the accelerator table at Offset, which is
212 /// incremented by the number of bytes read.
213 std::optional<uint32_t> readStringOffsetAt(uint64_t &Offset) const {
214 return readU32FromAccel(Offset, /*UseRelocation*/ true);
215 }
216
217 /// Scans through all Hashes in the BucketIdx-th bucket, attempting to find
218 /// HashToFind. If it is found, its index in the list of hashes is returned.
219 std::optional<uint32_t> idxOfHashInBucket(uint32_t HashToFind,
220 uint32_t BucketIdx) const;
221
222public:
223 /// Apple-specific implementation of an Accelerator Entry.
224 class LLVM_ABI Entry final : public DWARFAcceleratorTable::Entry {
225 const AppleAcceleratorTable &Table;
226
227 Entry(const AppleAcceleratorTable &Table);
228 void extract(uint64_t *Offset);
229
230 public:
231 std::optional<uint64_t> getCUOffset() const override;
232
233 /// Returns the Section Offset of the Debug Info Entry associated with this
234 /// Accelerator Entry or std::nullopt if the DIE offset is not recorded in
235 /// this Accelerator Entry. The returned offset is relative to the start of
236 /// the Section containing the DIE.
237 std::optional<uint64_t> getDIESectionOffset() const;
238
239 std::optional<dwarf::Tag> getTag() const override;
240
241 /// Returns the value of the Atom in this Accelerator Entry, if the Entry
242 /// contains such Atom.
243 std::optional<DWARFFormValue> lookup(HeaderData::AtomType Atom) const;
244
246 friend class ValueIterator;
247 };
248
249 /// An iterator for Entries all having the same string as key.
251 : public iterator_facade_base<SameNameIterator, std::forward_iterator_tag,
252 Entry> {
253 Entry Current;
254 uint64_t Offset = 0;
255
256 public:
257 /// Construct a new iterator for the entries at \p DataOffset.
259 uint64_t DataOffset);
260
261 const Entry &operator*() {
262 uint64_t OffsetCopy = Offset;
263 Current.extract(&OffsetCopy);
264 return Current;
265 }
267 Offset += Current.Table.getHashDataEntryLength();
268 return *this;
269 }
270 friend bool operator==(const SameNameIterator &A,
271 const SameNameIterator &B) {
272 return A.Offset == B.Offset;
273 }
274 };
275
278 : BaseEntry(Table), StrOffset(0) {}
279
280 std::optional<StringRef> readName() const {
281 return BaseEntry.Table.readStringFromStrSection(StrOffset);
282 }
283
286 };
287
288 /// An iterator for all entries in the table.
290 : public iterator_facade_base<Iterator, std::forward_iterator_tag,
291 EntryWithName> {
292 constexpr static auto EndMarker = std::numeric_limits<uint64_t>::max();
293
294 EntryWithName Current;
295 uint32_t OffsetIdx = 0;
296 uint64_t Offset = EndMarker;
297 uint32_t NumEntriesToCome = 0;
298
299 void setToEnd() { Offset = EndMarker; }
300 bool isEnd() const { return Offset == EndMarker; }
301 const AppleAcceleratorTable &getTable() const {
302 return Current.BaseEntry.Table;
303 }
304
305 /// Reads the next Entry in the table, populating `Current`.
306 /// If not possible (e.g. end of the section), becomes the end iterator.
307 LLVM_ABI void prepareNextEntryOrEnd();
308
309 /// Reads the next string pointer and the entry count for that string,
310 /// populating `NumEntriesToCome`.
311 /// If not possible (e.g. end of the section), becomes the end iterator.
312 /// If `Offset` is zero, then the next valid string offset will be fetched
313 /// from the Offsets array, otherwise it will continue to parse the current
314 /// entry's strings.
315 void prepareNextStringOrEnd();
316
317 public:
318 LLVM_ABI Iterator(const AppleAcceleratorTable &Table, bool SetEnd = false);
319
321 prepareNextEntryOrEnd();
322 return *this;
323 }
324 bool operator==(const Iterator &It) const { return Offset == It.Offset; }
325 const EntryWithName &operator*() const {
326 assert(!isEnd() && "dereferencing end iterator");
327 return Current;
328 }
329 };
330
334
335 Error extract() override;
336 uint32_t getNumBuckets() const;
337 uint32_t getNumHashes() const;
338 uint32_t getSizeHdr() const;
339 uint32_t getHeaderDataLength() const;
340
341 /// Returns the size of one HashData entry.
342 uint32_t getHashDataEntryLength() const { return HashDataEntryLength; }
343
344 /// Return the Atom description, which can be used to interpret the raw values
345 /// of the Accelerator Entries in this table.
347
348 /// Returns true iff `AtomTy` is one of the atoms available in Entries of this
349 /// table.
350 bool containsAtomType(HeaderData::AtomType AtomTy) const {
351 return is_contained(make_first_range(HdrData.Atoms), AtomTy);
352 }
353
354 bool validateForms();
355
356 /// Return information related to the DWARF DIE we're looking for when
357 /// performing a lookup by name.
358 ///
359 /// \param HashDataOffset an offset into the hash data table
360 /// \returns <DieOffset, DieTag>
361 /// DieOffset is the offset into the .debug_info section for the DIE
362 /// related to the input hash data offset.
363 /// DieTag is the tag of the DIE
364 std::pair<uint64_t, dwarf::Tag> readAtoms(uint64_t *HashDataOffset);
365 void dump(raw_ostream &OS) const override;
366
367 /// Look up all entries in the accelerator table matching \c Key.
369
370 /// Lookup all entries in the accelerator table.
371 auto entries() const {
372 return make_range(Iterator(*this), Iterator(*this, /*SetEnd*/ true));
373 }
374};
375
376/// .debug_names section consists of one or more units. Each unit starts with a
377/// header, which is followed by a list of compilation units, local and foreign
378/// type units.
379///
380/// These may be followed by an (optional) hash lookup table, which consists of
381/// an array of buckets and hashes similar to the apple tables above. The only
382/// difference is that the hashes array is 1-based, and consequently an empty
383/// bucket is denoted by 0 and not UINT32_MAX.
384///
385/// Next is the name table, which consists of an array of names and array of
386/// entry offsets. This is different from the apple tables, which store names
387/// next to the actual entries.
388///
389/// The structure of the entries is described by an abbreviations table, which
390/// comes after the name table. Unlike the apple tables, which have a uniform
391/// entry structure described in the header, each .debug_names entry may have
392/// different index attributes (DW_IDX_???) attached to it.
393///
394/// The last segment consists of a list of entries, which is a 0-terminated list
395/// referenced by the name table and interpreted with the help of the
396/// abbreviation table.
398public:
399 class NameIndex;
400 class NameIterator;
401 class ValueIterator;
402
403 /// DWARF v5 Name Index header.
420
421 /// Index attribute and its encoding.
425
428
429 friend bool operator==(const AttributeEncoding &LHS,
430 const AttributeEncoding &RHS) {
431 return LHS.Index == RHS.Index && LHS.Form == RHS.Form;
432 }
433 };
434
435 /// Abbreviation describing the encoding of Name Index entries.
436 struct Abbrev {
437 uint64_t AbbrevOffset; /// < Abbreviation offset in the .debug_names section
438 uint32_t Code; ///< Abbreviation code
439 dwarf::Tag Tag; ///< Dwarf Tag of the described entity.
440 std::vector<AttributeEncoding> Attributes; ///< List of index attributes.
441
446
447 LLVM_ABI void dump(ScopedPrinter &W) const;
448 };
449
450 /// DWARF v5-specific implementation of an Accelerator Entry.
451 class LLVM_ABI Entry final : public DWARFAcceleratorTable::Entry {
452 const NameIndex *NameIdx;
453 const Abbrev *Abbr;
454
455 Entry(const NameIndex &NameIdx, const Abbrev &Abbr);
456
457 public:
458 const NameIndex *getNameIndex() const { return NameIdx; }
459 std::optional<uint64_t> getCUOffset() const override;
460 std::optional<uint64_t> getLocalTUOffset() const override;
461 std::optional<uint64_t> getForeignTUTypeSignature() const override;
462 std::optional<dwarf::Tag> getTag() const override { return tag(); }
463
464 // Special function that will return the related CU offset needed type
465 // units. This gets used to find the .dwo file that originated the entries
466 // for a given type unit.
467 std::optional<uint64_t> getRelatedCUOffset() const;
468
469 /// Returns the Index into the Compilation Unit list of the owning Name
470 /// Index or std::nullopt if this Accelerator Entry does not have an
471 /// associated Compilation Unit. It is up to the user to verify that the
472 /// returned Index is valid in the owning NameIndex (or use getCUOffset(),
473 /// which will handle that check itself). Note that entries in NameIndexes
474 /// which index just a single Compilation Unit are implicitly associated
475 /// with that unit, so this function will return 0 even without an explicit
476 /// DW_IDX_compile_unit attribute, unless there is a DW_IDX_type_unit
477 /// attribute.
478 std::optional<uint64_t> getCUIndex() const;
479
480 /// Similar functionality to getCUIndex() but without the DW_IDX_type_unit
481 /// restriction. This allows us to get the associated a compilation unit
482 /// index for an entry that is a type unit.
483 std::optional<uint64_t> getRelatedCUIndex() const;
484
485 /// Returns the index of the Type Unit of the owning
486 /// Name
487 /// Index or std::nullopt if this Accelerator Entry does not have an
488 /// associated Type Unit. It is up to the user to verify that the
489 /// returned Index is a valid index in the owning NameIndex (or use
490 /// getLocalTUOffset(), which will handle that check itself).
491 std::optional<uint64_t> getTUIndex() const;
492
493 /// .debug_names-specific getter, which always succeeds (DWARF v5 index
494 /// entries always have a tag).
495 dwarf::Tag tag() const { return Abbr->Tag; }
496
497 /// Returns the Offset of the DIE within the containing CU or TU.
498 std::optional<uint64_t> getDIEUnitOffset() const;
499
500 /// Returns true if this Entry has information about its parent DIE (i.e. if
501 /// it has an IDX_parent attribute)
502 bool hasParentInformation() const;
503
504 /// Returns the Entry corresponding to the parent of the DIE represented by
505 /// `this` Entry. If the parent is not in the table, nullopt is returned.
506 /// Precondition: hasParentInformation() == true.
507 /// An error is returned for ill-formed tables.
508 Expected<std::optional<DWARFDebugNames::Entry>> getParentDIEEntry() const;
509
510 /// Return the Abbreviation that can be used to interpret the raw values of
511 /// this Accelerator Entry.
512 const Abbrev &getAbbrev() const { return *Abbr; }
513
514 /// Returns the value of the Index Attribute in this Accelerator Entry, if
515 /// the Entry contains such Attribute.
516 std::optional<DWARFFormValue> lookup(dwarf::Index Index) const;
517
518 void dump(ScopedPrinter &W) const;
519 void dumpParentIdx(ScopedPrinter &W, const DWARFFormValue &FormValue) const;
520
521 friend class NameIndex;
522 friend class ValueIterator;
523 };
524
525 /// Error returned by NameIndex::getEntry to report it has reached the end of
526 /// the entry list.
527 class LLVM_ABI SentinelError : public ErrorInfo<SentinelError> {
528 public:
529 static char ID;
530
531 void log(raw_ostream &OS) const override { OS << "Sentinel"; }
532 std::error_code convertToErrorCode() const override;
533 };
534
535private:
536 /// DenseMapInfo for struct Abbrev.
537 struct AbbrevMapInfo {
538 LLVM_ABI static Abbrev getEmptyKey();
539 LLVM_ABI static Abbrev getTombstoneKey();
540 static unsigned getHashValue(uint32_t Code) {
542 }
543 static unsigned getHashValue(const Abbrev &Abbr) {
544 return getHashValue(Abbr.Code);
545 }
546 static bool isEqual(uint32_t LHS, const Abbrev &RHS) {
547 return LHS == RHS.Code;
548 }
549 static bool isEqual(const Abbrev &LHS, const Abbrev &RHS) {
550 return LHS.Code == RHS.Code;
551 }
552 };
553
554public:
555 /// A single entry in the Name Table (DWARF v5 sect. 6.1.1.4.6) of the Name
556 /// Index.
558 DataExtractor StrData;
559
560 uint32_t Index;
561 uint64_t StringOffset;
562 uint64_t EntryOffset;
563
564 public:
565 NameTableEntry(const DataExtractor &StrData, uint32_t Index,
566 uint64_t StringOffset, uint64_t EntryOffset)
567 : StrData(StrData), Index(Index), StringOffset(StringOffset),
568 EntryOffset(EntryOffset) {}
569
570 /// Return the index of this name in the parent Name Index.
571 uint32_t getIndex() const { return Index; }
572
573 /// Returns the offset of the name of the described entities.
574 uint64_t getStringOffset() const { return StringOffset; }
575
576 /// Return the string referenced by this name table entry or nullptr if the
577 /// string offset is not valid.
578 const char *getString() const {
579 uint64_t Off = StringOffset;
580 return StrData.getCStr(&Off);
581 }
582
583 /// Compares the name of this entry against Target, returning true if they
584 /// are equal. This is more efficient in hot code paths that do not need the
585 /// length of the name.
587 // Note: this is not the name, but the rest of debug_str starting from
588 // name. This handles corrupt data (non-null terminated) without
589 // overrunning the buffer.
590 StringRef Data = StrData.getData().substr(StringOffset);
591 size_t TargetSize = Target.size();
592 return Data.size() > TargetSize && !Data[TargetSize] &&
593 strncmp(Data.data(), Target.data(), TargetSize) == 0;
594 }
595
596 /// Returns the offset of the first Entry in the list.
597 uint64_t getEntryOffset() const { return EntryOffset; }
598 };
599
600 /// Offsets for the start of various important tables from the start of the
601 /// section.
610
611 /// Represents a single accelerator table within the DWARF v5 .debug_names
612 /// section.
613 class NameIndex {
615 struct Header Hdr;
616 const DWARFDebugNames &Section;
617
618 // Base of the whole unit and of various important tables, as offsets from
619 // the start of the section.
620 uint64_t Base;
622
623 void dumpCUs(ScopedPrinter &W) const;
624 void dumpLocalTUs(ScopedPrinter &W) const;
625 void dumpForeignTUs(ScopedPrinter &W) const;
626 void dumpAbbreviations(ScopedPrinter &W) const;
627 bool dumpEntry(ScopedPrinter &W, uint64_t *Offset) const;
628 void dumpName(ScopedPrinter &W, const NameTableEntry &NTE,
629 std::optional<uint32_t> Hash) const;
630 void dumpBucket(ScopedPrinter &W, uint32_t Bucket) const;
631
632 Expected<AttributeEncoding> extractAttributeEncoding(uint64_t *Offset);
633
635 extractAttributeEncodings(uint64_t *Offset);
636
637 Expected<Abbrev> extractAbbrev(uint64_t *Offset);
638
639 public:
640 NameIndex(const DWARFDebugNames &Section, uint64_t Base)
641 : Section(Section), Base(Base) {}
642
643 /// Returns Hdr field
644 Header getHeader() const { return Hdr; }
645
646 /// Returns Offsets field
647 DWARFDebugNamesOffsets getOffsets() const { return Offsets; }
648
649 /// Reads offset of compilation unit CU. CU is 0-based.
650 LLVM_ABI uint64_t getCUOffset(uint32_t CU) const;
651 uint32_t getCUCount() const { return Hdr.CompUnitCount; }
652
653 /// Reads offset of local type unit TU, TU is 0-based.
654 LLVM_ABI uint64_t getLocalTUOffset(uint32_t TU) const;
655 uint32_t getLocalTUCount() const { return Hdr.LocalTypeUnitCount; }
656
657 /// Reads signature of foreign type unit TU. TU is 0-based.
658 LLVM_ABI uint64_t getForeignTUSignature(uint32_t TU) const;
659 uint32_t getForeignTUCount() const { return Hdr.ForeignTypeUnitCount; }
660
661 /// Reads an entry in the Bucket Array for the given Bucket. The returned
662 /// value is a (1-based) index into the Names, StringOffsets and
663 /// EntryOffsets arrays. The input Bucket index is 0-based.
664 LLVM_ABI uint32_t getBucketArrayEntry(uint32_t Bucket) const;
665 uint32_t getBucketCount() const { return Hdr.BucketCount; }
666
667 /// Reads an entry in the Hash Array for the given Index. The input Index
668 /// is 1-based.
669 LLVM_ABI uint32_t getHashArrayEntry(uint32_t Index) const;
670
671 /// Reads an entry in the Name Table for the given Index. The Name Table
672 /// consists of two arrays -- String Offsets and Entry Offsets. The returned
673 /// offsets are relative to the starts of respective sections. Input Index
674 /// is 1-based.
675 LLVM_ABI NameTableEntry getNameTableEntry(uint32_t Index) const;
676
677 uint32_t getNameCount() const { return Hdr.NameCount; }
678
680 return Abbrevs;
681 }
682
683 LLVM_ABI Expected<Entry> getEntry(uint64_t *Offset) const;
684
685 /// Returns the Entry at the relative `Offset` from the start of the Entry
686 /// pool.
688 auto OffsetFromSection = Offset + this->Offsets.EntriesBase;
689 return getEntry(&OffsetFromSection);
690 }
691
692 /// Look up all entries in this Name Index matching \c Key.
694
695 NameIterator begin() const { return NameIterator(this, 1); }
696 NameIterator end() const { return NameIterator(this, getNameCount() + 1); }
697
699 uint64_t getUnitOffset() const { return Base; }
701 return Base + dwarf::getUnitLengthFieldByteSize(Hdr.Format) +
702 Hdr.UnitLength;
703 }
704 LLVM_ABI void dump(ScopedPrinter &W) const;
705
706 friend class DWARFDebugNames;
707 };
708
710 public:
711 using iterator_category = std::input_iterator_tag;
713 using difference_type = std::ptrdiff_t;
716
717 private:
718 /// The Name Index we are currently iterating through. The implementation
719 /// relies on the fact that this can also be used as an iterator into the
720 /// "NameIndices" vector in the Accelerator section.
721 const NameIndex *CurrentIndex = nullptr;
722
723 /// Whether this is a local iterator (searches in CurrentIndex only) or not
724 /// (searches all name indices).
725 bool IsLocal;
726
727 std::optional<Entry> CurrentEntry;
728 uint64_t DataOffset = 0; ///< Offset into the section.
729 std::string Key; ///< The Key we are searching for.
730 std::optional<uint32_t> Hash; ///< Hash of Key, if it has been computed.
731
732 bool getEntryAtCurrentOffset();
733 std::optional<uint64_t> findEntryOffsetInCurrentIndex();
734 bool findInCurrentIndex();
735 void searchFromStartOfCurrentIndex();
736 LLVM_ABI void next();
737
738 /// Set the iterator to the "end" state.
739 void setEnd() { *this = ValueIterator(); }
740
741 public:
742 /// Create a "begin" iterator for looping over all entries in the
743 /// accelerator table matching Key. The iterator will run through all Name
744 /// Indexes in the section in sequence.
746
747 /// Create a "begin" iterator for looping over all entries in a specific
748 /// Name Index. Other indices in the section will not be visited.
750
751 /// End marker.
752 ValueIterator() = default;
753
754 const Entry &operator*() const { return *CurrentEntry; }
756 next();
757 return *this;
758 }
760 ValueIterator I = *this;
761 next();
762 return I;
763 }
764
765 friend bool operator==(const ValueIterator &A, const ValueIterator &B) {
766 return A.CurrentIndex == B.CurrentIndex && A.DataOffset == B.DataOffset;
767 }
768 friend bool operator!=(const ValueIterator &A, const ValueIterator &B) {
769 return !(A == B);
770 }
771 };
772
774
775 /// The Name Index we are iterating through.
776 const NameIndex *CurrentIndex;
777
778 /// The current name in the Name Index.
779 uint32_t CurrentName;
780
781 void next() {
782 assert(CurrentName <= CurrentIndex->getNameCount());
783 ++CurrentName;
784 }
785
786 public:
787 using size_type = size_t;
788 using iterator_category = std::input_iterator_tag;
792 using reference = NameTableEntry; // We return entries by value.
793
794 /// Creates an iterator whose initial position is name CurrentName in
795 /// CurrentIndex.
796 NameIterator(const NameIndex *CurrentIndex, uint32_t CurrentName)
797 : CurrentIndex(CurrentIndex), CurrentName(CurrentName) {}
798
800 return CurrentIndex->getNameTableEntry(CurrentName);
801 }
803 next();
804 return *this;
805 }
807 NameIterator I = *this;
808 next();
809 return I;
810 }
811 /// Accesses entry at specific index (1-based internally, 0-based
812 /// externally). For example how this is used in parallelForEach.
814 return CurrentIndex->getNameTableEntry(idx + 1);
815 }
816 /// Computes difference between iterators (used in parallelForEach).
818 assert(CurrentIndex == other.CurrentIndex);
819 return this->CurrentName - other.CurrentName;
820 }
821
822 friend bool operator==(const NameIterator &A, const NameIterator &B) {
823 return A.CurrentIndex == B.CurrentIndex && A.CurrentName == B.CurrentName;
824 }
825 friend bool operator!=(const NameIterator &A, const NameIterator &B) {
826 return !(A == B);
827 }
828 };
829
830private:
831 SmallVector<NameIndex, 0> NameIndices;
832 DenseMap<uint64_t, const NameIndex *> UnitOffsetToNameIndex;
833
834public:
838
839 Error extract() override;
840 void dump(raw_ostream &OS) const override;
841
842 /// Look up all entries in the accelerator table matching \c Key.
844
846 const_iterator begin() const { return NameIndices.begin(); }
847 const_iterator end() const { return NameIndices.end(); }
848
849 /// Return the Name Index covering the compile unit or local type unit at
850 /// UnitOffset, or nullptr if there is no Name Index covering that unit.
851 const NameIndex *getCUOrTUNameIndex(uint64_t UnitOffset);
852};
853
854/// Calculates the starting offsets for various sections within the
855/// .debug_names section.
856namespace dwarf {
857LLVM_ABI DWARFDebugNames::DWARFDebugNamesOffsets
858findDebugNamesOffsets(uint64_t EndOfHeaderOffset,
859 const DWARFDebugNames::Header &Hdr);
860}
861
862/// If `Name` is the name of a templated function that includes template
863/// parameters, returns a substring of `Name` containing no template
864/// parameters.
865/// E.g.: StripTemplateParameters("foo<int>") = "foo".
866LLVM_ABI std::optional<StringRef> StripTemplateParameters(StringRef Name);
867
869 /// For "-[A(Category) method:]", this would be "method:"
871 /// For "-[A(Category) method:]", this would be "A(category)"
873 /// For "-[A(Category) method:]", this would be "A"
874 std::optional<StringRef> ClassNameNoCategory;
875 /// For "-[A(Category) method:]", this would be "A method:"
876 std::optional<std::string> MethodNameNoCategory;
877};
878
879/// If `Name` is the AT_name of a DIE which refers to an Objective-C selector,
880/// returns an instance of ObjCSelectorNames. The Selector and ClassName fields
881/// are guaranteed to be non-empty in the result.
882LLVM_ABI std::optional<ObjCSelectorNames>
884
885} // end namespace llvm
886
887#endif // LLVM_DEBUGINFO_DWARF_DWARFACCELERATORTABLE_H
static std::optional< unsigned > getTag(const TargetRegisterInfo *TRI, const MachineInstr &MI, const LoadInfo &LI)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static bool isEqual(const Function &Caller, const Function &Callee)
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_ABI
Definition Compiler.h:213
This file defines the DenseSet and SmallDenseSet classes.
This file contains constants used for implementing Dwarf debug support.
static bool lookup(const GsymReader &GR, DataExtractor &Data, uint64_t &Offset, uint64_t BaseAddr, uint64_t Addr, SourceLocations &SrcLocs, llvm::Error &Err)
A Lookup helper functions.
loop extract
#define I(x, y, z)
Definition MD5.cpp:57
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:203
Apple-specific implementation of an Accelerator Entry.
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< 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
LLVM_ABI Iterator(const AppleAcceleratorTable &Table, bool SetEnd=false)
LLVM_ABI SameNameIterator(const AppleAcceleratorTable &AccelTable, uint64_t DataOffset)
Construct a new iterator for the entries at DataOffset.
friend bool operator==(const SameNameIterator &A, const SameNameIterator &B)
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.
uint32_t getHashDataEntryLength() const
Returns the size of one HashData entry.
void dump(raw_ostream &OS) const override
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:40
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...
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 DWARFDataExtractor (typically for an in-memory copy of an object-file section) plus a relocation ma...
DWARF v5-specific implementation of an Accelerator Entry.
const Abbrev & getAbbrev() const
Return the Abbreviation that can be used to interpret the raw values of this Accelerator Entry.
const NameIndex * getNameIndex() const
dwarf::Tag tag() const
.debug_names-specific getter, which always succeeds (DWARF v5 index entries always have a tag).
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...
Represents a single accelerator table within the DWARF v5 .debug_names section.
Header getHeader() const
Returns Hdr field.
LLVM_ABI Expected< Entry > getEntry(uint64_t *Offset) const
NameIndex(const DWARFDebugNames &Section, uint64_t Base)
const DenseSet< Abbrev, AbbrevMapInfo > & getAbbrevs() const
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.
difference_type operator-(const NameIterator &other) const
Computes difference between iterators (used in parallelForEach).
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.
reference operator[](size_type idx)
Accesses entry at specific index (1-based internally, 0-based externally).
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.
friend bool operator==(const ValueIterator &A, const ValueIterator &B)
friend bool operator!=(const ValueIterator &A, const ValueIterator &B)
ValueIterator()=default
End marker.
LLVM_ABI ValueIterator(const DWARFDebugNames &AccelTable, StringRef Key)
Create a "begin" iterator for looping over all entries in the accelerator table matching Key.
const_iterator end() const
SmallVector< NameIndex, 0 >::const_iterator const_iterator
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
Implements a dense probed hash-table based set.
Definition DenseSet.h:279
Base class for user error types.
Definition Error.h:354
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
Tagged union holding either a T or a Error.
Definition Error.h:485
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...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
Target - Wrapper for Target specific information.
LLVM Value Representation.
Definition Value.h:75
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:53
uint8_t getUnitLengthFieldByteSize(DwarfFormat Format)
Get the byte size of the unit length field depending on the DWARF format.
Definition Dwarf.h:1139
LLVM_ABI 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:93
This is an optimization pass for GlobalISel generic memory operations.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
@ Offset
Definition DWP.cpp:532
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
FunctionAddr VTableAddr uintptr_t uintptr_t Version
Definition InstrProf.h:302
auto make_first_range(ContainerTy &&c)
Given a container of pairs, return a range over the first elements.
Definition STLExtras.h:1397
LLVM_ABI std::optional< StringRef > StripTemplateParameters(StringRef Name)
If Name is the name of a templated function that includes template parameters, returns a substring of...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
FunctionAddr VTableAddr uintptr_t uintptr_t Data
Definition InstrProf.h:189
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:1867
LLVM_ABI 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:1897
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:867
EntryWithName(const AppleAcceleratorTable &Table)
std::optional< StringRef > readName() const
Abbreviation describing the encoding of Name Index entries.
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.
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.
LLVM_ABI void dump(ScopedPrinter &W) const
An information struct used to provide DenseMap with the various necessary components for a given valu...
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:1110