xref: /freebsd/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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 &regex,
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 &regex,
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