1 //===-- ManualDWARFIndex.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_MANUALDWARFINDEX_H 10 #define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_MANUALDWARFINDEX_H 11 12 #include "Plugins/SymbolFile/DWARF/DWARFIndex.h" 13 #include "Plugins/SymbolFile/DWARF/NameToDIE.h" 14 #include "llvm/ADT/DenseSet.h" 15 16 namespace lldb_private::plugin { 17 namespace dwarf { 18 class DWARFDebugInfo; 19 class SymbolFileDWARFDwo; 20 21 class ManualDWARFIndex : public DWARFIndex { 22 public: 23 ManualDWARFIndex(Module &module, SymbolFileDWARF &dwarf, 24 llvm::DenseSet<dw_offset_t> units_to_avoid = {}, 25 llvm::DenseSet<uint64_t> type_sigs_to_avoid = {}) DWARFIndex(module)26 : DWARFIndex(module), m_dwarf(&dwarf), 27 m_units_to_avoid(std::move(units_to_avoid)), 28 m_type_sigs_to_avoid(std::move(type_sigs_to_avoid)) {} 29 Preload()30 void Preload() override { Index(); } 31 32 void 33 GetGlobalVariables(ConstString basename, 34 llvm::function_ref<bool(DWARFDIE die)> callback) override; 35 void 36 GetGlobalVariables(const RegularExpression ®ex, 37 llvm::function_ref<bool(DWARFDIE die)> callback) override; 38 void 39 GetGlobalVariables(DWARFUnit &unit, 40 llvm::function_ref<bool(DWARFDIE die)> callback) override; 41 void GetObjCMethods(ConstString class_name, 42 llvm::function_ref<bool(DWARFDIE die)> callback) override; 43 void GetCompleteObjCClass( 44 ConstString class_name, bool must_be_implementation, 45 llvm::function_ref<bool(DWARFDIE die)> callback) override; 46 void GetTypes(ConstString name, 47 llvm::function_ref<bool(DWARFDIE die)> callback) override; 48 void GetTypes(const DWARFDeclContext &context, 49 llvm::function_ref<bool(DWARFDIE die)> callback) override; 50 void GetNamespaces(ConstString name, 51 llvm::function_ref<bool(DWARFDIE die)> callback) override; 52 void GetFunctions(const Module::LookupInfo &lookup_info, 53 SymbolFileDWARF &dwarf, 54 const CompilerDeclContext &parent_decl_ctx, 55 llvm::function_ref<bool(DWARFDIE die)> callback) override; 56 void GetFunctions(const RegularExpression ®ex, 57 llvm::function_ref<bool(DWARFDIE die)> callback) override; 58 59 void Dump(Stream &s) override; 60 61 // Make IndexSet public so we can unit test the encoding and decoding logic. 62 struct IndexSet { 63 NameToDIE function_basenames; 64 NameToDIE function_fullnames; 65 NameToDIE function_methods; 66 NameToDIE function_selectors; 67 NameToDIE objc_class_selectors; 68 NameToDIE globals; 69 NameToDIE types; 70 NameToDIE namespaces; 71 bool Decode(const DataExtractor &data, lldb::offset_t *offset_ptr); 72 void Encode(DataEncoder &encoder) const; 73 bool operator==(const IndexSet &rhs) const { 74 return function_basenames == rhs.function_basenames && 75 function_fullnames == rhs.function_fullnames && 76 function_methods == rhs.function_methods && 77 function_selectors == rhs.function_selectors && 78 objc_class_selectors == rhs.objc_class_selectors && 79 globals == rhs.globals && types == rhs.types && 80 namespaces == rhs.namespaces; 81 } 82 }; 83 84 private: 85 void Index(); 86 87 /// Decode a serialized version of this object from data. 88 /// 89 /// \param data 90 /// The decoder object that references the serialized data. 91 /// 92 /// \param offset_ptr 93 /// A pointer that contains the offset from which the data will be decoded 94 /// from that gets updated as data gets decoded. 95 /// 96 /// \param strtab 97 /// All strings in cache files are put into string tables for efficiency 98 /// and cache file size reduction. Strings are stored as uint32_t string 99 /// table offsets in the cache data. 100 bool Decode(const DataExtractor &data, lldb::offset_t *offset_ptr, 101 bool &signature_mismatch); 102 103 /// Encode this object into a data encoder object. 104 /// 105 /// This allows this object to be serialized to disk. 106 /// 107 /// \param encoder 108 /// A data encoder object that serialized bytes will be encoded into. 109 /// 110 /// \param strtab 111 /// All strings in cache files are put into string tables for efficiency 112 /// and cache file size reduction. Strings are stored as uint32_t string 113 /// table offsets in the cache data. 114 /// 115 /// \return 116 /// True if the symbol table's object file can generate a valid signature 117 /// and all data for the symbol table was encoded, false otherwise. 118 bool Encode(DataEncoder &encoder) const; 119 120 /// Get the cache key string for this symbol table. 121 /// 122 /// The cache key must start with the module's cache key and is followed 123 /// by information that indicates this key is for caching the symbol table 124 /// contents and should also include the has of the object file. A module can 125 /// be represented by an ObjectFile object for the main executable, but can 126 /// also have a symbol file that is from the same or a different object file. 127 /// This means we might have two symbol tables cached in the index cache, one 128 /// for the main executable and one for the symbol file. 129 /// 130 /// \return 131 /// The unique cache key used to save and retrieve data from the index 132 /// cache. 133 std::string GetCacheKey(); 134 135 /// Save the symbol table data out into a cache. 136 /// 137 /// The symbol table will only be saved to a cache file if caching is enabled. 138 /// 139 /// We cache the contents of the symbol table since symbol tables in LLDB take 140 /// some time to initialize. This is due to the many sources for data that are 141 /// used to create a symbol table: 142 /// - standard symbol table 143 /// - dynamic symbol table (ELF) 144 /// - compressed debug info sections 145 /// - unwind information 146 /// - function pointers found in runtimes for global constructor/destructors 147 /// - other sources. 148 /// All of the above sources are combined and one symbol table results after 149 /// all sources have been considered. 150 void SaveToCache(); 151 152 /// Load the symbol table from the index cache. 153 /// 154 /// Quickly load the finalized symbol table from the index cache. This saves 155 /// time when the debugger starts up. The index cache file for the symbol 156 /// table has the modification time set to the same time as the main module. 157 /// If the cache file exists and the modification times match, we will load 158 /// the symbol table from the serlized cache file. 159 /// 160 /// \return 161 /// True if the symbol table was successfully loaded from the index cache, 162 /// false if the symbol table wasn't cached or was out of date. 163 bool LoadFromCache(); 164 165 void IndexUnit(DWARFUnit &unit, SymbolFileDWARFDwo *dwp, IndexSet &set); 166 167 static void IndexUnitImpl(DWARFUnit &unit, 168 const lldb::LanguageType cu_language, 169 IndexSet &set); 170 171 /// The DWARF file which we are indexing. 172 SymbolFileDWARF *m_dwarf; 173 /// Which dwarf units should we skip while building the index. 174 llvm::DenseSet<dw_offset_t> m_units_to_avoid; 175 llvm::DenseSet<uint64_t> m_type_sigs_to_avoid; 176 177 IndexSet m_set; 178 bool m_indexed = false; 179 }; 180 } // namespace dwarf 181 } // namespace lldb_private::plugin 182 183 #endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_MANUALDWARFINDEX_H 184