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 
20 using namespace lldb;
21 using namespace lldb_private;
22 
23 Module::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 
53 Module::~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 
75 ModuleSP
76 Module::GetSP ()
77 {
78     return ModuleList::GetModuleSP (this);
79 }
80 
81 const UUID&
82 Module::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 
98 ClangASTContext &
99 Module::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 
115 void
116 Module::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 
155 void
156 Module::CalculateSymbolContext(SymbolContext* sc)
157 {
158     sc->module_sp = GetSP();
159 }
160 
161 void
162 Module::DumpSymbolContext(Stream *s)
163 {
164     s->Printf(", Module{0x%8.8x}", this);
165 }
166 
167 uint32_t
168 Module::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 
178 CompUnitSP
179 Module::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 
204 bool
205 Module::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 
215 uint32_t
216 Module::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 
269 uint32_t
270 Module::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 
283 uint32_t
284 Module::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 
306 uint32_t
307 Module::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 }
314 uint32_t
315 Module::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 
323 uint32_t
324 Module::FindFunctions (const ConstString &name,
325                        uint32_t name_type_mask,
326                        bool include_symbols,
327                        bool append,
328                        SymbolContextList& sc_list)
329 {
330     if (!append)
331         sc_list.Clear();
332 
333     const uint32_t start_size = sc_list.GetSize();
334 
335     // Find all the functions (not symbols, but debug information functions...
336     SymbolVendor *symbols = GetSymbolVendor ();
337     if (symbols)
338         symbols->FindFunctions(name, name_type_mask, append, sc_list);
339 
340     // Now check our symbol table for symbols that are code symbols if requested
341     if (include_symbols)
342     {
343         ObjectFile *objfile = GetObjectFile();
344         if (objfile)
345         {
346             Symtab *symtab = objfile->GetSymtab();
347             if (symtab)
348             {
349                 std::vector<uint32_t> symbol_indexes;
350                 symtab->FindAllSymbolsWithNameAndType (name, eSymbolTypeCode, Symtab::eDebugAny, Symtab::eVisibilityAny, symbol_indexes);
351                 const uint32_t num_matches = symbol_indexes.size();
352                 if (num_matches)
353                 {
354                     SymbolContext sc(this);
355                     for (uint32_t i=0; i<num_matches; i++)
356                     {
357                         sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]);
358                         sc_list.AppendIfUnique (sc);
359                     }
360                 }
361             }
362         }
363     }
364     return sc_list.GetSize() - start_size;
365 }
366 
367 uint32_t
368 Module::FindFunctions (const RegularExpression& regex,
369                        bool include_symbols,
370                        bool append,
371                        SymbolContextList& sc_list)
372 {
373     if (!append)
374         sc_list.Clear();
375 
376     const uint32_t start_size = sc_list.GetSize();
377 
378     SymbolVendor *symbols = GetSymbolVendor ();
379     if (symbols)
380         return symbols->FindFunctions(regex, append, sc_list);
381     // Now check our symbol table for symbols that are code symbols if requested
382     if (include_symbols)
383     {
384         ObjectFile *objfile = GetObjectFile();
385         if (objfile)
386         {
387             Symtab *symtab = objfile->GetSymtab();
388             if (symtab)
389             {
390                 std::vector<uint32_t> symbol_indexes;
391                 symtab->AppendSymbolIndexesMatchingRegExAndType (regex, eSymbolTypeCode, Symtab::eDebugAny, Symtab::eVisibilityAny, symbol_indexes);
392                 const uint32_t num_matches = symbol_indexes.size();
393                 if (num_matches)
394                 {
395                     SymbolContext sc(this);
396                     for (uint32_t i=0; i<num_matches; i++)
397                     {
398                         sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]);
399                         sc_list.AppendIfUnique (sc);
400                     }
401                 }
402             }
403         }
404     }
405     return sc_list.GetSize() - start_size;
406 }
407 
408 uint32_t
409 Module::FindTypes (const SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, TypeList& types)
410 {
411     Timer scoped_timer(__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
412     if (sc.module_sp.get() == NULL || sc.module_sp.get() == this)
413     {
414         SymbolVendor *symbols = GetSymbolVendor ();
415         if (symbols)
416             return symbols->FindTypes(sc, name, append, max_matches, types);
417     }
418     return 0;
419 }
420 
421 //uint32_t
422 //Module::FindTypes(const SymbolContext& sc, const RegularExpression& regex, bool append, uint32_t max_matches, Type::Encoding encoding, const char *udt_name, TypeList& types)
423 //{
424 //  Timer scoped_timer(__PRETTY_FUNCTION__);
425 //  SymbolVendor *symbols = GetSymbolVendor ();
426 //  if (symbols)
427 //      return symbols->FindTypes(sc, regex, append, max_matches, encoding, udt_name, types);
428 //  return 0;
429 //
430 //}
431 
432 SymbolVendor*
433 Module::GetSymbolVendor (bool can_create)
434 {
435     Mutex::Locker locker (m_mutex);
436     if (m_did_load_symbol_vendor == false && can_create)
437     {
438         ObjectFile *obj_file = GetObjectFile ();
439         if (obj_file != NULL)
440         {
441             Timer scoped_timer(__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
442             m_symfile_ap.reset(SymbolVendor::FindPlugin(this));
443             m_did_load_symbol_vendor = true;
444         }
445     }
446     return m_symfile_ap.get();
447 }
448 
449 const FileSpec &
450 Module::GetFileSpec () const
451 {
452     return m_file;
453 }
454 
455 void
456 Module::SetFileSpecAndObjectName (const FileSpec &file, const ConstString &object_name)
457 {
458     // Container objects whose paths do not specify a file directly can call
459     // this function to correct the file and object names.
460     m_file = file;
461     m_mod_time = file.GetModificationTime();
462     m_object_name = object_name;
463 }
464 
465 const ArchSpec&
466 Module::GetArchitecture () const
467 {
468     return m_arch;
469 }
470 
471 void
472 Module::GetDescription (Stream *s)
473 {
474     Mutex::Locker locker (m_mutex);
475 
476     if (m_arch.IsValid())
477         s->Printf("(%s) ", m_arch.AsCString());
478 
479     char path[PATH_MAX];
480     if (m_file.GetPath(path, sizeof(path)))
481         s->PutCString(path);
482 
483     const char *object_name = m_object_name.GetCString();
484     if (object_name)
485         s->Printf("(%s)", object_name);
486 }
487 
488 void
489 Module::Dump(Stream *s)
490 {
491     Mutex::Locker locker (m_mutex);
492     //s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
493     s->Indent();
494     s->Printf("Module %s/%s%s%s%s\n",
495               m_file.GetDirectory().AsCString(),
496               m_file.GetFilename().AsCString(),
497               m_object_name ? "(" : "",
498               m_object_name ? m_object_name.GetCString() : "",
499               m_object_name ? ")" : "");
500 
501     s->IndentMore();
502     ObjectFile *objfile = GetObjectFile ();
503 
504     if (objfile)
505         objfile->Dump(s);
506 
507     SymbolVendor *symbols = GetSymbolVendor ();
508 
509     if (symbols)
510         symbols->Dump(s);
511 
512     s->IndentLess();
513 }
514 
515 
516 TypeList*
517 Module::GetTypeList ()
518 {
519     SymbolVendor *symbols = GetSymbolVendor ();
520     if (symbols)
521         return &symbols->GetTypeList();
522     return NULL;
523 }
524 
525 const ConstString &
526 Module::GetObjectName() const
527 {
528     return m_object_name;
529 }
530 
531 ObjectFile *
532 Module::GetObjectFile()
533 {
534     Mutex::Locker locker (m_mutex);
535     if (m_did_load_objfile == false)
536     {
537         m_did_load_objfile = true;
538         Timer scoped_timer(__PRETTY_FUNCTION__,
539                            "Module::GetObjectFile () module = %s", GetFileSpec().GetFilename().AsCString(""));
540         m_objfile_ap.reset(ObjectFile::FindPlugin(this, &m_file, 0, m_file.GetByteSize()));
541     }
542     return m_objfile_ap.get();
543 }
544 
545 
546 const Symbol *
547 Module::FindFirstSymbolWithNameAndType (const ConstString &name, SymbolType symbol_type)
548 {
549     Timer scoped_timer(__PRETTY_FUNCTION__,
550                        "Module::FindFirstSymbolWithNameAndType (name = %s, type = %i)",
551                        name.AsCString(),
552                        symbol_type);
553     ObjectFile *objfile = GetObjectFile();
554     if (objfile)
555     {
556         Symtab *symtab = objfile->GetSymtab();
557         if (symtab)
558             return symtab->FindFirstSymbolWithNameAndType (name, symbol_type, Symtab::eDebugAny, Symtab::eVisibilityAny);
559     }
560     return NULL;
561 }
562 void
563 Module::SymbolIndicesToSymbolContextList (Symtab *symtab, std::vector<uint32_t> &symbol_indexes, SymbolContextList &sc_list)
564 {
565     // No need to protect this call using m_mutex all other method calls are
566     // already thread safe.
567 
568     size_t num_indices = symbol_indexes.size();
569     if (num_indices > 0)
570     {
571         SymbolContext sc;
572         CalculateSymbolContext (&sc);
573         for (size_t i = 0; i < num_indices; i++)
574         {
575             sc.symbol = symtab->SymbolAtIndex (symbol_indexes[i]);
576             if (sc.symbol)
577                 sc_list.Append (sc);
578         }
579     }
580 }
581 
582 size_t
583 Module::FindSymbolsWithNameAndType (const ConstString &name, SymbolType symbol_type, SymbolContextList &sc_list)
584 {
585     // No need to protect this call using m_mutex all other method calls are
586     // already thread safe.
587 
588 
589     Timer scoped_timer(__PRETTY_FUNCTION__,
590                        "Module::FindSymbolsWithNameAndType (name = %s, type = %i)",
591                        name.AsCString(),
592                        symbol_type);
593     const size_t initial_size = sc_list.GetSize();
594     ObjectFile *objfile = GetObjectFile ();
595     if (objfile)
596     {
597         Symtab *symtab = objfile->GetSymtab();
598         if (symtab)
599         {
600             std::vector<uint32_t> symbol_indexes;
601             symtab->FindAllSymbolsWithNameAndType (name, symbol_type, symbol_indexes);
602             SymbolIndicesToSymbolContextList (symtab, symbol_indexes, sc_list);
603         }
604     }
605     return sc_list.GetSize() - initial_size;
606 }
607 
608 size_t
609 Module::FindSymbolsMatchingRegExAndType (const RegularExpression &regex, SymbolType symbol_type, SymbolContextList &sc_list)
610 {
611     // No need to protect this call using m_mutex all other method calls are
612     // already thread safe.
613 
614     Timer scoped_timer(__PRETTY_FUNCTION__,
615                        "Module::FindSymbolsMatchingRegExAndType (regex = %s, type = %i)",
616                        regex.GetText(),
617                        symbol_type);
618     const size_t initial_size = sc_list.GetSize();
619     ObjectFile *objfile = GetObjectFile ();
620     if (objfile)
621     {
622         Symtab *symtab = objfile->GetSymtab();
623         if (symtab)
624         {
625             std::vector<uint32_t> symbol_indexes;
626             symtab->FindAllSymbolsMatchingRexExAndType (regex, symbol_type, Symtab::eDebugAny, Symtab::eVisibilityAny, symbol_indexes);
627             SymbolIndicesToSymbolContextList (symtab, symbol_indexes, sc_list);
628         }
629     }
630     return sc_list.GetSize() - initial_size;
631 }
632 
633 const TimeValue &
634 Module::GetModificationTime () const
635 {
636     return m_mod_time;
637 }
638 
639 bool
640 Module::IsExecutable ()
641 {
642     if (GetObjectFile() == NULL)
643         return false;
644     else
645         return GetObjectFile()->IsExecutable();
646 }
647 
648 bool
649 Module::SetArchitecture (const ArchSpec &new_arch)
650 {
651     if (m_arch == new_arch)
652         return true;
653     else if (!m_arch.IsValid())
654     {
655         m_arch = new_arch;
656         return true;
657     }
658     else
659     {
660         return false;
661     }
662 
663 }
664 
665