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