1 //===-- SymbolFileOnDemand.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_SYMBOL_SYMBOLFILEONDEMAND_H
10 #define LLDB_SYMBOL_SYMBOLFILEONDEMAND_H
11 
12 #include <mutex>
13 #include <vector>
14 
15 #include "lldb/Symbol/ObjectFile.h"
16 #include "lldb/Symbol/SymbolContext.h"
17 #include "lldb/Symbol/SymbolFile.h"
18 #include "lldb/Target/Statistics.h"
19 #include "lldb/Utility/ConstString.h"
20 #include "lldb/Utility/Flags.h"
21 #include "lldb/Utility/LLDBLog.h"
22 #include "lldb/Utility/Log.h"
23 #include "lldb/lldb-private.h"
24 
25 namespace lldb_private {
26 
27 /// SymbolFileOnDemand wraps an actual SymbolFile by providing
28 /// on demand symbol parsing/indexing to improve performance.
29 /// By default SymbolFileOnDemand will skip load the underlying
30 /// symbols. Any client can on demand hydrate the underlying
31 /// SymbolFile via SymbolFile::SetLoadDebugInfoEnabled().
32 class SymbolFileOnDemand : public lldb_private::SymbolFile {
33   /// LLVM RTTI support.
34   static char ID;
35 
36 public:
37   /// LLVM RTTI support.
38   /// \{
39   bool isA(const void *ClassID) const override {
40     return ClassID == &ID || SymbolFile::isA(ClassID);
41   }
42   static bool classof(const SymbolFile *obj) { return obj->isA(&ID); }
43   /// \}
44 
45   SymbolFileOnDemand(std::unique_ptr<SymbolFile> &&symbol_file);
46   ~SymbolFileOnDemand() override;
47 
48   // PluginInterface protocol
49   llvm::StringRef GetPluginName() override { return "ondemand"; }
50 
51   bool GetLoadDebugInfoEnabled() override { return m_debug_info_enabled; }
52 
53   void SetLoadDebugInfoEnabled() override;
54 
55   uint32_t GetNumCompileUnits() override;
56   lldb::CompUnitSP GetCompileUnitAtIndex(uint32_t idx) override;
57 
58   SymbolFile *GetBackingSymbolFile() override { return m_sym_file_impl.get(); }
59 
60   uint32_t CalculateAbilities() override;
61 
62   std::recursive_mutex &GetModuleMutex() const override;
63 
64   lldb::LanguageType
65   ParseLanguage(lldb_private::CompileUnit &comp_unit) override;
66 
67   lldb_private::XcodeSDK
68   ParseXcodeSDK(lldb_private::CompileUnit &comp_unit) override;
69 
70   void InitializeObject() override;
71 
72   size_t ParseFunctions(lldb_private::CompileUnit &comp_unit) override;
73 
74   bool ParseLineTable(lldb_private::CompileUnit &comp_unit) override;
75 
76   bool ParseDebugMacros(lldb_private::CompileUnit &comp_unit) override;
77 
78   bool ForEachExternalModule(
79       lldb_private::CompileUnit &, llvm::DenseSet<lldb_private::SymbolFile *> &,
80       llvm::function_ref<bool(lldb_private::Module &)>) override;
81 
82   bool ParseSupportFiles(lldb_private::CompileUnit &comp_unit,
83                          lldb_private::FileSpecList &support_files) override;
84 
85   bool ParseIsOptimized(lldb_private::CompileUnit &comp_unit) override;
86 
87   size_t ParseTypes(lldb_private::CompileUnit &comp_unit) override;
88 
89   bool ParseImportedModules(
90       const lldb_private::SymbolContext &sc,
91       std::vector<lldb_private::SourceModule> &imported_modules) override;
92 
93   size_t ParseBlocksRecursive(lldb_private::Function &func) override;
94 
95   size_t
96   ParseVariablesForContext(const lldb_private::SymbolContext &sc) override;
97 
98   lldb_private::Type *ResolveTypeUID(lldb::user_id_t type_uid) override;
99   llvm::Optional<ArrayInfo> GetDynamicArrayInfoForUID(
100       lldb::user_id_t type_uid,
101       const lldb_private::ExecutionContext *exe_ctx) override;
102 
103   bool CompleteType(lldb_private::CompilerType &compiler_type) override;
104 
105   lldb_private::CompilerDecl GetDeclForUID(lldb::user_id_t uid) override;
106 
107   lldb_private::CompilerDeclContext
108   GetDeclContextForUID(lldb::user_id_t uid) override;
109 
110   lldb_private::CompilerDeclContext
111   GetDeclContextContainingUID(lldb::user_id_t uid) override;
112 
113   void
114   ParseDeclsForContext(lldb_private::CompilerDeclContext decl_ctx) override;
115 
116   uint32_t ResolveSymbolContext(const lldb_private::Address &so_addr,
117                                 lldb::SymbolContextItem resolve_scope,
118                                 lldb_private::SymbolContext &sc) override;
119 
120   uint32_t ResolveSymbolContext(
121       const lldb_private::SourceLocationSpec &src_location_spec,
122       lldb::SymbolContextItem resolve_scope,
123       lldb_private::SymbolContextList &sc_list) override;
124 
125   void Dump(lldb_private::Stream &s) override;
126   void DumpClangAST(lldb_private::Stream &s) override;
127 
128   void
129   FindGlobalVariables(lldb_private::ConstString name,
130                       const lldb_private::CompilerDeclContext &parent_decl_ctx,
131                       uint32_t max_matches,
132                       lldb_private::VariableList &variables) override;
133 
134   void FindGlobalVariables(const lldb_private::RegularExpression &regex,
135                            uint32_t max_matches,
136                            lldb_private::VariableList &variables) override;
137 
138   void FindFunctions(lldb_private::ConstString name,
139                      const lldb_private::CompilerDeclContext &parent_decl_ctx,
140                      lldb::FunctionNameType name_type_mask,
141                      bool include_inlines,
142                      lldb_private::SymbolContextList &sc_list) override;
143 
144   void FindFunctions(const lldb_private::RegularExpression &regex,
145                      bool include_inlines,
146                      lldb_private::SymbolContextList &sc_list) override;
147 
148   void GetMangledNamesForFunction(
149       const std::string &scope_qualified_name,
150       std::vector<lldb_private::ConstString> &mangled_names) override;
151 
152   void
153   FindTypes(lldb_private::ConstString name,
154             const lldb_private::CompilerDeclContext &parent_decl_ctx,
155             uint32_t max_matches,
156             llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
157             lldb_private::TypeMap &types) override;
158 
159   void FindTypes(llvm::ArrayRef<lldb_private::CompilerContext> pattern,
160                  lldb_private::LanguageSet languages,
161                  llvm::DenseSet<SymbolFile *> &searched_symbol_files,
162                  lldb_private::TypeMap &types) override;
163 
164   void GetTypes(lldb_private::SymbolContextScope *sc_scope,
165                 lldb::TypeClass type_mask,
166                 lldb_private::TypeList &type_list) override;
167 
168   llvm::Expected<lldb_private::TypeSystem &>
169   GetTypeSystemForLanguage(lldb::LanguageType language) override;
170 
171   lldb_private::CompilerDeclContext FindNamespace(
172       lldb_private::ConstString name,
173       const lldb_private::CompilerDeclContext &parent_decl_ctx) override;
174 
175   std::vector<std::unique_ptr<lldb_private::CallEdge>>
176   ParseCallEdgesInFunction(UserID func_id) override;
177 
178   lldb::UnwindPlanSP
179   GetUnwindPlan(const Address &address,
180                 const RegisterInfoResolver &resolver) override;
181 
182   llvm::Expected<lldb::addr_t> GetParameterStackSize(Symbol &symbol) override;
183 
184   void PreloadSymbols() override;
185 
186   uint64_t GetDebugInfoSize() override;
187   lldb_private::StatsDuration::Duration GetDebugInfoParseTime() override;
188   lldb_private::StatsDuration::Duration GetDebugInfoIndexTime() override;
189 
190   uint32_t GetAbilities() override;
191 
192   Symtab *GetSymtab() override { return m_sym_file_impl->GetSymtab(); }
193 
194   ObjectFile *GetObjectFile() override {
195     return m_sym_file_impl->GetObjectFile();
196   }
197   const ObjectFile *GetObjectFile() const override {
198     return m_sym_file_impl->GetObjectFile();
199   }
200   ObjectFile *GetMainObjectFile() override {
201     return m_sym_file_impl->GetMainObjectFile();
202   }
203 
204   void SectionFileAddressesChanged() override {
205     return m_sym_file_impl->SectionFileAddressesChanged();
206   }
207 
208   bool GetDebugInfoIndexWasLoadedFromCache() const override {
209     return m_sym_file_impl->GetDebugInfoIndexWasLoadedFromCache();
210   }
211   void SetDebugInfoIndexWasLoadedFromCache() override {
212     m_sym_file_impl->SetDebugInfoIndexWasLoadedFromCache();
213   }
214   bool GetDebugInfoIndexWasSavedToCache() const override {
215     return m_sym_file_impl->GetDebugInfoIndexWasSavedToCache();
216   }
217   void SetDebugInfoIndexWasSavedToCache() override {
218     m_sym_file_impl->SetDebugInfoIndexWasSavedToCache();
219   }
220 
221 private:
222   Log *GetLog() const { return ::lldb_private::GetLog(LLDBLog::OnDemand); }
223 
224   ConstString GetSymbolFileName() {
225     return GetObjectFile()->GetFileSpec().GetFilename();
226   }
227 
228 private:
229   bool m_debug_info_enabled = false;
230   bool m_preload_symbols = false;
231   std::unique_ptr<SymbolFile> m_sym_file_impl;
232 };
233 } // namespace lldb_private
234 
235 #endif // LLDB_SYMBOL_SYMBOLFILEONDEMAND_H
236