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