1 //===-- SymbolVendor.cpp ----------------------------------------*- 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 #include "lldb/Symbol/SymbolVendor.h"
10 
11 #include "lldb/Core/Module.h"
12 #include "lldb/Core/PluginManager.h"
13 #include "lldb/Symbol/CompileUnit.h"
14 #include "lldb/Symbol/ObjectFile.h"
15 #include "lldb/Symbol/SymbolFile.h"
16 #include "lldb/Utility/Stream.h"
17 
18 using namespace lldb;
19 using namespace lldb_private;
20 
21 // FindPlugin
22 //
23 // Platforms can register a callback to use when creating symbol vendors to
24 // allow for complex debug information file setups, and to also allow for
25 // finding separate debug information files.
26 SymbolVendor *SymbolVendor::FindPlugin(const lldb::ModuleSP &module_sp,
27                                        lldb_private::Stream *feedback_strm) {
28   std::unique_ptr<SymbolVendor> instance_up;
29   SymbolVendorCreateInstance create_callback;
30 
31   for (size_t idx = 0;
32        (create_callback = PluginManager::GetSymbolVendorCreateCallbackAtIndex(
33             idx)) != nullptr;
34        ++idx) {
35     instance_up.reset(create_callback(module_sp, feedback_strm));
36 
37     if (instance_up) {
38       return instance_up.release();
39     }
40   }
41   // The default implementation just tries to create debug information using
42   // the file representation for the module.
43   ObjectFileSP sym_objfile_sp;
44   FileSpec sym_spec = module_sp->GetSymbolFileFileSpec();
45   if (sym_spec && sym_spec != module_sp->GetObjectFile()->GetFileSpec()) {
46     DataBufferSP data_sp;
47     offset_t data_offset = 0;
48     sym_objfile_sp = ObjectFile::FindPlugin(
49         module_sp, &sym_spec, 0, FileSystem::Instance().GetByteSize(sym_spec),
50         data_sp, data_offset);
51   }
52   if (!sym_objfile_sp)
53     sym_objfile_sp = module_sp->GetObjectFile()->shared_from_this();
54   instance_up.reset(new SymbolVendor(module_sp));
55   instance_up->AddSymbolFileRepresentation(sym_objfile_sp);
56   return instance_up.release();
57 }
58 
59 // SymbolVendor constructor
60 SymbolVendor::SymbolVendor(const lldb::ModuleSP &module_sp)
61     : ModuleChild(module_sp), m_sym_file_up() {}
62 
63 // Destructor
64 SymbolVendor::~SymbolVendor() {}
65 
66 // Add a representation given an object file.
67 void SymbolVendor::AddSymbolFileRepresentation(const ObjectFileSP &objfile_sp) {
68   ModuleSP module_sp(GetModule());
69   if (module_sp) {
70     std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
71     if (objfile_sp)
72       m_sym_file_up.reset(SymbolFile::FindPlugin(objfile_sp));
73   }
74 }
75 
76 size_t SymbolVendor::GetNumCompileUnits() {
77   if (m_sym_file_up)
78     return m_sym_file_up->GetNumCompileUnits();
79   return 0;
80 }
81 
82 lldb::LanguageType SymbolVendor::ParseLanguage(CompileUnit &comp_unit) {
83   if (m_sym_file_up)
84     return m_sym_file_up->ParseLanguage(comp_unit);
85   return eLanguageTypeUnknown;
86 }
87 
88 size_t SymbolVendor::ParseFunctions(CompileUnit &comp_unit) {
89   if (m_sym_file_up)
90     return m_sym_file_up->ParseFunctions(comp_unit);
91   return 0;
92 }
93 
94 bool SymbolVendor::ParseLineTable(CompileUnit &comp_unit) {
95   if (m_sym_file_up)
96     return m_sym_file_up->ParseLineTable(comp_unit);
97   return false;
98 }
99 
100 bool SymbolVendor::ParseDebugMacros(CompileUnit &comp_unit) {
101   if (m_sym_file_up)
102     return m_sym_file_up->ParseDebugMacros(comp_unit);
103   return false;
104 }
105 bool SymbolVendor::ParseSupportFiles(CompileUnit &comp_unit,
106                                      FileSpecList &support_files) {
107   if (m_sym_file_up)
108     return m_sym_file_up->ParseSupportFiles(comp_unit, support_files);
109   return false;
110 }
111 
112 bool SymbolVendor::ParseIsOptimized(CompileUnit &comp_unit) {
113   if (m_sym_file_up)
114     return m_sym_file_up->ParseIsOptimized(comp_unit);
115   return false;
116 }
117 
118 bool SymbolVendor::ParseImportedModules(
119     const SymbolContext &sc, std::vector<SourceModule> &imported_modules) {
120   if (m_sym_file_up)
121     return m_sym_file_up->ParseImportedModules(sc, imported_modules);
122   return false;
123 }
124 
125 size_t SymbolVendor::ParseBlocksRecursive(Function &func) {
126   if (m_sym_file_up)
127     return m_sym_file_up->ParseBlocksRecursive(func);
128   return 0;
129 }
130 
131 size_t SymbolVendor::ParseTypes(CompileUnit &comp_unit) {
132   if (m_sym_file_up)
133     return m_sym_file_up->ParseTypes(comp_unit);
134   return 0;
135 }
136 
137 size_t SymbolVendor::ParseVariablesForContext(const SymbolContext &sc) {
138   if (m_sym_file_up)
139     return m_sym_file_up->ParseVariablesForContext(sc);
140   return 0;
141 }
142 
143 Type *SymbolVendor::ResolveTypeUID(lldb::user_id_t type_uid) {
144   if (m_sym_file_up)
145     return m_sym_file_up->ResolveTypeUID(type_uid);
146   return nullptr;
147 }
148 
149 uint32_t SymbolVendor::ResolveSymbolContext(const Address &so_addr,
150                                             SymbolContextItem resolve_scope,
151                                             SymbolContext &sc) {
152   if (m_sym_file_up)
153     return m_sym_file_up->ResolveSymbolContext(so_addr, resolve_scope, sc);
154   return 0;
155 }
156 
157 uint32_t SymbolVendor::ResolveSymbolContext(const FileSpec &file_spec,
158                                             uint32_t line, bool check_inlines,
159                                             SymbolContextItem resolve_scope,
160                                             SymbolContextList &sc_list) {
161   if (m_sym_file_up)
162     return m_sym_file_up->ResolveSymbolContext(file_spec, line, check_inlines,
163                                                resolve_scope, sc_list);
164   return 0;
165 }
166 
167 size_t
168 SymbolVendor::FindGlobalVariables(ConstString name,
169                                   const CompilerDeclContext *parent_decl_ctx,
170                                   size_t max_matches, VariableList &variables) {
171   if (m_sym_file_up)
172     return m_sym_file_up->FindGlobalVariables(name, parent_decl_ctx,
173                                               max_matches, variables);
174   return 0;
175 }
176 
177 size_t SymbolVendor::FindGlobalVariables(const RegularExpression &regex,
178                                          size_t max_matches,
179                                          VariableList &variables) {
180   if (m_sym_file_up)
181     return m_sym_file_up->FindGlobalVariables(regex, max_matches, variables);
182   return 0;
183 }
184 
185 size_t SymbolVendor::FindFunctions(ConstString name,
186                                    const CompilerDeclContext *parent_decl_ctx,
187                                    FunctionNameType name_type_mask,
188                                    bool include_inlines, bool append,
189                                    SymbolContextList &sc_list) {
190   if (m_sym_file_up)
191     return m_sym_file_up->FindFunctions(name, parent_decl_ctx, name_type_mask,
192                                         include_inlines, append, sc_list);
193   return 0;
194 }
195 
196 size_t SymbolVendor::FindFunctions(const RegularExpression &regex,
197                                    bool include_inlines, bool append,
198                                    SymbolContextList &sc_list) {
199   if (m_sym_file_up)
200     return m_sym_file_up->FindFunctions(regex, include_inlines, append,
201                                         sc_list);
202   return 0;
203 }
204 
205 size_t SymbolVendor::FindTypes(
206     ConstString name, const CompilerDeclContext *parent_decl_ctx,
207     bool append, size_t max_matches,
208     llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
209     TypeMap &types) {
210   if (m_sym_file_up)
211     return m_sym_file_up->FindTypes(name, parent_decl_ctx, append, max_matches,
212                                     searched_symbol_files, types);
213   if (!append)
214     types.Clear();
215   return 0;
216 }
217 
218 size_t SymbolVendor::FindTypes(const std::vector<CompilerContext> &context,
219                                bool append, TypeMap &types) {
220   if (m_sym_file_up)
221     return m_sym_file_up->FindTypes(context, append, types);
222   if (!append)
223     types.Clear();
224   return 0;
225 }
226 
227 size_t SymbolVendor::GetTypes(SymbolContextScope *sc_scope, TypeClass type_mask,
228                               lldb_private::TypeList &type_list) {
229   if (m_sym_file_up)
230     return m_sym_file_up->GetTypes(sc_scope, type_mask, type_list);
231   return 0;
232 }
233 
234 CompilerDeclContext
235 SymbolVendor::FindNamespace(ConstString name,
236                             const CompilerDeclContext *parent_decl_ctx) {
237   CompilerDeclContext namespace_decl_ctx;
238   if (m_sym_file_up)
239     namespace_decl_ctx = m_sym_file_up->FindNamespace(name, parent_decl_ctx);
240   return namespace_decl_ctx;
241 }
242 
243 void SymbolVendor::Dump(Stream *s) {
244   ModuleSP module_sp(GetModule());
245   if (module_sp) {
246     std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
247 
248     s->Printf("%p: ", static_cast<void *>(this));
249     s->Indent();
250     s->PutCString("SymbolVendor");
251     if (m_sym_file_up) {
252       *s << " " << m_sym_file_up->GetPluginName();
253       ObjectFile *objfile = m_sym_file_up->GetObjectFile();
254       if (objfile) {
255         const FileSpec &objfile_file_spec = objfile->GetFileSpec();
256         if (objfile_file_spec) {
257           s->PutCString(" (");
258           objfile_file_spec.Dump(s);
259           s->PutChar(')');
260         }
261       }
262     }
263     s->EOL();
264     if (m_sym_file_up)
265       m_sym_file_up->Dump(*s);
266     s->IndentMore();
267 
268     if (Symtab *symtab = GetSymtab())
269       symtab->Dump(s, nullptr, eSortOrderNone);
270 
271     s->IndentLess();
272   }
273 }
274 
275 CompUnitSP SymbolVendor::GetCompileUnitAtIndex(size_t idx) {
276   if (m_sym_file_up)
277     return m_sym_file_up->GetCompileUnitAtIndex(idx);
278   return nullptr;
279 }
280 
281 FileSpec SymbolVendor::GetMainFileSpec() const {
282   if (m_sym_file_up) {
283     const ObjectFile *symfile_objfile = m_sym_file_up->GetObjectFile();
284     if (symfile_objfile)
285       return symfile_objfile->GetFileSpec();
286   }
287 
288   return FileSpec();
289 }
290 
291 Symtab *SymbolVendor::GetSymtab() {
292   if (m_sym_file_up)
293     return m_sym_file_up->GetSymtab();
294   return nullptr;
295 }
296 
297 void SymbolVendor::SectionFileAddressesChanged() {
298   if (m_sym_file_up)
299     m_sym_file_up->SectionFileAddressesChanged();
300 }
301 
302 // PluginInterface protocol
303 lldb_private::ConstString SymbolVendor::GetPluginName() {
304   static ConstString g_name("vendor-default");
305   return g_name;
306 }
307 
308 uint32_t SymbolVendor::GetPluginVersion() { return 1; }
309