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.
84 ArrayRef<DWARFFormValue> getValues() const { return Values; }
85 };
86
88 DataExtractor StringSection)
89 : AccelSection(AccelSection), StringSection(StringSection) {}
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;
104 uint16_t Version;
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 uint64_t getIthHashBase(uint32_t I) const { return getHashBase() + I * 4; }
157
158 /// Return the offset into the section where the offset list begins.
159 uint64_t getOffsetBase() const { return getHashBase() + getNumHashes() * 4; }
160
161 /// Return the offset into the section where the table entries begin.
162 uint64_t getEntriesBase() const {
163 return getOffsetBase() + getNumHashes() * 4;
164 }
165
166 /// Return the offset into the section where the I-th offset is.
167 uint64_t getIthOffsetBase(uint32_t I) const {
168 return getOffsetBase() + I * 4;
169 }
170
171 /// Returns the index of the bucket where a hypothetical Hash would be.
172 uint32_t hashToBucketIdx(uint32_t Hash) const {
173 return Hash % getNumBuckets();
174 }
175
176 /// Returns true iff a hypothetical Hash would be assigned to the BucketIdx-th
177 /// bucket.
178 bool wouldHashBeInBucket(uint32_t Hash, uint32_t BucketIdx) const {
179 return hashToBucketIdx(Hash) == BucketIdx;
180 }
181
182 /// Reads the contents of the I-th bucket, that is, the index in the hash list
183 /// where the hashes corresponding to this bucket begin.
184 std::optional<uint32_t> readIthBucket(uint32_t I) const {
185 uint64_t Offset = getIthBucketBase(I);
186 return readU32FromAccel(Offset);
187 }
188
189 /// Reads the I-th hash in the hash list.
190 std::optional<uint32_t> readIthHash(uint32_t I) const {
191 uint64_t Offset = getIthHashBase(I);
192 return readU32FromAccel(Offset);
193 }
194
195 /// Reads the I-th offset in the offset list.
196 std::optional<uint32_t> readIthOffset(uint32_t I) const {
197 uint64_t Offset = getIthOffsetBase(I);
198 return readU32FromAccel(Offset);
199 }
200
201 /// Reads a string offset from the accelerator table at Offset, which is
202 /// incremented by the number of bytes read.
203 std::optional<uint32_t> readStringOffsetAt(uint64_t &Offset) const {
204 return readU32FromAccel(Offset, /*UseRelocation*/ true);
205 }
206
207 /// Scans through all Hashes in the BucketIdx-th bucket, attempting to find
208 /// HashToFind. If it is found, its index in the list of hashes is returned.
209 std::optional<uint32_t> idxOfHashInBucket(uint32_t HashToFind,
210 uint32_t BucketIdx) const;
211
212public:
213 /// Apple-specific implementation of an Accelerator Entry.
215 const AppleAcceleratorTable &Table;
216
217 Entry(const AppleAcceleratorTable &Table);
218 void extract(uint64_t *Offset);
219
220 public:
221 std::optional<uint64_t> getCUOffset() const override;
222
223 /// Returns the Section Offset of the Debug Info Entry associated with this
224 /// Accelerator Entry or std::nullopt if the DIE offset is not recorded in
225 /// this Accelerator Entry. The returned offset is relative to the start of
226 /// the Section containing the DIE.
227 std::optional<uint64_t> getDIESectionOffset() const;
228
229 std::optional<dwarf::Tag> getTag() const override;
230
231 /// Returns the value of the Atom in this Accelerator Entry, if the Entry
232 /// contains such Atom.
233 std::optional<DWARFFormValue> lookup(HeaderData::AtomType Atom) const;
234
236 friend class ValueIterator;
237 };
238
239 /// An iterator for Entries all having the same string as key.
241 : public iterator_facade_base<SameNameIterator, std::forward_iterator_tag,
242 Entry> {
243 Entry Current;
244 uint64_t Offset = 0;
245
246 public:
247 /// Construct a new iterator for the entries at \p DataOffset.
249 uint64_t DataOffset);
250
251 const Entry &operator*() {
252 uint64_t OffsetCopy = Offset;
253 Current.extract(&OffsetCopy);
254 return Current;
255 }
257 Offset += Current.Table.getHashDataEntryLength();
258 return *this;
259 }
260 friend bool operator==(const SameNameIterator &A,
261 const SameNameIterator &B) {
262 return A.Offset == B.Offset;
263 }
264 };
265
268 : BaseEntry(Table), StrOffset(0) {}
269
270 std::optional<StringRef> readName() const {
271 return BaseEntry.Table.readStringFromStrSection(StrOffset);
272 }
273
276 };
277
278 /// An iterator for all entries in the table.
280 : public iterator_facade_base<Iterator, std::forward_iterator_tag,
281 EntryWithName> {
282 constexpr static auto EndMarker = std::numeric_limits<uint64_t>::max();
283
284 EntryWithName Current;
285 uint64_t Offset = EndMarker;
286 uint32_t NumEntriesToCome = 0;
287
288 void setToEnd() { Offset = EndMarker; }
289 bool isEnd() const { return Offset == EndMarker; }
290 const AppleAcceleratorTable &getTable() const {
291 return Current.BaseEntry.Table;
292 }
293
294 /// Reads the next Entry in the table, populating `Current`.
295 /// If not possible (e.g. end of the section), becomes the end iterator.
296 LLVM_ABI void prepareNextEntryOrEnd();
297
298 /// Reads the next string pointer and the entry count for that string,
299 /// populating `NumEntriesToCome`.
300 /// If not possible (e.g. end of the section), becomes the end iterator.
301 /// Assumes `Offset` points to a string reference.
302 void prepareNextStringOrEnd();
303
304 public:
305 LLVM_ABI Iterator(const AppleAcceleratorTable &Table, bool SetEnd = false);
306
308 prepareNextEntryOrEnd();
309 return *this;
310 }
311 bool operator==(const Iterator &It) const { return Offset == It.Offset; }
312 const EntryWithName &operator*() const {
313 assert(!isEnd() && "dereferencing end iterator");
314 return Current;
315 }
316 };
317
319 DataExtractor StringSection)
320 : DWARFAcceleratorTable(AccelSection, StringSection) {}
321
322 Error extract() override;
323 uint32_t getNumBuckets() const;
324 uint32_t getNumHashes() const;
325 uint32_t getSizeHdr() const;
326 uint32_t getHeaderDataLength() const;
327
328 /// Returns the size of one HashData entry.
329 uint32_t getHashDataEntryLength() const { return HashDataEntryLength; }
330
331 /// Return the Atom description, which can be used to interpret the raw values
332 /// of the Accelerator Entries in this table.
334
335 /// Returns true iff `AtomTy` is one of the atoms available in Entries of this
336 /// table.
338 return is_contained(make_first_range(HdrData.Atoms), AtomTy);
339 }
340
341 bool validateForms();
342
343 /// Return information related to the DWARF DIE we're looking for when
344 /// performing a lookup by name.
345 ///
346 /// \param HashDataOffset an offset into the hash data table
347 /// \returns <DieOffset, DieTag>
348 /// DieOffset is the offset into the .debug_info section for the DIE
349 /// related to the input hash data offset.
350 /// DieTag is the tag of the DIE
351 std::pair<uint64_t, dwarf::Tag> readAtoms(uint64_t *HashDataOffset);
352 void dump(raw_ostream &OS) const override;
353
354 /// Look up all entries in the accelerator table matching \c Key.
355 iterator_range<SameNameIterator> equal_range(StringRef Key) const;
356
357 /// Lookup all entries in the accelerator table.
358 auto entries() const {
359 return make_range(Iterator(*this), Iterator(*this, /*SetEnd*/ true));
360 }
361};
362
363/// .debug_names section consists of one or more units. Each unit starts with a
364/// header, which is followed by a list of compilation units, local and foreign
365/// type units.
366///
367/// These may be followed by an (optional) hash lookup table, which consists of
368/// an array of buckets and hashes similar to the apple tables above. The only
369/// difference is that the hashes array is 1-based, and consequently an empty
370/// bucket is denoted by 0 and not UINT32_MAX.
371///
372/// Next is the name table, which consists of an array of names and array of
373/// entry offsets. This is different from the apple tables, which store names
374/// next to the actual entries.
375///
376/// The structure of the entries is described by an abbreviations table, which
377/// comes after the name table. Unlike the apple tables, which have a uniform
378/// entry structure described in the header, each .debug_names entry may have
379/// different index attributes (DW_IDX_???) attached to it.
380///
381/// The last segment consists of a list of entries, which is a 0-terminated list
382/// referenced by the name table and interpreted with the help of the
383/// abbreviation table.
385public:
386 class NameIndex;
387 class NameIterator;
388 class ValueIterator;
389
390 /// DWARF v5 Name Index header.
391 struct Header {
403
405 LLVM_ABI void dump(ScopedPrinter &W) const;
406 };
407
408 /// Index attribute and its encoding.
412
414 : Index(Index), Form(Form) {}
415
416 friend bool operator==(const AttributeEncoding &LHS,
417 const AttributeEncoding &RHS) {
418 return LHS.Index == RHS.Index && LHS.Form == RHS.Form;
419 }
420 };
421
422 /// Abbreviation describing the encoding of Name Index entries.
423 struct Abbrev {
424 uint64_t AbbrevOffset; /// < Abbreviation offset in the .debug_names section
425 uint32_t Code; ///< Abbreviation code
426 dwarf::Tag Tag; ///< Dwarf Tag of the described entity.
427 std::vector<AttributeEncoding> Attributes; ///< List of index attributes.
428
429 Abbrev(uint32_t Code, dwarf::Tag Tag, uint64_t AbbrevOffset,
430 std::vector<AttributeEncoding> Attributes)
431 : AbbrevOffset(AbbrevOffset), Code(Code), Tag(Tag),
433
434 LLVM_ABI void dump(ScopedPrinter &W) const;
435 };
436
437 /// DWARF v5-specific implementation of an Accelerator Entry.
439 const NameIndex *NameIdx;
440 const Abbrev *Abbr;
441
442 Entry(const NameIndex &NameIdx, const Abbrev &Abbr);
443
444 public:
445 const NameIndex *getNameIndex() const { return NameIdx; }
446 std::optional<uint64_t> getCUOffset() const override;
447 std::optional<uint64_t> getLocalTUOffset() const override;
448 std::optional<uint64_t> getForeignTUTypeSignature() const override;
449 std::optional<dwarf::Tag> getTag() const override { return tag(); }
450
451 // Special function that will return the related CU offset needed type
452 // units. This gets used to find the .dwo file that originated the entries
453 // for a given type unit.
454 std::optional<uint64_t> getRelatedCUOffset() const;
455
456 /// Returns the Index into the Compilation Unit list of the owning Name
457 /// Index or std::nullopt if this Accelerator Entry does not have an
458 /// associated Compilation Unit. It is up to the user to verify that the
459 /// returned Index is valid in the owning NameIndex (or use getCUOffset(),
460 /// which will handle that check itself). Note that entries in NameIndexes
461 /// which index just a single Compilation Unit are implicitly associated
462 /// with that unit, so this function will return 0 even without an explicit
463 /// DW_IDX_compile_unit attribute, unless there is a DW_IDX_type_unit
464 /// attribute.
465 std::optional<uint64_t> getCUIndex() const;
466
467 /// Similar functionality to getCUIndex() but without the DW_IDX_type_unit
468 /// restriction. This allows us to get the associated a compilation unit
469 /// index for an entry that is a type unit.
470 std::optional<uint64_t> getRelatedCUIndex() const;
471
472 /// Returns the index of the Type Unit of the owning
473 /// Name
474 /// Index or std::nullopt if this Accelerator Entry does not have an
475 /// associated Type Unit. It is up to the user to verify that the
476 /// returned Index is a valid index in the owning NameIndex (or use
477 /// getLocalTUOffset(), which will handle that check itself).
478 std::optional<uint64_t> getTUIndex() const;
479
480 /// .debug_names-specific getter, which always succeeds (DWARF v5 index
481 /// entries always have a tag).
482 dwarf::Tag tag() const { return Abbr->Tag; }
483
484 /// Returns the Offset of the DIE within the containing CU or TU.
485 std::optional<uint64_t> getDIEUnitOffset() const;
486
487 /// Returns true if this Entry has information about its parent DIE (i.e. if
488 /// it has an IDX_parent attribute)
489 bool hasParentInformation() const;
490
491 /// Returns the Entry corresponding to the parent of the DIE represented by
492 /// `this` Entry. If the parent is not in the table, nullopt is returned.
493 /// Precondition: hasParentInformation() == true.
494 /// An error is returned for ill-formed tables.
495 Expected<std::optional<DWARFDebugNames::Entry>> getParentDIEEntry() const;
496
497 /// Return the Abbreviation that can be used to interpret the raw values of
498 /// this Accelerator Entry.
499 const Abbrev &getAbbrev() const { return *Abbr; }
500
501 /// Returns the value of the Index Attribute in this Accelerator Entry, if
502 /// the Entry contains such Attribute.
503 std::optional<DWARFFormValue> lookup(dwarf::Index Index) const;
504
505 void dump(ScopedPrinter &W) const;
506 void dumpParentIdx(ScopedPrinter &W, const DWARFFormValue &FormValue) const;
507
508 friend class NameIndex;
509 friend class ValueIterator;
510 };
511
512 /// Error returned by NameIndex::getEntry to report it has reached the end of
513 /// the entry list.
514 class LLVM_ABI SentinelError : public ErrorInfo<SentinelError> {
515 public:
516 static char ID;
517
518 void log(raw_ostream &OS) const override { OS << "Sentinel"; }
519 std::error_code convertToErrorCode() const override;
520 };
521
522private:
523 /// DenseMapInfo for struct Abbrev.
524 struct AbbrevMapInfo {
525 LLVM_ABI static Abbrev getEmptyKey();
526 LLVM_ABI static Abbrev getTombstoneKey();
527 static unsigned getHashValue(uint32_t Code) {
529 }
530 static unsigned getHashValue(const Abbrev &Abbr) {
531 return getHashValue(Abbr.Code);
532 }
533 static bool isEqual(uint32_t LHS, const Abbrev &RHS) {
534 return LHS == RHS.Code;
535 }
536 static bool isEqual(const Abbrev &LHS, const Abbrev &RHS) {
537 return LHS.Code == RHS.Code;
538 }
539 };
540
541public:
542 /// A single entry in the Name Table (DWARF v5 sect. 6.1.1.4.6) of the Name
543 /// Index.
545 DataExtractor StrData;
546
548 uint64_t StringOffset;
549 uint64_t EntryOffset;
550
551 public:
553 uint64_t StringOffset, uint64_t EntryOffset)
554 : StrData(StrData), Index(Index), StringOffset(StringOffset),
555 EntryOffset(EntryOffset) {}
556
557 /// Return the index of this name in the parent Name Index.
558 uint32_t getIndex() const { return Index; }
559
560 /// Returns the offset of the name of the described entities.
561 uint64_t getStringOffset() const { return StringOffset; }
562
563 /// Return the string referenced by this name table entry or nullptr if the
564 /// string offset is not valid.
565 const char *getString() const {
566 uint64_t Off = StringOffset;
567 return StrData.getCStr(&Off);
568 }
569
570 /// Compares the name of this entry against Target, returning true if they
571 /// are equal. This is more efficient in hot code paths that do not need the
572 /// length of the name.
574 // Note: this is not the name, but the rest of debug_str starting from
575 // name. This handles corrupt data (non-null terminated) without
576 // overrunning the buffer.
577 StringRef Data = StrData.getData().substr(StringOffset);
578 size_t TargetSize = Target.size();
579 return Data.size() > TargetSize && !Data[TargetSize] &&
580 strncmp(Data.data(), Target.data(), TargetSize) == 0;
581 }
582
583 /// Returns the offset of the first Entry in the list.
584 uint64_t getEntryOffset() const { return EntryOffset; }
585 };
586
587 /// Offsets for the start of various important tables from the start of the
588 /// section.
596 };
597
598 /// Represents a single accelerator table within the DWARF v5 .debug_names
599 /// section.
600 class NameIndex {
602 struct Header Hdr;
603 const DWARFDebugNames &Section;
604
605 // Base of the whole unit and of various important tables, as offsets from
606 // the start of the section.
609
610 void dumpCUs(ScopedPrinter &W) const;
611 void dumpLocalTUs(ScopedPrinter &W) const;
612 void dumpForeignTUs(ScopedPrinter &W) const;
613 void dumpAbbreviations(ScopedPrinter &W) const;
614 bool dumpEntry(ScopedPrinter &W, uint64_t *Offset) const;
615 void dumpName(ScopedPrinter &W, const NameTableEntry &NTE,
616 std::optional<uint32_t> Hash) const;
617 void dumpBucket(ScopedPrinter &W, uint32_t Bucket) const;
618
619 Expected<AttributeEncoding> extractAttributeEncoding(uint64_t *Offset);
620
622 extractAttributeEncodings(uint64_t *Offset);
623
624 Expected<Abbrev> extractAbbrev(uint64_t *Offset);
625
626 public:
627 NameIndex(const DWARFDebugNames &Section, uint64_t Base)
628 : Section(Section), Base(Base) {}
629
630 /// Returns Hdr field
631 Header getHeader() const { return Hdr; }
632
633 /// Returns Offsets field
634 DWARFDebugNamesOffsets getOffsets() const { return Offsets; }
635
636 /// Reads offset of compilation unit CU. CU is 0-based.
637 LLVM_ABI uint64_t getCUOffset(uint32_t CU) const;
638 uint32_t getCUCount() const { return Hdr.CompUnitCount; }
639
640 /// Reads offset of local type unit TU, TU is 0-based.
641 LLVM_ABI uint64_t getLocalTUOffset(uint32_t TU) const;
642 uint32_t getLocalTUCount() const { return Hdr.LocalTypeUnitCount; }
643
644 /// Reads signature of foreign type unit TU. TU is 0-based.
645 LLVM_ABI uint64_t getForeignTUSignature(uint32_t TU) const;
646 uint32_t getForeignTUCount() const { return Hdr.ForeignTypeUnitCount; }
647
648 /// Reads an entry in the Bucket Array for the given Bucket. The returned
649 /// value is a (1-based) index into the Names, StringOffsets and
650 /// EntryOffsets arrays. The input Bucket index is 0-based.
651 LLVM_ABI uint32_t getBucketArrayEntry(uint32_t Bucket) const;
652 uint32_t getBucketCount() const { return Hdr.BucketCount; }
653
654 /// Reads an entry in the Hash Array for the given Index. The input Index
655 /// is 1-based.
656 LLVM_ABI uint32_t getHashArrayEntry(uint32_t Index) const;
657
658 /// Reads an entry in the Name Table for the given Index. The Name Table
659 /// consists of two arrays -- String Offsets and Entry Offsets. The returned
660 /// offsets are relative to the starts of respective sections. Input Index
661 /// is 1-based.
662 LLVM_ABI NameTableEntry getNameTableEntry(uint32_t Index) const;
663
664 uint32_t getNameCount() const { return Hdr.NameCount; }
665
667 return Abbrevs;
668 }
669
670 LLVM_ABI Expected<Entry> getEntry(uint64_t *Offset) const;
671
672 /// Returns the Entry at the relative `Offset` from the start of the Entry
673 /// pool.
675 auto OffsetFromSection = Offset + this->Offsets.EntriesBase;
676 return getEntry(&OffsetFromSection);
677 }
678
679 /// Look up all entries in this Name Index matching \c Key.
680 LLVM_ABI iterator_range<ValueIterator> equal_range(StringRef Key) const;
681
682 NameIterator begin() const { return NameIterator(this, 1); }
683 NameIterator end() const { return NameIterator(this, getNameCount() + 1); }
684
686 uint64_t getUnitOffset() const { return Base; }
688 return Base + dwarf::getUnitLengthFieldByteSize(Hdr.Format) +
689 Hdr.UnitLength;
690 }
691 LLVM_ABI void dump(ScopedPrinter &W) const;
692
693 friend class DWARFDebugNames;
694 };
695
697 public:
698 using iterator_category = std::input_iterator_tag;
700 using difference_type = std::ptrdiff_t;
703
704 private:
705 /// The Name Index we are currently iterating through. The implementation
706 /// relies on the fact that this can also be used as an iterator into the
707 /// "NameIndices" vector in the Accelerator section.
708 const NameIndex *CurrentIndex = nullptr;
709
710 /// Whether this is a local iterator (searches in CurrentIndex only) or not
711 /// (searches all name indices).
712 bool IsLocal;
713
714 std::optional<Entry> CurrentEntry;
715 uint64_t DataOffset = 0; ///< Offset into the section.
716 std::string Key; ///< The Key we are searching for.
717 std::optional<uint32_t> Hash; ///< Hash of Key, if it has been computed.
718
719 bool getEntryAtCurrentOffset();
720 std::optional<uint64_t> findEntryOffsetInCurrentIndex();
721 bool findInCurrentIndex();
722 void searchFromStartOfCurrentIndex();
723 LLVM_ABI void next();
724
725 /// Set the iterator to the "end" state.
726 void setEnd() { *this = ValueIterator(); }
727
728 public:
729 /// Create a "begin" iterator for looping over all entries in the
730 /// accelerator table matching Key. The iterator will run through all Name
731 /// Indexes in the section in sequence.
733
734 /// Create a "begin" iterator for looping over all entries in a specific
735 /// Name Index. Other indices in the section will not be visited.
737
738 /// End marker.
739 ValueIterator() = default;
740
741 const Entry &operator*() const { return *CurrentEntry; }
743 next();
744 return *this;
745 }
747 ValueIterator I = *this;
748 next();
749 return I;
750 }
751
752 friend bool operator==(const ValueIterator &A, const ValueIterator &B) {
753 return A.CurrentIndex == B.CurrentIndex && A.DataOffset == B.DataOffset;
754 }
755 friend bool operator!=(const ValueIterator &A, const ValueIterator &B) {
756 return !(A == B);
757 }
758 };
759
761
762 /// The Name Index we are iterating through.
763 const NameIndex *CurrentIndex;
764
765 /// The current name in the Name Index.
766 uint32_t CurrentName;
767
768 void next() {
769 assert(CurrentName <= CurrentIndex->getNameCount());
770 ++CurrentName;
771 }
772
773 public:
774 using size_type = size_t;
775 using iterator_category = std::input_iterator_tag;
779 using reference = NameTableEntry; // We return entries by value.
780
781 /// Creates an iterator whose initial position is name CurrentName in
782 /// CurrentIndex.
783 NameIterator(const NameIndex *CurrentIndex, uint32_t CurrentName)
784 : CurrentIndex(CurrentIndex), CurrentName(CurrentName) {}
785
787 return CurrentIndex->getNameTableEntry(CurrentName);
788 }
790 next();
791 return *this;
792 }
794 NameIterator I = *this;
795 next();
796 return I;
797 }
798 /// Accesses entry at specific index (1-based internally, 0-based
799 /// externally). For example how this is used in parallelForEach.
801 return CurrentIndex->getNameTableEntry(idx + 1);
802 }
803 /// Computes difference between iterators (used in parallelForEach).
805 assert(CurrentIndex == other.CurrentIndex);
806 return this->CurrentName - other.CurrentName;
807 }
808
809 friend bool operator==(const NameIterator &A, const NameIterator &B) {
810 return A.CurrentIndex == B.CurrentIndex && A.CurrentName == B.CurrentName;
811 }
812 friend bool operator!=(const NameIterator &A, const NameIterator &B) {
813 return !(A == B);
814 }
815 };
816
817private:
818 SmallVector<NameIndex, 0> NameIndices;
819 DenseMap<uint64_t, const NameIndex *> UnitOffsetToNameIndex;
820
821public:
823 DataExtractor StringSection)
824 : DWARFAcceleratorTable(AccelSection, StringSection) {}
825
826 Error extract() override;
827 void dump(raw_ostream &OS) const override;
828
829 /// Look up all entries in the accelerator table matching \c Key.
830 iterator_range<ValueIterator> equal_range(StringRef Key) const;
831
833 const_iterator begin() const { return NameIndices.begin(); }
834 const_iterator end() const { return NameIndices.end(); }
835
836 /// Return the Name Index covering the compile unit or local type unit at
837 /// UnitOffset, or nullptr if there is no Name Index covering that unit.
838 const NameIndex *getCUOrTUNameIndex(uint64_t UnitOffset);
839};
840
841/// Calculates the starting offsets for various sections within the
842/// .debug_names section.
843namespace dwarf {
844LLVM_ABI DWARFDebugNames::DWARFDebugNamesOffsets
845findDebugNamesOffsets(uint64_t EndOfHeaderOffset,
846 const DWARFDebugNames::Header &Hdr);
847}
848
849/// If `Name` is the name of a templated function that includes template
850/// parameters, returns a substring of `Name` containing no template
851/// parameters.
852/// E.g.: StripTemplateParameters("foo<int>") = "foo".
853LLVM_ABI std::optional<StringRef> StripTemplateParameters(StringRef Name);
854
856 /// For "-[A(Category) method:]", this would be "method:"
858 /// For "-[A(Category) method:]", this would be "A(category)"
860 /// For "-[A(Category) method:]", this would be "A"
861 std::optional<StringRef> ClassNameNoCategory;
862 /// For "-[A(Category) method:]", this would be "A method:"
863 std::optional<std::string> MethodNameNoCategory;
864};
865
866/// If `Name` is the AT_name of a DIE which refers to an Objective-C selector,
867/// returns an instance of ObjCSelectorNames. The Selector and ClassName fields
868/// are guaranteed to be non-empty in the result.
869LLVM_ABI std::optional<ObjCSelectorNames>
871
872} // end namespace llvm
873
874#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!")
AMDGPU Kernel Attributes
static bool isEqual(const Function &Caller, const Function &Callee)
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
#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.
std::string Name
uint32_t Index
uint64_t Offset
Definition: ELF_riscv.cpp:478
static bool lookup(const GsymReader &GR, DataExtractor &Data, uint64_t &Offset, uint64_t BaseAddr, uint64_t Addr, SourceLocations &SrcLocs, llvm::Error &Err)
A Lookup helper functions.
Definition: InlineInfo.cpp:108
loop extract
#define I(x, y, z)
Definition: MD5.cpp:58
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:203
Apple-specific implementation of an Accelerator Entry.
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...
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.
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 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 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
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.
.debug_names section consists of one or more units.
const_iterator end() const
const_iterator begin() const
DWARFDebugNames(const DWARFDataExtractor &AccelSection, DataExtractor StringSection)
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:96
Implements a dense probed hash-table based set.
Definition: DenseSet.h:263
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...
Definition: SmallVector.h:574
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1197
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:55
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition: StringRef.h:581
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
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:92
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
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:1444
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...
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:1886
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:1916
Implement std::hash so that hash_code can be used in STL containers.
Definition: BitVector.h:856
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.
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.
An information struct used to provide DenseMap with the various necessary components for a given valu...
Definition: DenseMapInfo.h:54
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:1093