1061da546Spatrick //===-- HashedNameToDIE.h ---------------------------------------*- C++ -*-===// 2061da546Spatrick // 3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information. 5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6061da546Spatrick // 7061da546Spatrick //===----------------------------------------------------------------------===// 8061da546Spatrick 9dda28197Spatrick #ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_HASHEDNAMETODIE_H 10dda28197Spatrick #define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_HASHEDNAMETODIE_H 11061da546Spatrick 12061da546Spatrick #include <vector> 13061da546Spatrick 14061da546Spatrick #include "lldb/Core/MappedHash.h" 15061da546Spatrick #include "lldb/Core/dwarf.h" 16061da546Spatrick #include "lldb/Utility/RegularExpression.h" 17061da546Spatrick #include "lldb/lldb-defines.h" 18061da546Spatrick 19061da546Spatrick #include "DWARFDefines.h" 20061da546Spatrick #include "DWARFFormValue.h" 21061da546Spatrick #include "NameToDIE.h" 22061da546Spatrick 23061da546Spatrick class DWARFMappedHash { 24061da546Spatrick public: 25061da546Spatrick enum AtomType : uint16_t { 26061da546Spatrick eAtomTypeNULL = 0u, 27061da546Spatrick /// DIE offset, check form for encoding. 28061da546Spatrick eAtomTypeDIEOffset = 1u, 29061da546Spatrick /// DIE offset of the compiler unit header that contains the item in 30061da546Spatrick /// question. 31061da546Spatrick eAtomTypeCUOffset = 2u, 32061da546Spatrick /// DW_TAG_xxx value, should be encoded as DW_FORM_data1 (if no tags exceed 33061da546Spatrick /// 255) or DW_FORM_data2. 34061da546Spatrick eAtomTypeTag = 3u, 35061da546Spatrick // Flags from enum NameFlags. 36061da546Spatrick eAtomTypeNameFlags = 4u, 37061da546Spatrick // Flags from enum TypeFlags. 38061da546Spatrick eAtomTypeTypeFlags = 5u, 39061da546Spatrick /// A 32 bit hash of the full qualified name (since all hash entries are 40061da546Spatrick /// basename only) For example a type like "std::vector<int>::iterator" 41061da546Spatrick /// would have a name of "iterator" and a 32 bit hash for 42061da546Spatrick /// "std::vector<int>::iterator" to allow us to not have to pull in debug 43061da546Spatrick /// info for a type when we know the fully qualified name. 44061da546Spatrick eAtomTypeQualNameHash = 6u 45061da546Spatrick }; 46061da546Spatrick 47061da546Spatrick /// Bit definitions for the eAtomTypeTypeFlags flags. 48061da546Spatrick enum TypeFlags { 49061da546Spatrick /// Always set for C++, only set for ObjC if this is the 50061da546Spatrick /// @implementation for class. 51061da546Spatrick eTypeFlagClassIsImplementation = (1u << 1) 52061da546Spatrick }; 53061da546Spatrick 54061da546Spatrick struct DIEInfo { 55061da546Spatrick dw_offset_t die_offset = DW_INVALID_OFFSET; 56061da546Spatrick dw_tag_t tag = llvm::dwarf::DW_TAG_null; 57061da546Spatrick 58061da546Spatrick /// Any flags for this DIEInfo. 59061da546Spatrick uint32_t type_flags = 0; 60061da546Spatrick 61061da546Spatrick /// A 32 bit hash of the fully qualified name. 62061da546Spatrick uint32_t qualified_name_hash = 0; 63061da546Spatrick 64061da546Spatrick DIEInfo() = default; 65061da546Spatrick DIEInfo(dw_offset_t o, dw_tag_t t, uint32_t f, uint32_t h); 66061da546Spatrick DIERefDIEInfo67061da546Spatrick explicit operator DIERef() const { 68*f6aab3d8Srobert return DIERef(std::nullopt, DIERef::Section::DebugInfo, die_offset); 69061da546Spatrick } 70061da546Spatrick }; 71061da546Spatrick 72061da546Spatrick struct Atom { 73061da546Spatrick AtomType type; 74061da546Spatrick dw_form_t form; 75061da546Spatrick }; 76061da546Spatrick 77061da546Spatrick typedef std::vector<DIEInfo> DIEInfoArray; 78061da546Spatrick typedef std::vector<Atom> AtomArray; 79061da546Spatrick 80061da546Spatrick class Prologue { 81061da546Spatrick public: 82061da546Spatrick Prologue(dw_offset_t _die_base_offset = 0); 83061da546Spatrick 84061da546Spatrick void ClearAtoms(); 85061da546Spatrick 86061da546Spatrick bool ContainsAtom(AtomType atom_type) const; 87061da546Spatrick 88061da546Spatrick void Clear(); 89061da546Spatrick 90061da546Spatrick void AppendAtom(AtomType type, dw_form_t form); 91061da546Spatrick 92061da546Spatrick lldb::offset_t Read(const lldb_private::DataExtractor &data, 93061da546Spatrick lldb::offset_t offset); 94061da546Spatrick 95061da546Spatrick size_t GetByteSize() const; 96061da546Spatrick 97061da546Spatrick size_t GetMinimumHashDataByteSize() const; 98061da546Spatrick 99061da546Spatrick bool HashDataHasFixedByteSize() const; 100061da546Spatrick 101061da546Spatrick /// DIE offset base so die offsets in hash_data can be CU relative. 102061da546Spatrick dw_offset_t die_base_offset; 103061da546Spatrick AtomArray atoms; 104be691f3bSpatrick uint32_t atom_mask = 0; 105be691f3bSpatrick size_t min_hash_data_byte_size = 0; 106be691f3bSpatrick bool hash_data_has_fixed_byte_size = true; 107061da546Spatrick }; 108061da546Spatrick 109061da546Spatrick class Header : public MappedHash::Header<Prologue> { 110061da546Spatrick public: 111061da546Spatrick size_t GetByteSize(const HeaderData &header_data) override; 112061da546Spatrick 113061da546Spatrick lldb::offset_t Read(lldb_private::DataExtractor &data, 114061da546Spatrick lldb::offset_t offset) override; 115061da546Spatrick 116061da546Spatrick bool Read(const lldb_private::DWARFDataExtractor &data, 117061da546Spatrick lldb::offset_t *offset_ptr, DIEInfo &hash_data) const; 118061da546Spatrick }; 119061da546Spatrick 120061da546Spatrick /// A class for reading and using a saved hash table from a block of data in 121061da546Spatrick /// memory. 122061da546Spatrick class MemoryTable 123061da546Spatrick : public MappedHash::MemoryTable<uint32_t, DWARFMappedHash::Header, 124061da546Spatrick DIEInfoArray> { 125061da546Spatrick public: 126061da546Spatrick MemoryTable(lldb_private::DWARFDataExtractor &table_data, 127061da546Spatrick const lldb_private::DWARFDataExtractor &string_table, 128061da546Spatrick const char *name); 129061da546Spatrick 130061da546Spatrick const char *GetStringForKeyType(KeyType key) const override; 131061da546Spatrick 132061da546Spatrick bool ReadHashData(uint32_t hash_data_offset, 133061da546Spatrick HashData &hash_data) const override; 134061da546Spatrick 135dda28197Spatrick void 136061da546Spatrick AppendAllDIEsThatMatchingRegex(const lldb_private::RegularExpression ®ex, 137061da546Spatrick DIEInfoArray &die_info_array) const; 138061da546Spatrick 139dda28197Spatrick void AppendAllDIEsInRange(const uint32_t die_offset_start, 140061da546Spatrick const uint32_t die_offset_end, 141061da546Spatrick DIEInfoArray &die_info_array) const; 142061da546Spatrick 143dda28197Spatrick bool FindByName(llvm::StringRef name, 144dda28197Spatrick llvm::function_ref<bool(DIERef ref)> callback); 145061da546Spatrick 146dda28197Spatrick void FindByNameAndTag(llvm::StringRef name, const dw_tag_t tag, 147dda28197Spatrick llvm::function_ref<bool(DIERef ref)> callback); 148061da546Spatrick 149dda28197Spatrick void FindByNameAndTagAndQualifiedNameHash( 150061da546Spatrick llvm::StringRef name, const dw_tag_t tag, 151dda28197Spatrick const uint32_t qualified_name_hash, 152dda28197Spatrick llvm::function_ref<bool(DIERef ref)> callback); 153061da546Spatrick 154dda28197Spatrick void 155dda28197Spatrick FindCompleteObjCClassByName(llvm::StringRef name, 156dda28197Spatrick llvm::function_ref<bool(DIERef ref)> callback, 157061da546Spatrick bool must_be_implementation); 158061da546Spatrick 159061da546Spatrick protected: 160061da546Spatrick Result AppendHashDataForRegularExpression( 161061da546Spatrick const lldb_private::RegularExpression ®ex, 162061da546Spatrick lldb::offset_t *hash_data_offset_ptr, Pair &pair) const; 163061da546Spatrick 164dda28197Spatrick void FindByName(llvm::StringRef name, DIEInfoArray &die_info_array); 165061da546Spatrick 166061da546Spatrick Result GetHashDataForName(llvm::StringRef name, 167061da546Spatrick lldb::offset_t *hash_data_offset_ptr, 168061da546Spatrick Pair &pair) const override; 169061da546Spatrick 170061da546Spatrick lldb_private::DWARFDataExtractor m_data; 171061da546Spatrick lldb_private::DWARFDataExtractor m_string_table; 172061da546Spatrick std::string m_name; 173061da546Spatrick }; 174061da546Spatrick 175dda28197Spatrick static bool ExtractDIEArray(const DIEInfoArray &die_info_array, 176dda28197Spatrick llvm::function_ref<bool(DIERef ref)> callback); 177061da546Spatrick 178061da546Spatrick protected: 179061da546Spatrick static void ExtractDIEArray(const DIEInfoArray &die_info_array, 180dda28197Spatrick const dw_tag_t tag, 181dda28197Spatrick llvm::function_ref<bool(DIERef ref)> callback); 182061da546Spatrick 183061da546Spatrick static void ExtractDIEArray(const DIEInfoArray &die_info_array, 184061da546Spatrick const dw_tag_t tag, 185061da546Spatrick const uint32_t qualified_name_hash, 186dda28197Spatrick llvm::function_ref<bool(DIERef ref)> callback); 187061da546Spatrick 188061da546Spatrick static void 189061da546Spatrick ExtractClassOrStructDIEArray(const DIEInfoArray &die_info_array, 190061da546Spatrick bool return_implementation_only_if_available, 191dda28197Spatrick llvm::function_ref<bool(DIERef ref)> callback); 192061da546Spatrick 193dda28197Spatrick static void 194dda28197Spatrick ExtractTypesFromDIEArray(const DIEInfoArray &die_info_array, 195dda28197Spatrick uint32_t type_flag_mask, uint32_t type_flag_value, 196dda28197Spatrick llvm::function_ref<bool(DIERef ref)> callback); 197061da546Spatrick 198061da546Spatrick static const char *GetAtomTypeName(uint16_t atom); 199061da546Spatrick }; 200061da546Spatrick 201dda28197Spatrick #endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_HASHEDNAMETODIE_H 202