1254721Semaste//===-- SymbolVendor.mm -----------------------------------------*- C++ -*-===//
2254721Semaste//
3254721Semaste//                     The LLVM Compiler Infrastructure
4254721Semaste//
5254721Semaste// This file is distributed under the University of Illinois Open Source
6254721Semaste// License. See LICENSE.TXT for details.
7254721Semaste//
8254721Semaste//===----------------------------------------------------------------------===//
9254721Semaste
10254721Semaste#include "lldb/Symbol/SymbolVendor.h"
11254721Semaste
12254721Semaste// C Includes
13254721Semaste// C++ Includes
14254721Semaste// Other libraries and framework includes
15254721Semaste// Project includes
16254721Semaste#include "lldb/Core/Module.h"
17254721Semaste#include "lldb/Core/PluginManager.h"
18254721Semaste#include "lldb/Core/Stream.h"
19254721Semaste#include "lldb/Symbol/CompileUnit.h"
20254721Semaste#include "lldb/Symbol/ObjectFile.h"
21254721Semaste#include "lldb/Symbol/SymbolFile.h"
22254721Semaste
23254721Semasteusing namespace lldb;
24254721Semasteusing namespace lldb_private;
25254721Semaste
26254721Semaste
27254721Semaste//----------------------------------------------------------------------
28254721Semaste// FindPlugin
29254721Semaste//
30254721Semaste// Platforms can register a callback to use when creating symbol
31254721Semaste// vendors to allow for complex debug information file setups, and to
32254721Semaste// also allow for finding separate debug information files.
33254721Semaste//----------------------------------------------------------------------
34254721SemasteSymbolVendor*
35254721SemasteSymbolVendor::FindPlugin (const lldb::ModuleSP &module_sp, lldb_private::Stream *feedback_strm)
36254721Semaste{
37254721Semaste    std::unique_ptr<SymbolVendor> instance_ap;
38254721Semaste    SymbolVendorCreateInstance create_callback;
39254721Semaste
40254721Semaste    for (size_t idx = 0; (create_callback = PluginManager::GetSymbolVendorCreateCallbackAtIndex(idx)) != NULL; ++idx)
41254721Semaste    {
42254721Semaste        instance_ap.reset(create_callback(module_sp, feedback_strm));
43254721Semaste
44254721Semaste        if (instance_ap.get())
45254721Semaste        {
46254721Semaste            return instance_ap.release();
47254721Semaste        }
48254721Semaste    }
49254721Semaste    // The default implementation just tries to create debug information using the
50254721Semaste    // file representation for the module.
51254721Semaste    instance_ap.reset(new SymbolVendor(module_sp));
52254721Semaste    if (instance_ap.get())
53254721Semaste    {
54254721Semaste        ObjectFile *objfile = module_sp->GetObjectFile();
55254721Semaste        if (objfile)
56254721Semaste            instance_ap->AddSymbolFileRepresentation(objfile->shared_from_this());
57254721Semaste    }
58254721Semaste    return instance_ap.release();
59254721Semaste}
60254721Semaste
61254721Semaste//----------------------------------------------------------------------
62254721Semaste// SymbolVendor constructor
63254721Semaste//----------------------------------------------------------------------
64254721SemasteSymbolVendor::SymbolVendor(const lldb::ModuleSP &module_sp) :
65254721Semaste    ModuleChild (module_sp),
66254721Semaste    m_type_list(),
67254721Semaste    m_compile_units(),
68254721Semaste    m_sym_file_ap()
69254721Semaste{
70254721Semaste}
71254721Semaste
72254721Semaste//----------------------------------------------------------------------
73254721Semaste// Destructor
74254721Semaste//----------------------------------------------------------------------
75254721SemasteSymbolVendor::~SymbolVendor()
76254721Semaste{
77254721Semaste}
78254721Semaste
79254721Semaste//----------------------------------------------------------------------
80254721Semaste// Add a represention given an object file.
81254721Semaste//----------------------------------------------------------------------
82254721Semastevoid
83254721SemasteSymbolVendor::AddSymbolFileRepresentation(const ObjectFileSP &objfile_sp)
84254721Semaste{
85254721Semaste    ModuleSP module_sp(GetModule());
86254721Semaste    if (module_sp)
87254721Semaste    {
88254721Semaste        lldb_private::Mutex::Locker locker(module_sp->GetMutex());
89254721Semaste        if (objfile_sp)
90254721Semaste        {
91254721Semaste            m_objfile_sp = objfile_sp;
92254721Semaste            m_sym_file_ap.reset(SymbolFile::FindPlugin(objfile_sp.get()));
93254721Semaste        }
94254721Semaste    }
95254721Semaste}
96254721Semaste
97254721Semastebool
98254721SemasteSymbolVendor::SetCompileUnitAtIndex (size_t idx, const CompUnitSP &cu_sp)
99254721Semaste{
100254721Semaste    ModuleSP module_sp(GetModule());
101254721Semaste    if (module_sp)
102254721Semaste    {
103254721Semaste        lldb_private::Mutex::Locker locker(module_sp->GetMutex());
104254721Semaste        const size_t num_compile_units = GetNumCompileUnits();
105254721Semaste        if (idx < num_compile_units)
106254721Semaste        {
107254721Semaste            // Fire off an assertion if this compile unit already exists for now.
108254721Semaste            // The partial parsing should take care of only setting the compile
109254721Semaste            // unit once, so if this assertion fails, we need to make sure that
110254721Semaste            // we don't have a race condition, or have a second parse of the same
111254721Semaste            // compile unit.
112254721Semaste            assert(m_compile_units[idx].get() == NULL);
113254721Semaste            m_compile_units[idx] = cu_sp;
114254721Semaste            return true;
115254721Semaste        }
116254721Semaste        else
117254721Semaste        {
118254721Semaste            // This should NOT happen, and if it does, we want to crash and know
119254721Semaste            // about it
120254721Semaste            assert (idx < num_compile_units);
121254721Semaste        }
122254721Semaste    }
123254721Semaste    return false;
124254721Semaste}
125254721Semaste
126254721Semastesize_t
127254721SemasteSymbolVendor::GetNumCompileUnits()
128254721Semaste{
129254721Semaste    ModuleSP module_sp(GetModule());
130254721Semaste    if (module_sp)
131254721Semaste    {
132254721Semaste        lldb_private::Mutex::Locker locker(module_sp->GetMutex());
133254721Semaste        if (m_compile_units.empty())
134254721Semaste        {
135254721Semaste            if (m_sym_file_ap.get())
136254721Semaste            {
137254721Semaste                // Resize our array of compile unit shared pointers -- which will
138254721Semaste                // each remain NULL until someone asks for the actual compile unit
139254721Semaste                // information. When this happens, the symbol file will be asked
140254721Semaste                // to parse this compile unit information.
141254721Semaste                m_compile_units.resize(m_sym_file_ap->GetNumCompileUnits());
142254721Semaste            }
143254721Semaste        }
144254721Semaste    }
145254721Semaste    return m_compile_units.size();
146254721Semaste}
147254721Semaste
148254721Semastelldb::LanguageType
149254721SemasteSymbolVendor::ParseCompileUnitLanguage (const SymbolContext& sc)
150254721Semaste{
151254721Semaste    ModuleSP module_sp(GetModule());
152254721Semaste    if (module_sp)
153254721Semaste    {
154254721Semaste        lldb_private::Mutex::Locker locker(module_sp->GetMutex());
155254721Semaste        if (m_sym_file_ap.get())
156254721Semaste            return m_sym_file_ap->ParseCompileUnitLanguage(sc);
157254721Semaste    }
158254721Semaste    return eLanguageTypeUnknown;
159254721Semaste}
160254721Semaste
161254721Semaste
162254721Semastesize_t
163254721SemasteSymbolVendor::ParseCompileUnitFunctions (const SymbolContext &sc)
164254721Semaste{
165254721Semaste    ModuleSP module_sp(GetModule());
166254721Semaste    if (module_sp)
167254721Semaste    {
168254721Semaste        lldb_private::Mutex::Locker locker(module_sp->GetMutex());
169254721Semaste        if (m_sym_file_ap.get())
170254721Semaste            return m_sym_file_ap->ParseCompileUnitFunctions(sc);
171254721Semaste    }
172254721Semaste    return 0;
173254721Semaste}
174254721Semaste
175254721Semastebool
176254721SemasteSymbolVendor::ParseCompileUnitLineTable (const SymbolContext &sc)
177254721Semaste{
178254721Semaste    ModuleSP module_sp(GetModule());
179254721Semaste    if (module_sp)
180254721Semaste    {
181254721Semaste        lldb_private::Mutex::Locker locker(module_sp->GetMutex());
182254721Semaste        if (m_sym_file_ap.get())
183254721Semaste            return m_sym_file_ap->ParseCompileUnitLineTable(sc);
184254721Semaste    }
185254721Semaste    return false;
186254721Semaste}
187254721Semaste
188254721Semastebool
189254721SemasteSymbolVendor::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList& support_files)
190254721Semaste{
191254721Semaste    ModuleSP module_sp(GetModule());
192254721Semaste    if (module_sp)
193254721Semaste    {
194254721Semaste        lldb_private::Mutex::Locker locker(module_sp->GetMutex());
195254721Semaste        if (m_sym_file_ap.get())
196254721Semaste            return m_sym_file_ap->ParseCompileUnitSupportFiles(sc, support_files);
197254721Semaste    }
198254721Semaste    return false;
199254721Semaste}
200254721Semaste
201254721Semastesize_t
202254721SemasteSymbolVendor::ParseFunctionBlocks (const SymbolContext &sc)
203254721Semaste{
204254721Semaste    ModuleSP module_sp(GetModule());
205254721Semaste    if (module_sp)
206254721Semaste    {
207254721Semaste        lldb_private::Mutex::Locker locker(module_sp->GetMutex());
208254721Semaste        if (m_sym_file_ap.get())
209254721Semaste            return m_sym_file_ap->ParseFunctionBlocks(sc);
210254721Semaste    }
211254721Semaste    return 0;
212254721Semaste}
213254721Semaste
214254721Semastesize_t
215254721SemasteSymbolVendor::ParseTypes (const SymbolContext &sc)
216254721Semaste{
217254721Semaste    ModuleSP module_sp(GetModule());
218254721Semaste    if (module_sp)
219254721Semaste    {
220254721Semaste        lldb_private::Mutex::Locker locker(module_sp->GetMutex());
221254721Semaste        if (m_sym_file_ap.get())
222254721Semaste            return m_sym_file_ap->ParseTypes(sc);
223254721Semaste    }
224254721Semaste    return 0;
225254721Semaste}
226254721Semaste
227254721Semastesize_t
228254721SemasteSymbolVendor::ParseVariablesForContext (const SymbolContext& sc)
229254721Semaste{
230254721Semaste    ModuleSP module_sp(GetModule());
231254721Semaste    if (module_sp)
232254721Semaste    {
233254721Semaste        lldb_private::Mutex::Locker locker(module_sp->GetMutex());
234254721Semaste        if (m_sym_file_ap.get())
235254721Semaste            return m_sym_file_ap->ParseVariablesForContext(sc);
236254721Semaste    }
237254721Semaste    return 0;
238254721Semaste}
239254721Semaste
240254721SemasteType*
241254721SemasteSymbolVendor::ResolveTypeUID(lldb::user_id_t type_uid)
242254721Semaste{
243254721Semaste    ModuleSP module_sp(GetModule());
244254721Semaste    if (module_sp)
245254721Semaste    {
246254721Semaste        lldb_private::Mutex::Locker locker(module_sp->GetMutex());
247254721Semaste        if (m_sym_file_ap.get())
248254721Semaste            return m_sym_file_ap->ResolveTypeUID(type_uid);
249254721Semaste    }
250254721Semaste    return NULL;
251254721Semaste}
252254721Semaste
253254721Semaste
254254721Semasteuint32_t
255254721SemasteSymbolVendor::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
256254721Semaste{
257254721Semaste    ModuleSP module_sp(GetModule());
258254721Semaste    if (module_sp)
259254721Semaste    {
260254721Semaste        lldb_private::Mutex::Locker locker(module_sp->GetMutex());
261254721Semaste        if (m_sym_file_ap.get())
262254721Semaste            return m_sym_file_ap->ResolveSymbolContext(so_addr, resolve_scope, sc);
263254721Semaste    }
264254721Semaste    return 0;
265254721Semaste}
266254721Semaste
267254721Semasteuint32_t
268254721SemasteSymbolVendor::ResolveSymbolContext (const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
269254721Semaste{
270254721Semaste    ModuleSP module_sp(GetModule());
271254721Semaste    if (module_sp)
272254721Semaste    {
273254721Semaste        lldb_private::Mutex::Locker locker(module_sp->GetMutex());
274254721Semaste        if (m_sym_file_ap.get())
275254721Semaste            return m_sym_file_ap->ResolveSymbolContext(file_spec, line, check_inlines, resolve_scope, sc_list);
276254721Semaste    }
277254721Semaste    return 0;
278254721Semaste}
279254721Semaste
280254721Semastesize_t
281254721SemasteSymbolVendor::FindGlobalVariables (const ConstString &name, const ClangNamespaceDecl *namespace_decl, bool append, size_t max_matches, VariableList& variables)
282254721Semaste{
283254721Semaste    ModuleSP module_sp(GetModule());
284254721Semaste    if (module_sp)
285254721Semaste    {
286254721Semaste        lldb_private::Mutex::Locker locker(module_sp->GetMutex());
287254721Semaste        if (m_sym_file_ap.get())
288254721Semaste            return m_sym_file_ap->FindGlobalVariables(name, namespace_decl, append, max_matches, variables);
289254721Semaste    }
290254721Semaste    return 0;
291254721Semaste}
292254721Semaste
293254721Semastesize_t
294254721SemasteSymbolVendor::FindGlobalVariables (const RegularExpression& regex, bool append, size_t max_matches, VariableList& variables)
295254721Semaste{
296254721Semaste    ModuleSP module_sp(GetModule());
297254721Semaste    if (module_sp)
298254721Semaste    {
299254721Semaste        lldb_private::Mutex::Locker locker(module_sp->GetMutex());
300254721Semaste        if (m_sym_file_ap.get())
301254721Semaste            return m_sym_file_ap->FindGlobalVariables(regex, append, max_matches, variables);
302254721Semaste    }
303254721Semaste    return 0;
304254721Semaste}
305254721Semaste
306254721Semastesize_t
307254721SemasteSymbolVendor::FindFunctions(const ConstString &name, const ClangNamespaceDecl *namespace_decl, uint32_t name_type_mask, bool include_inlines, bool append, SymbolContextList& sc_list)
308254721Semaste{
309254721Semaste    ModuleSP module_sp(GetModule());
310254721Semaste    if (module_sp)
311254721Semaste    {
312254721Semaste        lldb_private::Mutex::Locker locker(module_sp->GetMutex());
313254721Semaste        if (m_sym_file_ap.get())
314254721Semaste            return m_sym_file_ap->FindFunctions(name, namespace_decl, name_type_mask, include_inlines, append, sc_list);
315254721Semaste    }
316254721Semaste    return 0;
317254721Semaste}
318254721Semaste
319254721Semastesize_t
320254721SemasteSymbolVendor::FindFunctions(const RegularExpression& regex, bool include_inlines, bool append, SymbolContextList& sc_list)
321254721Semaste{
322254721Semaste    ModuleSP module_sp(GetModule());
323254721Semaste    if (module_sp)
324254721Semaste    {
325254721Semaste        lldb_private::Mutex::Locker locker(module_sp->GetMutex());
326254721Semaste        if (m_sym_file_ap.get())
327254721Semaste            return m_sym_file_ap->FindFunctions(regex, include_inlines, append, sc_list);
328254721Semaste    }
329254721Semaste    return 0;
330254721Semaste}
331254721Semaste
332254721Semaste
333254721Semastesize_t
334254721SemasteSymbolVendor::FindTypes (const SymbolContext& sc, const ConstString &name, const ClangNamespaceDecl *namespace_decl, bool append, size_t max_matches, TypeList& types)
335254721Semaste{
336254721Semaste    ModuleSP module_sp(GetModule());
337254721Semaste    if (module_sp)
338254721Semaste    {
339254721Semaste        lldb_private::Mutex::Locker locker(module_sp->GetMutex());
340254721Semaste        if (m_sym_file_ap.get())
341254721Semaste            return m_sym_file_ap->FindTypes(sc, name, namespace_decl, append, max_matches, types);
342254721Semaste    }
343254721Semaste    if (!append)
344254721Semaste        types.Clear();
345254721Semaste    return 0;
346254721Semaste}
347254721Semaste
348254721Semastesize_t
349254721SemasteSymbolVendor::GetTypes (SymbolContextScope *sc_scope,
350254721Semaste                        uint32_t type_mask,
351254721Semaste                        lldb_private::TypeList &type_list)
352254721Semaste{
353254721Semaste    ModuleSP module_sp(GetModule());
354254721Semaste    if (module_sp)
355254721Semaste    {
356254721Semaste        lldb_private::Mutex::Locker locker(module_sp->GetMutex());
357254721Semaste        if (m_sym_file_ap.get())
358254721Semaste            return m_sym_file_ap->GetTypes (sc_scope, type_mask, type_list);
359254721Semaste    }
360254721Semaste    return 0;
361254721Semaste}
362254721Semaste
363254721SemasteClangNamespaceDecl
364254721SemasteSymbolVendor::FindNamespace(const SymbolContext& sc, const ConstString &name, const ClangNamespaceDecl *parent_namespace_decl)
365254721Semaste{
366254721Semaste    ClangNamespaceDecl namespace_decl;
367254721Semaste    ModuleSP module_sp(GetModule());
368254721Semaste    if (module_sp)
369254721Semaste    {
370254721Semaste        lldb_private::Mutex::Locker locker(module_sp->GetMutex());
371254721Semaste        if (m_sym_file_ap.get())
372254721Semaste            namespace_decl = m_sym_file_ap->FindNamespace (sc, name, parent_namespace_decl);
373254721Semaste    }
374254721Semaste    return namespace_decl;
375254721Semaste}
376254721Semaste
377254721Semastevoid
378254721SemasteSymbolVendor::Dump(Stream *s)
379254721Semaste{
380254721Semaste    ModuleSP module_sp(GetModule());
381254721Semaste    if (module_sp)
382254721Semaste    {
383254721Semaste        bool show_context = false;
384254721Semaste
385254721Semaste        s->Printf("%p: ", this);
386254721Semaste        s->Indent();
387254721Semaste        s->PutCString("SymbolVendor");
388254721Semaste        if (m_sym_file_ap.get())
389254721Semaste        {
390254721Semaste            ObjectFile *objfile = m_sym_file_ap->GetObjectFile();
391254721Semaste            if (objfile)
392254721Semaste            {
393254721Semaste                const FileSpec &objfile_file_spec = objfile->GetFileSpec();
394254721Semaste                if (objfile_file_spec)
395254721Semaste                {
396254721Semaste                    s->PutCString(" (");
397254721Semaste                    objfile_file_spec.Dump(s);
398254721Semaste                    s->PutChar(')');
399254721Semaste                }
400254721Semaste            }
401254721Semaste        }
402254721Semaste        s->EOL();
403254721Semaste        s->IndentMore();
404254721Semaste        m_type_list.Dump(s, show_context);
405254721Semaste
406254721Semaste        CompileUnitConstIter cu_pos, cu_end;
407254721Semaste        cu_end = m_compile_units.end();
408254721Semaste        for (cu_pos = m_compile_units.begin(); cu_pos != cu_end; ++cu_pos)
409254721Semaste        {
410254721Semaste            // We currently only dump the compile units that have been parsed
411254721Semaste            if (cu_pos->get())
412254721Semaste                (*cu_pos)->Dump(s, show_context);
413254721Semaste        }
414254721Semaste
415254721Semaste        s->IndentLess();
416254721Semaste    }
417254721Semaste}
418254721Semaste
419254721SemasteCompUnitSP
420254721SemasteSymbolVendor::GetCompileUnitAtIndex(size_t idx)
421254721Semaste{
422254721Semaste    CompUnitSP cu_sp;
423254721Semaste    ModuleSP module_sp(GetModule());
424254721Semaste    if (module_sp)
425254721Semaste    {
426254721Semaste        const size_t num_compile_units = GetNumCompileUnits();
427254721Semaste        if (idx < num_compile_units)
428254721Semaste        {
429254721Semaste            cu_sp = m_compile_units[idx];
430254721Semaste            if (cu_sp.get() == NULL)
431254721Semaste            {
432254721Semaste                m_compile_units[idx] = m_sym_file_ap->ParseCompileUnitAtIndex(idx);
433254721Semaste                cu_sp = m_compile_units[idx];
434254721Semaste            }
435254721Semaste        }
436254721Semaste    }
437254721Semaste    return cu_sp;
438254721Semaste}
439254721Semaste
440254721SemasteSymtab *
441254721SemasteSymbolVendor::GetSymtab ()
442254721Semaste{
443254721Semaste    ModuleSP module_sp(GetModule());
444254721Semaste    if (module_sp)
445254721Semaste    {
446254721Semaste        ObjectFile *objfile = module_sp->GetObjectFile();
447254721Semaste        if (objfile)
448254721Semaste        {
449254721Semaste            // Get symbol table from unified section list.
450254721Semaste            return objfile->GetSymtab ();
451254721Semaste        }
452254721Semaste    }
453254721Semaste    return NULL;
454254721Semaste}
455254721Semaste
456254721Semastevoid
457254721SemasteSymbolVendor::ClearSymtab()
458254721Semaste{
459254721Semaste    ModuleSP module_sp(GetModule());
460254721Semaste    if (module_sp)
461254721Semaste    {
462254721Semaste        ObjectFile *objfile = module_sp->GetObjectFile();
463254721Semaste        if (objfile)
464254721Semaste        {
465254721Semaste            // Clear symbol table from unified section list.
466254721Semaste            objfile->ClearSymtab ();
467254721Semaste        }
468254721Semaste    }
469254721Semaste}
470254721Semaste
471254721Semaste//------------------------------------------------------------------
472254721Semaste// PluginInterface protocol
473254721Semaste//------------------------------------------------------------------
474254721Semastelldb_private::ConstString
475254721SemasteSymbolVendor::GetPluginName()
476254721Semaste{
477254721Semaste    static ConstString g_name("vendor-default");
478254721Semaste    return g_name;
479254721Semaste}
480254721Semaste
481254721Semasteuint32_t
482254721SemasteSymbolVendor::GetPluginVersion()
483254721Semaste{
484254721Semaste    return 1;
485254721Semaste}
486254721Semaste
487