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