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