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
16namespace lldb_private::plugin {
17namespace dwarf {
18class DWARFDebugInfo;
19class SymbolFileDWARFDwo;
20
21class ManualDWARFIndex : public DWARFIndex {
22public:
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 &regex,
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 &regex,
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
82private:
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

source code of lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h