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