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