1 //===-- HashedNameToDIE.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 LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_HASHEDNAMETODIE_H 10 #define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_HASHEDNAMETODIE_H 11 12 #include <vector> 13 14 #include "lldb/Core/MappedHash.h" 15 #include "lldb/Core/dwarf.h" 16 #include "lldb/Utility/RegularExpression.h" 17 #include "lldb/lldb-defines.h" 18 19 #include "DWARFDefines.h" 20 #include "DWARFFormValue.h" 21 #include "NameToDIE.h" 22 23 class DWARFMappedHash { 24 public: 25 enum AtomType : uint16_t { 26 eAtomTypeNULL = 0u, 27 /// DIE offset, check form for encoding. 28 eAtomTypeDIEOffset = 1u, 29 /// DIE offset of the compiler unit header that contains the item in 30 /// question. 31 eAtomTypeCUOffset = 2u, 32 /// DW_TAG_xxx value, should be encoded as DW_FORM_data1 (if no tags exceed 33 /// 255) or DW_FORM_data2. 34 eAtomTypeTag = 3u, 35 // Flags from enum NameFlags. 36 eAtomTypeNameFlags = 4u, 37 // Flags from enum TypeFlags. 38 eAtomTypeTypeFlags = 5u, 39 /// A 32 bit hash of the full qualified name (since all hash entries are 40 /// basename only) For example a type like "std::vector<int>::iterator" 41 /// would have a name of "iterator" and a 32 bit hash for 42 /// "std::vector<int>::iterator" to allow us to not have to pull in debug 43 /// info for a type when we know the fully qualified name. 44 eAtomTypeQualNameHash = 6u 45 }; 46 47 /// Bit definitions for the eAtomTypeTypeFlags flags. 48 enum TypeFlags { 49 /// Always set for C++, only set for ObjC if this is the 50 /// @implementation for class. 51 eTypeFlagClassIsImplementation = (1u << 1) 52 }; 53 54 struct DIEInfo { 55 dw_offset_t die_offset = DW_INVALID_OFFSET; 56 dw_tag_t tag = llvm::dwarf::DW_TAG_null; 57 58 /// Any flags for this DIEInfo. 59 uint32_t type_flags = 0; 60 61 /// A 32 bit hash of the fully qualified name. 62 uint32_t qualified_name_hash = 0; 63 64 DIEInfo() = default; 65 DIEInfo(dw_offset_t o, dw_tag_t t, uint32_t f, uint32_t h); 66 DIERefDIEInfo67 explicit operator DIERef() const { 68 return DIERef(std::nullopt, DIERef::Section::DebugInfo, die_offset); 69 } 70 }; 71 72 struct Atom { 73 AtomType type; 74 dw_form_t form; 75 }; 76 77 typedef std::vector<DIEInfo> DIEInfoArray; 78 typedef std::vector<Atom> AtomArray; 79 80 class Prologue { 81 public: 82 Prologue(dw_offset_t _die_base_offset = 0); 83 84 void ClearAtoms(); 85 86 bool ContainsAtom(AtomType atom_type) const; 87 88 void Clear(); 89 90 void AppendAtom(AtomType type, dw_form_t form); 91 92 lldb::offset_t Read(const lldb_private::DataExtractor &data, 93 lldb::offset_t offset); 94 95 size_t GetByteSize() const; 96 97 size_t GetMinimumHashDataByteSize() const; 98 99 bool HashDataHasFixedByteSize() const; 100 101 /// DIE offset base so die offsets in hash_data can be CU relative. 102 dw_offset_t die_base_offset; 103 AtomArray atoms; 104 uint32_t atom_mask = 0; 105 size_t min_hash_data_byte_size = 0; 106 bool hash_data_has_fixed_byte_size = true; 107 }; 108 109 class Header : public MappedHash::Header<Prologue> { 110 public: 111 size_t GetByteSize(const HeaderData &header_data) override; 112 113 lldb::offset_t Read(lldb_private::DataExtractor &data, 114 lldb::offset_t offset) override; 115 116 bool Read(const lldb_private::DWARFDataExtractor &data, 117 lldb::offset_t *offset_ptr, DIEInfo &hash_data) const; 118 }; 119 120 /// A class for reading and using a saved hash table from a block of data in 121 /// memory. 122 class MemoryTable 123 : public MappedHash::MemoryTable<uint32_t, DWARFMappedHash::Header, 124 DIEInfoArray> { 125 public: 126 MemoryTable(lldb_private::DWARFDataExtractor &table_data, 127 const lldb_private::DWARFDataExtractor &string_table, 128 const char *name); 129 130 const char *GetStringForKeyType(KeyType key) const override; 131 132 bool ReadHashData(uint32_t hash_data_offset, 133 HashData &hash_data) const override; 134 135 void 136 AppendAllDIEsThatMatchingRegex(const lldb_private::RegularExpression ®ex, 137 DIEInfoArray &die_info_array) const; 138 139 void AppendAllDIEsInRange(const uint32_t die_offset_start, 140 const uint32_t die_offset_end, 141 DIEInfoArray &die_info_array) const; 142 143 bool FindByName(llvm::StringRef name, 144 llvm::function_ref<bool(DIERef ref)> callback); 145 146 void FindByNameAndTag(llvm::StringRef name, const dw_tag_t tag, 147 llvm::function_ref<bool(DIERef ref)> callback); 148 149 void FindByNameAndTagAndQualifiedNameHash( 150 llvm::StringRef name, const dw_tag_t tag, 151 const uint32_t qualified_name_hash, 152 llvm::function_ref<bool(DIERef ref)> callback); 153 154 void 155 FindCompleteObjCClassByName(llvm::StringRef name, 156 llvm::function_ref<bool(DIERef ref)> callback, 157 bool must_be_implementation); 158 159 protected: 160 Result AppendHashDataForRegularExpression( 161 const lldb_private::RegularExpression ®ex, 162 lldb::offset_t *hash_data_offset_ptr, Pair &pair) const; 163 164 void FindByName(llvm::StringRef name, DIEInfoArray &die_info_array); 165 166 Result GetHashDataForName(llvm::StringRef name, 167 lldb::offset_t *hash_data_offset_ptr, 168 Pair &pair) const override; 169 170 lldb_private::DWARFDataExtractor m_data; 171 lldb_private::DWARFDataExtractor m_string_table; 172 std::string m_name; 173 }; 174 175 static bool ExtractDIEArray(const DIEInfoArray &die_info_array, 176 llvm::function_ref<bool(DIERef ref)> callback); 177 178 protected: 179 static void ExtractDIEArray(const DIEInfoArray &die_info_array, 180 const dw_tag_t tag, 181 llvm::function_ref<bool(DIERef ref)> callback); 182 183 static void ExtractDIEArray(const DIEInfoArray &die_info_array, 184 const dw_tag_t tag, 185 const uint32_t qualified_name_hash, 186 llvm::function_ref<bool(DIERef ref)> callback); 187 188 static void 189 ExtractClassOrStructDIEArray(const DIEInfoArray &die_info_array, 190 bool return_implementation_only_if_available, 191 llvm::function_ref<bool(DIERef ref)> callback); 192 193 static void 194 ExtractTypesFromDIEArray(const DIEInfoArray &die_info_array, 195 uint32_t type_flag_mask, uint32_t type_flag_value, 196 llvm::function_ref<bool(DIERef ref)> callback); 197 198 static const char *GetAtomTypeName(uint16_t atom); 199 }; 200 201 #endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_HASHEDNAMETODIE_H 202