blob: 0b400075c1ac9098051081f3c7ea84b2f7c2d65f [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- ModuleList.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/ModuleList.h"
11
12// C Includes
13// C++ Includes
14// Other libraries and framework includes
15// Project includes
Greg Clayton427f2902010-12-14 02:59:59 +000016#include "lldb/Core/Log.h"
Chris Lattner24943d22010-06-08 16:52:24 +000017#include "lldb/Core/Module.h"
Greg Claytondf6dc882012-01-05 03:57:59 +000018#include "lldb/Host/Host.h"
Chris Lattner24943d22010-06-08 16:52:24 +000019#include "lldb/Host/Symbols.h"
Sean Callanan3e80cd92011-10-12 02:08:07 +000020#include "lldb/Symbol/ClangNamespaceDecl.h"
Chris Lattner24943d22010-06-08 16:52:24 +000021#include "lldb/Symbol/ObjectFile.h"
22#include "lldb/Symbol/VariableList.h"
23
24using namespace lldb;
25using namespace lldb_private;
26
27//----------------------------------------------------------------------
28// ModuleList constructor
29//----------------------------------------------------------------------
30ModuleList::ModuleList() :
31 m_modules(),
32 m_modules_mutex (Mutex::eMutexTypeRecursive)
33{
34}
35
36//----------------------------------------------------------------------
37// Copy constructor
38//----------------------------------------------------------------------
39ModuleList::ModuleList(const ModuleList& rhs) :
40 m_modules(rhs.m_modules)
41{
42}
43
44//----------------------------------------------------------------------
45// Assignment operator
46//----------------------------------------------------------------------
47const ModuleList&
48ModuleList::operator= (const ModuleList& rhs)
49{
50 if (this != &rhs)
51 {
52 Mutex::Locker locker(m_modules_mutex);
53 m_modules = rhs.m_modules;
54 }
55 return *this;
56}
57
58//----------------------------------------------------------------------
59// Destructor
60//----------------------------------------------------------------------
61ModuleList::~ModuleList()
62{
63}
64
65void
Greg Clayton3e8c25f2011-09-24 00:52:29 +000066ModuleList::Append (const ModuleSP &module_sp)
Chris Lattner24943d22010-06-08 16:52:24 +000067{
Greg Claytonb72d0f02011-04-12 05:54:46 +000068 if (module_sp)
69 {
70 Mutex::Locker locker(m_modules_mutex);
71 m_modules.push_back(module_sp);
72 }
Chris Lattner24943d22010-06-08 16:52:24 +000073}
74
75bool
Greg Clayton3e8c25f2011-09-24 00:52:29 +000076ModuleList::AppendIfNeeded (const ModuleSP &module_sp)
Chris Lattner24943d22010-06-08 16:52:24 +000077{
Greg Claytonb72d0f02011-04-12 05:54:46 +000078 if (module_sp)
Chris Lattner24943d22010-06-08 16:52:24 +000079 {
Greg Claytonb72d0f02011-04-12 05:54:46 +000080 Mutex::Locker locker(m_modules_mutex);
81 collection::iterator pos, end = m_modules.end();
82 for (pos = m_modules.begin(); pos != end; ++pos)
83 {
84 if (pos->get() == module_sp.get())
85 return false; // Already in the list
86 }
87 // Only push module_sp on the list if it wasn't already in there.
88 m_modules.push_back(module_sp);
89 return true;
Chris Lattner24943d22010-06-08 16:52:24 +000090 }
Greg Claytonb72d0f02011-04-12 05:54:46 +000091 return false;
Chris Lattner24943d22010-06-08 16:52:24 +000092}
93
94bool
Greg Clayton3e8c25f2011-09-24 00:52:29 +000095ModuleList::Remove (const ModuleSP &module_sp)
Chris Lattner24943d22010-06-08 16:52:24 +000096{
Greg Claytonb72d0f02011-04-12 05:54:46 +000097 if (module_sp)
Chris Lattner24943d22010-06-08 16:52:24 +000098 {
Greg Claytonb72d0f02011-04-12 05:54:46 +000099 Mutex::Locker locker(m_modules_mutex);
100 collection::iterator pos, end = m_modules.end();
101 for (pos = m_modules.begin(); pos != end; ++pos)
Chris Lattner24943d22010-06-08 16:52:24 +0000102 {
Greg Claytonb72d0f02011-04-12 05:54:46 +0000103 if (pos->get() == module_sp.get())
104 {
105 m_modules.erase (pos);
106 return true;
107 }
Chris Lattner24943d22010-06-08 16:52:24 +0000108 }
109 }
110 return false;
111}
112
Greg Clayton5beb99d2011-08-11 02:48:45 +0000113
114size_t
115ModuleList::RemoveOrphans ()
116{
117 Mutex::Locker locker(m_modules_mutex);
Greg Claytonb01760c2011-08-11 04:30:39 +0000118 collection::iterator pos = m_modules.begin();
Greg Clayton5beb99d2011-08-11 02:48:45 +0000119 size_t remove_count = 0;
Greg Claytonb01760c2011-08-11 04:30:39 +0000120 while (pos != m_modules.end())
Greg Clayton5beb99d2011-08-11 02:48:45 +0000121 {
122 if (pos->unique())
123 {
124 pos = m_modules.erase (pos);
125 ++remove_count;
126 }
127 else
128 {
129 ++pos;
130 }
131 }
132 return remove_count;
133}
134
Greg Clayton7b9fcc02010-12-06 23:51:26 +0000135size_t
136ModuleList::Remove (ModuleList &module_list)
137{
138 Mutex::Locker locker(m_modules_mutex);
139 size_t num_removed = 0;
140 collection::iterator pos, end = module_list.m_modules.end();
141 for (pos = module_list.m_modules.begin(); pos != end; ++pos)
142 {
143 if (Remove (*pos))
144 ++num_removed;
145 }
146 return num_removed;
147}
148
Chris Lattner24943d22010-06-08 16:52:24 +0000149
150
151void
152ModuleList::Clear()
153{
154 Mutex::Locker locker(m_modules_mutex);
155 m_modules.clear();
156}
157
Greg Clayton08205a62012-01-27 18:45:39 +0000158void
159ModuleList::Destroy()
160{
161 Mutex::Locker locker(m_modules_mutex);
162 collection empty;
163 m_modules.swap(empty);
164}
165
Chris Lattner24943d22010-06-08 16:52:24 +0000166Module*
167ModuleList::GetModulePointerAtIndex (uint32_t idx) const
168{
169 Mutex::Locker locker(m_modules_mutex);
170 if (idx < m_modules.size())
171 return m_modules[idx].get();
172 return NULL;
173}
174
175ModuleSP
176ModuleList::GetModuleAtIndex(uint32_t idx)
177{
178 Mutex::Locker locker(m_modules_mutex);
179 ModuleSP module_sp;
180 if (idx < m_modules.size())
181 module_sp = m_modules[idx];
182 return module_sp;
183}
184
Greg Clayton801417e2011-07-07 01:59:51 +0000185uint32_t
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000186ModuleList::FindFunctions (const ConstString &name,
187 uint32_t name_type_mask,
188 bool include_symbols,
189 bool append,
190 SymbolContextList &sc_list)
Chris Lattner24943d22010-06-08 16:52:24 +0000191{
Sean Callanan0fc73582010-07-27 00:55:47 +0000192 if (!append)
193 sc_list.Clear();
194
Chris Lattner24943d22010-06-08 16:52:24 +0000195 Mutex::Locker locker(m_modules_mutex);
196 collection::const_iterator pos, end = m_modules.end();
197 for (pos = m_modules.begin(); pos != end; ++pos)
198 {
Sean Callanan3e80cd92011-10-12 02:08:07 +0000199 (*pos)->FindFunctions (name, NULL, name_type_mask, include_symbols, true, sc_list);
Chris Lattner24943d22010-06-08 16:52:24 +0000200 }
Sean Callanan0fc73582010-07-27 00:55:47 +0000201
Chris Lattner24943d22010-06-08 16:52:24 +0000202 return sc_list.GetSize();
203}
204
205uint32_t
Greg Clayton801417e2011-07-07 01:59:51 +0000206ModuleList::FindCompileUnits (const FileSpec &path,
207 bool append,
208 SymbolContextList &sc_list)
209{
210 if (!append)
211 sc_list.Clear();
212
213 Mutex::Locker locker(m_modules_mutex);
214 collection::const_iterator pos, end = m_modules.end();
215 for (pos = m_modules.begin(); pos != end; ++pos)
216 {
217 (*pos)->FindCompileUnits (path, true, sc_list);
218 }
219
220 return sc_list.GetSize();
221}
222
223uint32_t
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000224ModuleList::FindGlobalVariables (const ConstString &name,
225 bool append,
226 uint32_t max_matches,
227 VariableList& variable_list)
Chris Lattner24943d22010-06-08 16:52:24 +0000228{
229 size_t initial_size = variable_list.GetSize();
230 Mutex::Locker locker(m_modules_mutex);
231 collection::iterator pos, end = m_modules.end();
232 for (pos = m_modules.begin(); pos != end; ++pos)
233 {
Sean Callanan3e80cd92011-10-12 02:08:07 +0000234 (*pos)->FindGlobalVariables (name, NULL, append, max_matches, variable_list);
Chris Lattner24943d22010-06-08 16:52:24 +0000235 }
236 return variable_list.GetSize() - initial_size;
237}
238
239
240uint32_t
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000241ModuleList::FindGlobalVariables (const RegularExpression& regex,
242 bool append,
243 uint32_t max_matches,
244 VariableList& variable_list)
Chris Lattner24943d22010-06-08 16:52:24 +0000245{
246 size_t initial_size = variable_list.GetSize();
247 Mutex::Locker locker(m_modules_mutex);
248 collection::iterator pos, end = m_modules.end();
249 for (pos = m_modules.begin(); pos != end; ++pos)
250 {
251 (*pos)->FindGlobalVariables (regex, append, max_matches, variable_list);
252 }
253 return variable_list.GetSize() - initial_size;
254}
255
256
257size_t
Greg Clayton28d5fcc2011-01-27 06:44:37 +0000258ModuleList::FindSymbolsWithNameAndType (const ConstString &name,
259 SymbolType symbol_type,
Jim Ingham323ce422011-11-19 00:19:25 +0000260 SymbolContextList &sc_list,
261 bool append)
Chris Lattner24943d22010-06-08 16:52:24 +0000262{
263 Mutex::Locker locker(m_modules_mutex);
Jim Ingham323ce422011-11-19 00:19:25 +0000264 if (!append)
265 sc_list.Clear();
266 size_t initial_size = sc_list.GetSize();
267
Chris Lattner24943d22010-06-08 16:52:24 +0000268 collection::iterator pos, end = m_modules.end();
269 for (pos = m_modules.begin(); pos != end; ++pos)
Sean Callananaa4a5532011-10-13 16:49:47 +0000270 (*pos)->FindSymbolsWithNameAndType (name, symbol_type, sc_list);
Jim Ingham323ce422011-11-19 00:19:25 +0000271 return sc_list.GetSize() - initial_size;
272}
273
274 size_t
275ModuleList::FindSymbolsMatchingRegExAndType (const RegularExpression &regex,
276 lldb::SymbolType symbol_type,
277 SymbolContextList &sc_list,
278 bool append)
279{
280 Mutex::Locker locker(m_modules_mutex);
281 if (!append)
282 sc_list.Clear();
283 size_t initial_size = sc_list.GetSize();
284
285 collection::iterator pos, end = m_modules.end();
286 for (pos = m_modules.begin(); pos != end; ++pos)
287 (*pos)->FindSymbolsMatchingRegExAndType (regex, symbol_type, sc_list);
288 return sc_list.GetSize() - initial_size;
Chris Lattner24943d22010-06-08 16:52:24 +0000289}
290
291class ModuleMatches
292{
293public:
294 //--------------------------------------------------------------
295 /// Construct with the user ID to look for.
296 //--------------------------------------------------------------
297 ModuleMatches (const FileSpec *file_spec_ptr,
298 const ArchSpec *arch_ptr,
Greg Clayton0467c782011-02-04 18:53:10 +0000299 const lldb_private::UUID *uuid_ptr,
Greg Clayton24bc5d92011-03-30 18:16:51 +0000300 const ConstString *object_name,
301 bool file_spec_is_platform) :
Chris Lattner24943d22010-06-08 16:52:24 +0000302 m_file_spec_ptr (file_spec_ptr),
303 m_arch_ptr (arch_ptr),
304 m_uuid_ptr (uuid_ptr),
Greg Clayton24bc5d92011-03-30 18:16:51 +0000305 m_object_name (object_name),
306 m_file_spec_compare_basename_only (false),
307 m_file_spec_is_platform (file_spec_is_platform)
Chris Lattner24943d22010-06-08 16:52:24 +0000308 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000309 if (file_spec_ptr)
310 m_file_spec_compare_basename_only = file_spec_ptr->GetDirectory();
Chris Lattner24943d22010-06-08 16:52:24 +0000311 }
312
Greg Clayton24bc5d92011-03-30 18:16:51 +0000313
Chris Lattner24943d22010-06-08 16:52:24 +0000314 //--------------------------------------------------------------
315 /// Unary predicate function object callback.
316 //--------------------------------------------------------------
317 bool
318 operator () (const ModuleSP& module_sp) const
319 {
320 if (m_file_spec_ptr)
321 {
Greg Clayton24bc5d92011-03-30 18:16:51 +0000322 if (m_file_spec_is_platform)
323 {
324 if (!FileSpec::Equal (*m_file_spec_ptr,
325 module_sp->GetPlatformFileSpec(),
326 m_file_spec_compare_basename_only))
327 return false;
328
329 }
330 else
331 {
332 if (!FileSpec::Equal (*m_file_spec_ptr,
333 module_sp->GetFileSpec(),
334 m_file_spec_compare_basename_only))
335 return false;
336 }
Chris Lattner24943d22010-06-08 16:52:24 +0000337 }
338
Greg Clayton58e844b2010-12-08 05:08:21 +0000339 if (m_arch_ptr && m_arch_ptr->IsValid())
Chris Lattner24943d22010-06-08 16:52:24 +0000340 {
341 if (module_sp->GetArchitecture() != *m_arch_ptr)
342 return false;
343 }
344
Greg Clayton58e844b2010-12-08 05:08:21 +0000345 if (m_uuid_ptr && m_uuid_ptr->IsValid())
Chris Lattner24943d22010-06-08 16:52:24 +0000346 {
347 if (module_sp->GetUUID() != *m_uuid_ptr)
348 return false;
349 }
350
351 if (m_object_name)
352 {
353 if (module_sp->GetObjectName() != *m_object_name)
354 return false;
355 }
356 return true;
357 }
358
359private:
360 //--------------------------------------------------------------
361 // Member variables.
362 //--------------------------------------------------------------
Greg Clayton0467c782011-02-04 18:53:10 +0000363 const FileSpec * m_file_spec_ptr;
364 const ArchSpec * m_arch_ptr;
365 const lldb_private::UUID * m_uuid_ptr;
366 const ConstString * m_object_name;
Greg Clayton24bc5d92011-03-30 18:16:51 +0000367 bool m_file_spec_compare_basename_only;
368 bool m_file_spec_is_platform;
Chris Lattner24943d22010-06-08 16:52:24 +0000369};
370
371size_t
372ModuleList::FindModules
373(
374 const FileSpec *file_spec_ptr,
375 const ArchSpec *arch_ptr,
Greg Clayton0467c782011-02-04 18:53:10 +0000376 const lldb_private::UUID *uuid_ptr,
Chris Lattner24943d22010-06-08 16:52:24 +0000377 const ConstString *object_name,
378 ModuleList& matching_module_list
379) const
380{
381 size_t existing_matches = matching_module_list.GetSize();
Greg Clayton24bc5d92011-03-30 18:16:51 +0000382 ModuleMatches matcher (file_spec_ptr, arch_ptr, uuid_ptr, object_name, false);
Chris Lattner24943d22010-06-08 16:52:24 +0000383
384 Mutex::Locker locker(m_modules_mutex);
385 collection::const_iterator end = m_modules.end();
386 collection::const_iterator pos;
387
388 for (pos = std::find_if (m_modules.begin(), end, matcher);
389 pos != end;
390 pos = std::find_if (++pos, end, matcher))
391 {
392 ModuleSP module_sp(*pos);
393 matching_module_list.Append(module_sp);
394 }
395 return matching_module_list.GetSize() - existing_matches;
396}
397
398ModuleSP
Greg Claytonb04e7a82010-08-24 21:05:24 +0000399ModuleList::FindModule (const Module *module_ptr)
Chris Lattner24943d22010-06-08 16:52:24 +0000400{
401 ModuleSP module_sp;
402
403 // Scope for "locker"
404 {
405 Mutex::Locker locker(m_modules_mutex);
406 collection::const_iterator pos, end = m_modules.end();
407
408 for (pos = m_modules.begin(); pos != end; ++pos)
409 {
410 if ((*pos).get() == module_ptr)
411 {
412 module_sp = (*pos);
413 break;
414 }
415 }
416 }
417 return module_sp;
418
419}
420
Greg Clayton24bc5d92011-03-30 18:16:51 +0000421ModuleSP
422ModuleList::FindModule (const UUID &uuid)
423{
424 ModuleSP module_sp;
425
426 if (uuid.IsValid())
427 {
428 Mutex::Locker locker(m_modules_mutex);
429 collection::const_iterator pos, end = m_modules.end();
430
431 for (pos = m_modules.begin(); pos != end; ++pos)
432 {
433 if ((*pos)->GetUUID() == uuid)
434 {
435 module_sp = (*pos);
436 break;
437 }
438 }
439 }
440 return module_sp;
441}
442
Chris Lattner24943d22010-06-08 16:52:24 +0000443
Greg Clayton7aff9ff2010-08-03 01:26:16 +0000444uint32_t
Jim Inghama334c9d2012-01-12 22:35:29 +0000445ModuleList::FindTypes (const SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, TypeList& types)
Greg Clayton7aff9ff2010-08-03 01:26:16 +0000446{
447 Mutex::Locker locker(m_modules_mutex);
448
449 if (!append)
450 types.Clear();
451
452 uint32_t total_matches = 0;
453 collection::const_iterator pos, end = m_modules.end();
454 for (pos = m_modules.begin(); pos != end; ++pos)
455 {
456 if (sc.module_sp.get() == NULL || sc.module_sp.get() == (*pos).get())
Sean Callanan3e80cd92011-10-12 02:08:07 +0000457 total_matches += (*pos)->FindTypes (sc, name, NULL, true, max_matches, types);
Greg Clayton7aff9ff2010-08-03 01:26:16 +0000458
459 if (total_matches >= max_matches)
460 break;
461 }
462 return total_matches;
463}
464
Chris Lattner24943d22010-06-08 16:52:24 +0000465ModuleSP
Greg Clayton24bc5d92011-03-30 18:16:51 +0000466ModuleList::FindFirstModuleForFileSpec (const FileSpec &file_spec,
467 const ArchSpec *arch_ptr,
468 const ConstString *object_name)
Chris Lattner24943d22010-06-08 16:52:24 +0000469{
470 ModuleSP module_sp;
Greg Clayton24bc5d92011-03-30 18:16:51 +0000471 ModuleMatches matcher (&file_spec,
472 arch_ptr,
473 NULL,
474 object_name,
475 false);
Chris Lattner24943d22010-06-08 16:52:24 +0000476
477 // Scope for "locker"
478 {
479 Mutex::Locker locker(m_modules_mutex);
480 collection::const_iterator end = m_modules.end();
481 collection::const_iterator pos = m_modules.begin();
482
483 pos = std::find_if (pos, end, matcher);
484 if (pos != end)
485 module_sp = (*pos);
486 }
487 return module_sp;
488
489}
490
Greg Clayton24bc5d92011-03-30 18:16:51 +0000491ModuleSP
492ModuleList::FindFirstModuleForPlatormFileSpec (const FileSpec &file_spec,
493 const ArchSpec *arch_ptr,
494 const ConstString *object_name)
495{
496 ModuleSP module_sp;
497 ModuleMatches matcher (&file_spec,
498 arch_ptr,
499 NULL,
500 object_name,
501 true);
502
503 // Scope for "locker"
504 {
505 Mutex::Locker locker(m_modules_mutex);
506 collection::const_iterator end = m_modules.end();
507 collection::const_iterator pos = m_modules.begin();
508
509 pos = std::find_if (pos, end, matcher);
510 if (pos != end)
511 module_sp = (*pos);
512 }
513 return module_sp;
514
515}
516
Chris Lattner24943d22010-06-08 16:52:24 +0000517
518size_t
519ModuleList::GetSize() const
520{
521 size_t size = 0;
522 {
523 Mutex::Locker locker(m_modules_mutex);
524 size = m_modules.size();
525 }
526 return size;
527}
528
529
530void
531ModuleList::Dump(Stream *s) const
532{
533// s.Printf("%.*p: ", (int)sizeof(void*) * 2, this);
534// s.Indent();
535// s << "ModuleList\n";
536
537 Mutex::Locker locker(m_modules_mutex);
538 collection::const_iterator pos, end = m_modules.end();
539 for (pos = m_modules.begin(); pos != end; ++pos)
540 {
541 (*pos)->Dump(s);
542 }
543}
544
Greg Clayton427f2902010-12-14 02:59:59 +0000545void
546ModuleList::LogUUIDAndPaths (LogSP &log_sp, const char *prefix_cstr)
547{
548 if (log_sp)
549 {
550 Mutex::Locker locker(m_modules_mutex);
551 char uuid_cstr[256];
552 collection::const_iterator pos, begin = m_modules.begin(), end = m_modules.end();
553 for (pos = begin; pos != end; ++pos)
554 {
555 Module *module = pos->get();
556 module->GetUUID().GetAsCString (uuid_cstr, sizeof(uuid_cstr));
557 const FileSpec &module_file_spec = module->GetFileSpec();
558 log_sp->Printf ("%s[%u] %s (%s) \"%s/%s\"",
559 prefix_cstr ? prefix_cstr : "",
560 (uint32_t)std::distance (begin, pos),
561 uuid_cstr,
Greg Clayton940b1032011-02-23 00:35:02 +0000562 module->GetArchitecture().GetArchitectureName(),
Greg Clayton427f2902010-12-14 02:59:59 +0000563 module_file_spec.GetDirectory().GetCString(),
564 module_file_spec.GetFilename().GetCString());
565 }
566 }
567}
Chris Lattner24943d22010-06-08 16:52:24 +0000568
569bool
570ModuleList::ResolveFileAddress (lldb::addr_t vm_addr, Address& so_addr)
571{
572 Mutex::Locker locker(m_modules_mutex);
573 collection::const_iterator pos, end = m_modules.end();
574 for (pos = m_modules.begin(); pos != end; ++pos)
575 {
576 if ((*pos)->ResolveFileAddress (vm_addr, so_addr))
577 return true;
578 }
579
580 return false;
581}
582
583uint32_t
584ModuleList::ResolveSymbolContextForAddress (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
585{
586 // The address is already section offset so it has a module
587 uint32_t resolved_flags = 0;
Greg Clayton13d24fb2012-01-29 20:56:30 +0000588 Module *module = so_addr.GetModulePtr();
Chris Lattner24943d22010-06-08 16:52:24 +0000589 if (module)
590 {
591 resolved_flags = module->ResolveSymbolContextForAddress (so_addr,
592 resolve_scope,
593 sc);
594 }
595 else
596 {
597 Mutex::Locker locker(m_modules_mutex);
598 collection::const_iterator pos, end = m_modules.end();
599 for (pos = m_modules.begin(); pos != end; ++pos)
600 {
601 resolved_flags = (*pos)->ResolveSymbolContextForAddress (so_addr,
602 resolve_scope,
603 sc);
604 if (resolved_flags != 0)
605 break;
606 }
607 }
608
609 return resolved_flags;
610}
611
612uint32_t
Greg Clayton537a7a82010-10-20 20:54:39 +0000613ModuleList::ResolveSymbolContextForFilePath
614(
615 const char *file_path,
616 uint32_t line,
617 bool check_inlines,
618 uint32_t resolve_scope,
619 SymbolContextList& sc_list
620)
Chris Lattner24943d22010-06-08 16:52:24 +0000621{
Greg Clayton537a7a82010-10-20 20:54:39 +0000622 FileSpec file_spec(file_path, false);
Chris Lattner24943d22010-06-08 16:52:24 +0000623 return ResolveSymbolContextsForFileSpec (file_spec, line, check_inlines, resolve_scope, sc_list);
624}
625
626uint32_t
627ModuleList::ResolveSymbolContextsForFileSpec (const FileSpec &file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
628{
629 Mutex::Locker locker(m_modules_mutex);
630 collection::const_iterator pos, end = m_modules.end();
631 for (pos = m_modules.begin(); pos != end; ++pos)
632 {
633 (*pos)->ResolveSymbolContextsForFileSpec (file_spec, line, check_inlines, resolve_scope, sc_list);
634 }
635
636 return sc_list.GetSize();
637}
638
639uint32_t
640ModuleList::GetIndexForModule (const Module *module) const
641{
642 if (module)
643 {
644 Mutex::Locker locker(m_modules_mutex);
645 collection::const_iterator pos;
646 collection::const_iterator begin = m_modules.begin();
647 collection::const_iterator end = m_modules.end();
648 for (pos = begin; pos != end; ++pos)
649 {
650 if ((*pos).get() == module)
651 return std::distance (begin, pos);
652 }
653 }
654 return LLDB_INVALID_INDEX32;
655}
656
657static ModuleList &
658GetSharedModuleList ()
659{
660 static ModuleList g_shared_module_list;
661 return g_shared_module_list;
662}
663
Greg Clayton08205a62012-01-27 18:45:39 +0000664bool
665ModuleList::ModuleIsInCache (const Module *module_ptr)
Chris Lattner24943d22010-06-08 16:52:24 +0000666{
Chris Lattner24943d22010-06-08 16:52:24 +0000667 if (module_ptr)
668 {
669 ModuleList &shared_module_list = GetSharedModuleList ();
Greg Clayton08205a62012-01-27 18:45:39 +0000670 return shared_module_list.FindModule (module_ptr).get() != NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000671 }
Greg Clayton08205a62012-01-27 18:45:39 +0000672 return false;
Chris Lattner24943d22010-06-08 16:52:24 +0000673}
674
Greg Clayton661825b2010-06-28 23:51:11 +0000675size_t
676ModuleList::FindSharedModules
677(
678 const FileSpec& in_file_spec,
679 const ArchSpec& arch,
Greg Clayton0467c782011-02-04 18:53:10 +0000680 const lldb_private::UUID *uuid_ptr,
Greg Clayton661825b2010-06-28 23:51:11 +0000681 const ConstString *object_name_ptr,
682 ModuleList &matching_module_list
683)
684{
685 ModuleList &shared_module_list = GetSharedModuleList ();
Greg Clayton661825b2010-06-28 23:51:11 +0000686 return shared_module_list.FindModules (&in_file_spec, &arch, uuid_ptr, object_name_ptr, matching_module_list);
687}
Chris Lattner24943d22010-06-08 16:52:24 +0000688
Greg Clayton5beb99d2011-08-11 02:48:45 +0000689uint32_t
690ModuleList::RemoveOrphanSharedModules ()
691{
692 return GetSharedModuleList ().RemoveOrphans();
693}
Greg Claytonc51ffbf2011-08-12 21:40:01 +0000694//#define ENABLE_MODULE_SP_LOGGING
695#if defined (ENABLE_MODULE_SP_LOGGING)
696#include "lldb/Core/StreamFile.h"
697#include "lldb/Host/Host.h"
698static void
699ModuleSharedPtrLogger(void* p, const ModuleSP& sp, bool will_decrement)
700{
701 if (sp.get())
702 {
703 const char *module_basename = sp->GetFileSpec().GetFilename().GetCString();
704 // If "p" is set, then it is the basename of a module to watch for. This
705 // basename MUST be uniqued first by getting it from a ConstString or this
706 // won't work.
707 if (p && p != module_basename)
708 {
709 return;
710 }
711 long use_count = sp.use_count();
712 if (will_decrement)
713 --use_count;
714
715 printf("\nModuleSP(%p): %c %p {%lu} %s/%s\n", &sp, will_decrement ? '-' : '+', sp.get(), use_count, sp->GetFileSpec().GetDirectory().GetCString(), module_basename);
716 StreamFile stdout_strm(stdout, false);
717 Host::Backtrace (stdout_strm, 512);
718 }
719}
720#endif
Greg Clayton5beb99d2011-08-11 02:48:45 +0000721
Chris Lattner24943d22010-06-08 16:52:24 +0000722Error
723ModuleList::GetSharedModule
724(
725 const FileSpec& in_file_spec,
726 const ArchSpec& arch,
Greg Clayton0467c782011-02-04 18:53:10 +0000727 const lldb_private::UUID *uuid_ptr,
Chris Lattner24943d22010-06-08 16:52:24 +0000728 const ConstString *object_name_ptr,
729 off_t object_offset,
730 ModuleSP &module_sp,
731 ModuleSP *old_module_sp_ptr,
Greg Claytondd506e12011-03-15 03:56:33 +0000732 bool *did_create_ptr,
733 bool always_create
Chris Lattner24943d22010-06-08 16:52:24 +0000734)
735{
736 ModuleList &shared_module_list = GetSharedModuleList ();
Greg Claytondd506e12011-03-15 03:56:33 +0000737 Mutex::Locker locker(shared_module_list.m_modules_mutex);
Chris Lattner24943d22010-06-08 16:52:24 +0000738 char path[PATH_MAX];
739 char uuid_cstr[64];
740
741 Error error;
742
743 module_sp.reset();
744
745 if (did_create_ptr)
746 *did_create_ptr = false;
747 if (old_module_sp_ptr)
748 old_module_sp_ptr->reset();
749
750
751 // First just try and get the file where it purports to be (path in
752 // in_file_spec), then check and uuid.
753
754 if (in_file_spec)
755 {
756 // Make sure no one else can try and get or create a module while this
757 // function is actively working on it by doing an extra lock on the
758 // global mutex list.
Greg Claytondd506e12011-03-15 03:56:33 +0000759 if (always_create == false)
Chris Lattner24943d22010-06-08 16:52:24 +0000760 {
Greg Claytondd506e12011-03-15 03:56:33 +0000761 ModuleList matching_module_list;
762 const size_t num_matching_modules = shared_module_list.FindModules (&in_file_spec, &arch, NULL, object_name_ptr, matching_module_list);
763 if (num_matching_modules > 0)
Chris Lattner24943d22010-06-08 16:52:24 +0000764 {
Greg Claytondd506e12011-03-15 03:56:33 +0000765 for (uint32_t module_idx = 0; module_idx < num_matching_modules; ++module_idx)
Chris Lattner24943d22010-06-08 16:52:24 +0000766 {
Greg Claytondd506e12011-03-15 03:56:33 +0000767 module_sp = matching_module_list.GetModuleAtIndex(module_idx);
768 if (uuid_ptr && uuid_ptr->IsValid())
Chris Lattner24943d22010-06-08 16:52:24 +0000769 {
Greg Claytondd506e12011-03-15 03:56:33 +0000770 // We found the module we were looking for.
771 if (module_sp->GetUUID() == *uuid_ptr)
772 return error;
Chris Lattner24943d22010-06-08 16:52:24 +0000773 }
Greg Claytondd506e12011-03-15 03:56:33 +0000774 else
775 {
776 // If we didn't have a UUID in mind when looking for the object file,
777 // then we should make sure the modification time hasn't changed!
778 TimeValue file_spec_mod_time(in_file_spec.GetModificationTime());
779 if (file_spec_mod_time.IsValid())
780 {
781 if (file_spec_mod_time == module_sp->GetModificationTime())
782 return error;
783 }
784 }
785 if (old_module_sp_ptr && !old_module_sp_ptr->get())
786 *old_module_sp_ptr = module_sp;
787 shared_module_list.Remove (module_sp);
788 module_sp.reset();
Chris Lattner24943d22010-06-08 16:52:24 +0000789 }
790 }
791 }
792
Greg Claytondd506e12011-03-15 03:56:33 +0000793 if (module_sp)
794 return error;
795 else
Chris Lattner24943d22010-06-08 16:52:24 +0000796 {
Greg Claytonc51ffbf2011-08-12 21:40:01 +0000797#if defined ENABLE_MODULE_SP_LOGGING
798 ModuleSP logging_module_sp (new Module (in_file_spec, arch, object_name_ptr, object_offset), ModuleSharedPtrLogger, (void *)ConstString("a.out").GetCString());
799 module_sp = logging_module_sp;
800#else
Chris Lattner24943d22010-06-08 16:52:24 +0000801 module_sp.reset (new Module (in_file_spec, arch, object_name_ptr, object_offset));
Greg Claytonc51ffbf2011-08-12 21:40:01 +0000802#endif
Greg Clayton153ccd72011-08-10 02:10:13 +0000803 // Make sure there are a module and an object file since we can specify
804 // a valid file path with an architecture that might not be in that file.
805 // By getting the object file we can guarantee that the architecture matches
806 if (module_sp && module_sp->GetObjectFile())
Chris Lattner24943d22010-06-08 16:52:24 +0000807 {
808 // If we get in here we got the correct arch, now we just need
809 // to verify the UUID if one was given
810 if (uuid_ptr && *uuid_ptr != module_sp->GetUUID())
811 module_sp.reset();
812 else
813 {
814 if (did_create_ptr)
815 *did_create_ptr = true;
Greg Clayton153ccd72011-08-10 02:10:13 +0000816
Chris Lattner24943d22010-06-08 16:52:24 +0000817 shared_module_list.Append(module_sp);
818 return error;
819 }
820 }
821 }
822 }
823
824 // Either the file didn't exist where at the path, or no path was given, so
825 // we now have to use more extreme measures to try and find the appropriate
826 // module.
827
828 // Fixup the incoming path in case the path points to a valid file, yet
829 // the arch or UUID (if one was passed in) don't match.
Greg Clayton0fa51242011-07-19 03:57:15 +0000830 FileSpec file_spec = Symbols::LocateExecutableObjectFile (in_file_spec ? &in_file_spec : NULL,
831 arch.IsValid() ? &arch : NULL,
832 uuid_ptr);
Chris Lattner24943d22010-06-08 16:52:24 +0000833
834 // Don't look for the file if it appears to be the same one we already
835 // checked for above...
836 if (file_spec != in_file_spec)
837 {
838 if (!file_spec.Exists())
839 {
840 file_spec.GetPath(path, sizeof(path));
Greg Claytondb2dc2b2012-01-12 05:25:17 +0000841 if (path[0] == '\0')
842 in_file_spec.GetPath(path, sizeof(path));
Chris Lattner24943d22010-06-08 16:52:24 +0000843 if (file_spec.Exists())
844 {
845 if (uuid_ptr && uuid_ptr->IsValid())
846 uuid_ptr->GetAsCString(uuid_cstr, sizeof (uuid_cstr));
847 else
848 uuid_cstr[0] = '\0';
849
850
851 if (arch.IsValid())
852 {
853 if (uuid_cstr[0])
Greg Clayton9c236732011-10-26 00:56:27 +0000854 error.SetErrorStringWithFormat("'%s' does not contain the %s architecture and UUID %s", path, arch.GetArchitectureName(), uuid_cstr);
Chris Lattner24943d22010-06-08 16:52:24 +0000855 else
Greg Clayton9c236732011-10-26 00:56:27 +0000856 error.SetErrorStringWithFormat("'%s' does not contain the %s architecture.", path, arch.GetArchitectureName());
Chris Lattner24943d22010-06-08 16:52:24 +0000857 }
858 }
859 else
860 {
Greg Clayton9c236732011-10-26 00:56:27 +0000861 error.SetErrorStringWithFormat("'%s' does not exist", path);
Chris Lattner24943d22010-06-08 16:52:24 +0000862 }
Greg Claytonb5a8f142012-02-05 02:38:54 +0000863 if (error.Fail())
864 module_sp.reset();
Chris Lattner24943d22010-06-08 16:52:24 +0000865 return error;
866 }
867
868
869 // Make sure no one else can try and get or create a module while this
870 // function is actively working on it by doing an extra lock on the
871 // global mutex list.
Chris Lattner24943d22010-06-08 16:52:24 +0000872 ModuleList matching_module_list;
873 if (shared_module_list.FindModules (&file_spec, &arch, uuid_ptr, object_name_ptr, matching_module_list) > 0)
874 {
875 module_sp = matching_module_list.GetModuleAtIndex(0);
876
877 // If we didn't have a UUID in mind when looking for the object file,
878 // then we should make sure the modification time hasn't changed!
879 if (uuid_ptr == NULL)
880 {
881 TimeValue file_spec_mod_time(file_spec.GetModificationTime());
882 if (file_spec_mod_time.IsValid())
883 {
884 if (file_spec_mod_time != module_sp->GetModificationTime())
885 {
886 if (old_module_sp_ptr)
887 *old_module_sp_ptr = module_sp;
888 shared_module_list.Remove (module_sp);
889 module_sp.reset();
890 }
891 }
892 }
893 }
894
895 if (module_sp.get() == NULL)
896 {
Greg Claytonc51ffbf2011-08-12 21:40:01 +0000897#if defined ENABLE_MODULE_SP_LOGGING
898 ModuleSP logging_module_sp (new Module (file_spec, arch, object_name_ptr, object_offset), ModuleSharedPtrLogger, 0);
899 module_sp = logging_module_sp;
900#else
Chris Lattner24943d22010-06-08 16:52:24 +0000901 module_sp.reset (new Module (file_spec, arch, object_name_ptr, object_offset));
Greg Claytonc51ffbf2011-08-12 21:40:01 +0000902#endif
Greg Clayton153ccd72011-08-10 02:10:13 +0000903 // Make sure there are a module and an object file since we can specify
904 // a valid file path with an architecture that might not be in that file.
905 // By getting the object file we can guarantee that the architecture matches
906 if (module_sp && module_sp->GetObjectFile())
Chris Lattner24943d22010-06-08 16:52:24 +0000907 {
908 if (did_create_ptr)
909 *did_create_ptr = true;
910
911 shared_module_list.Append(module_sp);
912 }
913 else
914 {
915 file_spec.GetPath(path, sizeof(path));
916
917 if (file_spec)
918 {
919 if (arch.IsValid())
Greg Clayton9c236732011-10-26 00:56:27 +0000920 error.SetErrorStringWithFormat("unable to open %s architecture in '%s'", arch.GetArchitectureName(), path);
Chris Lattner24943d22010-06-08 16:52:24 +0000921 else
Greg Clayton9c236732011-10-26 00:56:27 +0000922 error.SetErrorStringWithFormat("unable to open '%s'", path);
Chris Lattner24943d22010-06-08 16:52:24 +0000923 }
924 else
925 {
926 if (uuid_ptr && uuid_ptr->IsValid())
927 uuid_ptr->GetAsCString(uuid_cstr, sizeof (uuid_cstr));
928 else
929 uuid_cstr[0] = '\0';
930
931 if (uuid_cstr[0])
Greg Clayton9c236732011-10-26 00:56:27 +0000932 error.SetErrorStringWithFormat("cannot locate a module for UUID '%s'", uuid_cstr);
Chris Lattner24943d22010-06-08 16:52:24 +0000933 else
Greg Clayton9c236732011-10-26 00:56:27 +0000934 error.SetErrorStringWithFormat("cannot locate a module");
Chris Lattner24943d22010-06-08 16:52:24 +0000935 }
936 }
937 }
938 }
939
940 return error;
941}
942
Greg Claytondd506e12011-03-15 03:56:33 +0000943bool
944ModuleList::RemoveSharedModule (lldb::ModuleSP &module_sp)
945{
946 return GetSharedModuleList ().Remove (module_sp);
947}
948
949