]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Symbol/SymbolVendor.cpp
Merge clang 7.0.1 and several follow-up changes
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Symbol / SymbolVendor.cpp
1 //===-- SymbolVendor.cpp ----------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "lldb/Symbol/SymbolVendor.h"
11
12 // C Includes
13 // C++ Includes
14 // Other libraries and framework includes
15 // Project 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"
22
23 using namespace lldb;
24 using namespace lldb_private;
25
26 //----------------------------------------------------------------------
27 // FindPlugin
28 //
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;
37
38   for (size_t idx = 0;
39        (create_callback = PluginManager::GetSymbolVendorCreateCallbackAtIndex(
40             idx)) != nullptr;
41        ++idx) {
42     instance_ap.reset(create_callback(module_sp, feedback_strm));
43
44     if (instance_ap.get()) {
45       return instance_ap.release();
46     }
47   }
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();
53     if (objfile)
54       instance_ap->AddSymbolFileRepresentation(objfile->shared_from_this());
55   }
56   return instance_ap.release();
57 }
58
59 //----------------------------------------------------------------------
60 // SymbolVendor constructor
61 //----------------------------------------------------------------------
62 SymbolVendor::SymbolVendor(const lldb::ModuleSP &module_sp)
63     : ModuleChild(module_sp), m_type_list(), m_compile_units(),
64       m_sym_file_ap() {}
65
66 //----------------------------------------------------------------------
67 // Destructor
68 //----------------------------------------------------------------------
69 SymbolVendor::~SymbolVendor() {}
70
71 //----------------------------------------------------------------------
72 // Add a representation given an object file.
73 //----------------------------------------------------------------------
74 void SymbolVendor::AddSymbolFileRepresentation(const ObjectFileSP &objfile_sp) {
75   ModuleSP module_sp(GetModule());
76   if (module_sp) {
77     std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
78     if (objfile_sp) {
79       m_objfile_sp = objfile_sp;
80       m_sym_file_ap.reset(SymbolFile::FindPlugin(objfile_sp.get()));
81     }
82   }
83 }
84
85 bool SymbolVendor::SetCompileUnitAtIndex(size_t idx, const CompUnitSP &cu_sp) {
86   ModuleSP module_sp(GetModule());
87   if (module_sp) {
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
95       // unit.
96       assert(m_compile_units[idx].get() == nullptr);
97       m_compile_units[idx] = cu_sp;
98       return true;
99     } else {
100       // This should NOT happen, and if it does, we want to crash and know
101       // about it
102       assert(idx < num_compile_units);
103     }
104   }
105   return false;
106 }
107
108 size_t SymbolVendor::GetNumCompileUnits() {
109   ModuleSP module_sp(GetModule());
110   if (module_sp) {
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());
119       }
120     }
121   }
122   return m_compile_units.size();
123 }
124
125 lldb::LanguageType
126 SymbolVendor::ParseCompileUnitLanguage(const SymbolContext &sc) {
127   ModuleSP module_sp(GetModule());
128   if (module_sp) {
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);
132   }
133   return eLanguageTypeUnknown;
134 }
135
136 size_t SymbolVendor::ParseCompileUnitFunctions(const SymbolContext &sc) {
137   ModuleSP module_sp(GetModule());
138   if (module_sp) {
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);
142   }
143   return 0;
144 }
145
146 bool SymbolVendor::ParseCompileUnitLineTable(const SymbolContext &sc) {
147   ModuleSP module_sp(GetModule());
148   if (module_sp) {
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);
152   }
153   return false;
154 }
155
156 bool SymbolVendor::ParseCompileUnitDebugMacros(const SymbolContext &sc) {
157   ModuleSP module_sp(GetModule());
158   if (module_sp) {
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);
162   }
163   return false;
164 }
165 bool SymbolVendor::ParseCompileUnitSupportFiles(const SymbolContext &sc,
166                                                 FileSpecList &support_files) {
167   ModuleSP module_sp(GetModule());
168   if (module_sp) {
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);
172   }
173   return false;
174 }
175
176 bool SymbolVendor::ParseCompileUnitIsOptimized(const SymbolContext &sc) {
177   ModuleSP module_sp(GetModule());
178   if (module_sp) {
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);
182   }
183   return false;
184 }
185
186 bool SymbolVendor::ParseImportedModules(
187     const SymbolContext &sc, std::vector<ConstString> &imported_modules) {
188   ModuleSP module_sp(GetModule());
189   if (module_sp) {
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);
193   }
194   return false;
195 }
196
197 size_t SymbolVendor::ParseFunctionBlocks(const SymbolContext &sc) {
198   ModuleSP module_sp(GetModule());
199   if (module_sp) {
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);
203   }
204   return 0;
205 }
206
207 size_t SymbolVendor::ParseTypes(const SymbolContext &sc) {
208   ModuleSP module_sp(GetModule());
209   if (module_sp) {
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);
213   }
214   return 0;
215 }
216
217 size_t SymbolVendor::ParseVariablesForContext(const SymbolContext &sc) {
218   ModuleSP module_sp(GetModule());
219   if (module_sp) {
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);
223   }
224   return 0;
225 }
226
227 Type *SymbolVendor::ResolveTypeUID(lldb::user_id_t type_uid) {
228   ModuleSP module_sp(GetModule());
229   if (module_sp) {
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);
233   }
234   return nullptr;
235 }
236
237 uint32_t SymbolVendor::ResolveSymbolContext(const Address &so_addr,
238                                             uint32_t resolve_scope,
239                                             SymbolContext &sc) {
240   ModuleSP module_sp(GetModule());
241   if (module_sp) {
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);
245   }
246   return 0;
247 }
248
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());
254   if (module_sp) {
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);
259   }
260   return 0;
261 }
262
263 size_t
264 SymbolVendor::FindGlobalVariables(const ConstString &name,
265                                   const CompilerDeclContext *parent_decl_ctx,
266                                   size_t max_matches, VariableList &variables) {
267   ModuleSP module_sp(GetModule());
268   if (module_sp) {
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);
273   }
274   return 0;
275 }
276
277 size_t SymbolVendor::FindGlobalVariables(const RegularExpression &regex,
278                                          size_t max_matches,
279                                          VariableList &variables) {
280   ModuleSP module_sp(GetModule());
281   if (module_sp) {
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);
285   }
286   return 0;
287 }
288
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());
295   if (module_sp) {
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);
300   }
301   return 0;
302 }
303
304 size_t SymbolVendor::FindFunctions(const RegularExpression &regex,
305                                    bool include_inlines, bool append,
306                                    SymbolContextList &sc_list) {
307   ModuleSP module_sp(GetModule());
308   if (module_sp) {
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,
312                                           sc_list);
313   }
314   return 0;
315 }
316
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,
321     TypeMap &types) {
322   ModuleSP module_sp(GetModule());
323   if (module_sp) {
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,
328                                       types);
329   }
330   if (!append)
331     types.Clear();
332   return 0;
333 }
334
335 size_t SymbolVendor::FindTypes(const std::vector<CompilerContext> &context,
336                                bool append, TypeMap &types) {
337   ModuleSP module_sp(GetModule());
338   if (module_sp) {
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);
342   }
343   if (!append)
344     types.Clear();
345   return 0;
346 }
347
348 size_t SymbolVendor::GetTypes(SymbolContextScope *sc_scope, uint32_t type_mask,
349                               lldb_private::TypeList &type_list) {
350   ModuleSP module_sp(GetModule());
351   if (module_sp) {
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);
355   }
356   return 0;
357 }
358
359 CompilerDeclContext
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());
364   if (module_sp) {
365     std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
366     if (m_sym_file_ap.get())
367       namespace_decl_ctx =
368           m_sym_file_ap->FindNamespace(sc, name, parent_decl_ctx);
369   }
370   return namespace_decl_ctx;
371 }
372
373 void SymbolVendor::Dump(Stream *s) {
374   ModuleSP module_sp(GetModule());
375   if (module_sp) {
376     std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
377
378     bool show_context = false;
379
380     s->Printf("%p: ", static_cast<void *>(this));
381     s->Indent();
382     s->PutCString("SymbolVendor");
383     if (m_sym_file_ap.get()) {
384       ObjectFile *objfile = m_sym_file_ap->GetObjectFile();
385       if (objfile) {
386         const FileSpec &objfile_file_spec = objfile->GetFileSpec();
387         if (objfile_file_spec) {
388           s->PutCString(" (");
389           objfile_file_spec.Dump(s);
390           s->PutChar(')');
391         }
392       }
393     }
394     s->EOL();
395     if (m_sym_file_ap)
396       m_sym_file_ap->Dump(*s);
397     s->IndentMore();
398     m_type_list.Dump(s, show_context);
399
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
404       if (cu_pos->get())
405         (*cu_pos)->Dump(s, show_context);
406     }
407
408     s->IndentLess();
409   }
410 }
411
412 CompUnitSP SymbolVendor::GetCompileUnitAtIndex(size_t idx) {
413   CompUnitSP cu_sp;
414   ModuleSP module_sp(GetModule());
415   if (module_sp) {
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];
423       }
424     }
425   }
426   return cu_sp;
427 }
428
429 FileSpec SymbolVendor::GetMainFileSpec() const {
430   if (m_sym_file_ap.get()) {
431     const ObjectFile *symfile_objfile = m_sym_file_ap->GetObjectFile();
432     if (symfile_objfile)
433       return symfile_objfile->GetFileSpec();
434   }
435
436   return FileSpec();
437 }
438
439 Symtab *SymbolVendor::GetSymtab() {
440   ModuleSP module_sp(GetModule());
441   if (module_sp) {
442     ObjectFile *objfile = module_sp->GetObjectFile();
443     if (objfile) {
444       // Get symbol table from unified section list.
445       return objfile->GetSymtab();
446     }
447   }
448   return nullptr;
449 }
450
451 void SymbolVendor::ClearSymtab() {
452   ModuleSP module_sp(GetModule());
453   if (module_sp) {
454     ObjectFile *objfile = module_sp->GetObjectFile();
455     if (objfile) {
456       // Clear symbol table from unified section list.
457       objfile->ClearSymtab();
458     }
459   }
460 }
461
462 void SymbolVendor::SectionFileAddressesChanged() {
463   ModuleSP module_sp(GetModule());
464   if (module_sp) {
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();
470     }
471     Symtab *symtab = GetSymtab();
472     if (symtab) {
473       symtab->SectionFileAddressesChanged();
474     }
475   }
476 }
477
478 //------------------------------------------------------------------
479 // PluginInterface protocol
480 //------------------------------------------------------------------
481 lldb_private::ConstString SymbolVendor::GetPluginName() {
482   static ConstString g_name("vendor-default");
483   return g_name;
484 }
485
486 uint32_t SymbolVendor::GetPluginVersion() { return 1; }