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