]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Symbol/SymbolVendor.cpp
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Symbol / SymbolVendor.cpp
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_type_list(), m_compile_units(), m_sym_file_up(),
62       m_symtab() {}
63
64 // Destructor
65 SymbolVendor::~SymbolVendor() {}
66
67 // Add a representation given an object file.
68 void SymbolVendor::AddSymbolFileRepresentation(const ObjectFileSP &objfile_sp) {
69   ModuleSP module_sp(GetModule());
70   if (module_sp) {
71     std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
72     if (objfile_sp) {
73       m_objfile_sp = objfile_sp;
74       m_sym_file_up.reset(SymbolFile::FindPlugin(objfile_sp.get()));
75     }
76   }
77 }
78
79 bool SymbolVendor::SetCompileUnitAtIndex(size_t idx, const CompUnitSP &cu_sp) {
80   ModuleSP module_sp(GetModule());
81   if (module_sp) {
82     std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
83     const size_t num_compile_units = GetNumCompileUnits();
84     if (idx < num_compile_units) {
85       // Fire off an assertion if this compile unit already exists for now. The
86       // partial parsing should take care of only setting the compile unit
87       // once, so if this assertion fails, we need to make sure that we don't
88       // have a race condition, or have a second parse of the same compile
89       // unit.
90       assert(m_compile_units[idx].get() == nullptr);
91       m_compile_units[idx] = cu_sp;
92       return true;
93     } else {
94       // This should NOT happen, and if it does, we want to crash and know
95       // about it
96       assert(idx < num_compile_units);
97     }
98   }
99   return false;
100 }
101
102 size_t SymbolVendor::GetNumCompileUnits() {
103   ModuleSP module_sp(GetModule());
104   if (module_sp) {
105     std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
106     if (m_compile_units.empty()) {
107       if (m_sym_file_up) {
108         // Resize our array of compile unit shared pointers -- which will each
109         // remain NULL until someone asks for the actual compile unit
110         // information. When this happens, the symbol file will be asked to
111         // parse this compile unit information.
112         m_compile_units.resize(m_sym_file_up->GetNumCompileUnits());
113       }
114     }
115   }
116   return m_compile_units.size();
117 }
118
119 lldb::LanguageType SymbolVendor::ParseLanguage(CompileUnit &comp_unit) {
120   ModuleSP module_sp(GetModule());
121   if (module_sp) {
122     std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
123     if (m_sym_file_up)
124       return m_sym_file_up->ParseLanguage(comp_unit);
125   }
126   return eLanguageTypeUnknown;
127 }
128
129 size_t SymbolVendor::ParseFunctions(CompileUnit &comp_unit) {
130   ModuleSP module_sp(GetModule());
131   if (module_sp) {
132     std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
133     if (m_sym_file_up)
134       return m_sym_file_up->ParseFunctions(comp_unit);
135   }
136   return 0;
137 }
138
139 bool SymbolVendor::ParseLineTable(CompileUnit &comp_unit) {
140   ModuleSP module_sp(GetModule());
141   if (module_sp) {
142     std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
143     if (m_sym_file_up)
144       return m_sym_file_up->ParseLineTable(comp_unit);
145   }
146   return false;
147 }
148
149 bool SymbolVendor::ParseDebugMacros(CompileUnit &comp_unit) {
150   ModuleSP module_sp(GetModule());
151   if (module_sp) {
152     std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
153     if (m_sym_file_up)
154       return m_sym_file_up->ParseDebugMacros(comp_unit);
155   }
156   return false;
157 }
158 bool SymbolVendor::ParseSupportFiles(CompileUnit &comp_unit,
159                                      FileSpecList &support_files) {
160   ModuleSP module_sp(GetModule());
161   if (module_sp) {
162     std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
163     if (m_sym_file_up)
164       return m_sym_file_up->ParseSupportFiles(comp_unit, support_files);
165   }
166   return false;
167 }
168
169 bool SymbolVendor::ParseIsOptimized(CompileUnit &comp_unit) {
170   ModuleSP module_sp(GetModule());
171   if (module_sp) {
172     std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
173     if (m_sym_file_up)
174       return m_sym_file_up->ParseIsOptimized(comp_unit);
175   }
176   return false;
177 }
178
179 bool SymbolVendor::ParseImportedModules(
180     const SymbolContext &sc, std::vector<SourceModule> &imported_modules) {
181   ModuleSP module_sp(GetModule());
182   if (module_sp) {
183     std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
184     if (m_sym_file_up)
185       return m_sym_file_up->ParseImportedModules(sc, imported_modules);
186   }
187   return false;
188 }
189
190 size_t SymbolVendor::ParseBlocksRecursive(Function &func) {
191   ModuleSP module_sp(GetModule());
192   if (module_sp) {
193     std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
194     if (m_sym_file_up)
195       return m_sym_file_up->ParseBlocksRecursive(func);
196   }
197   return 0;
198 }
199
200 size_t SymbolVendor::ParseTypes(CompileUnit &comp_unit) {
201   ModuleSP module_sp(GetModule());
202   if (module_sp) {
203     std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
204     if (m_sym_file_up)
205       return m_sym_file_up->ParseTypes(comp_unit);
206   }
207   return 0;
208 }
209
210 size_t SymbolVendor::ParseVariablesForContext(const SymbolContext &sc) {
211   ModuleSP module_sp(GetModule());
212   if (module_sp) {
213     std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
214     if (m_sym_file_up)
215       return m_sym_file_up->ParseVariablesForContext(sc);
216   }
217   return 0;
218 }
219
220 Type *SymbolVendor::ResolveTypeUID(lldb::user_id_t type_uid) {
221   ModuleSP module_sp(GetModule());
222   if (module_sp) {
223     std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
224     if (m_sym_file_up)
225       return m_sym_file_up->ResolveTypeUID(type_uid);
226   }
227   return nullptr;
228 }
229
230 uint32_t SymbolVendor::ResolveSymbolContext(const Address &so_addr,
231                                             SymbolContextItem resolve_scope,
232                                             SymbolContext &sc) {
233   ModuleSP module_sp(GetModule());
234   if (module_sp) {
235     std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
236     if (m_sym_file_up)
237       return m_sym_file_up->ResolveSymbolContext(so_addr, resolve_scope, sc);
238   }
239   return 0;
240 }
241
242 uint32_t SymbolVendor::ResolveSymbolContext(const FileSpec &file_spec,
243                                             uint32_t line, bool check_inlines,
244                                             SymbolContextItem resolve_scope,
245                                             SymbolContextList &sc_list) {
246   ModuleSP module_sp(GetModule());
247   if (module_sp) {
248     std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
249     if (m_sym_file_up)
250       return m_sym_file_up->ResolveSymbolContext(file_spec, line, check_inlines,
251                                                  resolve_scope, sc_list);
252   }
253   return 0;
254 }
255
256 size_t
257 SymbolVendor::FindGlobalVariables(ConstString name,
258                                   const CompilerDeclContext *parent_decl_ctx,
259                                   size_t max_matches, VariableList &variables) {
260   ModuleSP module_sp(GetModule());
261   if (module_sp) {
262     std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
263     if (m_sym_file_up)
264       return m_sym_file_up->FindGlobalVariables(name, parent_decl_ctx,
265                                                 max_matches, variables);
266   }
267   return 0;
268 }
269
270 size_t SymbolVendor::FindGlobalVariables(const RegularExpression &regex,
271                                          size_t max_matches,
272                                          VariableList &variables) {
273   ModuleSP module_sp(GetModule());
274   if (module_sp) {
275     std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
276     if (m_sym_file_up)
277       return m_sym_file_up->FindGlobalVariables(regex, max_matches, variables);
278   }
279   return 0;
280 }
281
282 size_t SymbolVendor::FindFunctions(ConstString name,
283                                    const CompilerDeclContext *parent_decl_ctx,
284                                    FunctionNameType name_type_mask,
285                                    bool include_inlines, bool append,
286                                    SymbolContextList &sc_list) {
287   ModuleSP module_sp(GetModule());
288   if (module_sp) {
289     std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
290     if (m_sym_file_up)
291       return m_sym_file_up->FindFunctions(name, parent_decl_ctx, name_type_mask,
292                                           include_inlines, append, sc_list);
293   }
294   return 0;
295 }
296
297 size_t SymbolVendor::FindFunctions(const RegularExpression &regex,
298                                    bool include_inlines, bool append,
299                                    SymbolContextList &sc_list) {
300   ModuleSP module_sp(GetModule());
301   if (module_sp) {
302     std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
303     if (m_sym_file_up)
304       return m_sym_file_up->FindFunctions(regex, include_inlines, append,
305                                           sc_list);
306   }
307   return 0;
308 }
309
310 size_t SymbolVendor::FindTypes(
311     ConstString name, const CompilerDeclContext *parent_decl_ctx,
312     bool append, size_t max_matches,
313     llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
314     TypeMap &types) {
315   ModuleSP module_sp(GetModule());
316   if (module_sp) {
317     std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
318     if (m_sym_file_up)
319       return m_sym_file_up->FindTypes(name, parent_decl_ctx, append,
320                                       max_matches, searched_symbol_files,
321                                       types);
322   }
323   if (!append)
324     types.Clear();
325   return 0;
326 }
327
328 size_t SymbolVendor::FindTypes(const std::vector<CompilerContext> &context,
329                                bool append, TypeMap &types) {
330   ModuleSP module_sp(GetModule());
331   if (module_sp) {
332     std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
333     if (m_sym_file_up)
334       return m_sym_file_up->FindTypes(context, append, types);
335   }
336   if (!append)
337     types.Clear();
338   return 0;
339 }
340
341 size_t SymbolVendor::GetTypes(SymbolContextScope *sc_scope, TypeClass type_mask,
342                               lldb_private::TypeList &type_list) {
343   ModuleSP module_sp(GetModule());
344   if (module_sp) {
345     std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
346     if (m_sym_file_up)
347       return m_sym_file_up->GetTypes(sc_scope, type_mask, type_list);
348   }
349   return 0;
350 }
351
352 CompilerDeclContext
353 SymbolVendor::FindNamespace(ConstString name,
354                             const CompilerDeclContext *parent_decl_ctx) {
355   CompilerDeclContext namespace_decl_ctx;
356   ModuleSP module_sp(GetModule());
357   if (module_sp) {
358     std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
359     if (m_sym_file_up)
360       namespace_decl_ctx = m_sym_file_up->FindNamespace(name, parent_decl_ctx);
361   }
362   return namespace_decl_ctx;
363 }
364
365 void SymbolVendor::Dump(Stream *s) {
366   ModuleSP module_sp(GetModule());
367   if (module_sp) {
368     std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
369
370     bool show_context = false;
371
372     s->Printf("%p: ", static_cast<void *>(this));
373     s->Indent();
374     s->PutCString("SymbolVendor");
375     if (m_sym_file_up) {
376       *s << " " << m_sym_file_up->GetPluginName();
377       ObjectFile *objfile = m_sym_file_up->GetObjectFile();
378       if (objfile) {
379         const FileSpec &objfile_file_spec = objfile->GetFileSpec();
380         if (objfile_file_spec) {
381           s->PutCString(" (");
382           objfile_file_spec.Dump(s);
383           s->PutChar(')');
384         }
385       }
386     }
387     s->EOL();
388     if (m_sym_file_up)
389       m_sym_file_up->Dump(*s);
390     s->IndentMore();
391     m_type_list.Dump(s, show_context);
392
393     CompileUnitConstIter cu_pos, cu_end;
394     cu_end = m_compile_units.end();
395     for (cu_pos = m_compile_units.begin(); cu_pos != cu_end; ++cu_pos) {
396       // We currently only dump the compile units that have been parsed
397       if (*cu_pos)
398         (*cu_pos)->Dump(s, show_context);
399     }
400
401     if (Symtab *symtab = GetSymtab())
402       symtab->Dump(s, nullptr, eSortOrderNone);
403
404     s->IndentLess();
405   }
406 }
407
408 CompUnitSP SymbolVendor::GetCompileUnitAtIndex(size_t idx) {
409   CompUnitSP cu_sp;
410   ModuleSP module_sp(GetModule());
411   if (module_sp) {
412     std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
413     const size_t num_compile_units = GetNumCompileUnits();
414     if (idx < num_compile_units) {
415       cu_sp = m_compile_units[idx];
416       if (cu_sp.get() == nullptr) {
417         m_compile_units[idx] = m_sym_file_up->ParseCompileUnitAtIndex(idx);
418         cu_sp = m_compile_units[idx];
419       }
420     }
421   }
422   return cu_sp;
423 }
424
425 FileSpec SymbolVendor::GetMainFileSpec() const {
426   if (m_sym_file_up) {
427     const ObjectFile *symfile_objfile = m_sym_file_up->GetObjectFile();
428     if (symfile_objfile)
429       return symfile_objfile->GetFileSpec();
430   }
431
432   return FileSpec();
433 }
434
435 Symtab *SymbolVendor::GetSymtab() {
436   ModuleSP module_sp(GetModule());
437   if (!module_sp)
438     return nullptr;
439
440   std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
441
442   if (m_symtab)
443     return m_symtab;
444
445   ObjectFile *objfile = module_sp->GetObjectFile();
446   if (!objfile)
447     return nullptr;
448
449   m_symtab = objfile->GetSymtab();
450   if (m_symtab && m_sym_file_up)
451     m_sym_file_up->AddSymbols(*m_symtab);
452
453   return m_symtab;
454 }
455
456 void SymbolVendor::ClearSymtab() {
457   ModuleSP module_sp(GetModule());
458   if (module_sp) {
459     ObjectFile *objfile = module_sp->GetObjectFile();
460     if (objfile) {
461       // Clear symbol table from unified section list.
462       objfile->ClearSymtab();
463     }
464   }
465 }
466
467 void SymbolVendor::SectionFileAddressesChanged() {
468   ModuleSP module_sp(GetModule());
469   if (module_sp) {
470     ObjectFile *module_objfile = module_sp->GetObjectFile();
471     if (m_sym_file_up) {
472       ObjectFile *symfile_objfile = m_sym_file_up->GetObjectFile();
473       if (symfile_objfile != module_objfile)
474         symfile_objfile->SectionFileAddressesChanged();
475     }
476     Symtab *symtab = GetSymtab();
477     if (symtab) {
478       symtab->SectionFileAddressesChanged();
479     }
480   }
481 }
482
483 // PluginInterface protocol
484 lldb_private::ConstString SymbolVendor::GetPluginName() {
485   static ConstString g_name("vendor-default");
486   return g_name;
487 }
488
489 uint32_t SymbolVendor::GetPluginVersion() { return 1; }