1 //===-- 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
16 #include "lldb/Core/Log.h"
17 #include "lldb/Core/Module.h"
18 #include "lldb/Host/Symbols.h"
19 #include "lldb/Symbol/ClangNamespaceDecl.h"
20 #include "lldb/Symbol/ObjectFile.h"
21 #include "lldb/Symbol/VariableList.h"
22 
23 using namespace lldb;
24 using namespace lldb_private;
25 
26 //----------------------------------------------------------------------
27 // ModuleList constructor
28 //----------------------------------------------------------------------
29 ModuleList::ModuleList() :
30     m_modules(),
31     m_modules_mutex (Mutex::eMutexTypeRecursive)
32 {
33 }
34 
35 //----------------------------------------------------------------------
36 // Copy constructor
37 //----------------------------------------------------------------------
38 ModuleList::ModuleList(const ModuleList& rhs) :
39     m_modules(rhs.m_modules)
40 {
41 }
42 
43 //----------------------------------------------------------------------
44 // Assignment operator
45 //----------------------------------------------------------------------
46 const ModuleList&
47 ModuleList::operator= (const ModuleList& rhs)
48 {
49     if (this != &rhs)
50     {
51         Mutex::Locker locker(m_modules_mutex);
52         m_modules = rhs.m_modules;
53     }
54     return *this;
55 }
56 
57 //----------------------------------------------------------------------
58 // Destructor
59 //----------------------------------------------------------------------
60 ModuleList::~ModuleList()
61 {
62 }
63 
64 void
65 ModuleList::Append (const ModuleSP &module_sp)
66 {
67     if (module_sp)
68     {
69         Mutex::Locker locker(m_modules_mutex);
70         m_modules.push_back(module_sp);
71     }
72 }
73 
74 bool
75 ModuleList::AppendIfNeeded (const ModuleSP &module_sp)
76 {
77     if (module_sp)
78     {
79         Mutex::Locker locker(m_modules_mutex);
80         collection::iterator pos, end = m_modules.end();
81         for (pos = m_modules.begin(); pos != end; ++pos)
82         {
83             if (pos->get() == module_sp.get())
84                 return false; // Already in the list
85         }
86         // Only push module_sp on the list if it wasn't already in there.
87         m_modules.push_back(module_sp);
88         return true;
89     }
90     return false;
91 }
92 
93 bool
94 ModuleList::Remove (const ModuleSP &module_sp)
95 {
96     if (module_sp)
97     {
98         Mutex::Locker locker(m_modules_mutex);
99         collection::iterator pos, end = m_modules.end();
100         for (pos = m_modules.begin(); pos != end; ++pos)
101         {
102             if (pos->get() == module_sp.get())
103             {
104                 m_modules.erase (pos);
105                 return true;
106             }
107         }
108     }
109     return false;
110 }
111 
112 
113 size_t
114 ModuleList::RemoveOrphans ()
115 {
116     Mutex::Locker locker(m_modules_mutex);
117     collection::iterator pos = m_modules.begin();
118     size_t remove_count = 0;
119     while (pos != m_modules.end())
120     {
121         if (pos->unique())
122         {
123             pos = m_modules.erase (pos);
124             ++remove_count;
125         }
126         else
127         {
128             ++pos;
129         }
130     }
131     return remove_count;
132 }
133 
134 size_t
135 ModuleList::Remove (ModuleList &module_list)
136 {
137     Mutex::Locker locker(m_modules_mutex);
138     size_t num_removed = 0;
139     collection::iterator pos, end = module_list.m_modules.end();
140     for (pos = module_list.m_modules.begin(); pos != end; ++pos)
141     {
142         if (Remove (*pos))
143             ++num_removed;
144     }
145     return num_removed;
146 }
147 
148 
149 
150 void
151 ModuleList::Clear()
152 {
153     Mutex::Locker locker(m_modules_mutex);
154     m_modules.clear();
155 }
156 
157 Module*
158 ModuleList::GetModulePointerAtIndex (uint32_t idx) const
159 {
160     Mutex::Locker locker(m_modules_mutex);
161     if (idx < m_modules.size())
162         return m_modules[idx].get();
163     return NULL;
164 }
165 
166 ModuleSP
167 ModuleList::GetModuleAtIndex(uint32_t idx)
168 {
169     Mutex::Locker locker(m_modules_mutex);
170     ModuleSP module_sp;
171     if (idx < m_modules.size())
172         module_sp = m_modules[idx];
173     return module_sp;
174 }
175 
176 uint32_t
177 ModuleList::FindFunctions (const ConstString &name,
178                            uint32_t name_type_mask,
179                            bool include_symbols,
180                            bool append,
181                            SymbolContextList &sc_list)
182 {
183     if (!append)
184         sc_list.Clear();
185 
186     Mutex::Locker locker(m_modules_mutex);
187     collection::const_iterator pos, end = m_modules.end();
188     for (pos = m_modules.begin(); pos != end; ++pos)
189     {
190         (*pos)->FindFunctions (name, NULL, name_type_mask, include_symbols, true, sc_list);
191     }
192 
193     return sc_list.GetSize();
194 }
195 
196 uint32_t
197 ModuleList::FindCompileUnits (const FileSpec &path,
198                               bool append,
199                               SymbolContextList &sc_list)
200 {
201     if (!append)
202         sc_list.Clear();
203 
204     Mutex::Locker locker(m_modules_mutex);
205     collection::const_iterator pos, end = m_modules.end();
206     for (pos = m_modules.begin(); pos != end; ++pos)
207     {
208         (*pos)->FindCompileUnits (path, true, sc_list);
209     }
210 
211     return sc_list.GetSize();
212 }
213 
214 uint32_t
215 ModuleList::FindGlobalVariables (const ConstString &name,
216                                  bool append,
217                                  uint32_t max_matches,
218                                  VariableList& variable_list)
219 {
220     size_t initial_size = variable_list.GetSize();
221     Mutex::Locker locker(m_modules_mutex);
222     collection::iterator pos, end = m_modules.end();
223     for (pos = m_modules.begin(); pos != end; ++pos)
224     {
225         (*pos)->FindGlobalVariables (name, NULL, append, max_matches, variable_list);
226     }
227     return variable_list.GetSize() - initial_size;
228 }
229 
230 
231 uint32_t
232 ModuleList::FindGlobalVariables (const RegularExpression& regex,
233                                  bool append,
234                                  uint32_t max_matches,
235                                  VariableList& variable_list)
236 {
237     size_t initial_size = variable_list.GetSize();
238     Mutex::Locker locker(m_modules_mutex);
239     collection::iterator pos, end = m_modules.end();
240     for (pos = m_modules.begin(); pos != end; ++pos)
241     {
242         (*pos)->FindGlobalVariables (regex, append, max_matches, variable_list);
243     }
244     return variable_list.GetSize() - initial_size;
245 }
246 
247 
248 size_t
249 ModuleList::FindSymbolsWithNameAndType (const ConstString &name,
250                                         SymbolType symbol_type,
251                                         SymbolContextList &sc_list)
252 {
253     Mutex::Locker locker(m_modules_mutex);
254     sc_list.Clear();
255     collection::iterator pos, end = m_modules.end();
256     for (pos = m_modules.begin(); pos != end; ++pos)
257         (*pos)->FindSymbolsWithNameAndType (name, NULL, symbol_type, sc_list);
258     return sc_list.GetSize();
259 }
260 
261 class ModuleMatches
262 {
263 public:
264     //--------------------------------------------------------------
265     /// Construct with the user ID to look for.
266     //--------------------------------------------------------------
267     ModuleMatches (const FileSpec *file_spec_ptr,
268                    const ArchSpec *arch_ptr,
269                    const lldb_private::UUID *uuid_ptr,
270                    const ConstString *object_name,
271                    bool file_spec_is_platform) :
272         m_file_spec_ptr (file_spec_ptr),
273         m_arch_ptr (arch_ptr),
274         m_uuid_ptr (uuid_ptr),
275         m_object_name (object_name),
276         m_file_spec_compare_basename_only (false),
277         m_file_spec_is_platform (file_spec_is_platform)
278     {
279         if (file_spec_ptr)
280             m_file_spec_compare_basename_only = file_spec_ptr->GetDirectory();
281     }
282 
283 
284     //--------------------------------------------------------------
285     /// Unary predicate function object callback.
286     //--------------------------------------------------------------
287     bool
288     operator () (const ModuleSP& module_sp) const
289     {
290         if (m_file_spec_ptr)
291         {
292             if (m_file_spec_is_platform)
293             {
294                 if (!FileSpec::Equal (*m_file_spec_ptr,
295                                       module_sp->GetPlatformFileSpec(),
296                                       m_file_spec_compare_basename_only))
297                     return false;
298 
299             }
300             else
301             {
302                 if (!FileSpec::Equal (*m_file_spec_ptr,
303                                       module_sp->GetFileSpec(),
304                                       m_file_spec_compare_basename_only))
305                     return false;
306             }
307         }
308 
309         if (m_arch_ptr && m_arch_ptr->IsValid())
310         {
311             if (module_sp->GetArchitecture() != *m_arch_ptr)
312                 return false;
313         }
314 
315         if (m_uuid_ptr && m_uuid_ptr->IsValid())
316         {
317             if (module_sp->GetUUID() != *m_uuid_ptr)
318                 return false;
319         }
320 
321         if (m_object_name)
322         {
323             if (module_sp->GetObjectName() != *m_object_name)
324                 return false;
325         }
326         return true;
327     }
328 
329 private:
330     //--------------------------------------------------------------
331     // Member variables.
332     //--------------------------------------------------------------
333     const FileSpec *            m_file_spec_ptr;
334     const ArchSpec *            m_arch_ptr;
335     const lldb_private::UUID *  m_uuid_ptr;
336     const ConstString *         m_object_name;
337     bool                        m_file_spec_compare_basename_only;
338     bool                        m_file_spec_is_platform;
339 };
340 
341 size_t
342 ModuleList::FindModules
343 (
344     const FileSpec *file_spec_ptr,
345     const ArchSpec *arch_ptr,
346     const lldb_private::UUID *uuid_ptr,
347     const ConstString *object_name,
348     ModuleList& matching_module_list
349 ) const
350 {
351     size_t existing_matches = matching_module_list.GetSize();
352     ModuleMatches matcher (file_spec_ptr, arch_ptr, uuid_ptr, object_name, false);
353 
354     Mutex::Locker locker(m_modules_mutex);
355     collection::const_iterator end = m_modules.end();
356     collection::const_iterator pos;
357 
358     for (pos = std::find_if (m_modules.begin(), end, matcher);
359          pos != end;
360          pos = std::find_if (++pos, end, matcher))
361     {
362         ModuleSP module_sp(*pos);
363         matching_module_list.Append(module_sp);
364     }
365     return matching_module_list.GetSize() - existing_matches;
366 }
367 
368 ModuleSP
369 ModuleList::FindModule (const Module *module_ptr)
370 {
371     ModuleSP module_sp;
372 
373     // Scope for "locker"
374     {
375         Mutex::Locker locker(m_modules_mutex);
376         collection::const_iterator pos, end = m_modules.end();
377 
378         for (pos = m_modules.begin(); pos != end; ++pos)
379         {
380             if ((*pos).get() == module_ptr)
381             {
382                 module_sp = (*pos);
383                 break;
384             }
385         }
386     }
387     return module_sp;
388 
389 }
390 
391 ModuleSP
392 ModuleList::FindModule (const UUID &uuid)
393 {
394     ModuleSP module_sp;
395 
396     if (uuid.IsValid())
397     {
398         Mutex::Locker locker(m_modules_mutex);
399         collection::const_iterator pos, end = m_modules.end();
400 
401         for (pos = m_modules.begin(); pos != end; ++pos)
402         {
403             if ((*pos)->GetUUID() == uuid)
404             {
405                 module_sp = (*pos);
406                 break;
407             }
408         }
409     }
410     return module_sp;
411 }
412 
413 
414 uint32_t
415 ModuleList::FindTypes_Impl (const SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, TypeList& types)
416 {
417     Mutex::Locker locker(m_modules_mutex);
418 
419     if (!append)
420         types.Clear();
421 
422     uint32_t total_matches = 0;
423     collection::const_iterator pos, end = m_modules.end();
424     for (pos = m_modules.begin(); pos != end; ++pos)
425     {
426         if (sc.module_sp.get() == NULL || sc.module_sp.get() == (*pos).get())
427             total_matches += (*pos)->FindTypes (sc, name, NULL, true, max_matches, types);
428 
429         if (total_matches >= max_matches)
430             break;
431     }
432     return total_matches;
433 }
434 
435 // depending on implementation details, type lookup might fail because of
436 // embedded spurious namespace:: prefixes. this call strips them, paying
437 // attention to the fact that a type might have namespace'd type names as
438 // arguments to templates, and those must not be stripped off
439 static const char*
440 StripTypeName(const char* name_cstr)
441 {
442     const char* skip_namespace = strstr(name_cstr, "::");
443     const char* template_arg_char = strchr(name_cstr, '<');
444     while (skip_namespace != NULL)
445     {
446         if (template_arg_char != NULL &&
447             skip_namespace > template_arg_char) // but namespace'd template arguments are still good to go
448             break;
449         name_cstr = skip_namespace+2;
450         skip_namespace = strstr(name_cstr, "::");
451     }
452     return name_cstr;
453 }
454 
455 uint32_t
456 ModuleList::FindTypes (const SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, TypeList& types)
457 {
458     uint32_t retval = FindTypes_Impl(sc, name, append, max_matches, types);
459 
460     if (retval == 0)
461     {
462         const char *stripped = StripTypeName(name.GetCString());
463         return FindTypes_Impl(sc, ConstString(stripped), append, max_matches, types);
464     }
465     else
466         return retval;
467 
468 }
469 
470 ModuleSP
471 ModuleList::FindFirstModuleForFileSpec (const FileSpec &file_spec,
472                                         const ArchSpec *arch_ptr,
473                                         const ConstString *object_name)
474 {
475     ModuleSP module_sp;
476     ModuleMatches matcher (&file_spec,
477                            arch_ptr,
478                            NULL,
479                            object_name,
480                            false);
481 
482     // Scope for "locker"
483     {
484         Mutex::Locker locker(m_modules_mutex);
485         collection::const_iterator end = m_modules.end();
486         collection::const_iterator pos = m_modules.begin();
487 
488         pos = std::find_if (pos, end, matcher);
489         if (pos != end)
490             module_sp = (*pos);
491     }
492     return module_sp;
493 
494 }
495 
496 ModuleSP
497 ModuleList::FindFirstModuleForPlatormFileSpec (const FileSpec &file_spec,
498                                                const ArchSpec *arch_ptr,
499                                                const ConstString *object_name)
500 {
501     ModuleSP module_sp;
502     ModuleMatches matcher (&file_spec,
503                            arch_ptr,
504                            NULL,
505                            object_name,
506                            true);
507 
508     // Scope for "locker"
509     {
510         Mutex::Locker locker(m_modules_mutex);
511         collection::const_iterator end = m_modules.end();
512         collection::const_iterator pos = m_modules.begin();
513 
514         pos = std::find_if (pos, end, matcher);
515         if (pos != end)
516             module_sp = (*pos);
517     }
518     return module_sp;
519 
520 }
521 
522 
523 size_t
524 ModuleList::GetSize() const
525 {
526     size_t size = 0;
527     {
528         Mutex::Locker locker(m_modules_mutex);
529         size = m_modules.size();
530     }
531     return size;
532 }
533 
534 
535 void
536 ModuleList::Dump(Stream *s) const
537 {
538 //  s.Printf("%.*p: ", (int)sizeof(void*) * 2, this);
539 //  s.Indent();
540 //  s << "ModuleList\n";
541 
542     Mutex::Locker locker(m_modules_mutex);
543     collection::const_iterator pos, end = m_modules.end();
544     for (pos = m_modules.begin(); pos != end; ++pos)
545     {
546         (*pos)->Dump(s);
547     }
548 }
549 
550 void
551 ModuleList::LogUUIDAndPaths (LogSP &log_sp, const char *prefix_cstr)
552 {
553     if (log_sp)
554     {
555         Mutex::Locker locker(m_modules_mutex);
556         char uuid_cstr[256];
557         collection::const_iterator pos, begin = m_modules.begin(), end = m_modules.end();
558         for (pos = begin; pos != end; ++pos)
559         {
560             Module *module = pos->get();
561             module->GetUUID().GetAsCString (uuid_cstr, sizeof(uuid_cstr));
562             const FileSpec &module_file_spec = module->GetFileSpec();
563             log_sp->Printf ("%s[%u] %s (%s) \"%s/%s\"",
564                             prefix_cstr ? prefix_cstr : "",
565                             (uint32_t)std::distance (begin, pos),
566                             uuid_cstr,
567                             module->GetArchitecture().GetArchitectureName(),
568                             module_file_spec.GetDirectory().GetCString(),
569                             module_file_spec.GetFilename().GetCString());
570         }
571     }
572 }
573 
574 bool
575 ModuleList::ResolveFileAddress (lldb::addr_t vm_addr, Address& so_addr)
576 {
577     Mutex::Locker locker(m_modules_mutex);
578     collection::const_iterator pos, end = m_modules.end();
579     for (pos = m_modules.begin(); pos != end; ++pos)
580     {
581         if ((*pos)->ResolveFileAddress (vm_addr, so_addr))
582             return true;
583     }
584 
585     return false;
586 }
587 
588 uint32_t
589 ModuleList::ResolveSymbolContextForAddress (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
590 {
591     // The address is already section offset so it has a module
592     uint32_t resolved_flags = 0;
593     Module *module = so_addr.GetModule();
594     if (module)
595     {
596         resolved_flags = module->ResolveSymbolContextForAddress (so_addr,
597                                                                  resolve_scope,
598                                                                  sc);
599     }
600     else
601     {
602         Mutex::Locker locker(m_modules_mutex);
603         collection::const_iterator pos, end = m_modules.end();
604         for (pos = m_modules.begin(); pos != end; ++pos)
605         {
606             resolved_flags = (*pos)->ResolveSymbolContextForAddress (so_addr,
607                                                                      resolve_scope,
608                                                                      sc);
609             if (resolved_flags != 0)
610                 break;
611         }
612     }
613 
614     return resolved_flags;
615 }
616 
617 uint32_t
618 ModuleList::ResolveSymbolContextForFilePath
619 (
620     const char *file_path,
621     uint32_t line,
622     bool check_inlines,
623     uint32_t resolve_scope,
624     SymbolContextList& sc_list
625 )
626 {
627     FileSpec file_spec(file_path, false);
628     return ResolveSymbolContextsForFileSpec (file_spec, line, check_inlines, resolve_scope, sc_list);
629 }
630 
631 uint32_t
632 ModuleList::ResolveSymbolContextsForFileSpec (const FileSpec &file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
633 {
634     Mutex::Locker locker(m_modules_mutex);
635     collection::const_iterator pos, end = m_modules.end();
636     for (pos = m_modules.begin(); pos != end; ++pos)
637     {
638         (*pos)->ResolveSymbolContextsForFileSpec (file_spec, line, check_inlines, resolve_scope, sc_list);
639     }
640 
641     return sc_list.GetSize();
642 }
643 
644 uint32_t
645 ModuleList::GetIndexForModule (const Module *module) const
646 {
647     if (module)
648     {
649         Mutex::Locker locker(m_modules_mutex);
650         collection::const_iterator pos;
651         collection::const_iterator begin = m_modules.begin();
652         collection::const_iterator end = m_modules.end();
653         for (pos = begin; pos != end; ++pos)
654         {
655             if ((*pos).get() == module)
656                 return std::distance (begin, pos);
657         }
658     }
659     return LLDB_INVALID_INDEX32;
660 }
661 
662 static ModuleList &
663 GetSharedModuleList ()
664 {
665     static ModuleList g_shared_module_list;
666     return g_shared_module_list;
667 }
668 
669 const lldb::ModuleSP
670 ModuleList::GetModuleSP (const Module *module_ptr)
671 {
672     lldb::ModuleSP module_sp;
673     if (module_ptr)
674     {
675         ModuleList &shared_module_list = GetSharedModuleList ();
676         module_sp = shared_module_list.FindModule (module_ptr);
677         if (module_sp.get() == NULL)
678         {
679             char uuid_cstr[256];
680             const_cast<Module *>(module_ptr)->GetUUID().GetAsCString (uuid_cstr, sizeof(uuid_cstr));
681             const FileSpec &module_file_spec = module_ptr->GetFileSpec();
682             fprintf (stderr, "warning: module not in shared module list: %s (%s) \"%s/%s\"\n",
683                      uuid_cstr,
684                      module_ptr->GetArchitecture().GetArchitectureName(),
685                      module_file_spec.GetDirectory().GetCString(),
686                      module_file_spec.GetFilename().GetCString());
687         }
688     }
689     return module_sp;
690 }
691 
692 size_t
693 ModuleList::FindSharedModules
694 (
695     const FileSpec& in_file_spec,
696     const ArchSpec& arch,
697     const lldb_private::UUID *uuid_ptr,
698     const ConstString *object_name_ptr,
699     ModuleList &matching_module_list
700 )
701 {
702     ModuleList &shared_module_list = GetSharedModuleList ();
703     return shared_module_list.FindModules (&in_file_spec, &arch, uuid_ptr, object_name_ptr, matching_module_list);
704 }
705 
706 uint32_t
707 ModuleList::RemoveOrphanSharedModules ()
708 {
709     return GetSharedModuleList ().RemoveOrphans();
710 }
711 //#define ENABLE_MODULE_SP_LOGGING
712 #if defined (ENABLE_MODULE_SP_LOGGING)
713 #include "lldb/Core/StreamFile.h"
714 #include "lldb/Host/Host.h"
715 static void
716 ModuleSharedPtrLogger(void* p, const ModuleSP& sp, bool will_decrement)
717 {
718     if (sp.get())
719     {
720         const char *module_basename = sp->GetFileSpec().GetFilename().GetCString();
721         // If "p" is set, then it is the basename of a module to watch for. This
722         // basename MUST be uniqued first by getting it from a ConstString or this
723         // won't work.
724         if (p && p != module_basename)
725         {
726             return;
727         }
728         long use_count = sp.use_count();
729         if (will_decrement)
730             --use_count;
731 
732         printf("\nModuleSP(%p): %c %p {%lu} %s/%s\n", &sp, will_decrement ? '-' : '+', sp.get(), use_count, sp->GetFileSpec().GetDirectory().GetCString(), module_basename);
733         StreamFile stdout_strm(stdout, false);
734         Host::Backtrace (stdout_strm, 512);
735     }
736 }
737 #endif
738 
739 Error
740 ModuleList::GetSharedModule
741 (
742     const FileSpec& in_file_spec,
743     const ArchSpec& arch,
744     const lldb_private::UUID *uuid_ptr,
745     const ConstString *object_name_ptr,
746     off_t object_offset,
747     ModuleSP &module_sp,
748     ModuleSP *old_module_sp_ptr,
749     bool *did_create_ptr,
750     bool always_create
751 )
752 {
753     ModuleList &shared_module_list = GetSharedModuleList ();
754     Mutex::Locker locker(shared_module_list.m_modules_mutex);
755     char path[PATH_MAX];
756     char uuid_cstr[64];
757 
758     Error error;
759 
760     module_sp.reset();
761 
762     if (did_create_ptr)
763         *did_create_ptr = false;
764     if (old_module_sp_ptr)
765         old_module_sp_ptr->reset();
766 
767 
768     // First just try and get the file where it purports to be (path in
769     // in_file_spec), then check and uuid.
770 
771     if (in_file_spec)
772     {
773         // Make sure no one else can try and get or create a module while this
774         // function is actively working on it by doing an extra lock on the
775         // global mutex list.
776         if (always_create == false)
777         {
778             ModuleList matching_module_list;
779             const size_t num_matching_modules = shared_module_list.FindModules (&in_file_spec, &arch, NULL, object_name_ptr, matching_module_list);
780             if (num_matching_modules > 0)
781             {
782                 for (uint32_t module_idx = 0; module_idx < num_matching_modules; ++module_idx)
783                 {
784                     module_sp = matching_module_list.GetModuleAtIndex(module_idx);
785                     if (uuid_ptr && uuid_ptr->IsValid())
786                     {
787                         // We found the module we were looking for.
788                         if (module_sp->GetUUID() == *uuid_ptr)
789                             return error;
790                     }
791                     else
792                     {
793                         // If we didn't have a UUID in mind when looking for the object file,
794                         // then we should make sure the modification time hasn't changed!
795                         TimeValue file_spec_mod_time(in_file_spec.GetModificationTime());
796                         if (file_spec_mod_time.IsValid())
797                         {
798                             if (file_spec_mod_time == module_sp->GetModificationTime())
799                                 return error;
800                         }
801                     }
802                     if (old_module_sp_ptr && !old_module_sp_ptr->get())
803                         *old_module_sp_ptr = module_sp;
804                     shared_module_list.Remove (module_sp);
805                     module_sp.reset();
806                 }
807             }
808         }
809 
810         if (module_sp)
811             return error;
812         else
813         {
814 #if defined ENABLE_MODULE_SP_LOGGING
815             ModuleSP logging_module_sp (new Module (in_file_spec, arch, object_name_ptr, object_offset), ModuleSharedPtrLogger, (void *)ConstString("a.out").GetCString());
816             module_sp = logging_module_sp;
817 #else
818             module_sp.reset (new Module (in_file_spec, arch, object_name_ptr, object_offset));
819 #endif
820             // Make sure there are a module and an object file since we can specify
821             // a valid file path with an architecture that might not be in that file.
822             // By getting the object file we can guarantee that the architecture matches
823             if (module_sp && module_sp->GetObjectFile())
824             {
825                 // If we get in here we got the correct arch, now we just need
826                 // to verify the UUID if one was given
827                 if (uuid_ptr && *uuid_ptr != module_sp->GetUUID())
828                     module_sp.reset();
829                 else
830                 {
831                     if (did_create_ptr)
832                         *did_create_ptr = true;
833 
834                     shared_module_list.Append(module_sp);
835                     return error;
836                 }
837             }
838         }
839     }
840 
841     // Either the file didn't exist where at the path, or no path was given, so
842     // we now have to use more extreme measures to try and find the appropriate
843     // module.
844 
845     // Fixup the incoming path in case the path points to a valid file, yet
846     // the arch or UUID (if one was passed in) don't match.
847     FileSpec file_spec = Symbols::LocateExecutableObjectFile (in_file_spec ? &in_file_spec : NULL,
848                                                               arch.IsValid() ? &arch : NULL,
849                                                               uuid_ptr);
850 
851     // Don't look for the file if it appears to be the same one we already
852     // checked for above...
853     if (file_spec != in_file_spec)
854     {
855         if (!file_spec.Exists())
856         {
857             file_spec.GetPath(path, sizeof(path));
858             if (file_spec.Exists())
859             {
860                 if (uuid_ptr && uuid_ptr->IsValid())
861                     uuid_ptr->GetAsCString(uuid_cstr, sizeof (uuid_cstr));
862                 else
863                     uuid_cstr[0] = '\0';
864 
865 
866                 if (arch.IsValid())
867                 {
868                     if (uuid_cstr[0])
869                         error.SetErrorStringWithFormat("'%s' does not contain the %s architecture and UUID %s.\n", path, arch.GetArchitectureName(), uuid_cstr);
870                     else
871                         error.SetErrorStringWithFormat("'%s' does not contain the %s architecture.\n", path, arch.GetArchitectureName());
872                 }
873             }
874             else
875             {
876                 error.SetErrorStringWithFormat("'%s' does not exist.\n", path);
877             }
878             return error;
879         }
880 
881 
882         // Make sure no one else can try and get or create a module while this
883         // function is actively working on it by doing an extra lock on the
884         // global mutex list.
885         ModuleList matching_module_list;
886         if (shared_module_list.FindModules (&file_spec, &arch, uuid_ptr, object_name_ptr, matching_module_list) > 0)
887         {
888             module_sp = matching_module_list.GetModuleAtIndex(0);
889 
890             // If we didn't have a UUID in mind when looking for the object file,
891             // then we should make sure the modification time hasn't changed!
892             if (uuid_ptr == NULL)
893             {
894                 TimeValue file_spec_mod_time(file_spec.GetModificationTime());
895                 if (file_spec_mod_time.IsValid())
896                 {
897                     if (file_spec_mod_time != module_sp->GetModificationTime())
898                     {
899                         if (old_module_sp_ptr)
900                             *old_module_sp_ptr = module_sp;
901                         shared_module_list.Remove (module_sp);
902                         module_sp.reset();
903                     }
904                 }
905             }
906         }
907 
908         if (module_sp.get() == NULL)
909         {
910 #if defined ENABLE_MODULE_SP_LOGGING
911             ModuleSP logging_module_sp (new Module (file_spec, arch, object_name_ptr, object_offset), ModuleSharedPtrLogger, 0);
912             module_sp = logging_module_sp;
913 #else
914             module_sp.reset (new Module (file_spec, arch, object_name_ptr, object_offset));
915 #endif
916             // Make sure there are a module and an object file since we can specify
917             // a valid file path with an architecture that might not be in that file.
918             // By getting the object file we can guarantee that the architecture matches
919             if (module_sp && module_sp->GetObjectFile())
920             {
921                 if (did_create_ptr)
922                     *did_create_ptr = true;
923 
924                 shared_module_list.Append(module_sp);
925             }
926             else
927             {
928                 file_spec.GetPath(path, sizeof(path));
929 
930                 if (file_spec)
931                 {
932                     if (arch.IsValid())
933                         error.SetErrorStringWithFormat("Unable to open %s architecture in '%s'.\n", arch.GetArchitectureName(), path);
934                     else
935                         error.SetErrorStringWithFormat("Unable to open '%s'.\n", path);
936                 }
937                 else
938                 {
939                     if (uuid_ptr && uuid_ptr->IsValid())
940                         uuid_ptr->GetAsCString(uuid_cstr, sizeof (uuid_cstr));
941                     else
942                         uuid_cstr[0] = '\0';
943 
944                     if (uuid_cstr[0])
945                         error.SetErrorStringWithFormat("Cannot locate a module for UUID '%s'.\n", uuid_cstr);
946                     else
947                         error.SetErrorStringWithFormat("Cannot locate a module.\n");
948                 }
949             }
950         }
951     }
952 
953     return error;
954 }
955 
956 bool
957 ModuleList::RemoveSharedModule (lldb::ModuleSP &module_sp)
958 {
959     return GetSharedModuleList ().Remove (module_sp);
960 }
961 
962 
963