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