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