Module.cpp revision 395fc33dc4b06c048ed35047ec461bc092ef2df3
1//===-- Module.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/Core/Module.h"
11#include "lldb/Core/Log.h"
12#include "lldb/Core/ModuleList.h"
13#include "lldb/Core/RegularExpression.h"
14#include "lldb/Core/Timer.h"
15#include "lldb/lldb-private-log.h"
16#include "lldb/Symbol/ObjectFile.h"
17#include "lldb/Symbol/SymbolContext.h"
18#include "lldb/Symbol/SymbolVendor.h"
19
20using namespace lldb;
21using namespace lldb_private;
22
23Module::Module(const FileSpec& file_spec, const ArchSpec& arch, const ConstString *object_name, off_t object_offset) :
24    m_mutex (Mutex::eMutexTypeRecursive),
25    m_mod_time (file_spec.GetModificationTime()),
26    m_arch (arch),
27    m_uuid (),
28    m_file (file_spec),
29    m_object_name (),
30    m_objfile_ap (),
31    m_symfile_ap (),
32    m_ast (),
33    m_did_load_objfile (false),
34    m_did_load_symbol_vendor (false),
35    m_did_parse_uuid (false),
36    m_did_init_ast (false),
37    m_is_dynamic_loader_module (false)
38{
39    if (object_name)
40        m_object_name = *object_name;
41    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
42    if (log)
43        log->Printf ("%p Module::Module((%s) '%s/%s%s%s%s')",
44                     this,
45                     m_arch.AsCString(),
46                     m_file.GetDirectory().AsCString(""),
47                     m_file.GetFilename().AsCString(""),
48                     m_object_name.IsEmpty() ? "" : "(",
49                     m_object_name.IsEmpty() ? "" : m_object_name.AsCString(""),
50                     m_object_name.IsEmpty() ? "" : ")");
51}
52
53Module::~Module()
54{
55    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
56    if (log)
57        log->Printf ("%p Module::~Module((%s) '%s/%s%s%s%s')",
58                     this,
59                     m_arch.AsCString(),
60                     m_file.GetDirectory().AsCString(""),
61                     m_file.GetFilename().AsCString(""),
62                     m_object_name.IsEmpty() ? "" : "(",
63                     m_object_name.IsEmpty() ? "" : m_object_name.AsCString(""),
64                     m_object_name.IsEmpty() ? "" : ")");
65    // Release any auto pointers before we start tearing down our member
66    // variables since the object file and symbol files might need to make
67    // function calls back into this module object. The ordering is important
68    // here because symbol files can require the module object file. So we tear
69    // down the symbol file first, then the object file.
70    m_symfile_ap.reset();
71    m_objfile_ap.reset();
72}
73
74
75ModuleSP
76Module::GetSP ()
77{
78    return ModuleList::GetModuleSP (this);
79}
80
81const lldb_private::UUID&
82Module::GetUUID()
83{
84    Mutex::Locker locker (m_mutex);
85    if (m_did_parse_uuid == false)
86    {
87        ObjectFile * obj_file = GetObjectFile ();
88
89        if (obj_file != NULL)
90        {
91            obj_file->GetUUID(&m_uuid);
92            m_did_parse_uuid = true;
93        }
94    }
95    return m_uuid;
96}
97
98ClangASTContext &
99Module::GetClangASTContext ()
100{
101    Mutex::Locker locker (m_mutex);
102    if (m_did_init_ast == false)
103    {
104        ObjectFile * objfile = GetObjectFile();
105        ArchSpec object_arch;
106        if (objfile && objfile->GetArchitecture(object_arch))
107        {
108            m_did_init_ast = true;
109            m_ast.SetArchitecture (object_arch);
110        }
111    }
112    return m_ast;
113}
114
115void
116Module::ParseAllDebugSymbols()
117{
118    Mutex::Locker locker (m_mutex);
119    uint32_t num_comp_units = GetNumCompileUnits();
120    if (num_comp_units == 0)
121        return;
122
123    TargetSP null_target;
124    SymbolContext sc(null_target, GetSP());
125    uint32_t cu_idx;
126    SymbolVendor *symbols = GetSymbolVendor ();
127
128    for (cu_idx = 0; cu_idx < num_comp_units; cu_idx++)
129    {
130        sc.comp_unit = symbols->GetCompileUnitAtIndex(cu_idx).get();
131        if (sc.comp_unit)
132        {
133            sc.function = NULL;
134            symbols->ParseVariablesForContext(sc);
135
136            symbols->ParseCompileUnitFunctions(sc);
137
138            uint32_t func_idx;
139            for (func_idx = 0; (sc.function = sc.comp_unit->GetFunctionAtIndex(func_idx).get()) != NULL; ++func_idx)
140            {
141                symbols->ParseFunctionBlocks(sc);
142
143                // Parse the variables for this function and all its blocks
144                symbols->ParseVariablesForContext(sc);
145            }
146
147
148            // Parse all types for this compile unit
149            sc.function = NULL;
150            symbols->ParseTypes(sc);
151        }
152    }
153}
154
155void
156Module::CalculateSymbolContext(SymbolContext* sc)
157{
158    sc->module_sp = GetSP();
159}
160
161void
162Module::DumpSymbolContext(Stream *s)
163{
164    s->Printf(", Module{0x%8.8x}", this);
165}
166
167uint32_t
168Module::GetNumCompileUnits()
169{
170    Mutex::Locker locker (m_mutex);
171    Timer scoped_timer(__PRETTY_FUNCTION__, "Module::GetNumCompileUnits (module = %p)", this);
172    SymbolVendor *symbols = GetSymbolVendor ();
173    if (symbols)
174        return symbols->GetNumCompileUnits();
175    return 0;
176}
177
178CompUnitSP
179Module::GetCompileUnitAtIndex (uint32_t index)
180{
181    Mutex::Locker locker (m_mutex);
182    uint32_t num_comp_units = GetNumCompileUnits ();
183    CompUnitSP cu_sp;
184
185    if (index < num_comp_units)
186    {
187        SymbolVendor *symbols = GetSymbolVendor ();
188        if (symbols)
189            cu_sp = symbols->GetCompileUnitAtIndex(index);
190    }
191    return cu_sp;
192}
193
194//CompUnitSP
195//Module::FindCompUnit(lldb::user_id_t uid)
196//{
197//  CompUnitSP cu_sp;
198//  SymbolVendor *symbols = GetSymbolVendor ();
199//  if (symbols)
200//      cu_sp = symbols->FindCompUnit(uid);
201//  return cu_sp;
202//}
203
204bool
205Module::ResolveFileAddress (lldb::addr_t vm_addr, Address& so_addr)
206{
207    Mutex::Locker locker (m_mutex);
208    Timer scoped_timer(__PRETTY_FUNCTION__, "Module::ResolveFileAddress (vm_addr = 0x%llx)", vm_addr);
209    ObjectFile* ofile = GetObjectFile();
210    if (ofile)
211        return so_addr.ResolveAddressUsingFileSections(vm_addr, ofile->GetSectionList());
212    return false;
213}
214
215uint32_t
216Module::ResolveSymbolContextForAddress (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
217{
218    Mutex::Locker locker (m_mutex);
219    uint32_t resolved_flags = 0;
220
221    // Clear the result symbol context in case we don't find anything
222    sc.Clear();
223
224    // Get the section from the section/offset address.
225    const Section *section = so_addr.GetSection();
226
227    // Make sure the section matches this module before we try and match anything
228    if (section && section->GetModule() == this)
229    {
230        // If the section offset based address resolved itself, then this
231        // is the right module.
232        sc.module_sp = GetSP();
233        resolved_flags |= eSymbolContextModule;
234
235        // Resolve the compile unit, function, block, line table or line
236        // entry if requested.
237        if (resolve_scope & eSymbolContextCompUnit    ||
238            resolve_scope & eSymbolContextFunction    ||
239            resolve_scope & eSymbolContextBlock       ||
240            resolve_scope & eSymbolContextLineEntry   )
241        {
242            SymbolVendor *symbols = GetSymbolVendor ();
243            if (symbols)
244                resolved_flags |= symbols->ResolveSymbolContext (so_addr, resolve_scope, sc);
245        }
246
247        // Resolve the symbol if requested, but don't re-look it up if we've already found it.
248        if (resolve_scope & eSymbolContextSymbol && !(resolved_flags & eSymbolContextSymbol))
249        {
250            ObjectFile* ofile = GetObjectFile();
251            if (ofile)
252            {
253                Symtab *symtab = ofile->GetSymtab();
254                if (symtab)
255                {
256                    if (so_addr.IsSectionOffset())
257                    {
258                        sc.symbol = symtab->FindSymbolContainingFileAddress(so_addr.GetFileAddress());
259                        if (sc.symbol)
260                            resolved_flags |= eSymbolContextSymbol;
261                    }
262                }
263            }
264        }
265    }
266    return resolved_flags;
267}
268
269uint32_t
270Module::ResolveSymbolContextForFilePath
271(
272    const char *file_path,
273    uint32_t line,
274    bool check_inlines,
275    uint32_t resolve_scope,
276    SymbolContextList& sc_list
277)
278{
279    FileSpec file_spec(file_path, false);
280    return ResolveSymbolContextsForFileSpec (file_spec, line, check_inlines, resolve_scope, sc_list);
281}
282
283uint32_t
284Module::ResolveSymbolContextsForFileSpec (const FileSpec &file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
285{
286    Mutex::Locker locker (m_mutex);
287    Timer scoped_timer(__PRETTY_FUNCTION__,
288                       "Module::ResolveSymbolContextForFilePath (%s%s%s:%u, check_inlines = %s, resolve_scope = 0x%8.8x)",
289                       file_spec.GetDirectory().AsCString(""),
290                       file_spec.GetDirectory() ? "/" : "",
291                       file_spec.GetFilename().AsCString(""),
292                       line,
293                       check_inlines ? "yes" : "no",
294                       resolve_scope);
295
296    const uint32_t initial_count = sc_list.GetSize();
297
298    SymbolVendor *symbols = GetSymbolVendor  ();
299    if (symbols)
300        symbols->ResolveSymbolContext (file_spec, line, check_inlines, resolve_scope, sc_list);
301
302    return sc_list.GetSize() - initial_count;
303}
304
305
306uint32_t
307Module::FindGlobalVariables(const ConstString &name, bool append, uint32_t max_matches, VariableList& variables)
308{
309    SymbolVendor *symbols = GetSymbolVendor ();
310    if (symbols)
311        return symbols->FindGlobalVariables(name, append, max_matches, variables);
312    return 0;
313}
314uint32_t
315Module::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
316{
317    SymbolVendor *symbols = GetSymbolVendor ();
318    if (symbols)
319        return symbols->FindGlobalVariables(regex, append, max_matches, variables);
320    return 0;
321}
322
323uint32_t
324Module::FindFunctions (const ConstString &name,
325                       uint32_t name_type_mask,
326                       bool include_symbols,
327                       bool append,
328                       SymbolContextList& sc_list)
329{
330    if (!append)
331        sc_list.Clear();
332
333    const uint32_t start_size = sc_list.GetSize();
334
335    // Find all the functions (not symbols, but debug information functions...
336    SymbolVendor *symbols = GetSymbolVendor ();
337    if (symbols)
338        symbols->FindFunctions(name, name_type_mask, append, sc_list);
339
340    // Now check our symbol table for symbols that are code symbols if requested
341    if (include_symbols)
342    {
343        ObjectFile *objfile = GetObjectFile();
344        if (objfile)
345        {
346            Symtab *symtab = objfile->GetSymtab();
347            if (symtab)
348            {
349                std::vector<uint32_t> symbol_indexes;
350                symtab->FindAllSymbolsWithNameAndType (name, eSymbolTypeCode, Symtab::eDebugAny, Symtab::eVisibilityAny, symbol_indexes);
351                const uint32_t num_matches = symbol_indexes.size();
352                if (num_matches)
353                {
354                    SymbolContext sc(this);
355                    for (uint32_t i=0; i<num_matches; i++)
356                    {
357                        sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]);
358                        sc_list.AppendIfUnique (sc);
359                    }
360                }
361            }
362        }
363    }
364    return sc_list.GetSize() - start_size;
365}
366
367uint32_t
368Module::FindFunctions (const RegularExpression& regex,
369                       bool include_symbols,
370                       bool append,
371                       SymbolContextList& sc_list)
372{
373    if (!append)
374        sc_list.Clear();
375
376    const uint32_t start_size = sc_list.GetSize();
377
378    SymbolVendor *symbols = GetSymbolVendor ();
379    if (symbols)
380        return symbols->FindFunctions(regex, append, sc_list);
381    // Now check our symbol table for symbols that are code symbols if requested
382    if (include_symbols)
383    {
384        ObjectFile *objfile = GetObjectFile();
385        if (objfile)
386        {
387            Symtab *symtab = objfile->GetSymtab();
388            if (symtab)
389            {
390                std::vector<uint32_t> symbol_indexes;
391                symtab->AppendSymbolIndexesMatchingRegExAndType (regex, eSymbolTypeCode, Symtab::eDebugAny, Symtab::eVisibilityAny, symbol_indexes);
392                const uint32_t num_matches = symbol_indexes.size();
393                if (num_matches)
394                {
395                    SymbolContext sc(this);
396                    for (uint32_t i=0; i<num_matches; i++)
397                    {
398                        sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]);
399                        sc_list.AppendIfUnique (sc);
400                    }
401                }
402            }
403        }
404    }
405    return sc_list.GetSize() - start_size;
406}
407
408uint32_t
409Module::FindTypes (const SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, TypeList& types)
410{
411    Timer scoped_timer(__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
412    if (sc.module_sp.get() == NULL || sc.module_sp.get() == this)
413    {
414        SymbolVendor *symbols = GetSymbolVendor ();
415        if (symbols)
416            return symbols->FindTypes(sc, name, append, max_matches, types);
417    }
418    return 0;
419}
420
421//uint32_t
422//Module::FindTypes(const SymbolContext& sc, const RegularExpression& regex, bool append, uint32_t max_matches, Type::Encoding encoding, const char *udt_name, TypeList& types)
423//{
424//  Timer scoped_timer(__PRETTY_FUNCTION__);
425//  SymbolVendor *symbols = GetSymbolVendor ();
426//  if (symbols)
427//      return symbols->FindTypes(sc, regex, append, max_matches, encoding, udt_name, types);
428//  return 0;
429//
430//}
431
432SymbolVendor*
433Module::GetSymbolVendor (bool can_create)
434{
435    Mutex::Locker locker (m_mutex);
436    if (m_did_load_symbol_vendor == false && can_create)
437    {
438        ObjectFile *obj_file = GetObjectFile ();
439        if (obj_file != NULL)
440        {
441            Timer scoped_timer(__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
442            m_symfile_ap.reset(SymbolVendor::FindPlugin(this));
443            m_did_load_symbol_vendor = true;
444        }
445    }
446    return m_symfile_ap.get();
447}
448
449const FileSpec &
450Module::GetFileSpec () const
451{
452    return m_file;
453}
454
455void
456Module::SetFileSpecAndObjectName (const FileSpec &file, const ConstString &object_name)
457{
458    // Container objects whose paths do not specify a file directly can call
459    // this function to correct the file and object names.
460    m_file = file;
461    m_mod_time = file.GetModificationTime();
462    m_object_name = object_name;
463}
464
465const ArchSpec&
466Module::GetArchitecture () const
467{
468    return m_arch;
469}
470
471void
472Module::GetDescription (Stream *s)
473{
474    Mutex::Locker locker (m_mutex);
475
476    if (m_arch.IsValid())
477        s->Printf("(%s) ", m_arch.AsCString());
478
479    char path[PATH_MAX];
480    if (m_file.GetPath(path, sizeof(path)))
481        s->PutCString(path);
482
483    const char *object_name = m_object_name.GetCString();
484    if (object_name)
485        s->Printf("(%s)", object_name);
486}
487
488void
489Module::Dump(Stream *s)
490{
491    Mutex::Locker locker (m_mutex);
492    //s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
493    s->Indent();
494    s->Printf("Module %s/%s%s%s%s\n",
495              m_file.GetDirectory().AsCString(),
496              m_file.GetFilename().AsCString(),
497              m_object_name ? "(" : "",
498              m_object_name ? m_object_name.GetCString() : "",
499              m_object_name ? ")" : "");
500
501    s->IndentMore();
502    ObjectFile *objfile = GetObjectFile ();
503
504    if (objfile)
505        objfile->Dump(s);
506
507    SymbolVendor *symbols = GetSymbolVendor ();
508
509    if (symbols)
510        symbols->Dump(s);
511
512    s->IndentLess();
513}
514
515
516TypeList*
517Module::GetTypeList ()
518{
519    SymbolVendor *symbols = GetSymbolVendor ();
520    if (symbols)
521        return &symbols->GetTypeList();
522    return NULL;
523}
524
525const ConstString &
526Module::GetObjectName() const
527{
528    return m_object_name;
529}
530
531ObjectFile *
532Module::GetObjectFile()
533{
534    Mutex::Locker locker (m_mutex);
535    if (m_did_load_objfile == false)
536    {
537        m_did_load_objfile = true;
538        Timer scoped_timer(__PRETTY_FUNCTION__,
539                           "Module::GetObjectFile () module = %s", GetFileSpec().GetFilename().AsCString(""));
540        m_objfile_ap.reset(ObjectFile::FindPlugin(this, &m_file, 0, m_file.GetByteSize()));
541    }
542    return m_objfile_ap.get();
543}
544
545
546const Symbol *
547Module::FindFirstSymbolWithNameAndType (const ConstString &name, SymbolType symbol_type)
548{
549    Timer scoped_timer(__PRETTY_FUNCTION__,
550                       "Module::FindFirstSymbolWithNameAndType (name = %s, type = %i)",
551                       name.AsCString(),
552                       symbol_type);
553    ObjectFile *objfile = GetObjectFile();
554    if (objfile)
555    {
556        Symtab *symtab = objfile->GetSymtab();
557        if (symtab)
558            return symtab->FindFirstSymbolWithNameAndType (name, symbol_type, Symtab::eDebugAny, Symtab::eVisibilityAny);
559    }
560    return NULL;
561}
562void
563Module::SymbolIndicesToSymbolContextList (Symtab *symtab, std::vector<uint32_t> &symbol_indexes, SymbolContextList &sc_list)
564{
565    // No need to protect this call using m_mutex all other method calls are
566    // already thread safe.
567
568    size_t num_indices = symbol_indexes.size();
569    if (num_indices > 0)
570    {
571        SymbolContext sc;
572        CalculateSymbolContext (&sc);
573        for (size_t i = 0; i < num_indices; i++)
574        {
575            sc.symbol = symtab->SymbolAtIndex (symbol_indexes[i]);
576            if (sc.symbol)
577                sc_list.Append (sc);
578        }
579    }
580}
581
582size_t
583Module::FindSymbolsWithNameAndType (const ConstString &name, SymbolType symbol_type, SymbolContextList &sc_list)
584{
585    // No need to protect this call using m_mutex all other method calls are
586    // already thread safe.
587
588
589    Timer scoped_timer(__PRETTY_FUNCTION__,
590                       "Module::FindSymbolsWithNameAndType (name = %s, type = %i)",
591                       name.AsCString(),
592                       symbol_type);
593    const size_t initial_size = sc_list.GetSize();
594    ObjectFile *objfile = GetObjectFile ();
595    if (objfile)
596    {
597        Symtab *symtab = objfile->GetSymtab();
598        if (symtab)
599        {
600            std::vector<uint32_t> symbol_indexes;
601            symtab->FindAllSymbolsWithNameAndType (name, symbol_type, symbol_indexes);
602            SymbolIndicesToSymbolContextList (symtab, symbol_indexes, sc_list);
603        }
604    }
605    return sc_list.GetSize() - initial_size;
606}
607
608size_t
609Module::FindSymbolsMatchingRegExAndType (const RegularExpression &regex, SymbolType symbol_type, SymbolContextList &sc_list)
610{
611    // No need to protect this call using m_mutex all other method calls are
612    // already thread safe.
613
614    Timer scoped_timer(__PRETTY_FUNCTION__,
615                       "Module::FindSymbolsMatchingRegExAndType (regex = %s, type = %i)",
616                       regex.GetText(),
617                       symbol_type);
618    const size_t initial_size = sc_list.GetSize();
619    ObjectFile *objfile = GetObjectFile ();
620    if (objfile)
621    {
622        Symtab *symtab = objfile->GetSymtab();
623        if (symtab)
624        {
625            std::vector<uint32_t> symbol_indexes;
626            symtab->FindAllSymbolsMatchingRexExAndType (regex, symbol_type, Symtab::eDebugAny, Symtab::eVisibilityAny, symbol_indexes);
627            SymbolIndicesToSymbolContextList (symtab, symbol_indexes, sc_list);
628        }
629    }
630    return sc_list.GetSize() - initial_size;
631}
632
633const TimeValue &
634Module::GetModificationTime () const
635{
636    return m_mod_time;
637}
638
639bool
640Module::IsExecutable ()
641{
642    if (GetObjectFile() == NULL)
643        return false;
644    else
645        return GetObjectFile()->IsExecutable();
646}
647
648bool
649Module::SetArchitecture (const ArchSpec &new_arch)
650{
651    if (m_arch == new_arch)
652        return true;
653    else if (!m_arch.IsValid())
654    {
655        m_arch = new_arch;
656        return true;
657    }
658    else
659    {
660        return false;
661    }
662
663}
664
665