blob: d54f9699a49fb03b9f4977ff3eee500d98906d93 [file] [log] [blame]
Chris Lattner24943d22010-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 Clayton899025f2011-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 Lattner24943d22010-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 Clayton24bc5d92011-03-30 18:16:51 +000068 m_platform_file(),
Chris Lattner24943d22010-06-08 16:52:24 +000069 m_object_name (),
Greg Claytonb72d0f02011-04-12 05:54:46 +000070 m_object_offset (object_offset),
Greg Claytone40b6422011-09-18 18:59:15 +000071 m_objfile_sp (),
Greg Clayton236c1c72010-09-07 23:40:05 +000072 m_symfile_ap (),
Greg Claytonb01000f2011-01-17 03:46:26 +000073 m_ast (),
Greg Clayton236c1c72010-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 Claytonb01000f2011-01-17 03:46:26 +000077 m_did_init_ast (false),
Greg Clayton236c1c72010-09-07 23:40:05 +000078 m_is_dynamic_loader_module (false)
Chris Lattner24943d22010-06-08 16:52:24 +000079{
Greg Clayton899025f2011-08-09 00:01:09 +000080 // Scope for locker below...
81 {
82 Mutex::Locker locker (GetAllocationModuleCollectionMutex());
83 GetModuleCollection().push_back(this);
84 }
85
Chris Lattner24943d22010-06-08 16:52:24 +000086 if (object_name)
87 m_object_name = *object_name;
Greg Claytone005f2c2010-11-06 01:53:30 +000088 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
Chris Lattner24943d22010-06-08 16:52:24 +000089 if (log)
90 log->Printf ("%p Module::Module((%s) '%s/%s%s%s%s')",
91 this,
Greg Clayton940b1032011-02-23 00:35:02 +000092 m_arch.GetArchitectureName(),
Chris Lattner24943d22010-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 Lattner24943d22010-06-08 16:52:24 +000098}
99
100Module::~Module()
101{
Greg Clayton899025f2011-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 Claytone005f2c2010-11-06 01:53:30 +0000111 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
Chris Lattner24943d22010-06-08 16:52:24 +0000112 if (log)
113 log->Printf ("%p Module::~Module((%s) '%s/%s%s%s%s')",
114 this,
Greg Clayton940b1032011-02-23 00:35:02 +0000115 m_arch.GetArchitectureName(),
Chris Lattner24943d22010-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 Claytonb01000f2011-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();
Greg Claytone40b6422011-09-18 18:59:15 +0000127 m_objfile_sp.reset();
Chris Lattner24943d22010-06-08 16:52:24 +0000128}
129
130
Greg Clayton0467c782011-02-04 18:53:10 +0000131const lldb_private::UUID&
Chris Lattner24943d22010-06-08 16:52:24 +0000132Module::GetUUID()
133{
134 Mutex::Locker locker (m_mutex);
Greg Clayton236c1c72010-09-07 23:40:05 +0000135 if (m_did_parse_uuid == false)
Chris Lattner24943d22010-06-08 16:52:24 +0000136 {
137 ObjectFile * obj_file = GetObjectFile ();
138
139 if (obj_file != NULL)
140 {
141 obj_file->GetUUID(&m_uuid);
Greg Clayton236c1c72010-09-07 23:40:05 +0000142 m_did_parse_uuid = true;
Chris Lattner24943d22010-06-08 16:52:24 +0000143 }
144 }
145 return m_uuid;
146}
147
Greg Claytonb01000f2011-01-17 03:46:26 +0000148ClangASTContext &
149Module::GetClangASTContext ()
150{
151 Mutex::Locker locker (m_mutex);
152 if (m_did_init_ast == false)
153 {
154 ObjectFile * objfile = GetObjectFile();
Greg Clayton395fc332011-02-15 21:59:32 +0000155 ArchSpec object_arch;
156 if (objfile && objfile->GetArchitecture(object_arch))
Greg Claytonb01000f2011-01-17 03:46:26 +0000157 {
158 m_did_init_ast = true;
Greg Clayton395fc332011-02-15 21:59:32 +0000159 m_ast.SetArchitecture (object_arch);
Greg Claytonb01000f2011-01-17 03:46:26 +0000160 }
161 }
162 return m_ast;
163}
164
Chris Lattner24943d22010-06-08 16:52:24 +0000165void
166Module::ParseAllDebugSymbols()
167{
168 Mutex::Locker locker (m_mutex);
169 uint32_t num_comp_units = GetNumCompileUnits();
170 if (num_comp_units == 0)
171 return;
172
Greg Clayton02e210c2011-09-17 07:23:18 +0000173 SymbolContext sc;
174 sc.module_sp = this;
Chris Lattner24943d22010-06-08 16:52:24 +0000175 uint32_t cu_idx;
176 SymbolVendor *symbols = GetSymbolVendor ();
177
178 for (cu_idx = 0; cu_idx < num_comp_units; cu_idx++)
179 {
180 sc.comp_unit = symbols->GetCompileUnitAtIndex(cu_idx).get();
181 if (sc.comp_unit)
182 {
183 sc.function = NULL;
184 symbols->ParseVariablesForContext(sc);
185
186 symbols->ParseCompileUnitFunctions(sc);
187
188 uint32_t func_idx;
189 for (func_idx = 0; (sc.function = sc.comp_unit->GetFunctionAtIndex(func_idx).get()) != NULL; ++func_idx)
190 {
191 symbols->ParseFunctionBlocks(sc);
192
193 // Parse the variables for this function and all its blocks
194 symbols->ParseVariablesForContext(sc);
195 }
196
197
198 // Parse all types for this compile unit
199 sc.function = NULL;
200 symbols->ParseTypes(sc);
201 }
202 }
203}
204
205void
206Module::CalculateSymbolContext(SymbolContext* sc)
207{
Greg Clayton02e210c2011-09-17 07:23:18 +0000208 sc->module_sp = this;
Chris Lattner24943d22010-06-08 16:52:24 +0000209}
210
Greg Claytonc51ffbf2011-08-12 21:40:01 +0000211Module *
212Module::CalculateSymbolContextModule ()
213{
214 return this;
215}
216
Chris Lattner24943d22010-06-08 16:52:24 +0000217void
218Module::DumpSymbolContext(Stream *s)
219{
220 s->Printf(", Module{0x%8.8x}", this);
221}
222
223uint32_t
224Module::GetNumCompileUnits()
225{
226 Mutex::Locker locker (m_mutex);
227 Timer scoped_timer(__PRETTY_FUNCTION__, "Module::GetNumCompileUnits (module = %p)", this);
228 SymbolVendor *symbols = GetSymbolVendor ();
229 if (symbols)
230 return symbols->GetNumCompileUnits();
231 return 0;
232}
233
234CompUnitSP
235Module::GetCompileUnitAtIndex (uint32_t index)
236{
237 Mutex::Locker locker (m_mutex);
238 uint32_t num_comp_units = GetNumCompileUnits ();
239 CompUnitSP cu_sp;
240
241 if (index < num_comp_units)
242 {
243 SymbolVendor *symbols = GetSymbolVendor ();
244 if (symbols)
245 cu_sp = symbols->GetCompileUnitAtIndex(index);
246 }
247 return cu_sp;
248}
249
Chris Lattner24943d22010-06-08 16:52:24 +0000250bool
251Module::ResolveFileAddress (lldb::addr_t vm_addr, Address& so_addr)
252{
253 Mutex::Locker locker (m_mutex);
254 Timer scoped_timer(__PRETTY_FUNCTION__, "Module::ResolveFileAddress (vm_addr = 0x%llx)", vm_addr);
255 ObjectFile* ofile = GetObjectFile();
256 if (ofile)
257 return so_addr.ResolveAddressUsingFileSections(vm_addr, ofile->GetSectionList());
258 return false;
259}
260
261uint32_t
262Module::ResolveSymbolContextForAddress (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
263{
264 Mutex::Locker locker (m_mutex);
265 uint32_t resolved_flags = 0;
266
267 // Clear the result symbol context in case we don't find anything
268 sc.Clear();
269
270 // Get the section from the section/offset address.
271 const Section *section = so_addr.GetSection();
272
273 // Make sure the section matches this module before we try and match anything
274 if (section && section->GetModule() == this)
275 {
276 // If the section offset based address resolved itself, then this
277 // is the right module.
Greg Clayton02e210c2011-09-17 07:23:18 +0000278 sc.module_sp = this;
Chris Lattner24943d22010-06-08 16:52:24 +0000279 resolved_flags |= eSymbolContextModule;
280
281 // Resolve the compile unit, function, block, line table or line
282 // entry if requested.
283 if (resolve_scope & eSymbolContextCompUnit ||
284 resolve_scope & eSymbolContextFunction ||
285 resolve_scope & eSymbolContextBlock ||
286 resolve_scope & eSymbolContextLineEntry )
287 {
288 SymbolVendor *symbols = GetSymbolVendor ();
289 if (symbols)
290 resolved_flags |= symbols->ResolveSymbolContext (so_addr, resolve_scope, sc);
291 }
292
Jim Inghambddb7892010-08-31 23:51:36 +0000293 // Resolve the symbol if requested, but don't re-look it up if we've already found it.
294 if (resolve_scope & eSymbolContextSymbol && !(resolved_flags & eSymbolContextSymbol))
Chris Lattner24943d22010-06-08 16:52:24 +0000295 {
296 ObjectFile* ofile = GetObjectFile();
297 if (ofile)
298 {
299 Symtab *symtab = ofile->GetSymtab();
300 if (symtab)
301 {
302 if (so_addr.IsSectionOffset())
303 {
304 sc.symbol = symtab->FindSymbolContainingFileAddress(so_addr.GetFileAddress());
305 if (sc.symbol)
306 resolved_flags |= eSymbolContextSymbol;
307 }
308 }
309 }
310 }
311 }
312 return resolved_flags;
313}
314
315uint32_t
Greg Clayton537a7a82010-10-20 20:54:39 +0000316Module::ResolveSymbolContextForFilePath
317(
318 const char *file_path,
319 uint32_t line,
320 bool check_inlines,
321 uint32_t resolve_scope,
322 SymbolContextList& sc_list
323)
Chris Lattner24943d22010-06-08 16:52:24 +0000324{
Greg Clayton537a7a82010-10-20 20:54:39 +0000325 FileSpec file_spec(file_path, false);
Chris Lattner24943d22010-06-08 16:52:24 +0000326 return ResolveSymbolContextsForFileSpec (file_spec, line, check_inlines, resolve_scope, sc_list);
327}
328
329uint32_t
330Module::ResolveSymbolContextsForFileSpec (const FileSpec &file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
331{
332 Mutex::Locker locker (m_mutex);
333 Timer scoped_timer(__PRETTY_FUNCTION__,
334 "Module::ResolveSymbolContextForFilePath (%s%s%s:%u, check_inlines = %s, resolve_scope = 0x%8.8x)",
335 file_spec.GetDirectory().AsCString(""),
336 file_spec.GetDirectory() ? "/" : "",
337 file_spec.GetFilename().AsCString(""),
338 line,
339 check_inlines ? "yes" : "no",
340 resolve_scope);
341
342 const uint32_t initial_count = sc_list.GetSize();
343
344 SymbolVendor *symbols = GetSymbolVendor ();
345 if (symbols)
346 symbols->ResolveSymbolContext (file_spec, line, check_inlines, resolve_scope, sc_list);
347
348 return sc_list.GetSize() - initial_count;
349}
350
351
352uint32_t
353Module::FindGlobalVariables(const ConstString &name, bool append, uint32_t max_matches, VariableList& variables)
354{
355 SymbolVendor *symbols = GetSymbolVendor ();
356 if (symbols)
357 return symbols->FindGlobalVariables(name, append, max_matches, variables);
358 return 0;
359}
360uint32_t
361Module::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
362{
363 SymbolVendor *symbols = GetSymbolVendor ();
364 if (symbols)
365 return symbols->FindGlobalVariables(regex, append, max_matches, variables);
366 return 0;
367}
368
369uint32_t
Greg Clayton801417e2011-07-07 01:59:51 +0000370Module::FindCompileUnits (const FileSpec &path,
371 bool append,
372 SymbolContextList &sc_list)
373{
374 if (!append)
375 sc_list.Clear();
376
377 const uint32_t start_size = sc_list.GetSize();
378 const uint32_t num_compile_units = GetNumCompileUnits();
379 SymbolContext sc;
Greg Clayton02e210c2011-09-17 07:23:18 +0000380 sc.module_sp = this;
Greg Clayton801417e2011-07-07 01:59:51 +0000381 const bool compare_directory = path.GetDirectory();
382 for (uint32_t i=0; i<num_compile_units; ++i)
383 {
384 sc.comp_unit = GetCompileUnitAtIndex(i).get();
385 if (FileSpec::Equal (*sc.comp_unit, path, compare_directory))
386 sc_list.Append(sc);
387 }
388 return sc_list.GetSize() - start_size;
389}
390
391uint32_t
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000392Module::FindFunctions (const ConstString &name,
393 uint32_t name_type_mask,
394 bool include_symbols,
395 bool append,
396 SymbolContextList& sc_list)
Chris Lattner24943d22010-06-08 16:52:24 +0000397{
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000398 if (!append)
399 sc_list.Clear();
400
401 const uint32_t start_size = sc_list.GetSize();
402
403 // Find all the functions (not symbols, but debug information functions...
Chris Lattner24943d22010-06-08 16:52:24 +0000404 SymbolVendor *symbols = GetSymbolVendor ();
405 if (symbols)
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000406 symbols->FindFunctions(name, name_type_mask, append, sc_list);
407
408 // Now check our symbol table for symbols that are code symbols if requested
409 if (include_symbols)
410 {
411 ObjectFile *objfile = GetObjectFile();
412 if (objfile)
413 {
414 Symtab *symtab = objfile->GetSymtab();
415 if (symtab)
416 {
417 std::vector<uint32_t> symbol_indexes;
418 symtab->FindAllSymbolsWithNameAndType (name, eSymbolTypeCode, Symtab::eDebugAny, Symtab::eVisibilityAny, symbol_indexes);
419 const uint32_t num_matches = symbol_indexes.size();
420 if (num_matches)
421 {
Greg Clayton889fbd02011-03-26 19:14:58 +0000422 const bool merge_symbol_into_function = true;
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000423 SymbolContext sc(this);
424 for (uint32_t i=0; i<num_matches; i++)
425 {
426 sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]);
Greg Clayton889fbd02011-03-26 19:14:58 +0000427 sc_list.AppendIfUnique (sc, merge_symbol_into_function);
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000428 }
429 }
430 }
431 }
432 }
433 return sc_list.GetSize() - start_size;
Chris Lattner24943d22010-06-08 16:52:24 +0000434}
435
436uint32_t
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000437Module::FindFunctions (const RegularExpression& regex,
438 bool include_symbols,
439 bool append,
440 SymbolContextList& sc_list)
Chris Lattner24943d22010-06-08 16:52:24 +0000441{
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000442 if (!append)
443 sc_list.Clear();
444
445 const uint32_t start_size = sc_list.GetSize();
446
Chris Lattner24943d22010-06-08 16:52:24 +0000447 SymbolVendor *symbols = GetSymbolVendor ();
448 if (symbols)
Jim Ingham9935a862011-05-18 05:02:10 +0000449 symbols->FindFunctions(regex, append, sc_list);
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000450 // Now check our symbol table for symbols that are code symbols if requested
451 if (include_symbols)
452 {
453 ObjectFile *objfile = GetObjectFile();
454 if (objfile)
455 {
456 Symtab *symtab = objfile->GetSymtab();
457 if (symtab)
458 {
459 std::vector<uint32_t> symbol_indexes;
460 symtab->AppendSymbolIndexesMatchingRegExAndType (regex, eSymbolTypeCode, Symtab::eDebugAny, Symtab::eVisibilityAny, symbol_indexes);
461 const uint32_t num_matches = symbol_indexes.size();
462 if (num_matches)
463 {
Greg Clayton889fbd02011-03-26 19:14:58 +0000464 const bool merge_symbol_into_function = true;
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000465 SymbolContext sc(this);
466 for (uint32_t i=0; i<num_matches; i++)
467 {
468 sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]);
Greg Clayton889fbd02011-03-26 19:14:58 +0000469 sc_list.AppendIfUnique (sc, merge_symbol_into_function);
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000470 }
471 }
472 }
473 }
474 }
475 return sc_list.GetSize() - start_size;
Chris Lattner24943d22010-06-08 16:52:24 +0000476}
477
Greg Clayton7aff9ff2010-08-03 01:26:16 +0000478uint32_t
Enrico Granata979e20d2011-07-29 19:53:35 +0000479Module::FindTypes_Impl (const SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, TypeList& types)
Greg Clayton7aff9ff2010-08-03 01:26:16 +0000480{
481 Timer scoped_timer(__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
482 if (sc.module_sp.get() == NULL || sc.module_sp.get() == this)
483 {
484 SymbolVendor *symbols = GetSymbolVendor ();
485 if (symbols)
486 return symbols->FindTypes(sc, name, append, max_matches, types);
487 }
488 return 0;
489}
490
Enrico Granata979e20d2011-07-29 19:53:35 +0000491// depending on implementation details, type lookup might fail because of
492// embedded spurious namespace:: prefixes. this call strips them, paying
493// attention to the fact that a type might have namespace'd type names as
494// arguments to templates, and those must not be stripped off
495static const char*
496StripTypeName(const char* name_cstr)
497{
498 const char* skip_namespace = strstr(name_cstr, "::");
499 const char* template_arg_char = strchr(name_cstr, '<');
500 while (skip_namespace != NULL)
501 {
502 if (template_arg_char != NULL &&
503 skip_namespace > template_arg_char) // but namespace'd template arguments are still good to go
504 break;
505 name_cstr = skip_namespace+2;
506 skip_namespace = strstr(name_cstr, "::");
507 }
508 return name_cstr;
509}
510
511uint32_t
512Module::FindTypes (const SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, TypeList& types)
513{
514 uint32_t retval = FindTypes_Impl(sc, name, append, max_matches, types);
515
516 if (retval == 0)
517 {
518 const char *stripped = StripTypeName(name.GetCString());
519 return FindTypes_Impl(sc, ConstString(stripped), append, max_matches, types);
520 }
521 else
522 return retval;
523
524}
525
Chris Lattner24943d22010-06-08 16:52:24 +0000526//uint32_t
527//Module::FindTypes(const SymbolContext& sc, const RegularExpression& regex, bool append, uint32_t max_matches, Type::Encoding encoding, const char *udt_name, TypeList& types)
528//{
529// Timer scoped_timer(__PRETTY_FUNCTION__);
530// SymbolVendor *symbols = GetSymbolVendor ();
531// if (symbols)
532// return symbols->FindTypes(sc, regex, append, max_matches, encoding, udt_name, types);
533// return 0;
534//
535//}
536
537SymbolVendor*
538Module::GetSymbolVendor (bool can_create)
539{
540 Mutex::Locker locker (m_mutex);
Greg Clayton236c1c72010-09-07 23:40:05 +0000541 if (m_did_load_symbol_vendor == false && can_create)
Chris Lattner24943d22010-06-08 16:52:24 +0000542 {
543 ObjectFile *obj_file = GetObjectFile ();
544 if (obj_file != NULL)
545 {
546 Timer scoped_timer(__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
547 m_symfile_ap.reset(SymbolVendor::FindPlugin(this));
Greg Clayton236c1c72010-09-07 23:40:05 +0000548 m_did_load_symbol_vendor = true;
Chris Lattner24943d22010-06-08 16:52:24 +0000549 }
550 }
551 return m_symfile_ap.get();
552}
553
Chris Lattner24943d22010-06-08 16:52:24 +0000554void
555Module::SetFileSpecAndObjectName (const FileSpec &file, const ConstString &object_name)
556{
557 // Container objects whose paths do not specify a file directly can call
558 // this function to correct the file and object names.
559 m_file = file;
560 m_mod_time = file.GetModificationTime();
561 m_object_name = object_name;
562}
563
564const ArchSpec&
565Module::GetArchitecture () const
566{
567 return m_arch;
568}
569
570void
Caroline Tice7826c882010-10-26 03:11:13 +0000571Module::GetDescription (Stream *s)
572{
573 Mutex::Locker locker (m_mutex);
574
Greg Clayton49ce6822010-10-31 03:01:06 +0000575 if (m_arch.IsValid())
Greg Clayton940b1032011-02-23 00:35:02 +0000576 s->Printf("(%s) ", m_arch.GetArchitectureName());
Caroline Tice7826c882010-10-26 03:11:13 +0000577
Greg Clayton49ce6822010-10-31 03:01:06 +0000578 char path[PATH_MAX];
579 if (m_file.GetPath(path, sizeof(path)))
580 s->PutCString(path);
581
582 const char *object_name = m_object_name.GetCString();
583 if (object_name)
584 s->Printf("(%s)", object_name);
Caroline Tice7826c882010-10-26 03:11:13 +0000585}
586
587void
Chris Lattner24943d22010-06-08 16:52:24 +0000588Module::Dump(Stream *s)
589{
590 Mutex::Locker locker (m_mutex);
Greg Clayton3fed8b92010-10-08 00:21:05 +0000591 //s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
Chris Lattner24943d22010-06-08 16:52:24 +0000592 s->Indent();
593 s->Printf("Module %s/%s%s%s%s\n",
594 m_file.GetDirectory().AsCString(),
595 m_file.GetFilename().AsCString(),
596 m_object_name ? "(" : "",
597 m_object_name ? m_object_name.GetCString() : "",
598 m_object_name ? ")" : "");
599
600 s->IndentMore();
601 ObjectFile *objfile = GetObjectFile ();
602
603 if (objfile)
604 objfile->Dump(s);
605
606 SymbolVendor *symbols = GetSymbolVendor ();
607
608 if (symbols)
609 symbols->Dump(s);
610
611 s->IndentLess();
612}
613
614
615TypeList*
616Module::GetTypeList ()
617{
618 SymbolVendor *symbols = GetSymbolVendor ();
619 if (symbols)
620 return &symbols->GetTypeList();
621 return NULL;
622}
623
624const ConstString &
625Module::GetObjectName() const
626{
627 return m_object_name;
628}
629
630ObjectFile *
631Module::GetObjectFile()
632{
633 Mutex::Locker locker (m_mutex);
Greg Clayton236c1c72010-09-07 23:40:05 +0000634 if (m_did_load_objfile == false)
Chris Lattner24943d22010-06-08 16:52:24 +0000635 {
Greg Clayton236c1c72010-09-07 23:40:05 +0000636 m_did_load_objfile = true;
Chris Lattner24943d22010-06-08 16:52:24 +0000637 Timer scoped_timer(__PRETTY_FUNCTION__,
638 "Module::GetObjectFile () module = %s", GetFileSpec().GetFilename().AsCString(""));
Greg Claytone40b6422011-09-18 18:59:15 +0000639 m_objfile_sp = ObjectFile::FindPlugin(this, &m_file, m_object_offset, m_file.GetByteSize());
Chris Lattner24943d22010-06-08 16:52:24 +0000640 }
Greg Claytone40b6422011-09-18 18:59:15 +0000641 return m_objfile_sp.get();
Chris Lattner24943d22010-06-08 16:52:24 +0000642}
643
644
645const Symbol *
646Module::FindFirstSymbolWithNameAndType (const ConstString &name, SymbolType symbol_type)
647{
648 Timer scoped_timer(__PRETTY_FUNCTION__,
649 "Module::FindFirstSymbolWithNameAndType (name = %s, type = %i)",
650 name.AsCString(),
651 symbol_type);
652 ObjectFile *objfile = GetObjectFile();
653 if (objfile)
654 {
655 Symtab *symtab = objfile->GetSymtab();
656 if (symtab)
Greg Clayton7c36fa02010-09-11 03:13:28 +0000657 return symtab->FindFirstSymbolWithNameAndType (name, symbol_type, Symtab::eDebugAny, Symtab::eVisibilityAny);
Chris Lattner24943d22010-06-08 16:52:24 +0000658 }
659 return NULL;
660}
661void
662Module::SymbolIndicesToSymbolContextList (Symtab *symtab, std::vector<uint32_t> &symbol_indexes, SymbolContextList &sc_list)
663{
664 // No need to protect this call using m_mutex all other method calls are
665 // already thread safe.
666
667 size_t num_indices = symbol_indexes.size();
668 if (num_indices > 0)
669 {
670 SymbolContext sc;
671 CalculateSymbolContext (&sc);
672 for (size_t i = 0; i < num_indices; i++)
673 {
674 sc.symbol = symtab->SymbolAtIndex (symbol_indexes[i]);
675 if (sc.symbol)
676 sc_list.Append (sc);
677 }
678 }
679}
680
681size_t
682Module::FindSymbolsWithNameAndType (const ConstString &name, SymbolType symbol_type, SymbolContextList &sc_list)
683{
684 // No need to protect this call using m_mutex all other method calls are
685 // already thread safe.
686
687
688 Timer scoped_timer(__PRETTY_FUNCTION__,
689 "Module::FindSymbolsWithNameAndType (name = %s, type = %i)",
690 name.AsCString(),
691 symbol_type);
692 const size_t initial_size = sc_list.GetSize();
693 ObjectFile *objfile = GetObjectFile ();
694 if (objfile)
695 {
696 Symtab *symtab = objfile->GetSymtab();
697 if (symtab)
698 {
699 std::vector<uint32_t> symbol_indexes;
700 symtab->FindAllSymbolsWithNameAndType (name, symbol_type, symbol_indexes);
701 SymbolIndicesToSymbolContextList (symtab, symbol_indexes, sc_list);
702 }
703 }
704 return sc_list.GetSize() - initial_size;
705}
706
707size_t
708Module::FindSymbolsMatchingRegExAndType (const RegularExpression &regex, SymbolType symbol_type, SymbolContextList &sc_list)
709{
710 // No need to protect this call using m_mutex all other method calls are
711 // already thread safe.
712
713 Timer scoped_timer(__PRETTY_FUNCTION__,
714 "Module::FindSymbolsMatchingRegExAndType (regex = %s, type = %i)",
715 regex.GetText(),
716 symbol_type);
717 const size_t initial_size = sc_list.GetSize();
718 ObjectFile *objfile = GetObjectFile ();
719 if (objfile)
720 {
721 Symtab *symtab = objfile->GetSymtab();
722 if (symtab)
723 {
724 std::vector<uint32_t> symbol_indexes;
Greg Clayton7c36fa02010-09-11 03:13:28 +0000725 symtab->FindAllSymbolsMatchingRexExAndType (regex, symbol_type, Symtab::eDebugAny, Symtab::eVisibilityAny, symbol_indexes);
Chris Lattner24943d22010-06-08 16:52:24 +0000726 SymbolIndicesToSymbolContextList (symtab, symbol_indexes, sc_list);
727 }
728 }
729 return sc_list.GetSize() - initial_size;
730}
731
732const TimeValue &
733Module::GetModificationTime () const
734{
735 return m_mod_time;
736}
Jim Ingham7508e732010-08-09 23:31:02 +0000737
738bool
739Module::IsExecutable ()
740{
741 if (GetObjectFile() == NULL)
742 return false;
743 else
744 return GetObjectFile()->IsExecutable();
745}
746
Jim Ingham51b11e02011-08-03 01:03:17 +0000747bool
748Module::IsLoadedInTarget (Target *target)
749{
750 ObjectFile *obj_file = GetObjectFile();
751 if (obj_file)
752 {
753 SectionList *sections = obj_file->GetSectionList();
754 if (sections != NULL)
755 {
756 size_t num_sections = sections->GetSize();
Jim Ingham51b11e02011-08-03 01:03:17 +0000757 for (size_t sect_idx = 0; sect_idx < num_sections; sect_idx++)
758 {
759 SectionSP section_sp = sections->GetSectionAtIndex(sect_idx);
760 if (section_sp->GetLoadBaseAddress(target) != LLDB_INVALID_ADDRESS)
761 {
762 return true;
763 }
764 }
765 }
766 }
767 return false;
768}
Jim Ingham7508e732010-08-09 23:31:02 +0000769bool
770Module::SetArchitecture (const ArchSpec &new_arch)
771{
Greg Clayton940b1032011-02-23 00:35:02 +0000772 if (!m_arch.IsValid())
Jim Ingham7508e732010-08-09 23:31:02 +0000773 {
774 m_arch = new_arch;
775 return true;
Greg Clayton940b1032011-02-23 00:35:02 +0000776 }
777 return m_arch == new_arch;
Jim Ingham7508e732010-08-09 23:31:02 +0000778}
779