LLDB  mainline
SymbolVendor.cpp
Go to the documentation of this file.
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 
10 
11 #include "lldb/Core/Module.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
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 
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 
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 
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 
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 
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 }
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 
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 
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 
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 
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 
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 
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 
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 
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
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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
485  static ConstString g_name("vendor-default");
486  return g_name;
487 }
488 
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
Definition: Stream.cpp:61
Defines a list of symbol context objects.
Enumerations for broadcasting.
Definition: SBLaunchInfo.h:14
lldb::ObjectFileSP m_objfile_sp
Definition: SymbolVendor.h:152
A stream class that can stream formatted output to a file.
Definition: Stream.h:28
FileSpec GetMainFileSpec() const
virtual void ClearSymtab()
Frees the symbol table.
Definition: ObjectFile.cpp:592
Defines a symbol context baton that can be handed other debug core functions.
Definition: SymbolContext.h:33
virtual FileSpec & GetFileSpec()
Get accessor to the object file specification.
Definition: ObjectFile.h:269
virtual lldb::CompUnitSP GetCompileUnitAtIndex(size_t idx)
static SymbolFile * FindPlugin(ObjectFile *obj_file)
Definition: SymbolFile.cpp:33
A file utility class.
Definition: FileSpec.h:55
"lldb/Utility/RegularExpression.h" A C++ wrapper class for regex.
A class that describes a function.
Definition: Function.h:323
virtual void Dump(Stream *s)
A plug-in interface definition class for object file parsers.
Definition: ObjectFile.h:58
virtual size_t FindGlobalVariables(ConstString name, const CompilerDeclContext *parent_decl_ctx, size_t max_matches, VariableList &variables)
void Dump(Stream *s) const
Dump this object to a Stream.
Definition: FileSpec.cpp:350
virtual bool ParseLineTable(CompileUnit &comp_unit)
virtual size_t ParseTypes(CompileUnit &comp_unit)
lldb::ModuleSP GetModule() const
Get const accessor for the module pointer.
Definition: ModuleChild.cpp:27
virtual bool SetCompileUnitAtIndex(size_t cu_idx, const lldb::CompUnitSP &cu_sp)
CompileUnits::const_iterator CompileUnitConstIter
Definition: SymbolVendor.h:148
A class that describes a compilation unit.
Definition: CompileUnit.h:35
virtual bool ParseSupportFiles(CompileUnit &comp_unit, FileSpecList &support_files)
virtual size_t ParseVariablesForContext(const SymbolContext &sc)
virtual CompilerDeclContext FindNamespace(ConstString name, const CompilerDeclContext *parent_decl_ctx)
void SectionFileAddressesChanged()
Definition: Symtab.cpp:68
void AddSymbolFileRepresentation(const lldb::ObjectFileSP &objfile_sp)
virtual uint32_t ResolveSymbolContext(const Address &so_addr, lldb::SymbolContextItem resolve_scope, SymbolContext &sc)
uint64_t user_id_t
Definition: lldb-types.h:84
LanguageType
Programming language type.
uint64_t offset_t
Definition: lldb-types.h:87
virtual lldb::LanguageType ParseLanguage(CompileUnit &comp_unit)
size_t EOL()
Output and End of Line character to the stream.
Definition: Stream.cpp:127
virtual size_t GetNumCompileUnits()
virtual bool ParseDebugMacros(CompileUnit &comp_unit)
virtual bool ParseImportedModules(const SymbolContext &sc, std::vector< SourceModule > &imported_modules)
void Dump(Stream *s, bool show_context)
Definition: TypeList.cpp:94
void IndentLess(int amount=2)
Decrement the current indentation level.
Definition: Stream.cpp:221
virtual size_t FindFunctions(ConstString name, const CompilerDeclContext *parent_decl_ctx, lldb::FunctionNameType name_type_mask, bool include_inlines, bool append, SymbolContextList &sc_list)
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition: Stream.cpp:106
virtual size_t ParseFunctions(CompileUnit &comp_unit)
A section + offset based address class.
Definition: Address.h:80
virtual bool ParseIsOptimized(CompileUnit &comp_unit)
virtual Type * ResolveTypeUID(lldb::user_id_t type_uid)
size_t PutChar(char ch)
Definition: Stream.cpp:103
virtual void SectionFileAddressesChanged()
Notify the SymbolVendor that the file addresses in the Sections for this module have been changed...
virtual size_t FindTypes(ConstString name, const CompilerDeclContext *parent_decl_ctx, bool append, size_t max_matches, llvm::DenseSet< lldb_private::SymbolFile *> &searched_symbol_files, TypeMap &types)
virtual void SectionFileAddressesChanged()
Notify the ObjectFile that the file addresses in the Sections for this module have been changed...
Definition: ObjectFile.h:299
A uniqued constant string class.
Definition: ConstString.h:38
Unknown or invalid language value.
virtual size_t GetTypes(SymbolContextScope *sc_scope, lldb::TypeClass type_mask, TypeList &type_list)
virtual size_t ParseBlocksRecursive(Function &func)
Definition: SBAddress.h:15
size_t Indent(const char *s=nullptr)
Indent the current line in the stream.
Definition: Stream.cpp:131
A mix in class that contains a pointer back to the module that owns the object which inherits from it...
Definition: ModuleChild.h:19
void IndentMore(int amount=2)
Increment the current indentation level.
Definition: Stream.cpp:218
ConstString GetPluginName() override
virtual Symtab * GetSymtab()=0
Gets the symbol table for the currently selected architecture (and object for archives).
uint32_t GetPluginVersion() override
std::unique_ptr< SymbolFile > m_sym_file_up
Definition: SymbolVendor.h:156
"lldb/Symbol/SymbolContextScope.h" Inherit from this if your object is part of a symbol context and c...
virtual Symtab * GetSymtab()