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
30 // vendors to allow for complex debug information file setups, and to
31 // also allow for 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 the
49 // 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.
92 // The partial parsing should take care of only setting the compile
93 // unit once, so if this assertion fails, we need to make sure that
94 // we don't have a race condition, or have a second parse of the same
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
115 // each remain NULL until someone asks for the actual compile unit
116 // information. When this happens, the symbol file will be asked
117 // to 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);
263 size_t SymbolVendor::FindGlobalVariables(
264 const ConstString &name, const CompilerDeclContext *parent_decl_ctx,
265 bool append, size_t max_matches, VariableList &variables) {
266 ModuleSP module_sp(GetModule());
268 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
269 if (m_sym_file_ap.get())
270 return m_sym_file_ap->FindGlobalVariables(name, parent_decl_ctx, append,
271 max_matches, variables);
276 size_t SymbolVendor::FindGlobalVariables(const RegularExpression ®ex,
277 bool append, size_t max_matches,
278 VariableList &variables) {
279 ModuleSP module_sp(GetModule());
281 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
282 if (m_sym_file_ap.get())
283 return m_sym_file_ap->FindGlobalVariables(regex, append, max_matches,
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_type_list.Dump(s, show_context);
398 CompileUnitConstIter cu_pos, cu_end;
399 cu_end = m_compile_units.end();
400 for (cu_pos = m_compile_units.begin(); cu_pos != cu_end; ++cu_pos) {
401 // We currently only dump the compile units that have been parsed
403 (*cu_pos)->Dump(s, show_context);
410 CompUnitSP SymbolVendor::GetCompileUnitAtIndex(size_t idx) {
412 ModuleSP module_sp(GetModule());
414 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
415 const size_t num_compile_units = GetNumCompileUnits();
416 if (idx < num_compile_units) {
417 cu_sp = m_compile_units[idx];
418 if (cu_sp.get() == nullptr) {
419 m_compile_units[idx] = m_sym_file_ap->ParseCompileUnitAtIndex(idx);
420 cu_sp = m_compile_units[idx];
427 FileSpec SymbolVendor::GetMainFileSpec() const {
428 if (m_sym_file_ap.get()) {
429 const ObjectFile *symfile_objfile = m_sym_file_ap->GetObjectFile();
431 return symfile_objfile->GetFileSpec();
437 Symtab *SymbolVendor::GetSymtab() {
438 ModuleSP module_sp(GetModule());
440 ObjectFile *objfile = module_sp->GetObjectFile();
442 // Get symbol table from unified section list.
443 return objfile->GetSymtab();
449 void SymbolVendor::ClearSymtab() {
450 ModuleSP module_sp(GetModule());
452 ObjectFile *objfile = module_sp->GetObjectFile();
454 // Clear symbol table from unified section list.
455 objfile->ClearSymtab();
460 void SymbolVendor::SectionFileAddressesChanged() {
461 ModuleSP module_sp(GetModule());
463 ObjectFile *module_objfile = module_sp->GetObjectFile();
464 if (m_sym_file_ap.get()) {
465 ObjectFile *symfile_objfile = m_sym_file_ap->GetObjectFile();
466 if (symfile_objfile != module_objfile)
467 symfile_objfile->SectionFileAddressesChanged();
469 Symtab *symtab = GetSymtab();
471 symtab->SectionFileAddressesChanged();
476 //------------------------------------------------------------------
477 // PluginInterface protocol
478 //------------------------------------------------------------------
479 lldb_private::ConstString SymbolVendor::GetPluginName() {
480 static ConstString g_name("vendor-default");
484 uint32_t SymbolVendor::GetPluginVersion() { return 1; }