xref: /openbsd-src/gnu/llvm/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h (revision f6aab3d83b51b91c24247ad2c2573574de475a82)
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 &regex,
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 &regex,
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