blob: 2786600b38032137d7334e8232366f95c81686af [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- 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
Greg Clayton65a03992011-08-09 00:01:09 +000023// Shared pointers to modules track module lifetimes in
24// targets and in the global module, but this collection
25// will track all module objects that are still alive
26typedef std::vector<Module *> ModuleCollection;
27
28static ModuleCollection &
29GetModuleCollection()
30{
31 static ModuleCollection g_module_collection;
32 return g_module_collection;
33}
34
35Mutex &
36Module::GetAllocationModuleCollectionMutex()
37{
38 static Mutex g_module_collection_mutex(Mutex::eMutexTypeRecursive);
39 return g_module_collection_mutex;
40}
41
42size_t
43Module::GetNumberAllocatedModules ()
44{
45 Mutex::Locker locker (GetAllocationModuleCollectionMutex());
46 return GetModuleCollection().size();
47}
48
49Module *
50Module::GetAllocatedModuleAtIndex (size_t idx)
51{
52 Mutex::Locker locker (GetAllocationModuleCollectionMutex());
53 ModuleCollection &modules = GetModuleCollection();
54 if (idx < modules.size())
55 return modules[idx];
56 return NULL;
57}
58
59
60
61
Chris Lattner30fdc8d2010-06-08 16:52:24 +000062Module::Module(const FileSpec& file_spec, const ArchSpec& arch, const ConstString *object_name, off_t object_offset) :
63 m_mutex (Mutex::eMutexTypeRecursive),
64 m_mod_time (file_spec.GetModificationTime()),
65 m_arch (arch),
66 m_uuid (),
67 m_file (file_spec),
Greg Clayton32e0a752011-03-30 18:16:51 +000068 m_platform_file(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000069 m_object_name (),
Greg Clayton8b82f082011-04-12 05:54:46 +000070 m_object_offset (object_offset),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000071 m_objfile_ap (),
Greg Claytone83e7312010-09-07 23:40:05 +000072 m_symfile_ap (),
Greg Clayton6beaaa62011-01-17 03:46:26 +000073 m_ast (),
Greg Claytone83e7312010-09-07 23:40:05 +000074 m_did_load_objfile (false),
75 m_did_load_symbol_vendor (false),
76 m_did_parse_uuid (false),
Greg Clayton6beaaa62011-01-17 03:46:26 +000077 m_did_init_ast (false),
Greg Claytone83e7312010-09-07 23:40:05 +000078 m_is_dynamic_loader_module (false)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000079{
Greg Clayton65a03992011-08-09 00:01:09 +000080 // Scope for locker below...
81 {
82 Mutex::Locker locker (GetAllocationModuleCollectionMutex());
83 GetModuleCollection().push_back(this);
84 }
85
Chris Lattner30fdc8d2010-06-08 16:52:24 +000086 if (object_name)
87 m_object_name = *object_name;
Greg Clayton2d4edfb2010-11-06 01:53:30 +000088 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
Chris Lattner30fdc8d2010-06-08 16:52:24 +000089 if (log)
90 log->Printf ("%p Module::Module((%s) '%s/%s%s%s%s')",
91 this,
Greg Clayton64195a22011-02-23 00:35:02 +000092 m_arch.GetArchitectureName(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000093 m_file.GetDirectory().AsCString(""),
94 m_file.GetFilename().AsCString(""),
95 m_object_name.IsEmpty() ? "" : "(",
96 m_object_name.IsEmpty() ? "" : m_object_name.AsCString(""),
97 m_object_name.IsEmpty() ? "" : ")");
Chris Lattner30fdc8d2010-06-08 16:52:24 +000098}
99
100Module::~Module()
101{
Greg Clayton65a03992011-08-09 00:01:09 +0000102 // Scope for locker below...
103 {
104 Mutex::Locker locker (GetAllocationModuleCollectionMutex());
105 ModuleCollection &modules = GetModuleCollection();
106 ModuleCollection::iterator end = modules.end();
107 ModuleCollection::iterator pos = std::find(modules.begin(), end, this);
108 if (pos != end)
109 modules.erase(pos);
110 }
Greg Clayton2d4edfb2010-11-06 01:53:30 +0000111 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000112 if (log)
113 log->Printf ("%p Module::~Module((%s) '%s/%s%s%s%s')",
114 this,
Greg Clayton64195a22011-02-23 00:35:02 +0000115 m_arch.GetArchitectureName(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000116 m_file.GetDirectory().AsCString(""),
117 m_file.GetFilename().AsCString(""),
118 m_object_name.IsEmpty() ? "" : "(",
119 m_object_name.IsEmpty() ? "" : m_object_name.AsCString(""),
120 m_object_name.IsEmpty() ? "" : ")");
Greg Clayton6beaaa62011-01-17 03:46:26 +0000121 // Release any auto pointers before we start tearing down our member
122 // variables since the object file and symbol files might need to make
123 // function calls back into this module object. The ordering is important
124 // here because symbol files can require the module object file. So we tear
125 // down the symbol file first, then the object file.
126 m_symfile_ap.reset();
127 m_objfile_ap.reset();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000128}
129
130
131ModuleSP
Greg Clayton05d2b7f2011-03-31 01:08:07 +0000132Module::GetSP () const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000133{
Greg Clayton747bcb02011-09-17 06:21:20 +0000134 ModuleSP module_sp(const_cast<Module*>(this));
135 return module_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000136}
137
Greg Clayton60830262011-02-04 18:53:10 +0000138const lldb_private::UUID&
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000139Module::GetUUID()
140{
141 Mutex::Locker locker (m_mutex);
Greg Claytone83e7312010-09-07 23:40:05 +0000142 if (m_did_parse_uuid == false)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000143 {
144 ObjectFile * obj_file = GetObjectFile ();
145
146 if (obj_file != NULL)
147 {
148 obj_file->GetUUID(&m_uuid);
Greg Claytone83e7312010-09-07 23:40:05 +0000149 m_did_parse_uuid = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000150 }
151 }
152 return m_uuid;
153}
154
Greg Clayton6beaaa62011-01-17 03:46:26 +0000155ClangASTContext &
156Module::GetClangASTContext ()
157{
158 Mutex::Locker locker (m_mutex);
159 if (m_did_init_ast == false)
160 {
161 ObjectFile * objfile = GetObjectFile();
Greg Clayton514487e2011-02-15 21:59:32 +0000162 ArchSpec object_arch;
163 if (objfile && objfile->GetArchitecture(object_arch))
Greg Clayton6beaaa62011-01-17 03:46:26 +0000164 {
165 m_did_init_ast = true;
Greg Clayton514487e2011-02-15 21:59:32 +0000166 m_ast.SetArchitecture (object_arch);
Greg Clayton6beaaa62011-01-17 03:46:26 +0000167 }
168 }
169 return m_ast;
170}
171
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000172void
173Module::ParseAllDebugSymbols()
174{
175 Mutex::Locker locker (m_mutex);
176 uint32_t num_comp_units = GetNumCompileUnits();
177 if (num_comp_units == 0)
178 return;
179
180 TargetSP null_target;
181 SymbolContext sc(null_target, GetSP());
182 uint32_t cu_idx;
183 SymbolVendor *symbols = GetSymbolVendor ();
184
185 for (cu_idx = 0; cu_idx < num_comp_units; cu_idx++)
186 {
187 sc.comp_unit = symbols->GetCompileUnitAtIndex(cu_idx).get();
188 if (sc.comp_unit)
189 {
190 sc.function = NULL;
191 symbols->ParseVariablesForContext(sc);
192
193 symbols->ParseCompileUnitFunctions(sc);
194
195 uint32_t func_idx;
196 for (func_idx = 0; (sc.function = sc.comp_unit->GetFunctionAtIndex(func_idx).get()) != NULL; ++func_idx)
197 {
198 symbols->ParseFunctionBlocks(sc);
199
200 // Parse the variables for this function and all its blocks
201 symbols->ParseVariablesForContext(sc);
202 }
203
204
205 // Parse all types for this compile unit
206 sc.function = NULL;
207 symbols->ParseTypes(sc);
208 }
209 }
210}
211
212void
213Module::CalculateSymbolContext(SymbolContext* sc)
214{
215 sc->module_sp = GetSP();
216}
217
Greg Clayton7e9b1fd2011-08-12 21:40:01 +0000218Module *
219Module::CalculateSymbolContextModule ()
220{
221 return this;
222}
223
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000224void
225Module::DumpSymbolContext(Stream *s)
226{
227 s->Printf(", Module{0x%8.8x}", this);
228}
229
230uint32_t
231Module::GetNumCompileUnits()
232{
233 Mutex::Locker locker (m_mutex);
234 Timer scoped_timer(__PRETTY_FUNCTION__, "Module::GetNumCompileUnits (module = %p)", this);
235 SymbolVendor *symbols = GetSymbolVendor ();
236 if (symbols)
237 return symbols->GetNumCompileUnits();
238 return 0;
239}
240
241CompUnitSP
242Module::GetCompileUnitAtIndex (uint32_t index)
243{
244 Mutex::Locker locker (m_mutex);
245 uint32_t num_comp_units = GetNumCompileUnits ();
246 CompUnitSP cu_sp;
247
248 if (index < num_comp_units)
249 {
250 SymbolVendor *symbols = GetSymbolVendor ();
251 if (symbols)
252 cu_sp = symbols->GetCompileUnitAtIndex(index);
253 }
254 return cu_sp;
255}
256
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000257bool
258Module::ResolveFileAddress (lldb::addr_t vm_addr, Address& so_addr)
259{
260 Mutex::Locker locker (m_mutex);
261 Timer scoped_timer(__PRETTY_FUNCTION__, "Module::ResolveFileAddress (vm_addr = 0x%llx)", vm_addr);
262 ObjectFile* ofile = GetObjectFile();
263 if (ofile)
264 return so_addr.ResolveAddressUsingFileSections(vm_addr, ofile->GetSectionList());
265 return false;
266}
267
268uint32_t
269Module::ResolveSymbolContextForAddress (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
270{
271 Mutex::Locker locker (m_mutex);
272 uint32_t resolved_flags = 0;
273
274 // Clear the result symbol context in case we don't find anything
275 sc.Clear();
276
277 // Get the section from the section/offset address.
278 const Section *section = so_addr.GetSection();
279
280 // Make sure the section matches this module before we try and match anything
281 if (section && section->GetModule() == this)
282 {
283 // If the section offset based address resolved itself, then this
284 // is the right module.
285 sc.module_sp = GetSP();
286 resolved_flags |= eSymbolContextModule;
287
288 // Resolve the compile unit, function, block, line table or line
289 // entry if requested.
290 if (resolve_scope & eSymbolContextCompUnit ||
291 resolve_scope & eSymbolContextFunction ||
292 resolve_scope & eSymbolContextBlock ||
293 resolve_scope & eSymbolContextLineEntry )
294 {
295 SymbolVendor *symbols = GetSymbolVendor ();
296 if (symbols)
297 resolved_flags |= symbols->ResolveSymbolContext (so_addr, resolve_scope, sc);
298 }
299
Jim Ingham680e1772010-08-31 23:51:36 +0000300 // Resolve the symbol if requested, but don't re-look it up if we've already found it.
301 if (resolve_scope & eSymbolContextSymbol && !(resolved_flags & eSymbolContextSymbol))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000302 {
303 ObjectFile* ofile = GetObjectFile();
304 if (ofile)
305 {
306 Symtab *symtab = ofile->GetSymtab();
307 if (symtab)
308 {
309 if (so_addr.IsSectionOffset())
310 {
311 sc.symbol = symtab->FindSymbolContainingFileAddress(so_addr.GetFileAddress());
312 if (sc.symbol)
313 resolved_flags |= eSymbolContextSymbol;
314 }
315 }
316 }
317 }
318 }
319 return resolved_flags;
320}
321
322uint32_t
Greg Clayton274060b2010-10-20 20:54:39 +0000323Module::ResolveSymbolContextForFilePath
324(
325 const char *file_path,
326 uint32_t line,
327 bool check_inlines,
328 uint32_t resolve_scope,
329 SymbolContextList& sc_list
330)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000331{
Greg Clayton274060b2010-10-20 20:54:39 +0000332 FileSpec file_spec(file_path, false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000333 return ResolveSymbolContextsForFileSpec (file_spec, line, check_inlines, resolve_scope, sc_list);
334}
335
336uint32_t
337Module::ResolveSymbolContextsForFileSpec (const FileSpec &file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
338{
339 Mutex::Locker locker (m_mutex);
340 Timer scoped_timer(__PRETTY_FUNCTION__,
341 "Module::ResolveSymbolContextForFilePath (%s%s%s:%u, check_inlines = %s, resolve_scope = 0x%8.8x)",
342 file_spec.GetDirectory().AsCString(""),
343 file_spec.GetDirectory() ? "/" : "",
344 file_spec.GetFilename().AsCString(""),
345 line,
346 check_inlines ? "yes" : "no",
347 resolve_scope);
348
349 const uint32_t initial_count = sc_list.GetSize();
350
351 SymbolVendor *symbols = GetSymbolVendor ();
352 if (symbols)
353 symbols->ResolveSymbolContext (file_spec, line, check_inlines, resolve_scope, sc_list);
354
355 return sc_list.GetSize() - initial_count;
356}
357
358
359uint32_t
360Module::FindGlobalVariables(const ConstString &name, bool append, uint32_t max_matches, VariableList& variables)
361{
362 SymbolVendor *symbols = GetSymbolVendor ();
363 if (symbols)
364 return symbols->FindGlobalVariables(name, append, max_matches, variables);
365 return 0;
366}
367uint32_t
368Module::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
369{
370 SymbolVendor *symbols = GetSymbolVendor ();
371 if (symbols)
372 return symbols->FindGlobalVariables(regex, append, max_matches, variables);
373 return 0;
374}
375
376uint32_t
Greg Clayton644247c2011-07-07 01:59:51 +0000377Module::FindCompileUnits (const FileSpec &path,
378 bool append,
379 SymbolContextList &sc_list)
380{
381 if (!append)
382 sc_list.Clear();
383
384 const uint32_t start_size = sc_list.GetSize();
385 const uint32_t num_compile_units = GetNumCompileUnits();
386 SymbolContext sc;
387 sc.module_sp = GetSP();
388 const bool compare_directory = path.GetDirectory();
389 for (uint32_t i=0; i<num_compile_units; ++i)
390 {
391 sc.comp_unit = GetCompileUnitAtIndex(i).get();
392 if (FileSpec::Equal (*sc.comp_unit, path, compare_directory))
393 sc_list.Append(sc);
394 }
395 return sc_list.GetSize() - start_size;
396}
397
398uint32_t
Greg Clayton931180e2011-01-27 06:44:37 +0000399Module::FindFunctions (const ConstString &name,
400 uint32_t name_type_mask,
401 bool include_symbols,
402 bool append,
403 SymbolContextList& sc_list)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000404{
Greg Clayton931180e2011-01-27 06:44:37 +0000405 if (!append)
406 sc_list.Clear();
407
408 const uint32_t start_size = sc_list.GetSize();
409
410 // Find all the functions (not symbols, but debug information functions...
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000411 SymbolVendor *symbols = GetSymbolVendor ();
412 if (symbols)
Greg Clayton931180e2011-01-27 06:44:37 +0000413 symbols->FindFunctions(name, name_type_mask, append, sc_list);
414
415 // Now check our symbol table for symbols that are code symbols if requested
416 if (include_symbols)
417 {
418 ObjectFile *objfile = GetObjectFile();
419 if (objfile)
420 {
421 Symtab *symtab = objfile->GetSymtab();
422 if (symtab)
423 {
424 std::vector<uint32_t> symbol_indexes;
425 symtab->FindAllSymbolsWithNameAndType (name, eSymbolTypeCode, Symtab::eDebugAny, Symtab::eVisibilityAny, symbol_indexes);
426 const uint32_t num_matches = symbol_indexes.size();
427 if (num_matches)
428 {
Greg Clayton357132e2011-03-26 19:14:58 +0000429 const bool merge_symbol_into_function = true;
Greg Clayton931180e2011-01-27 06:44:37 +0000430 SymbolContext sc(this);
431 for (uint32_t i=0; i<num_matches; i++)
432 {
433 sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]);
Greg Clayton357132e2011-03-26 19:14:58 +0000434 sc_list.AppendIfUnique (sc, merge_symbol_into_function);
Greg Clayton931180e2011-01-27 06:44:37 +0000435 }
436 }
437 }
438 }
439 }
440 return sc_list.GetSize() - start_size;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000441}
442
443uint32_t
Greg Clayton931180e2011-01-27 06:44:37 +0000444Module::FindFunctions (const RegularExpression& regex,
445 bool include_symbols,
446 bool append,
447 SymbolContextList& sc_list)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000448{
Greg Clayton931180e2011-01-27 06:44:37 +0000449 if (!append)
450 sc_list.Clear();
451
452 const uint32_t start_size = sc_list.GetSize();
453
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000454 SymbolVendor *symbols = GetSymbolVendor ();
455 if (symbols)
Jim Ingham832332d2011-05-18 05:02:10 +0000456 symbols->FindFunctions(regex, append, sc_list);
Greg Clayton931180e2011-01-27 06:44:37 +0000457 // Now check our symbol table for symbols that are code symbols if requested
458 if (include_symbols)
459 {
460 ObjectFile *objfile = GetObjectFile();
461 if (objfile)
462 {
463 Symtab *symtab = objfile->GetSymtab();
464 if (symtab)
465 {
466 std::vector<uint32_t> symbol_indexes;
467 symtab->AppendSymbolIndexesMatchingRegExAndType (regex, eSymbolTypeCode, Symtab::eDebugAny, Symtab::eVisibilityAny, symbol_indexes);
468 const uint32_t num_matches = symbol_indexes.size();
469 if (num_matches)
470 {
Greg Clayton357132e2011-03-26 19:14:58 +0000471 const bool merge_symbol_into_function = true;
Greg Clayton931180e2011-01-27 06:44:37 +0000472 SymbolContext sc(this);
473 for (uint32_t i=0; i<num_matches; i++)
474 {
475 sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]);
Greg Clayton357132e2011-03-26 19:14:58 +0000476 sc_list.AppendIfUnique (sc, merge_symbol_into_function);
Greg Clayton931180e2011-01-27 06:44:37 +0000477 }
478 }
479 }
480 }
481 }
482 return sc_list.GetSize() - start_size;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000483}
484
Greg Clayton3504eee2010-08-03 01:26:16 +0000485uint32_t
Enrico Granata6f3533f2011-07-29 19:53:35 +0000486Module::FindTypes_Impl (const SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, TypeList& types)
Greg Clayton3504eee2010-08-03 01:26:16 +0000487{
488 Timer scoped_timer(__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
489 if (sc.module_sp.get() == NULL || sc.module_sp.get() == this)
490 {
491 SymbolVendor *symbols = GetSymbolVendor ();
492 if (symbols)
493 return symbols->FindTypes(sc, name, append, max_matches, types);
494 }
495 return 0;
496}
497
Enrico Granata6f3533f2011-07-29 19:53:35 +0000498// depending on implementation details, type lookup might fail because of
499// embedded spurious namespace:: prefixes. this call strips them, paying
500// attention to the fact that a type might have namespace'd type names as
501// arguments to templates, and those must not be stripped off
502static const char*
503StripTypeName(const char* name_cstr)
504{
505 const char* skip_namespace = strstr(name_cstr, "::");
506 const char* template_arg_char = strchr(name_cstr, '<');
507 while (skip_namespace != NULL)
508 {
509 if (template_arg_char != NULL &&
510 skip_namespace > template_arg_char) // but namespace'd template arguments are still good to go
511 break;
512 name_cstr = skip_namespace+2;
513 skip_namespace = strstr(name_cstr, "::");
514 }
515 return name_cstr;
516}
517
518uint32_t
519Module::FindTypes (const SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, TypeList& types)
520{
521 uint32_t retval = FindTypes_Impl(sc, name, append, max_matches, types);
522
523 if (retval == 0)
524 {
525 const char *stripped = StripTypeName(name.GetCString());
526 return FindTypes_Impl(sc, ConstString(stripped), append, max_matches, types);
527 }
528 else
529 return retval;
530
531}
532
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000533//uint32_t
534//Module::FindTypes(const SymbolContext& sc, const RegularExpression& regex, bool append, uint32_t max_matches, Type::Encoding encoding, const char *udt_name, TypeList& types)
535//{
536// Timer scoped_timer(__PRETTY_FUNCTION__);
537// SymbolVendor *symbols = GetSymbolVendor ();
538// if (symbols)
539// return symbols->FindTypes(sc, regex, append, max_matches, encoding, udt_name, types);
540// return 0;
541//
542//}
543
544SymbolVendor*
545Module::GetSymbolVendor (bool can_create)
546{
547 Mutex::Locker locker (m_mutex);
Greg Claytone83e7312010-09-07 23:40:05 +0000548 if (m_did_load_symbol_vendor == false && can_create)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000549 {
550 ObjectFile *obj_file = GetObjectFile ();
551 if (obj_file != NULL)
552 {
553 Timer scoped_timer(__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
554 m_symfile_ap.reset(SymbolVendor::FindPlugin(this));
Greg Claytone83e7312010-09-07 23:40:05 +0000555 m_did_load_symbol_vendor = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000556 }
557 }
558 return m_symfile_ap.get();
559}
560
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000561void
562Module::SetFileSpecAndObjectName (const FileSpec &file, const ConstString &object_name)
563{
564 // Container objects whose paths do not specify a file directly can call
565 // this function to correct the file and object names.
566 m_file = file;
567 m_mod_time = file.GetModificationTime();
568 m_object_name = object_name;
569}
570
571const ArchSpec&
572Module::GetArchitecture () const
573{
574 return m_arch;
575}
576
577void
Caroline Ticeceb6b132010-10-26 03:11:13 +0000578Module::GetDescription (Stream *s)
579{
580 Mutex::Locker locker (m_mutex);
581
Greg Claytoncfd1ace2010-10-31 03:01:06 +0000582 if (m_arch.IsValid())
Greg Clayton64195a22011-02-23 00:35:02 +0000583 s->Printf("(%s) ", m_arch.GetArchitectureName());
Caroline Ticeceb6b132010-10-26 03:11:13 +0000584
Greg Claytoncfd1ace2010-10-31 03:01:06 +0000585 char path[PATH_MAX];
586 if (m_file.GetPath(path, sizeof(path)))
587 s->PutCString(path);
588
589 const char *object_name = m_object_name.GetCString();
590 if (object_name)
591 s->Printf("(%s)", object_name);
Caroline Ticeceb6b132010-10-26 03:11:13 +0000592}
593
594void
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000595Module::Dump(Stream *s)
596{
597 Mutex::Locker locker (m_mutex);
Greg Clayton89411422010-10-08 00:21:05 +0000598 //s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000599 s->Indent();
600 s->Printf("Module %s/%s%s%s%s\n",
601 m_file.GetDirectory().AsCString(),
602 m_file.GetFilename().AsCString(),
603 m_object_name ? "(" : "",
604 m_object_name ? m_object_name.GetCString() : "",
605 m_object_name ? ")" : "");
606
607 s->IndentMore();
608 ObjectFile *objfile = GetObjectFile ();
609
610 if (objfile)
611 objfile->Dump(s);
612
613 SymbolVendor *symbols = GetSymbolVendor ();
614
615 if (symbols)
616 symbols->Dump(s);
617
618 s->IndentLess();
619}
620
621
622TypeList*
623Module::GetTypeList ()
624{
625 SymbolVendor *symbols = GetSymbolVendor ();
626 if (symbols)
627 return &symbols->GetTypeList();
628 return NULL;
629}
630
631const ConstString &
632Module::GetObjectName() const
633{
634 return m_object_name;
635}
636
637ObjectFile *
638Module::GetObjectFile()
639{
640 Mutex::Locker locker (m_mutex);
Greg Claytone83e7312010-09-07 23:40:05 +0000641 if (m_did_load_objfile == false)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000642 {
Greg Claytone83e7312010-09-07 23:40:05 +0000643 m_did_load_objfile = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000644 Timer scoped_timer(__PRETTY_FUNCTION__,
645 "Module::GetObjectFile () module = %s", GetFileSpec().GetFilename().AsCString(""));
Greg Clayton8b82f082011-04-12 05:54:46 +0000646 m_objfile_ap.reset(ObjectFile::FindPlugin(this, &m_file, m_object_offset, m_file.GetByteSize()));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000647 }
648 return m_objfile_ap.get();
649}
650
651
652const Symbol *
653Module::FindFirstSymbolWithNameAndType (const ConstString &name, SymbolType symbol_type)
654{
655 Timer scoped_timer(__PRETTY_FUNCTION__,
656 "Module::FindFirstSymbolWithNameAndType (name = %s, type = %i)",
657 name.AsCString(),
658 symbol_type);
659 ObjectFile *objfile = GetObjectFile();
660 if (objfile)
661 {
662 Symtab *symtab = objfile->GetSymtab();
663 if (symtab)
Greg Claytonbcf2cfb2010-09-11 03:13:28 +0000664 return symtab->FindFirstSymbolWithNameAndType (name, symbol_type, Symtab::eDebugAny, Symtab::eVisibilityAny);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000665 }
666 return NULL;
667}
668void
669Module::SymbolIndicesToSymbolContextList (Symtab *symtab, std::vector<uint32_t> &symbol_indexes, SymbolContextList &sc_list)
670{
671 // No need to protect this call using m_mutex all other method calls are
672 // already thread safe.
673
674 size_t num_indices = symbol_indexes.size();
675 if (num_indices > 0)
676 {
677 SymbolContext sc;
678 CalculateSymbolContext (&sc);
679 for (size_t i = 0; i < num_indices; i++)
680 {
681 sc.symbol = symtab->SymbolAtIndex (symbol_indexes[i]);
682 if (sc.symbol)
683 sc_list.Append (sc);
684 }
685 }
686}
687
688size_t
689Module::FindSymbolsWithNameAndType (const ConstString &name, SymbolType symbol_type, SymbolContextList &sc_list)
690{
691 // No need to protect this call using m_mutex all other method calls are
692 // already thread safe.
693
694
695 Timer scoped_timer(__PRETTY_FUNCTION__,
696 "Module::FindSymbolsWithNameAndType (name = %s, type = %i)",
697 name.AsCString(),
698 symbol_type);
699 const size_t initial_size = sc_list.GetSize();
700 ObjectFile *objfile = GetObjectFile ();
701 if (objfile)
702 {
703 Symtab *symtab = objfile->GetSymtab();
704 if (symtab)
705 {
706 std::vector<uint32_t> symbol_indexes;
707 symtab->FindAllSymbolsWithNameAndType (name, symbol_type, symbol_indexes);
708 SymbolIndicesToSymbolContextList (symtab, symbol_indexes, sc_list);
709 }
710 }
711 return sc_list.GetSize() - initial_size;
712}
713
714size_t
715Module::FindSymbolsMatchingRegExAndType (const RegularExpression &regex, SymbolType symbol_type, SymbolContextList &sc_list)
716{
717 // No need to protect this call using m_mutex all other method calls are
718 // already thread safe.
719
720 Timer scoped_timer(__PRETTY_FUNCTION__,
721 "Module::FindSymbolsMatchingRegExAndType (regex = %s, type = %i)",
722 regex.GetText(),
723 symbol_type);
724 const size_t initial_size = sc_list.GetSize();
725 ObjectFile *objfile = GetObjectFile ();
726 if (objfile)
727 {
728 Symtab *symtab = objfile->GetSymtab();
729 if (symtab)
730 {
731 std::vector<uint32_t> symbol_indexes;
Greg Claytonbcf2cfb2010-09-11 03:13:28 +0000732 symtab->FindAllSymbolsMatchingRexExAndType (regex, symbol_type, Symtab::eDebugAny, Symtab::eVisibilityAny, symbol_indexes);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000733 SymbolIndicesToSymbolContextList (symtab, symbol_indexes, sc_list);
734 }
735 }
736 return sc_list.GetSize() - initial_size;
737}
738
739const TimeValue &
740Module::GetModificationTime () const
741{
742 return m_mod_time;
743}
Jim Ingham5aee1622010-08-09 23:31:02 +0000744
745bool
746Module::IsExecutable ()
747{
748 if (GetObjectFile() == NULL)
749 return false;
750 else
751 return GetObjectFile()->IsExecutable();
752}
753
Jim Inghamb53cb272011-08-03 01:03:17 +0000754bool
755Module::IsLoadedInTarget (Target *target)
756{
757 ObjectFile *obj_file = GetObjectFile();
758 if (obj_file)
759 {
760 SectionList *sections = obj_file->GetSectionList();
761 if (sections != NULL)
762 {
763 size_t num_sections = sections->GetSize();
Jim Inghamb53cb272011-08-03 01:03:17 +0000764 for (size_t sect_idx = 0; sect_idx < num_sections; sect_idx++)
765 {
766 SectionSP section_sp = sections->GetSectionAtIndex(sect_idx);
767 if (section_sp->GetLoadBaseAddress(target) != LLDB_INVALID_ADDRESS)
768 {
769 return true;
770 }
771 }
772 }
773 }
774 return false;
775}
Jim Ingham5aee1622010-08-09 23:31:02 +0000776bool
777Module::SetArchitecture (const ArchSpec &new_arch)
778{
Greg Clayton64195a22011-02-23 00:35:02 +0000779 if (!m_arch.IsValid())
Jim Ingham5aee1622010-08-09 23:31:02 +0000780 {
781 m_arch = new_arch;
782 return true;
Greg Clayton64195a22011-02-23 00:35:02 +0000783 }
784 return m_arch == new_arch;
Jim Ingham5aee1622010-08-09 23:31:02 +0000785}
786