Module.cpp revision 444fe998bf707bd076a70c3a779db8575533695e
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/DataBuffer.h"
12#include "lldb/Core/DataBufferHeap.h"
13#include "lldb/Core/Log.h"
14#include "lldb/Core/ModuleList.h"
15#include "lldb/Core/RegularExpression.h"
16#include "lldb/Core/StreamString.h"
17#include "lldb/Core/Timer.h"
18#include "lldb/Host/Host.h"
19#include "lldb/lldb-private-log.h"
20#include "lldb/Symbol/ObjectFile.h"
21#include "lldb/Symbol/SymbolContext.h"
22#include "lldb/Symbol/SymbolVendor.h"
23#include "lldb/Target/Process.h"
24#include "lldb/Target/Target.h"
25
26using namespace lldb;
27using namespace lldb_private;
28
29// Shared pointers to modules track module lifetimes in
30// targets and in the global module, but this collection
31// will track all module objects that are still alive
32typedef std::vector<Module *> ModuleCollection;
33
34static ModuleCollection &
35GetModuleCollection()
36{
37    // This module collection needs to live past any module, so we could either make it a
38    // shared pointer in each module or just leak is.  Since it is only an empty vector by
39    // the time all the modules have gone away, we just leak it for now.  If we decide this
40    // is a big problem we can introduce a Finalize method that will tear everything down in
41    // a predictable order.
42
43    static ModuleCollection *g_module_collection = NULL;
44    if (g_module_collection == NULL)
45        g_module_collection = new ModuleCollection();
46
47    return *g_module_collection;
48}
49
50Mutex *
51Module::GetAllocationModuleCollectionMutex()
52{
53    // NOTE: The mutex below must be leaked since the global module list in
54    // the ModuleList class will get torn at some point, and we can't know
55    // if it will tear itself down before the "g_module_collection_mutex" below
56    // will. So we leak a Mutex object below to safeguard against that
57
58    static Mutex *g_module_collection_mutex = NULL;
59    if (g_module_collection_mutex == NULL)
60        g_module_collection_mutex = new Mutex (Mutex::eMutexTypeRecursive); // NOTE: known leak
61    return g_module_collection_mutex;
62}
63
64size_t
65Module::GetNumberAllocatedModules ()
66{
67    Mutex::Locker locker (GetAllocationModuleCollectionMutex());
68    return GetModuleCollection().size();
69}
70
71Module *
72Module::GetAllocatedModuleAtIndex (size_t idx)
73{
74    Mutex::Locker locker (GetAllocationModuleCollectionMutex());
75    ModuleCollection &modules = GetModuleCollection();
76    if (idx < modules.size())
77        return modules[idx];
78    return NULL;
79}
80#if 0
81
82// These functions help us to determine if modules are still loaded, yet don't require that
83// you have a command interpreter and can easily be called from an external debugger.
84namespace lldb {
85
86    void
87    ClearModuleInfo (void)
88    {
89        ModuleList::RemoveOrphanSharedModules();
90    }
91
92    void
93    DumpModuleInfo (void)
94    {
95        Mutex::Locker locker (Module::GetAllocationModuleCollectionMutex());
96        ModuleCollection &modules = GetModuleCollection();
97        const size_t count = modules.size();
98        printf ("%s: %zu modules:\n", __PRETTY_FUNCTION__, count);
99        for (size_t i=0; i<count; ++i)
100        {
101
102            StreamString strm;
103            Module *module = modules[i];
104            const bool in_shared_module_list = ModuleList::ModuleIsInCache (module);
105            module->GetDescription(&strm, eDescriptionLevelFull);
106            printf ("%p: shared = %i, ref_count = %3u, module = %s\n",
107                    module,
108                    in_shared_module_list,
109                    (uint32_t)module->use_count(),
110                    strm.GetString().c_str());
111        }
112    }
113}
114
115#endif
116
117Module::Module (const ModuleSpec &module_spec) :
118    m_mutex (Mutex::eMutexTypeRecursive),
119    m_mod_time (module_spec.GetFileSpec().GetModificationTime()),
120    m_arch (module_spec.GetArchitecture()),
121    m_uuid (),
122    m_file (module_spec.GetFileSpec()),
123    m_platform_file(module_spec.GetPlatformFileSpec()),
124    m_symfile_spec (module_spec.GetSymbolFileSpec()),
125    m_object_name (module_spec.GetObjectName()),
126    m_object_offset (module_spec.GetObjectOffset()),
127    m_objfile_sp (),
128    m_symfile_ap (),
129    m_ast (),
130    m_did_load_objfile (false),
131    m_did_load_symbol_vendor (false),
132    m_did_parse_uuid (false),
133    m_did_init_ast (false),
134    m_is_dynamic_loader_module (false),
135    m_was_modified (false)
136{
137    // Scope for locker below...
138    {
139        Mutex::Locker locker (GetAllocationModuleCollectionMutex());
140        GetModuleCollection().push_back(this);
141    }
142
143    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
144    if (log)
145        log->Printf ("%p Module::Module((%s) '%s/%s%s%s%s')",
146                     this,
147                     m_arch.GetArchitectureName(),
148                     m_file.GetDirectory().AsCString(""),
149                     m_file.GetFilename().AsCString(""),
150                     m_object_name.IsEmpty() ? "" : "(",
151                     m_object_name.IsEmpty() ? "" : m_object_name.AsCString(""),
152                     m_object_name.IsEmpty() ? "" : ")");
153}
154
155Module::Module(const FileSpec& file_spec,
156               const ArchSpec& arch,
157               const ConstString *object_name,
158               off_t object_offset) :
159    m_mutex (Mutex::eMutexTypeRecursive),
160    m_mod_time (file_spec.GetModificationTime()),
161    m_arch (arch),
162    m_uuid (),
163    m_file (file_spec),
164    m_platform_file(),
165    m_symfile_spec (),
166    m_object_name (),
167    m_object_offset (object_offset),
168    m_objfile_sp (),
169    m_symfile_ap (),
170    m_ast (),
171    m_did_load_objfile (false),
172    m_did_load_symbol_vendor (false),
173    m_did_parse_uuid (false),
174    m_did_init_ast (false),
175    m_is_dynamic_loader_module (false),
176    m_was_modified (false)
177{
178    // Scope for locker below...
179    {
180        Mutex::Locker locker (GetAllocationModuleCollectionMutex());
181        GetModuleCollection().push_back(this);
182    }
183
184    if (object_name)
185        m_object_name = *object_name;
186    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
187    if (log)
188        log->Printf ("%p Module::Module((%s) '%s/%s%s%s%s')",
189                     this,
190                     m_arch.GetArchitectureName(),
191                     m_file.GetDirectory().AsCString(""),
192                     m_file.GetFilename().AsCString(""),
193                     m_object_name.IsEmpty() ? "" : "(",
194                     m_object_name.IsEmpty() ? "" : m_object_name.AsCString(""),
195                     m_object_name.IsEmpty() ? "" : ")");
196}
197
198Module::~Module()
199{
200    // Scope for locker below...
201    {
202        Mutex::Locker locker (GetAllocationModuleCollectionMutex());
203        ModuleCollection &modules = GetModuleCollection();
204        ModuleCollection::iterator end = modules.end();
205        ModuleCollection::iterator pos = std::find(modules.begin(), end, this);
206        if (pos != end)
207            modules.erase(pos);
208    }
209    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
210    if (log)
211        log->Printf ("%p Module::~Module((%s) '%s/%s%s%s%s')",
212                     this,
213                     m_arch.GetArchitectureName(),
214                     m_file.GetDirectory().AsCString(""),
215                     m_file.GetFilename().AsCString(""),
216                     m_object_name.IsEmpty() ? "" : "(",
217                     m_object_name.IsEmpty() ? "" : m_object_name.AsCString(""),
218                     m_object_name.IsEmpty() ? "" : ")");
219    // Release any auto pointers before we start tearing down our member
220    // variables since the object file and symbol files might need to make
221    // function calls back into this module object. The ordering is important
222    // here because symbol files can require the module object file. So we tear
223    // down the symbol file first, then the object file.
224    m_symfile_ap.reset();
225    m_objfile_sp.reset();
226}
227
228ObjectFile *
229Module::GetMemoryObjectFile (const lldb::ProcessSP &process_sp, lldb::addr_t header_addr, Error &error)
230{
231    if (m_objfile_sp)
232    {
233        error.SetErrorString ("object file already exists");
234    }
235    else
236    {
237        Mutex::Locker locker (m_mutex);
238        if (process_sp)
239        {
240            StreamString s;
241            if (m_file.GetFilename())
242                s << m_file.GetFilename();
243                s.Printf("[0x%16.16llx]", header_addr);
244                m_file.GetFilename().SetCString (s.GetData());
245            m_did_load_objfile = true;
246            std::auto_ptr<DataBufferHeap> data_ap (new DataBufferHeap (512, 0));
247            Error readmem_error;
248            const size_t bytes_read = process_sp->ReadMemory (header_addr,
249                                                              data_ap->GetBytes(),
250                                                              data_ap->GetByteSize(),
251                                                              readmem_error);
252            if (bytes_read == 512)
253            {
254                DataBufferSP data_sp(data_ap.release());
255                m_objfile_sp = ObjectFile::FindPlugin(shared_from_this(), process_sp, header_addr, data_sp);
256                if (m_objfile_sp)
257                {
258                    // Once we get the object file, update our module with the object file's
259                    // architecture since it might differ in vendor/os if some parts were
260                    // unknown.
261                    m_objfile_sp->GetArchitecture (m_arch);
262                }
263                else
264                {
265                    error.SetErrorString ("unable to find suitable object file plug-in");
266                }
267            }
268            else
269            {
270                error.SetErrorStringWithFormat ("unable to read header from memory: %s", readmem_error.AsCString());
271            }
272        }
273        else
274        {
275            error.SetErrorString ("invalid process");
276        }
277    }
278    return m_objfile_sp.get();
279}
280
281
282const lldb_private::UUID&
283Module::GetUUID()
284{
285    Mutex::Locker locker (m_mutex);
286    if (m_did_parse_uuid == false)
287    {
288        ObjectFile * obj_file = GetObjectFile ();
289
290        if (obj_file != NULL)
291        {
292            obj_file->GetUUID(&m_uuid);
293            m_did_parse_uuid = true;
294        }
295    }
296    return m_uuid;
297}
298
299ClangASTContext &
300Module::GetClangASTContext ()
301{
302    Mutex::Locker locker (m_mutex);
303    if (m_did_init_ast == false)
304    {
305        ObjectFile * objfile = GetObjectFile();
306        ArchSpec object_arch;
307        if (objfile && objfile->GetArchitecture(object_arch))
308        {
309            m_did_init_ast = true;
310            m_ast.SetArchitecture (object_arch);
311        }
312    }
313    return m_ast;
314}
315
316void
317Module::ParseAllDebugSymbols()
318{
319    Mutex::Locker locker (m_mutex);
320    uint32_t num_comp_units = GetNumCompileUnits();
321    if (num_comp_units == 0)
322        return;
323
324    SymbolContext sc;
325    sc.module_sp = shared_from_this();
326    uint32_t cu_idx;
327    SymbolVendor *symbols = GetSymbolVendor ();
328
329    for (cu_idx = 0; cu_idx < num_comp_units; cu_idx++)
330    {
331        sc.comp_unit = symbols->GetCompileUnitAtIndex(cu_idx).get();
332        if (sc.comp_unit)
333        {
334            sc.function = NULL;
335            symbols->ParseVariablesForContext(sc);
336
337            symbols->ParseCompileUnitFunctions(sc);
338
339            uint32_t func_idx;
340            for (func_idx = 0; (sc.function = sc.comp_unit->GetFunctionAtIndex(func_idx).get()) != NULL; ++func_idx)
341            {
342                symbols->ParseFunctionBlocks(sc);
343
344                // Parse the variables for this function and all its blocks
345                symbols->ParseVariablesForContext(sc);
346            }
347
348
349            // Parse all types for this compile unit
350            sc.function = NULL;
351            symbols->ParseTypes(sc);
352        }
353    }
354}
355
356void
357Module::CalculateSymbolContext(SymbolContext* sc)
358{
359    sc->module_sp = shared_from_this();
360}
361
362ModuleSP
363Module::CalculateSymbolContextModule ()
364{
365    return shared_from_this();
366}
367
368void
369Module::DumpSymbolContext(Stream *s)
370{
371    s->Printf(", Module{%p}", this);
372}
373
374uint32_t
375Module::GetNumCompileUnits()
376{
377    Mutex::Locker locker (m_mutex);
378    Timer scoped_timer(__PRETTY_FUNCTION__, "Module::GetNumCompileUnits (module = %p)", this);
379    SymbolVendor *symbols = GetSymbolVendor ();
380    if (symbols)
381        return symbols->GetNumCompileUnits();
382    return 0;
383}
384
385CompUnitSP
386Module::GetCompileUnitAtIndex (uint32_t index)
387{
388    Mutex::Locker locker (m_mutex);
389    uint32_t num_comp_units = GetNumCompileUnits ();
390    CompUnitSP cu_sp;
391
392    if (index < num_comp_units)
393    {
394        SymbolVendor *symbols = GetSymbolVendor ();
395        if (symbols)
396            cu_sp = symbols->GetCompileUnitAtIndex(index);
397    }
398    return cu_sp;
399}
400
401bool
402Module::ResolveFileAddress (lldb::addr_t vm_addr, Address& so_addr)
403{
404    Mutex::Locker locker (m_mutex);
405    Timer scoped_timer(__PRETTY_FUNCTION__, "Module::ResolveFileAddress (vm_addr = 0x%llx)", vm_addr);
406    ObjectFile* ofile = GetObjectFile();
407    if (ofile)
408        return so_addr.ResolveAddressUsingFileSections(vm_addr, ofile->GetSectionList());
409    return false;
410}
411
412uint32_t
413Module::ResolveSymbolContextForAddress (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
414{
415    Mutex::Locker locker (m_mutex);
416    uint32_t resolved_flags = 0;
417
418    // Clear the result symbol context in case we don't find anything
419    sc.Clear();
420
421    // Get the section from the section/offset address.
422    SectionSP section_sp (so_addr.GetSection());
423
424    // Make sure the section matches this module before we try and match anything
425    if (section_sp && section_sp->GetModule().get() == this)
426    {
427        // If the section offset based address resolved itself, then this
428        // is the right module.
429        sc.module_sp = shared_from_this();
430        resolved_flags |= eSymbolContextModule;
431
432        // Resolve the compile unit, function, block, line table or line
433        // entry if requested.
434        if (resolve_scope & eSymbolContextCompUnit    ||
435            resolve_scope & eSymbolContextFunction    ||
436            resolve_scope & eSymbolContextBlock       ||
437            resolve_scope & eSymbolContextLineEntry   )
438        {
439            SymbolVendor *symbols = GetSymbolVendor ();
440            if (symbols)
441                resolved_flags |= symbols->ResolveSymbolContext (so_addr, resolve_scope, sc);
442        }
443
444        // Resolve the symbol if requested, but don't re-look it up if we've already found it.
445        if (resolve_scope & eSymbolContextSymbol && !(resolved_flags & eSymbolContextSymbol))
446        {
447            ObjectFile* ofile = GetObjectFile();
448            if (ofile)
449            {
450                Symtab *symtab = ofile->GetSymtab();
451                if (symtab)
452                {
453                    if (so_addr.IsSectionOffset())
454                    {
455                        sc.symbol = symtab->FindSymbolContainingFileAddress(so_addr.GetFileAddress());
456                        if (sc.symbol)
457                            resolved_flags |= eSymbolContextSymbol;
458                    }
459                }
460            }
461        }
462    }
463    return resolved_flags;
464}
465
466uint32_t
467Module::ResolveSymbolContextForFilePath
468(
469    const char *file_path,
470    uint32_t line,
471    bool check_inlines,
472    uint32_t resolve_scope,
473    SymbolContextList& sc_list
474)
475{
476    FileSpec file_spec(file_path, false);
477    return ResolveSymbolContextsForFileSpec (file_spec, line, check_inlines, resolve_scope, sc_list);
478}
479
480uint32_t
481Module::ResolveSymbolContextsForFileSpec (const FileSpec &file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
482{
483    Mutex::Locker locker (m_mutex);
484    Timer scoped_timer(__PRETTY_FUNCTION__,
485                       "Module::ResolveSymbolContextForFilePath (%s%s%s:%u, check_inlines = %s, resolve_scope = 0x%8.8x)",
486                       file_spec.GetDirectory().AsCString(""),
487                       file_spec.GetDirectory() ? "/" : "",
488                       file_spec.GetFilename().AsCString(""),
489                       line,
490                       check_inlines ? "yes" : "no",
491                       resolve_scope);
492
493    const uint32_t initial_count = sc_list.GetSize();
494
495    SymbolVendor *symbols = GetSymbolVendor  ();
496    if (symbols)
497        symbols->ResolveSymbolContext (file_spec, line, check_inlines, resolve_scope, sc_list);
498
499    return sc_list.GetSize() - initial_count;
500}
501
502
503uint32_t
504Module::FindGlobalVariables(const ConstString &name, const ClangNamespaceDecl *namespace_decl, bool append, uint32_t max_matches, VariableList& variables)
505{
506    SymbolVendor *symbols = GetSymbolVendor ();
507    if (symbols)
508        return symbols->FindGlobalVariables(name, namespace_decl, append, max_matches, variables);
509    return 0;
510}
511uint32_t
512Module::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
513{
514    SymbolVendor *symbols = GetSymbolVendor ();
515    if (symbols)
516        return symbols->FindGlobalVariables(regex, append, max_matches, variables);
517    return 0;
518}
519
520uint32_t
521Module::FindCompileUnits (const FileSpec &path,
522                          bool append,
523                          SymbolContextList &sc_list)
524{
525    if (!append)
526        sc_list.Clear();
527
528    const uint32_t start_size = sc_list.GetSize();
529    const uint32_t num_compile_units = GetNumCompileUnits();
530    SymbolContext sc;
531    sc.module_sp = shared_from_this();
532    const bool compare_directory = path.GetDirectory();
533    for (uint32_t i=0; i<num_compile_units; ++i)
534    {
535        sc.comp_unit = GetCompileUnitAtIndex(i).get();
536        if (FileSpec::Equal (*sc.comp_unit, path, compare_directory))
537            sc_list.Append(sc);
538    }
539    return sc_list.GetSize() - start_size;
540}
541
542uint32_t
543Module::FindFunctions (const ConstString &name,
544                       const ClangNamespaceDecl *namespace_decl,
545                       uint32_t name_type_mask,
546                       bool include_symbols,
547                       bool include_inlines,
548                       bool append,
549                       SymbolContextList& sc_list)
550{
551    if (!append)
552        sc_list.Clear();
553
554    const uint32_t start_size = sc_list.GetSize();
555
556    // Find all the functions (not symbols, but debug information functions...
557    SymbolVendor *symbols = GetSymbolVendor ();
558    if (symbols)
559        symbols->FindFunctions(name, namespace_decl, name_type_mask, include_inlines, append, sc_list);
560
561    // Now check our symbol table for symbols that are code symbols if requested
562    if (include_symbols)
563    {
564        ObjectFile *objfile = GetObjectFile();
565        if (objfile)
566        {
567            Symtab *symtab = objfile->GetSymtab();
568            if (symtab)
569            {
570                std::vector<uint32_t> symbol_indexes;
571                symtab->FindAllSymbolsWithNameAndType (name, eSymbolTypeCode, Symtab::eDebugAny, Symtab::eVisibilityAny, symbol_indexes);
572                const uint32_t num_matches = symbol_indexes.size();
573                if (num_matches)
574                {
575                    const bool merge_symbol_into_function = true;
576                    SymbolContext sc(this);
577                    for (uint32_t i=0; i<num_matches; i++)
578                    {
579                        sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]);
580                        sc_list.AppendIfUnique (sc, merge_symbol_into_function);
581                    }
582                }
583            }
584        }
585    }
586    return sc_list.GetSize() - start_size;
587}
588
589uint32_t
590Module::FindFunctions (const RegularExpression& regex,
591                       bool include_symbols,
592                       bool include_inlines,
593                       bool append,
594                       SymbolContextList& sc_list)
595{
596    if (!append)
597        sc_list.Clear();
598
599    const uint32_t start_size = sc_list.GetSize();
600
601    SymbolVendor *symbols = GetSymbolVendor ();
602    if (symbols)
603        symbols->FindFunctions(regex, include_inlines, append, sc_list);
604    // Now check our symbol table for symbols that are code symbols if requested
605    if (include_symbols)
606    {
607        ObjectFile *objfile = GetObjectFile();
608        if (objfile)
609        {
610            Symtab *symtab = objfile->GetSymtab();
611            if (symtab)
612            {
613                std::vector<uint32_t> symbol_indexes;
614                symtab->AppendSymbolIndexesMatchingRegExAndType (regex, eSymbolTypeCode, Symtab::eDebugAny, Symtab::eVisibilityAny, symbol_indexes);
615                const uint32_t num_matches = symbol_indexes.size();
616                if (num_matches)
617                {
618                    const bool merge_symbol_into_function = true;
619                    SymbolContext sc(this);
620                    for (uint32_t i=0; i<num_matches; i++)
621                    {
622                        sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]);
623                        sc_list.AppendIfUnique (sc, merge_symbol_into_function);
624                    }
625                }
626            }
627        }
628    }
629    return sc_list.GetSize() - start_size;
630}
631
632uint32_t
633Module::FindTypes_Impl (const SymbolContext& sc, const ConstString &name, const ClangNamespaceDecl *namespace_decl, bool append, uint32_t max_matches, TypeList& types)
634{
635    Timer scoped_timer(__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
636    if (sc.module_sp.get() == NULL || sc.module_sp.get() == this)
637    {
638        SymbolVendor *symbols = GetSymbolVendor ();
639        if (symbols)
640            return symbols->FindTypes(sc, name, namespace_decl, append, max_matches, types);
641    }
642    return 0;
643}
644
645// depending on implementation details, type lookup might fail because of
646// embedded spurious namespace:: prefixes. this call strips them, paying
647// attention to the fact that a type might have namespace'd type names as
648// arguments to templates, and those must not be stripped off
649static const char*
650StripTypeName(const char* name_cstr)
651{
652    // Protect against null c string.
653    if (!name_cstr)
654        return name_cstr;
655    const char* skip_namespace = strstr(name_cstr, "::");
656    const char* template_arg_char = strchr(name_cstr, '<');
657    while (skip_namespace != NULL)
658    {
659        if (template_arg_char != NULL &&
660            skip_namespace > template_arg_char) // but namespace'd template arguments are still good to go
661            break;
662        name_cstr = skip_namespace+2;
663        skip_namespace = strstr(name_cstr, "::");
664    }
665    return name_cstr;
666}
667
668uint32_t
669Module::FindTypes (const SymbolContext& sc,  const ConstString &name, const ClangNamespaceDecl *namespace_decl, bool append, uint32_t max_matches, TypeList& types)
670{
671    uint32_t retval = FindTypes_Impl(sc, name, namespace_decl, append, max_matches, types);
672
673    if (retval == 0)
674    {
675        const char *orig_name = name.GetCString();
676        const char *stripped = StripTypeName(orig_name);
677        // Only do this lookup if StripTypeName has stripped the name:
678        if (stripped != orig_name)
679           return FindTypes_Impl(sc, ConstString(stripped), namespace_decl, append, max_matches, types);
680        else
681            return 0;
682    }
683    else
684        return retval;
685
686}
687
688//uint32_t
689//Module::FindTypes(const SymbolContext& sc, const RegularExpression& regex, bool append, uint32_t max_matches, Type::Encoding encoding, const char *udt_name, TypeList& types)
690//{
691//  Timer scoped_timer(__PRETTY_FUNCTION__);
692//  SymbolVendor *symbols = GetSymbolVendor ();
693//  if (symbols)
694//      return symbols->FindTypes(sc, regex, append, max_matches, encoding, udt_name, types);
695//  return 0;
696//
697//}
698
699SymbolVendor*
700Module::GetSymbolVendor (bool can_create)
701{
702    Mutex::Locker locker (m_mutex);
703    if (m_did_load_symbol_vendor == false && can_create)
704    {
705        ObjectFile *obj_file = GetObjectFile ();
706        if (obj_file != NULL)
707        {
708            Timer scoped_timer(__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
709            m_symfile_ap.reset(SymbolVendor::FindPlugin(shared_from_this()));
710            m_did_load_symbol_vendor = true;
711        }
712    }
713    return m_symfile_ap.get();
714}
715
716void
717Module::SetFileSpecAndObjectName (const FileSpec &file, const ConstString &object_name)
718{
719    // Container objects whose paths do not specify a file directly can call
720    // this function to correct the file and object names.
721    m_file = file;
722    m_mod_time = file.GetModificationTime();
723    m_object_name = object_name;
724}
725
726const ArchSpec&
727Module::GetArchitecture () const
728{
729    return m_arch;
730}
731
732void
733Module::GetDescription (Stream *s, lldb::DescriptionLevel level)
734{
735    Mutex::Locker locker (m_mutex);
736
737    if (level >= eDescriptionLevelFull)
738    {
739        if (m_arch.IsValid())
740            s->Printf("(%s) ", m_arch.GetArchitectureName());
741    }
742
743    if (level == eDescriptionLevelBrief)
744    {
745        const char *filename = m_file.GetFilename().GetCString();
746        if (filename)
747            s->PutCString (filename);
748    }
749    else
750    {
751        char path[PATH_MAX];
752        if (m_file.GetPath(path, sizeof(path)))
753            s->PutCString(path);
754    }
755
756    const char *object_name = m_object_name.GetCString();
757    if (object_name)
758        s->Printf("(%s)", object_name);
759}
760
761void
762Module::ReportError (const char *format, ...)
763{
764    if (format && format[0])
765    {
766        StreamString strm;
767        strm.PutCString("error: ");
768        GetDescription(&strm, lldb::eDescriptionLevelBrief);
769        strm.PutChar (' ');
770        va_list args;
771        va_start (args, format);
772        strm.PrintfVarArg(format, args);
773        va_end (args);
774
775        const int format_len = strlen(format);
776        if (format_len > 0)
777        {
778            const char last_char = format[format_len-1];
779            if (last_char != '\n' || last_char != '\r')
780                strm.EOL();
781        }
782        Host::SystemLog (Host::eSystemLogError, "%s", strm.GetString().c_str());
783
784    }
785}
786
787void
788Module::ReportErrorIfModifyDetected (const char *format, ...)
789{
790    if (!GetModified(true) && GetModified(false))
791    {
792        if (format)
793        {
794            StreamString strm;
795            strm.PutCString("error: the object file ");
796            GetDescription(&strm, lldb::eDescriptionLevelFull);
797            strm.PutCString (" has been modified\n");
798
799            va_list args;
800            va_start (args, format);
801            strm.PrintfVarArg(format, args);
802            va_end (args);
803
804            const int format_len = strlen(format);
805            if (format_len > 0)
806            {
807                const char last_char = format[format_len-1];
808                if (last_char != '\n' || last_char != '\r')
809                    strm.EOL();
810            }
811            strm.PutCString("The debug session should be aborted as the original debug information has been overwritten.\n");
812            Host::SystemLog (Host::eSystemLogError, "%s", strm.GetString().c_str());
813        }
814    }
815}
816
817void
818Module::ReportWarning (const char *format, ...)
819{
820    if (format && format[0])
821    {
822        StreamString strm;
823        strm.PutCString("warning: ");
824        GetDescription(&strm, lldb::eDescriptionLevelFull);
825        strm.PutChar (' ');
826
827        va_list args;
828        va_start (args, format);
829        strm.PrintfVarArg(format, args);
830        va_end (args);
831
832        const int format_len = strlen(format);
833        if (format_len > 0)
834        {
835            const char last_char = format[format_len-1];
836            if (last_char != '\n' || last_char != '\r')
837                strm.EOL();
838        }
839        Host::SystemLog (Host::eSystemLogWarning, "%s", strm.GetString().c_str());
840    }
841}
842
843void
844Module::LogMessage (Log *log, const char *format, ...)
845{
846    if (log)
847    {
848        StreamString log_message;
849        GetDescription(&log_message, lldb::eDescriptionLevelFull);
850        log_message.PutCString (": ");
851        va_list args;
852        va_start (args, format);
853        log_message.PrintfVarArg (format, args);
854        va_end (args);
855        log->PutCString(log_message.GetString().c_str());
856    }
857}
858
859bool
860Module::GetModified (bool use_cached_only)
861{
862    if (m_was_modified == false && use_cached_only == false)
863    {
864        TimeValue curr_mod_time (m_file.GetModificationTime());
865        m_was_modified = curr_mod_time != m_mod_time;
866    }
867    return m_was_modified;
868}
869
870bool
871Module::SetModified (bool b)
872{
873    const bool prev_value = m_was_modified;
874    m_was_modified = b;
875    return prev_value;
876}
877
878
879void
880Module::Dump(Stream *s)
881{
882    Mutex::Locker locker (m_mutex);
883    //s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
884    s->Indent();
885    s->Printf("Module %s/%s%s%s%s\n",
886              m_file.GetDirectory().AsCString(),
887              m_file.GetFilename().AsCString(),
888              m_object_name ? "(" : "",
889              m_object_name ? m_object_name.GetCString() : "",
890              m_object_name ? ")" : "");
891
892    s->IndentMore();
893    ObjectFile *objfile = GetObjectFile ();
894
895    if (objfile)
896        objfile->Dump(s);
897
898    SymbolVendor *symbols = GetSymbolVendor ();
899
900    if (symbols)
901        symbols->Dump(s);
902
903    s->IndentLess();
904}
905
906
907TypeList*
908Module::GetTypeList ()
909{
910    SymbolVendor *symbols = GetSymbolVendor ();
911    if (symbols)
912        return &symbols->GetTypeList();
913    return NULL;
914}
915
916const ConstString &
917Module::GetObjectName() const
918{
919    return m_object_name;
920}
921
922ObjectFile *
923Module::GetObjectFile()
924{
925    Mutex::Locker locker (m_mutex);
926    if (m_did_load_objfile == false)
927    {
928        m_did_load_objfile = true;
929        Timer scoped_timer(__PRETTY_FUNCTION__,
930                           "Module::GetObjectFile () module = %s", GetFileSpec().GetFilename().AsCString(""));
931        DataBufferSP file_data_sp;
932        m_objfile_sp = ObjectFile::FindPlugin (shared_from_this(),
933                                               &m_file,
934                                               m_object_offset,
935                                               m_file.GetByteSize(),
936                                               file_data_sp);
937        if (m_objfile_sp)
938        {
939			// Once we get the object file, update our module with the object file's
940			// architecture since it might differ in vendor/os if some parts were
941			// unknown.
942            m_objfile_sp->GetArchitecture (m_arch);
943        }
944    }
945    return m_objfile_sp.get();
946}
947
948
949const Symbol *
950Module::FindFirstSymbolWithNameAndType (const ConstString &name, SymbolType symbol_type)
951{
952    Timer scoped_timer(__PRETTY_FUNCTION__,
953                       "Module::FindFirstSymbolWithNameAndType (name = %s, type = %i)",
954                       name.AsCString(),
955                       symbol_type);
956    ObjectFile *objfile = GetObjectFile();
957    if (objfile)
958    {
959        Symtab *symtab = objfile->GetSymtab();
960        if (symtab)
961            return symtab->FindFirstSymbolWithNameAndType (name, symbol_type, Symtab::eDebugAny, Symtab::eVisibilityAny);
962    }
963    return NULL;
964}
965void
966Module::SymbolIndicesToSymbolContextList (Symtab *symtab, std::vector<uint32_t> &symbol_indexes, SymbolContextList &sc_list)
967{
968    // No need to protect this call using m_mutex all other method calls are
969    // already thread safe.
970
971    size_t num_indices = symbol_indexes.size();
972    if (num_indices > 0)
973    {
974        SymbolContext sc;
975        CalculateSymbolContext (&sc);
976        for (size_t i = 0; i < num_indices; i++)
977        {
978            sc.symbol = symtab->SymbolAtIndex (symbol_indexes[i]);
979            if (sc.symbol)
980                sc_list.Append (sc);
981        }
982    }
983}
984
985size_t
986Module::FindSymbolsWithNameAndType (const ConstString &name, SymbolType symbol_type, SymbolContextList &sc_list)
987{
988    // No need to protect this call using m_mutex all other method calls are
989    // already thread safe.
990
991
992    Timer scoped_timer(__PRETTY_FUNCTION__,
993                       "Module::FindSymbolsWithNameAndType (name = %s, type = %i)",
994                       name.AsCString(),
995                       symbol_type);
996    const size_t initial_size = sc_list.GetSize();
997    ObjectFile *objfile = GetObjectFile ();
998    if (objfile)
999    {
1000        Symtab *symtab = objfile->GetSymtab();
1001        if (symtab)
1002        {
1003            std::vector<uint32_t> symbol_indexes;
1004            symtab->FindAllSymbolsWithNameAndType (name, symbol_type, symbol_indexes);
1005            SymbolIndicesToSymbolContextList (symtab, symbol_indexes, sc_list);
1006        }
1007    }
1008    return sc_list.GetSize() - initial_size;
1009}
1010
1011size_t
1012Module::FindSymbolsMatchingRegExAndType (const RegularExpression &regex, SymbolType symbol_type, SymbolContextList &sc_list)
1013{
1014    // No need to protect this call using m_mutex all other method calls are
1015    // already thread safe.
1016
1017    Timer scoped_timer(__PRETTY_FUNCTION__,
1018                       "Module::FindSymbolsMatchingRegExAndType (regex = %s, type = %i)",
1019                       regex.GetText(),
1020                       symbol_type);
1021    const size_t initial_size = sc_list.GetSize();
1022    ObjectFile *objfile = GetObjectFile ();
1023    if (objfile)
1024    {
1025        Symtab *symtab = objfile->GetSymtab();
1026        if (symtab)
1027        {
1028            std::vector<uint32_t> symbol_indexes;
1029            symtab->FindAllSymbolsMatchingRexExAndType (regex, symbol_type, Symtab::eDebugAny, Symtab::eVisibilityAny, symbol_indexes);
1030            SymbolIndicesToSymbolContextList (symtab, symbol_indexes, sc_list);
1031        }
1032    }
1033    return sc_list.GetSize() - initial_size;
1034}
1035
1036const TimeValue &
1037Module::GetModificationTime () const
1038{
1039    return m_mod_time;
1040}
1041
1042bool
1043Module::IsExecutable ()
1044{
1045    if (GetObjectFile() == NULL)
1046        return false;
1047    else
1048        return GetObjectFile()->IsExecutable();
1049}
1050
1051bool
1052Module::IsLoadedInTarget (Target *target)
1053{
1054    ObjectFile *obj_file = GetObjectFile();
1055    if (obj_file)
1056    {
1057        SectionList *sections = obj_file->GetSectionList();
1058        if (sections != NULL)
1059        {
1060            size_t num_sections = sections->GetSize();
1061            for (size_t sect_idx = 0; sect_idx < num_sections; sect_idx++)
1062            {
1063                SectionSP section_sp = sections->GetSectionAtIndex(sect_idx);
1064                if (section_sp->GetLoadBaseAddress(target) != LLDB_INVALID_ADDRESS)
1065                {
1066                    return true;
1067                }
1068            }
1069        }
1070    }
1071    return false;
1072}
1073bool
1074Module::SetArchitecture (const ArchSpec &new_arch)
1075{
1076    if (!m_arch.IsValid())
1077    {
1078        m_arch = new_arch;
1079        return true;
1080    }
1081    return m_arch == new_arch;
1082}
1083
1084bool
1085Module::SetLoadAddress (Target &target, lldb::addr_t offset, bool &changed)
1086{
1087    changed = false;
1088    ObjectFile *image_object_file = GetObjectFile();
1089    if (image_object_file)
1090    {
1091        SectionList *section_list = image_object_file->GetSectionList ();
1092        if (section_list)
1093        {
1094            const size_t num_sections = section_list->GetSize();
1095            size_t sect_idx = 0;
1096            for (sect_idx = 0; sect_idx < num_sections; ++sect_idx)
1097            {
1098                // Iterate through the object file sections to find the
1099                // first section that starts of file offset zero and that
1100                // has bytes in the file...
1101                Section *section = section_list->GetSectionAtIndex (sect_idx).get();
1102                if (section)
1103                {
1104                    if (target.GetSectionLoadList().SetSectionLoadAddress (section, section->GetFileAddress() + offset))
1105                        changed = true;
1106                }
1107            }
1108            return sect_idx > 0;
1109        }
1110    }
1111    return false;
1112}
1113
1114
1115bool
1116Module::MatchesModuleSpec (const ModuleSpec &module_ref)
1117{
1118    const UUID &uuid = module_ref.GetUUID();
1119
1120    if (uuid.IsValid())
1121    {
1122        // If the UUID matches, then nothing more needs to match...
1123        if (uuid == GetUUID())
1124            return true;
1125        else
1126            return false;
1127    }
1128
1129    const FileSpec &file_spec = module_ref.GetFileSpec();
1130    if (file_spec)
1131    {
1132        if (!FileSpec::Equal (file_spec, m_file, file_spec.GetDirectory()))
1133            return false;
1134    }
1135
1136    const FileSpec &platform_file_spec = module_ref.GetPlatformFileSpec();
1137    if (platform_file_spec)
1138    {
1139        if (!FileSpec::Equal (platform_file_spec, m_platform_file, platform_file_spec.GetDirectory()))
1140            return false;
1141    }
1142
1143    const ArchSpec &arch = module_ref.GetArchitecture();
1144    if (arch.IsValid())
1145    {
1146        if (m_arch != arch)
1147            return false;
1148    }
1149
1150    const ConstString &object_name = module_ref.GetObjectName();
1151    if (object_name)
1152    {
1153        if (object_name != GetObjectName())
1154            return false;
1155    }
1156    return true;
1157}
1158
1159