1 //===-- SymbolVendor.cpp ----------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "lldb/Symbol/SymbolVendor.h"
14 // Other libraries and framework includes
16 #include "lldb/Core/Module.h"
17 #include "lldb/Core/PluginManager.h"
18 #include "lldb/Symbol/CompileUnit.h"
19 #include "lldb/Symbol/ObjectFile.h"
20 #include "lldb/Symbol/SymbolFile.h"
21 #include "lldb/Utility/Stream.h"
24 using namespace lldb_private;
26 //----------------------------------------------------------------------
29 // Platforms can register a callback to use when creating symbol vendors to
30 // allow for complex debug information file setups, and to also allow for
31 // finding separate debug information files.
32 //----------------------------------------------------------------------
33 SymbolVendor *SymbolVendor::FindPlugin(const lldb::ModuleSP &module_sp,
34 lldb_private::Stream *feedback_strm) {
35 std::unique_ptr<SymbolVendor> instance_ap;
36 SymbolVendorCreateInstance create_callback;
39 (create_callback = PluginManager::GetSymbolVendorCreateCallbackAtIndex(
42 instance_ap.reset(create_callback(module_sp, feedback_strm));
44 if (instance_ap.get()) {
45 return instance_ap.release();
48 // The default implementation just tries to create debug information using
49 // the file representation for the module.
50 instance_ap.reset(new SymbolVendor(module_sp));
51 if (instance_ap.get()) {
52 ObjectFile *objfile = module_sp->GetObjectFile();
54 instance_ap->AddSymbolFileRepresentation(objfile->shared_from_this());
56 return instance_ap.release();
59 //----------------------------------------------------------------------
60 // SymbolVendor constructor
61 //----------------------------------------------------------------------
62 SymbolVendor::SymbolVendor(const lldb::ModuleSP &module_sp)
63 : ModuleChild(module_sp), m_type_list(), m_compile_units(),
66 //----------------------------------------------------------------------
68 //----------------------------------------------------------------------
69 SymbolVendor::~SymbolVendor() {}
71 //----------------------------------------------------------------------
72 // Add a representation given an object file.
73 //----------------------------------------------------------------------
74 void SymbolVendor::AddSymbolFileRepresentation(const ObjectFileSP &objfile_sp) {
75 ModuleSP module_sp(GetModule());
77 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
79 m_objfile_sp = objfile_sp;
80 m_sym_file_ap.reset(SymbolFile::FindPlugin(objfile_sp.get()));
85 bool SymbolVendor::SetCompileUnitAtIndex(size_t idx, const CompUnitSP &cu_sp) {
86 ModuleSP module_sp(GetModule());
88 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
89 const size_t num_compile_units = GetNumCompileUnits();
90 if (idx < num_compile_units) {
91 // Fire off an assertion if this compile unit already exists for now. The
92 // partial parsing should take care of only setting the compile unit
93 // once, so if this assertion fails, we need to make sure that we don't
94 // have a race condition, or have a second parse of the same compile
96 assert(m_compile_units[idx].get() == nullptr);
97 m_compile_units[idx] = cu_sp;
100 // This should NOT happen, and if it does, we want to crash and know
102 assert(idx < num_compile_units);
108 size_t SymbolVendor::GetNumCompileUnits() {
109 ModuleSP module_sp(GetModule());
111 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
112 if (m_compile_units.empty()) {
113 if (m_sym_file_ap.get()) {
114 // Resize our array of compile unit shared pointers -- which will each
115 // remain NULL until someone asks for the actual compile unit
116 // information. When this happens, the symbol file will be asked to
117 // parse this compile unit information.
118 m_compile_units.resize(m_sym_file_ap->GetNumCompileUnits());
122 return m_compile_units.size();
126 SymbolVendor::ParseCompileUnitLanguage(const SymbolContext &sc) {
127 ModuleSP module_sp(GetModule());
129 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
130 if (m_sym_file_ap.get())
131 return m_sym_file_ap->ParseCompileUnitLanguage(sc);
133 return eLanguageTypeUnknown;
136 size_t SymbolVendor::ParseCompileUnitFunctions(const SymbolContext &sc) {
137 ModuleSP module_sp(GetModule());
139 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
140 if (m_sym_file_ap.get())
141 return m_sym_file_ap->ParseCompileUnitFunctions(sc);
146 bool SymbolVendor::ParseCompileUnitLineTable(const SymbolContext &sc) {
147 ModuleSP module_sp(GetModule());
149 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
150 if (m_sym_file_ap.get())
151 return m_sym_file_ap->ParseCompileUnitLineTable(sc);
156 bool SymbolVendor::ParseCompileUnitDebugMacros(const SymbolContext &sc) {
157 ModuleSP module_sp(GetModule());
159 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
160 if (m_sym_file_ap.get())
161 return m_sym_file_ap->ParseCompileUnitDebugMacros(sc);
165 bool SymbolVendor::ParseCompileUnitSupportFiles(const SymbolContext &sc,
166 FileSpecList &support_files) {
167 ModuleSP module_sp(GetModule());
169 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
170 if (m_sym_file_ap.get())
171 return m_sym_file_ap->ParseCompileUnitSupportFiles(sc, support_files);
176 bool SymbolVendor::ParseCompileUnitIsOptimized(const SymbolContext &sc) {
177 ModuleSP module_sp(GetModule());
179 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
180 if (m_sym_file_ap.get())
181 return m_sym_file_ap->ParseCompileUnitIsOptimized(sc);
186 bool SymbolVendor::ParseImportedModules(
187 const SymbolContext &sc, std::vector<ConstString> &imported_modules) {
188 ModuleSP module_sp(GetModule());
190 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
191 if (m_sym_file_ap.get())
192 return m_sym_file_ap->ParseImportedModules(sc, imported_modules);
197 size_t SymbolVendor::ParseFunctionBlocks(const SymbolContext &sc) {
198 ModuleSP module_sp(GetModule());
200 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
201 if (m_sym_file_ap.get())
202 return m_sym_file_ap->ParseFunctionBlocks(sc);
207 size_t SymbolVendor::ParseTypes(const SymbolContext &sc) {
208 ModuleSP module_sp(GetModule());
210 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
211 if (m_sym_file_ap.get())
212 return m_sym_file_ap->ParseTypes(sc);
217 size_t SymbolVendor::ParseVariablesForContext(const SymbolContext &sc) {
218 ModuleSP module_sp(GetModule());
220 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
221 if (m_sym_file_ap.get())
222 return m_sym_file_ap->ParseVariablesForContext(sc);
227 Type *SymbolVendor::ResolveTypeUID(lldb::user_id_t type_uid) {
228 ModuleSP module_sp(GetModule());
230 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
231 if (m_sym_file_ap.get())
232 return m_sym_file_ap->ResolveTypeUID(type_uid);
237 uint32_t SymbolVendor::ResolveSymbolContext(const Address &so_addr,
238 uint32_t resolve_scope,
240 ModuleSP module_sp(GetModule());
242 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
243 if (m_sym_file_ap.get())
244 return m_sym_file_ap->ResolveSymbolContext(so_addr, resolve_scope, sc);
249 uint32_t SymbolVendor::ResolveSymbolContext(const FileSpec &file_spec,
250 uint32_t line, bool check_inlines,
251 uint32_t resolve_scope,
252 SymbolContextList &sc_list) {
253 ModuleSP module_sp(GetModule());
255 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
256 if (m_sym_file_ap.get())
257 return m_sym_file_ap->ResolveSymbolContext(file_spec, line, check_inlines,
258 resolve_scope, sc_list);
264 SymbolVendor::FindGlobalVariables(const ConstString &name,
265 const CompilerDeclContext *parent_decl_ctx,
266 size_t max_matches, VariableList &variables) {
267 ModuleSP module_sp(GetModule());
269 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
270 if (m_sym_file_ap.get())
271 return m_sym_file_ap->FindGlobalVariables(name, parent_decl_ctx,
272 max_matches, variables);
277 size_t SymbolVendor::FindGlobalVariables(const RegularExpression ®ex,
279 VariableList &variables) {
280 ModuleSP module_sp(GetModule());
282 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
283 if (m_sym_file_ap.get())
284 return m_sym_file_ap->FindGlobalVariables(regex, max_matches, variables);
289 size_t SymbolVendor::FindFunctions(const ConstString &name,
290 const CompilerDeclContext *parent_decl_ctx,
291 uint32_t name_type_mask,
292 bool include_inlines, bool append,
293 SymbolContextList &sc_list) {
294 ModuleSP module_sp(GetModule());
296 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
297 if (m_sym_file_ap.get())
298 return m_sym_file_ap->FindFunctions(name, parent_decl_ctx, name_type_mask,
299 include_inlines, append, sc_list);
304 size_t SymbolVendor::FindFunctions(const RegularExpression ®ex,
305 bool include_inlines, bool append,
306 SymbolContextList &sc_list) {
307 ModuleSP module_sp(GetModule());
309 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
310 if (m_sym_file_ap.get())
311 return m_sym_file_ap->FindFunctions(regex, include_inlines, append,
317 size_t SymbolVendor::FindTypes(
318 const SymbolContext &sc, const ConstString &name,
319 const CompilerDeclContext *parent_decl_ctx, bool append, size_t max_matches,
320 llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
322 ModuleSP module_sp(GetModule());
324 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
325 if (m_sym_file_ap.get())
326 return m_sym_file_ap->FindTypes(sc, name, parent_decl_ctx, append,
327 max_matches, searched_symbol_files,
335 size_t SymbolVendor::FindTypes(const std::vector<CompilerContext> &context,
336 bool append, TypeMap &types) {
337 ModuleSP module_sp(GetModule());
339 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
340 if (m_sym_file_ap.get())
341 return m_sym_file_ap->FindTypes(context, append, types);
348 size_t SymbolVendor::GetTypes(SymbolContextScope *sc_scope, uint32_t type_mask,
349 lldb_private::TypeList &type_list) {
350 ModuleSP module_sp(GetModule());
352 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
353 if (m_sym_file_ap.get())
354 return m_sym_file_ap->GetTypes(sc_scope, type_mask, type_list);
360 SymbolVendor::FindNamespace(const SymbolContext &sc, const ConstString &name,
361 const CompilerDeclContext *parent_decl_ctx) {
362 CompilerDeclContext namespace_decl_ctx;
363 ModuleSP module_sp(GetModule());
365 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
366 if (m_sym_file_ap.get())
368 m_sym_file_ap->FindNamespace(sc, name, parent_decl_ctx);
370 return namespace_decl_ctx;
373 void SymbolVendor::Dump(Stream *s) {
374 ModuleSP module_sp(GetModule());
376 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
378 bool show_context = false;
380 s->Printf("%p: ", static_cast<void *>(this));
382 s->PutCString("SymbolVendor");
383 if (m_sym_file_ap.get()) {
384 ObjectFile *objfile = m_sym_file_ap->GetObjectFile();
386 const FileSpec &objfile_file_spec = objfile->GetFileSpec();
387 if (objfile_file_spec) {
389 objfile_file_spec.Dump(s);
396 m_sym_file_ap->Dump(*s);
398 m_type_list.Dump(s, show_context);
400 CompileUnitConstIter cu_pos, cu_end;
401 cu_end = m_compile_units.end();
402 for (cu_pos = m_compile_units.begin(); cu_pos != cu_end; ++cu_pos) {
403 // We currently only dump the compile units that have been parsed
405 (*cu_pos)->Dump(s, show_context);
412 CompUnitSP SymbolVendor::GetCompileUnitAtIndex(size_t idx) {
414 ModuleSP module_sp(GetModule());
416 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
417 const size_t num_compile_units = GetNumCompileUnits();
418 if (idx < num_compile_units) {
419 cu_sp = m_compile_units[idx];
420 if (cu_sp.get() == nullptr) {
421 m_compile_units[idx] = m_sym_file_ap->ParseCompileUnitAtIndex(idx);
422 cu_sp = m_compile_units[idx];
429 FileSpec SymbolVendor::GetMainFileSpec() const {
430 if (m_sym_file_ap.get()) {
431 const ObjectFile *symfile_objfile = m_sym_file_ap->GetObjectFile();
433 return symfile_objfile->GetFileSpec();
439 Symtab *SymbolVendor::GetSymtab() {
440 ModuleSP module_sp(GetModule());
442 ObjectFile *objfile = module_sp->GetObjectFile();
444 // Get symbol table from unified section list.
445 return objfile->GetSymtab();
451 void SymbolVendor::ClearSymtab() {
452 ModuleSP module_sp(GetModule());
454 ObjectFile *objfile = module_sp->GetObjectFile();
456 // Clear symbol table from unified section list.
457 objfile->ClearSymtab();
462 void SymbolVendor::SectionFileAddressesChanged() {
463 ModuleSP module_sp(GetModule());
465 ObjectFile *module_objfile = module_sp->GetObjectFile();
466 if (m_sym_file_ap.get()) {
467 ObjectFile *symfile_objfile = m_sym_file_ap->GetObjectFile();
468 if (symfile_objfile != module_objfile)
469 symfile_objfile->SectionFileAddressesChanged();
471 Symtab *symtab = GetSymtab();
473 symtab->SectionFileAddressesChanged();
478 //------------------------------------------------------------------
479 // PluginInterface protocol
480 //------------------------------------------------------------------
481 lldb_private::ConstString SymbolVendor::GetPluginName() {
482 static ConstString g_name("vendor-default");
486 uint32_t SymbolVendor::GetPluginVersion() { return 1; }