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