1 //===- DWARFAcceleratorTable.h ----------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef LLVM_DEBUGINFO_DWARFACCELERATORTABLE_H 11 #define LLVM_DEBUGINFO_DWARFACCELERATORTABLE_H 12 13 #include "llvm/ADT/SmallVector.h" 14 #include "llvm/BinaryFormat/Dwarf.h" 15 #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h" 16 #include "llvm/DebugInfo/DWARF/DWARFFormValue.h" 17 #include <cstdint> 18 #include <utility> 19 20 namespace llvm { 21 22 class raw_ostream; 23 24 /// This implements the Apple accelerator table format, a precursor of the 25 /// DWARF 5 accelerator table format. 26 /// TODO: Factor out a common base class for both formats. 27 class DWARFAcceleratorTable { 28 struct Header { 29 uint32_t Magic; 30 uint16_t Version; 31 uint16_t HashFunction; 32 uint32_t NumBuckets; 33 uint32_t NumHashes; 34 uint32_t HeaderDataLength; 35 }; 36 37 struct HeaderData { 38 using AtomType = uint16_t; 39 using Form = dwarf::Form; 40 41 uint32_t DIEOffsetBase; 42 SmallVector<std::pair<AtomType, Form>, 3> Atoms; 43 }; 44 45 struct Header Hdr; 46 struct HeaderData HdrData; 47 DWARFDataExtractor AccelSection; 48 DataExtractor StringSection; 49 bool IsValid = false; 50 51 public: 52 /// An iterator for the entries associated with one key. Each entry can have 53 /// multiple DWARFFormValues. 54 class ValueIterator : public std::iterator<std::input_iterator_tag, 55 ArrayRef<DWARFFormValue>> { 56 const DWARFAcceleratorTable *AccelTable = nullptr; 57 SmallVector<DWARFFormValue, 3> AtomForms; ///< The decoded data entry. 58 59 unsigned DataOffset = 0; ///< Offset into the section. 60 unsigned Data = 0; ///< Current data entry. 61 unsigned NumData = 0; ///< Number of data entries. 62 63 /// Advance the iterator. 64 void Next(); 65 public: 66 /// Construct a new iterator for the entries at \p DataOffset. 67 ValueIterator(const DWARFAcceleratorTable &AccelTable, unsigned DataOffset); 68 /// End marker. 69 ValueIterator() = default; 70 71 const ArrayRef<DWARFFormValue> operator*() const { 72 return AtomForms; 73 } 74 ValueIterator &operator++() { Next(); return *this; } 75 ValueIterator operator++(int) { 76 ValueIterator I = *this; 77 Next(); 78 return I; 79 } 80 friend bool operator==(const ValueIterator &A, const ValueIterator &B) { 81 return A.NumData == B.NumData && A.DataOffset == B.DataOffset; 82 } 83 friend bool operator!=(const ValueIterator &A, const ValueIterator &B) { 84 return !(A == B); 85 } 86 }; 87 88 89 DWARFAcceleratorTable(const DWARFDataExtractor &AccelSection, 90 DataExtractor StringSection) 91 : AccelSection(AccelSection), StringSection(StringSection) {} 92 93 bool extract(); 94 uint32_t getNumBuckets(); 95 uint32_t getNumHashes(); 96 uint32_t getSizeHdr(); 97 uint32_t getHeaderDataLength(); 98 ArrayRef<std::pair<HeaderData::AtomType, HeaderData::Form>> getAtomsDesc(); 99 bool validateForms(); 100 101 /// Return information related to the DWARF DIE we're looking for when 102 /// performing a lookup by name. 103 /// 104 /// \param HashDataOffset an offset into the hash data table 105 /// \returns <DieOffset, DieTag> 106 /// DieOffset is the offset into the .debug_info section for the DIE 107 /// related to the input hash data offset. 108 /// DieTag is the tag of the DIE 109 std::pair<uint32_t, dwarf::Tag> readAtoms(uint32_t &HashDataOffset); 110 void dump(raw_ostream &OS) const; 111 112 /// Look up all entries in the accelerator table matching \c Key. 113 iterator_range<ValueIterator> equal_range(StringRef Key) const; 114 }; 115 116 } // end namespace llvm 117 118 #endif // LLVM_DEBUGINFO_DWARFACCELERATORTABLE_H 119