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