Module.cpp revision b67c2a2f2a75fdba552a0eda0bf80df2095caa05
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
23// Shared pointers to modules track module lifetimes in
24// targets and in the global module, but this collection
25// will track all module objects that are still alive
26typedef std::vector<Module *> ModuleCollection;
27
28static ModuleCollection &
29GetModuleCollection()
30{
31    // This module collection needs to live past any module, so we could either make it a
32    // shared pointer in each module or just leak is.  Since it is only an empty vector by
33    // the time all the modules have gone away, we just leak it for now.  If we decide this
34    // is a big problem we can introduce a Finalize method that will tear everything down in
35    // a predictable order.
36
37    static ModuleCollection *g_module_collection = NULL;
38    if (g_module_collection == NULL)
39        g_module_collection = new ModuleCollection();
40
41    return *g_module_collection;
42}
43
44Mutex &
45Module::GetAllocationModuleCollectionMutex()
46{
47    static Mutex g_module_collection_mutex(Mutex::eMutexTypeRecursive);
48    return g_module_collection_mutex;
49}
50
51size_t
52Module::GetNumberAllocatedModules ()
53{
54    Mutex::Locker locker (GetAllocationModuleCollectionMutex());
55    return GetModuleCollection().size();
56}
57
58Module *
59Module::GetAllocatedModuleAtIndex (size_t idx)
60{
61    Mutex::Locker locker (GetAllocationModuleCollectionMutex());
62    ModuleCollection &modules = GetModuleCollection();
63    if (idx < modules.size())
64        return modules[idx];
65    return NULL;
66}
67
68
69
70
71Module::Module(const FileSpec& file_spec, const ArchSpec& arch, const ConstString *object_name, off_t object_offset) :
72    m_mutex (Mutex::eMutexTypeRecursive),
73    m_mod_time (file_spec.GetModificationTime()),
74    m_arch (arch),
75    m_uuid (),
76    m_file (file_spec),
77    m_platform_file(),
78    m_object_name (),
79    m_object_offset (object_offset),
80    m_objfile_sp (),
81    m_symfile_ap (),
82    m_ast (),
83    m_did_load_objfile (false),
84    m_did_load_symbol_vendor (false),
85    m_did_parse_uuid (false),
86    m_did_init_ast (false),
87    m_is_dynamic_loader_module (false)
88{
89    // Scope for locker below...
90    {
91        Mutex::Locker locker (GetAllocationModuleCollectionMutex());
92        GetModuleCollection().push_back(this);
93    }
94
95    if (object_name)
96        m_object_name = *object_name;
97    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
98    if (log)
99        log->Printf ("%p Module::Module((%s) '%s/%s%s%s%s')",
100                     this,
101                     m_arch.GetArchitectureName(),
102                     m_file.GetDirectory().AsCString(""),
103                     m_file.GetFilename().AsCString(""),
104                     m_object_name.IsEmpty() ? "" : "(",
105                     m_object_name.IsEmpty() ? "" : m_object_name.AsCString(""),
106                     m_object_name.IsEmpty() ? "" : ")");
107}
108
109Module::~Module()
110{
111    // Scope for locker below...
112    {
113        Mutex::Locker locker (GetAllocationModuleCollectionMutex());
114        ModuleCollection &modules = GetModuleCollection();
115        ModuleCollection::iterator end = modules.end();
116        ModuleCollection::iterator pos = std::find(modules.begin(), end, this);
117        if (pos != end)
118            modules.erase(pos);
119    }
120    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
121    if (log)
122        log->Printf ("%p Module::~Module((%s) '%s/%s%s%s%s')",
123                     this,
124                     m_arch.GetArchitectureName(),
125                     m_file.GetDirectory().AsCString(""),
126                     m_file.GetFilename().AsCString(""),
127                     m_object_name.IsEmpty() ? "" : "(",
128                     m_object_name.IsEmpty() ? "" : m_object_name.AsCString(""),
129                     m_object_name.IsEmpty() ? "" : ")");
130    // Release any auto pointers before we start tearing down our member
131    // variables since the object file and symbol files might need to make
132    // function calls back into this module object. The ordering is important
133    // here because symbol files can require the module object file. So we tear
134    // down the symbol file first, then the object file.
135    m_symfile_ap.reset();
136    m_objfile_sp.reset();
137}
138
139
140const lldb_private::UUID&
141Module::GetUUID()
142{
143    Mutex::Locker locker (m_mutex);
144    if (m_did_parse_uuid == false)
145    {
146        ObjectFile * obj_file = GetObjectFile ();
147
148        if (obj_file != NULL)
149        {
150            obj_file->GetUUID(&m_uuid);
151            m_did_parse_uuid = true;
152        }
153    }
154    return m_uuid;
155}
156
157ClangASTContext &
158Module::GetClangASTContext ()
159{
160    Mutex::Locker locker (m_mutex);
161    if (m_did_init_ast == false)
162    {
163        ObjectFile * objfile = GetObjectFile();
164        ArchSpec object_arch;
165        if (objfile && objfile->GetArchitecture(object_arch))
166        {
167            m_did_init_ast = true;
168            m_ast.SetArchitecture (object_arch);
169        }
170    }
171    return m_ast;
172}
173
174void
175Module::ParseAllDebugSymbols()
176{
177    Mutex::Locker locker (m_mutex);
178    uint32_t num_comp_units = GetNumCompileUnits();
179    if (num_comp_units == 0)
180        return;
181
182    SymbolContext sc;
183    sc.module_sp = this;
184    uint32_t cu_idx;
185    SymbolVendor *symbols = GetSymbolVendor ();
186
187    for (cu_idx = 0; cu_idx < num_comp_units; cu_idx++)
188    {
189        sc.comp_unit = symbols->GetCompileUnitAtIndex(cu_idx).get();
190        if (sc.comp_unit)
191        {
192            sc.function = NULL;
193            symbols->ParseVariablesForContext(sc);
194
195            symbols->ParseCompileUnitFunctions(sc);
196
197            uint32_t func_idx;
198            for (func_idx = 0; (sc.function = sc.comp_unit->GetFunctionAtIndex(func_idx).get()) != NULL; ++func_idx)
199            {
200                symbols->ParseFunctionBlocks(sc);
201
202                // Parse the variables for this function and all its blocks
203                symbols->ParseVariablesForContext(sc);
204            }
205
206
207            // Parse all types for this compile unit
208            sc.function = NULL;
209            symbols->ParseTypes(sc);
210        }
211    }
212}
213
214void
215Module::CalculateSymbolContext(SymbolContext* sc)
216{
217    sc->module_sp = this;
218}
219
220Module *
221Module::CalculateSymbolContextModule ()
222{
223    return this;
224}
225
226void
227Module::DumpSymbolContext(Stream *s)
228{
229    s->Printf(", Module{%p}", this);
230}
231
232uint32_t
233Module::GetNumCompileUnits()
234{
235    Mutex::Locker locker (m_mutex);
236    Timer scoped_timer(__PRETTY_FUNCTION__, "Module::GetNumCompileUnits (module = %p)", this);
237    SymbolVendor *symbols = GetSymbolVendor ();
238    if (symbols)
239        return symbols->GetNumCompileUnits();
240    return 0;
241}
242
243CompUnitSP
244Module::GetCompileUnitAtIndex (uint32_t index)
245{
246    Mutex::Locker locker (m_mutex);
247    uint32_t num_comp_units = GetNumCompileUnits ();
248    CompUnitSP cu_sp;
249
250    if (index < num_comp_units)
251    {
252        SymbolVendor *symbols = GetSymbolVendor ();
253        if (symbols)
254            cu_sp = symbols->GetCompileUnitAtIndex(index);
255    }
256    return cu_sp;
257}
258
259bool
260Module::ResolveFileAddress (lldb::addr_t vm_addr, Address& so_addr)
261{
262    Mutex::Locker locker (m_mutex);
263    Timer scoped_timer(__PRETTY_FUNCTION__, "Module::ResolveFileAddress (vm_addr = 0x%llx)", vm_addr);
264    ObjectFile* ofile = GetObjectFile();
265    if (ofile)
266        return so_addr.ResolveAddressUsingFileSections(vm_addr, ofile->GetSectionList());
267    return false;
268}
269
270uint32_t
271Module::ResolveSymbolContextForAddress (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
272{
273    Mutex::Locker locker (m_mutex);
274    uint32_t resolved_flags = 0;
275
276    // Clear the result symbol context in case we don't find anything
277    sc.Clear();
278
279    // Get the section from the section/offset address.
280    const Section *section = so_addr.GetSection();
281
282    // Make sure the section matches this module before we try and match anything
283    if (section && section->GetModule() == this)
284    {
285        // If the section offset based address resolved itself, then this
286        // is the right module.
287        sc.module_sp = this;
288        resolved_flags |= eSymbolContextModule;
289
290        // Resolve the compile unit, function, block, line table or line
291        // entry if requested.
292        if (resolve_scope & eSymbolContextCompUnit    ||
293            resolve_scope & eSymbolContextFunction    ||
294            resolve_scope & eSymbolContextBlock       ||
295            resolve_scope & eSymbolContextLineEntry   )
296        {
297            SymbolVendor *symbols = GetSymbolVendor ();
298            if (symbols)
299                resolved_flags |= symbols->ResolveSymbolContext (so_addr, resolve_scope, sc);
300        }
301
302        // Resolve the symbol if requested, but don't re-look it up if we've already found it.
303        if (resolve_scope & eSymbolContextSymbol && !(resolved_flags & eSymbolContextSymbol))
304        {
305            ObjectFile* ofile = GetObjectFile();
306            if (ofile)
307            {
308                Symtab *symtab = ofile->GetSymtab();
309                if (symtab)
310                {
311                    if (so_addr.IsSectionOffset())
312                    {
313                        sc.symbol = symtab->FindSymbolContainingFileAddress(so_addr.GetFileAddress());
314                        if (sc.symbol)
315                            resolved_flags |= eSymbolContextSymbol;
316                    }
317                }
318            }
319        }
320    }
321    return resolved_flags;
322}
323
324uint32_t
325Module::ResolveSymbolContextForFilePath
326(
327    const char *file_path,
328    uint32_t line,
329    bool check_inlines,
330    uint32_t resolve_scope,
331    SymbolContextList& sc_list
332)
333{
334    FileSpec file_spec(file_path, false);
335    return ResolveSymbolContextsForFileSpec (file_spec, line, check_inlines, resolve_scope, sc_list);
336}
337
338uint32_t
339Module::ResolveSymbolContextsForFileSpec (const FileSpec &file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
340{
341    Mutex::Locker locker (m_mutex);
342    Timer scoped_timer(__PRETTY_FUNCTION__,
343                       "Module::ResolveSymbolContextForFilePath (%s%s%s:%u, check_inlines = %s, resolve_scope = 0x%8.8x)",
344                       file_spec.GetDirectory().AsCString(""),
345                       file_spec.GetDirectory() ? "/" : "",
346                       file_spec.GetFilename().AsCString(""),
347                       line,
348                       check_inlines ? "yes" : "no",
349                       resolve_scope);
350
351    const uint32_t initial_count = sc_list.GetSize();
352
353    SymbolVendor *symbols = GetSymbolVendor  ();
354    if (symbols)
355        symbols->ResolveSymbolContext (file_spec, line, check_inlines, resolve_scope, sc_list);
356
357    return sc_list.GetSize() - initial_count;
358}
359
360
361uint32_t
362Module::FindGlobalVariables(const ConstString &name, const ClangNamespaceDecl *namespace_decl, bool append, uint32_t max_matches, VariableList& variables)
363{
364    SymbolVendor *symbols = GetSymbolVendor ();
365    if (symbols)
366        return symbols->FindGlobalVariables(name, namespace_decl, append, max_matches, variables);
367    return 0;
368}
369uint32_t
370Module::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
371{
372    SymbolVendor *symbols = GetSymbolVendor ();
373    if (symbols)
374        return symbols->FindGlobalVariables(regex, append, max_matches, variables);
375    return 0;
376}
377
378uint32_t
379Module::FindCompileUnits (const FileSpec &path,
380                          bool append,
381                          SymbolContextList &sc_list)
382{
383    if (!append)
384        sc_list.Clear();
385
386    const uint32_t start_size = sc_list.GetSize();
387    const uint32_t num_compile_units = GetNumCompileUnits();
388    SymbolContext sc;
389    sc.module_sp = this;
390    const bool compare_directory = path.GetDirectory();
391    for (uint32_t i=0; i<num_compile_units; ++i)
392    {
393        sc.comp_unit = GetCompileUnitAtIndex(i).get();
394        if (FileSpec::Equal (*sc.comp_unit, path, compare_directory))
395            sc_list.Append(sc);
396    }
397    return sc_list.GetSize() - start_size;
398}
399
400uint32_t
401Module::FindFunctions (const ConstString &name,
402                       const ClangNamespaceDecl *namespace_decl,
403                       uint32_t name_type_mask,
404                       bool include_symbols,
405                       bool append,
406                       SymbolContextList& sc_list)
407{
408    if (!append)
409        sc_list.Clear();
410
411    const uint32_t start_size = sc_list.GetSize();
412
413    // Find all the functions (not symbols, but debug information functions...
414    SymbolVendor *symbols = GetSymbolVendor ();
415    if (symbols)
416        symbols->FindFunctions(name, namespace_decl, name_type_mask, append, sc_list);
417
418    // Now check our symbol table for symbols that are code symbols if requested
419    if (include_symbols)
420    {
421        ObjectFile *objfile = GetObjectFile();
422        if (objfile)
423        {
424            Symtab *symtab = objfile->GetSymtab();
425            if (symtab)
426            {
427                std::vector<uint32_t> symbol_indexes;
428                symtab->FindAllSymbolsWithNameAndType (name, eSymbolTypeCode, Symtab::eDebugAny, Symtab::eVisibilityAny, symbol_indexes);
429                const uint32_t num_matches = symbol_indexes.size();
430                if (num_matches)
431                {
432                    const bool merge_symbol_into_function = true;
433                    SymbolContext sc(this);
434                    for (uint32_t i=0; i<num_matches; i++)
435                    {
436                        sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]);
437                        sc_list.AppendIfUnique (sc, merge_symbol_into_function);
438                    }
439                }
440            }
441        }
442    }
443    return sc_list.GetSize() - start_size;
444}
445
446uint32_t
447Module::FindFunctions (const RegularExpression& regex,
448                       bool include_symbols,
449                       bool append,
450                       SymbolContextList& sc_list)
451{
452    if (!append)
453        sc_list.Clear();
454
455    const uint32_t start_size = sc_list.GetSize();
456
457    SymbolVendor *symbols = GetSymbolVendor ();
458    if (symbols)
459        symbols->FindFunctions(regex, append, sc_list);
460    // Now check our symbol table for symbols that are code symbols if requested
461    if (include_symbols)
462    {
463        ObjectFile *objfile = GetObjectFile();
464        if (objfile)
465        {
466            Symtab *symtab = objfile->GetSymtab();
467            if (symtab)
468            {
469                std::vector<uint32_t> symbol_indexes;
470                symtab->AppendSymbolIndexesMatchingRegExAndType (regex, eSymbolTypeCode, Symtab::eDebugAny, Symtab::eVisibilityAny, symbol_indexes);
471                const uint32_t num_matches = symbol_indexes.size();
472                if (num_matches)
473                {
474                    const bool merge_symbol_into_function = true;
475                    SymbolContext sc(this);
476                    for (uint32_t i=0; i<num_matches; i++)
477                    {
478                        sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]);
479                        sc_list.AppendIfUnique (sc, merge_symbol_into_function);
480                    }
481                }
482            }
483        }
484    }
485    return sc_list.GetSize() - start_size;
486}
487
488uint32_t
489Module::FindTypes_Impl (const SymbolContext& sc, const ConstString &name, const ClangNamespaceDecl *namespace_decl, bool append, uint32_t max_matches, TypeList& types)
490{
491    Timer scoped_timer(__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
492    if (sc.module_sp.get() == NULL || sc.module_sp.get() == this)
493    {
494        SymbolVendor *symbols = GetSymbolVendor ();
495        if (symbols)
496            return symbols->FindTypes(sc, name, namespace_decl, append, max_matches, types);
497    }
498    return 0;
499}
500
501// depending on implementation details, type lookup might fail because of
502// embedded spurious namespace:: prefixes. this call strips them, paying
503// attention to the fact that a type might have namespace'd type names as
504// arguments to templates, and those must not be stripped off
505static const char*
506StripTypeName(const char* name_cstr)
507{
508    const char* skip_namespace = strstr(name_cstr, "::");
509    const char* template_arg_char = strchr(name_cstr, '<');
510    while (skip_namespace != NULL)
511    {
512        if (template_arg_char != NULL &&
513            skip_namespace > template_arg_char) // but namespace'd template arguments are still good to go
514            break;
515        name_cstr = skip_namespace+2;
516        skip_namespace = strstr(name_cstr, "::");
517    }
518    return name_cstr;
519}
520
521uint32_t
522Module::FindTypes (const SymbolContext& sc,  const ConstString &name, const ClangNamespaceDecl *namespace_decl, bool append, uint32_t max_matches, TypeList& types)
523{
524    uint32_t retval = FindTypes_Impl(sc, name, namespace_decl, append, max_matches, types);
525
526    if (retval == 0)
527    {
528        const char *stripped = StripTypeName(name.GetCString());
529        return FindTypes_Impl(sc, ConstString(stripped), namespace_decl, append, max_matches, types);
530    }
531    else
532        return retval;
533
534}
535
536//uint32_t
537//Module::FindTypes(const SymbolContext& sc, const RegularExpression& regex, bool append, uint32_t max_matches, Type::Encoding encoding, const char *udt_name, TypeList& types)
538//{
539//  Timer scoped_timer(__PRETTY_FUNCTION__);
540//  SymbolVendor *symbols = GetSymbolVendor ();
541//  if (symbols)
542//      return symbols->FindTypes(sc, regex, append, max_matches, encoding, udt_name, types);
543//  return 0;
544//
545//}
546
547SymbolVendor*
548Module::GetSymbolVendor (bool can_create)
549{
550    Mutex::Locker locker (m_mutex);
551    if (m_did_load_symbol_vendor == false && can_create)
552    {
553        ObjectFile *obj_file = GetObjectFile ();
554        if (obj_file != NULL)
555        {
556            Timer scoped_timer(__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
557            m_symfile_ap.reset(SymbolVendor::FindPlugin(this));
558            m_did_load_symbol_vendor = true;
559        }
560    }
561    return m_symfile_ap.get();
562}
563
564void
565Module::SetFileSpecAndObjectName (const FileSpec &file, const ConstString &object_name)
566{
567    // Container objects whose paths do not specify a file directly can call
568    // this function to correct the file and object names.
569    m_file = file;
570    m_mod_time = file.GetModificationTime();
571    m_object_name = object_name;
572}
573
574const ArchSpec&
575Module::GetArchitecture () const
576{
577    return m_arch;
578}
579
580void
581Module::GetDescription (Stream *s)
582{
583    Mutex::Locker locker (m_mutex);
584
585    if (m_arch.IsValid())
586        s->Printf("(%s) ", m_arch.GetArchitectureName());
587
588    char path[PATH_MAX];
589    if (m_file.GetPath(path, sizeof(path)))
590        s->PutCString(path);
591
592    const char *object_name = m_object_name.GetCString();
593    if (object_name)
594        s->Printf("(%s)", object_name);
595}
596
597void
598Module::Dump(Stream *s)
599{
600    Mutex::Locker locker (m_mutex);
601    //s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
602    s->Indent();
603    s->Printf("Module %s/%s%s%s%s\n",
604              m_file.GetDirectory().AsCString(),
605              m_file.GetFilename().AsCString(),
606              m_object_name ? "(" : "",
607              m_object_name ? m_object_name.GetCString() : "",
608              m_object_name ? ")" : "");
609
610    s->IndentMore();
611    ObjectFile *objfile = GetObjectFile ();
612
613    if (objfile)
614        objfile->Dump(s);
615
616    SymbolVendor *symbols = GetSymbolVendor ();
617
618    if (symbols)
619        symbols->Dump(s);
620
621    s->IndentLess();
622}
623
624
625TypeList*
626Module::GetTypeList ()
627{
628    SymbolVendor *symbols = GetSymbolVendor ();
629    if (symbols)
630        return &symbols->GetTypeList();
631    return NULL;
632}
633
634const ConstString &
635Module::GetObjectName() const
636{
637    return m_object_name;
638}
639
640ObjectFile *
641Module::GetObjectFile()
642{
643    Mutex::Locker locker (m_mutex);
644    if (m_did_load_objfile == false)
645    {
646        m_did_load_objfile = true;
647        Timer scoped_timer(__PRETTY_FUNCTION__,
648                           "Module::GetObjectFile () module = %s", GetFileSpec().GetFilename().AsCString(""));
649        m_objfile_sp = ObjectFile::FindPlugin(this, &m_file, m_object_offset, m_file.GetByteSize());
650        if (m_objfile_sp)
651        {
652			// Once we get the object file, update our module with the object file's
653			// architecture since it might differ in vendor/os if some parts were
654			// unknown.
655            m_objfile_sp->GetArchitecture (m_arch);
656        }
657    }
658    return m_objfile_sp.get();
659}
660
661
662const Symbol *
663Module::FindFirstSymbolWithNameAndType (const ConstString &name, SymbolType symbol_type)
664{
665    Timer scoped_timer(__PRETTY_FUNCTION__,
666                       "Module::FindFirstSymbolWithNameAndType (name = %s, type = %i)",
667                       name.AsCString(),
668                       symbol_type);
669    ObjectFile *objfile = GetObjectFile();
670    if (objfile)
671    {
672        Symtab *symtab = objfile->GetSymtab();
673        if (symtab)
674            return symtab->FindFirstSymbolWithNameAndType (name, symbol_type, Symtab::eDebugAny, Symtab::eVisibilityAny);
675    }
676    return NULL;
677}
678void
679Module::SymbolIndicesToSymbolContextList (Symtab *symtab, std::vector<uint32_t> &symbol_indexes, SymbolContextList &sc_list)
680{
681    // No need to protect this call using m_mutex all other method calls are
682    // already thread safe.
683
684    size_t num_indices = symbol_indexes.size();
685    if (num_indices > 0)
686    {
687        SymbolContext sc;
688        CalculateSymbolContext (&sc);
689        for (size_t i = 0; i < num_indices; i++)
690        {
691            sc.symbol = symtab->SymbolAtIndex (symbol_indexes[i]);
692            if (sc.symbol)
693                sc_list.Append (sc);
694        }
695    }
696}
697
698size_t
699Module::FindSymbolsWithNameAndType (const ConstString &name, SymbolType symbol_type, SymbolContextList &sc_list)
700{
701    // No need to protect this call using m_mutex all other method calls are
702    // already thread safe.
703
704
705    Timer scoped_timer(__PRETTY_FUNCTION__,
706                       "Module::FindSymbolsWithNameAndType (name = %s, type = %i)",
707                       name.AsCString(),
708                       symbol_type);
709    const size_t initial_size = sc_list.GetSize();
710    ObjectFile *objfile = GetObjectFile ();
711    if (objfile)
712    {
713        Symtab *symtab = objfile->GetSymtab();
714        if (symtab)
715        {
716            std::vector<uint32_t> symbol_indexes;
717            symtab->FindAllSymbolsWithNameAndType (name, symbol_type, symbol_indexes);
718            SymbolIndicesToSymbolContextList (symtab, symbol_indexes, sc_list);
719        }
720    }
721    return sc_list.GetSize() - initial_size;
722}
723
724size_t
725Module::FindSymbolsMatchingRegExAndType (const RegularExpression &regex, SymbolType symbol_type, SymbolContextList &sc_list)
726{
727    // No need to protect this call using m_mutex all other method calls are
728    // already thread safe.
729
730    Timer scoped_timer(__PRETTY_FUNCTION__,
731                       "Module::FindSymbolsMatchingRegExAndType (regex = %s, type = %i)",
732                       regex.GetText(),
733                       symbol_type);
734    const size_t initial_size = sc_list.GetSize();
735    ObjectFile *objfile = GetObjectFile ();
736    if (objfile)
737    {
738        Symtab *symtab = objfile->GetSymtab();
739        if (symtab)
740        {
741            std::vector<uint32_t> symbol_indexes;
742            symtab->FindAllSymbolsMatchingRexExAndType (regex, symbol_type, Symtab::eDebugAny, Symtab::eVisibilityAny, symbol_indexes);
743            SymbolIndicesToSymbolContextList (symtab, symbol_indexes, sc_list);
744        }
745    }
746    return sc_list.GetSize() - initial_size;
747}
748
749const TimeValue &
750Module::GetModificationTime () const
751{
752    return m_mod_time;
753}
754
755bool
756Module::IsExecutable ()
757{
758    if (GetObjectFile() == NULL)
759        return false;
760    else
761        return GetObjectFile()->IsExecutable();
762}
763
764bool
765Module::IsLoadedInTarget (Target *target)
766{
767    ObjectFile *obj_file = GetObjectFile();
768    if (obj_file)
769    {
770        SectionList *sections = obj_file->GetSectionList();
771        if (sections != NULL)
772        {
773            size_t num_sections = sections->GetSize();
774            for (size_t sect_idx = 0; sect_idx < num_sections; sect_idx++)
775            {
776                SectionSP section_sp = sections->GetSectionAtIndex(sect_idx);
777                if (section_sp->GetLoadBaseAddress(target) != LLDB_INVALID_ADDRESS)
778                {
779                    return true;
780                }
781            }
782        }
783    }
784    return false;
785}
786bool
787Module::SetArchitecture (const ArchSpec &new_arch)
788{
789    if (!m_arch.IsValid())
790    {
791        m_arch = new_arch;
792        return true;
793    }
794    return m_arch == new_arch;
795}
796
797