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 #include <cstdint>
15 #include <mutex>
16 
17 // Other libraries and framework includes
18 // Project includes
19 #include "lldb/Core/Log.h"
20 #include "lldb/Core/Module.h"
21 #include "lldb/Core/ModuleSpec.h"
22 #include "lldb/Host/Host.h"
23 #include "lldb/Host/Symbols.h"
24 #include "lldb/Symbol/ObjectFile.h"
25 #include "lldb/Symbol/SymbolFile.h"
26 #include "lldb/Symbol/VariableList.h"
27 
28 using namespace lldb;
29 using namespace lldb_private;
30 
31 ModuleList::ModuleList() : m_modules(), m_modules_mutex(), m_notifier(nullptr)
32 {
33 }
34 
35 ModuleList::ModuleList(const ModuleList &rhs) : m_modules(), m_modules_mutex(), m_notifier(nullptr)
36 {
37     std::lock_guard<std::recursive_mutex> lhs_guard(m_modules_mutex);
38     std::lock_guard<std::recursive_mutex> rhs_guard(rhs.m_modules_mutex);
39     m_modules = rhs.m_modules;
40 }
41 
42 ModuleList::ModuleList(ModuleList::Notifier *notifier) : m_modules(), m_modules_mutex(), m_notifier(notifier)
43 {
44 }
45 
46 const ModuleList&
47 ModuleList::operator= (const ModuleList& rhs)
48 {
49     if (this != &rhs)
50     {
51         // That's probably me nit-picking, but in theoretical situation:
52         //
53         // * that two threads A B and
54         // * two ModuleList's x y do opposite assignments ie.:
55         //
56         //  in thread A: | in thread B:
57         //    x = y;     |   y = x;
58         //
59         // This establishes correct(same) lock taking order and thus
60         // avoids priority inversion.
61         if (uintptr_t(this) > uintptr_t(&rhs))
62         {
63             std::lock_guard<std::recursive_mutex> lhs_guard(m_modules_mutex);
64             std::lock_guard<std::recursive_mutex> rhs_guard(rhs.m_modules_mutex);
65             m_modules = rhs.m_modules;
66         }
67         else
68         {
69             std::lock_guard<std::recursive_mutex> lhs_guard(m_modules_mutex);
70             std::lock_guard<std::recursive_mutex> rhs_guard(rhs.m_modules_mutex);
71             m_modules = rhs.m_modules;
72         }
73     }
74     return *this;
75 }
76 
77 ModuleList::~ModuleList() = default;
78 
79 void
80 ModuleList::AppendImpl (const ModuleSP &module_sp, bool use_notifier)
81 {
82     if (module_sp)
83     {
84         std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
85         m_modules.push_back(module_sp);
86         if (use_notifier && m_notifier)
87             m_notifier->ModuleAdded(*this, module_sp);
88     }
89 }
90 
91 void
92 ModuleList::Append (const ModuleSP &module_sp)
93 {
94     AppendImpl (module_sp);
95 }
96 
97 void
98 ModuleList::ReplaceEquivalent (const ModuleSP &module_sp)
99 {
100     if (module_sp)
101     {
102         std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
103 
104         // First remove any equivalent modules. Equivalent modules are modules
105         // whose path, platform path and architecture match.
106         ModuleSpec equivalent_module_spec (module_sp->GetFileSpec(), module_sp->GetArchitecture());
107         equivalent_module_spec.GetPlatformFileSpec() = module_sp->GetPlatformFileSpec();
108 
109         size_t idx = 0;
110         while (idx < m_modules.size())
111         {
112             ModuleSP module_sp (m_modules[idx]);
113             if (module_sp->MatchesModuleSpec (equivalent_module_spec))
114                 RemoveImpl(m_modules.begin() + idx);
115             else
116                 ++idx;
117         }
118         // Now add the new module to the list
119         Append(module_sp);
120     }
121 }
122 
123 bool
124 ModuleList::AppendIfNeeded (const ModuleSP &module_sp)
125 {
126     if (module_sp)
127     {
128         std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
129         collection::iterator pos, end = m_modules.end();
130         for (pos = m_modules.begin(); pos != end; ++pos)
131         {
132             if (pos->get() == module_sp.get())
133                 return false; // Already in the list
134         }
135         // Only push module_sp on the list if it wasn't already in there.
136         Append(module_sp);
137         return true;
138     }
139     return false;
140 }
141 
142 void
143 ModuleList::Append (const ModuleList& module_list)
144 {
145     for (auto pos : module_list.m_modules)
146         Append(pos);
147 }
148 
149 bool
150 ModuleList::AppendIfNeeded (const ModuleList& module_list)
151 {
152     bool any_in = false;
153     for (auto pos : module_list.m_modules)
154     {
155         if (AppendIfNeeded(pos))
156             any_in = true;
157     }
158     return any_in;
159 }
160 
161 bool
162 ModuleList::RemoveImpl (const ModuleSP &module_sp, bool use_notifier)
163 {
164     if (module_sp)
165     {
166         std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
167         collection::iterator pos, end = m_modules.end();
168         for (pos = m_modules.begin(); pos != end; ++pos)
169         {
170             if (pos->get() == module_sp.get())
171             {
172                 m_modules.erase (pos);
173                 if (use_notifier && m_notifier)
174                     m_notifier->ModuleRemoved(*this, module_sp);
175                 return true;
176             }
177         }
178     }
179     return false;
180 }
181 
182 ModuleList::collection::iterator
183 ModuleList::RemoveImpl (ModuleList::collection::iterator pos, bool use_notifier)
184 {
185     ModuleSP module_sp(*pos);
186     collection::iterator retval = m_modules.erase(pos);
187     if (use_notifier && m_notifier)
188         m_notifier->ModuleRemoved(*this, module_sp);
189     return retval;
190 }
191 
192 bool
193 ModuleList::Remove (const ModuleSP &module_sp)
194 {
195     return RemoveImpl (module_sp);
196 }
197 
198 bool
199 ModuleList::ReplaceModule (const lldb::ModuleSP &old_module_sp, const lldb::ModuleSP &new_module_sp)
200 {
201     if (!RemoveImpl(old_module_sp, false))
202         return false;
203     AppendImpl (new_module_sp, false);
204     if (m_notifier)
205         m_notifier->ModuleUpdated(*this, old_module_sp,new_module_sp);
206     return true;
207 }
208 
209 bool
210 ModuleList::RemoveIfOrphaned (const Module *module_ptr)
211 {
212     if (module_ptr)
213     {
214         std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
215         collection::iterator pos, end = m_modules.end();
216         for (pos = m_modules.begin(); pos != end; ++pos)
217         {
218             if (pos->get() == module_ptr)
219             {
220                 if (pos->unique())
221                 {
222                     pos = RemoveImpl(pos);
223                     return true;
224                 }
225                 else
226                     return false;
227             }
228         }
229     }
230     return false;
231 }
232 
233 size_t
234 ModuleList::RemoveOrphans (bool mandatory)
235 {
236     std::unique_lock<std::recursive_mutex> lock(m_modules_mutex, std::defer_lock);
237 
238     if (mandatory)
239     {
240         lock.lock();
241     }
242     else
243     {
244         // Not mandatory, remove orphans if we can get the mutex
245         if (!lock.try_lock())
246             return 0;
247     }
248     collection::iterator pos = m_modules.begin();
249     size_t remove_count = 0;
250     while (pos != m_modules.end())
251     {
252         if (pos->unique())
253         {
254             pos = RemoveImpl(pos);
255             ++remove_count;
256         }
257         else
258         {
259             ++pos;
260         }
261     }
262     return remove_count;
263 }
264 
265 size_t
266 ModuleList::Remove (ModuleList &module_list)
267 {
268     std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
269     size_t num_removed = 0;
270     collection::iterator pos, end = module_list.m_modules.end();
271     for (pos = module_list.m_modules.begin(); pos != end; ++pos)
272     {
273         if (Remove (*pos))
274             ++num_removed;
275     }
276     return num_removed;
277 }
278 
279 
280 void
281 ModuleList::Clear()
282 {
283     ClearImpl();
284 }
285 
286 void
287 ModuleList::Destroy()
288 {
289     ClearImpl();
290 }
291 
292 void
293 ModuleList::ClearImpl (bool use_notifier)
294 {
295     std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
296     if (use_notifier && m_notifier)
297         m_notifier->WillClearList(*this);
298     m_modules.clear();
299 }
300 
301 Module*
302 ModuleList::GetModulePointerAtIndex (size_t idx) const
303 {
304     std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
305     return GetModulePointerAtIndexUnlocked(idx);
306 }
307 
308 Module*
309 ModuleList::GetModulePointerAtIndexUnlocked (size_t idx) const
310 {
311     if (idx < m_modules.size())
312         return m_modules[idx].get();
313     return nullptr;
314 }
315 
316 ModuleSP
317 ModuleList::GetModuleAtIndex(size_t idx) const
318 {
319     std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
320     return GetModuleAtIndexUnlocked(idx);
321 }
322 
323 ModuleSP
324 ModuleList::GetModuleAtIndexUnlocked(size_t idx) const
325 {
326     ModuleSP module_sp;
327     if (idx < m_modules.size())
328         module_sp = m_modules[idx];
329     return module_sp;
330 }
331 
332 size_t
333 ModuleList::FindFunctions (const ConstString &name,
334                            uint32_t name_type_mask,
335                            bool include_symbols,
336                            bool include_inlines,
337                            bool append,
338                            SymbolContextList &sc_list) const
339 {
340     if (!append)
341         sc_list.Clear();
342 
343     const size_t old_size = sc_list.GetSize();
344 
345     if (name_type_mask & eFunctionNameTypeAuto)
346     {
347         ConstString lookup_name;
348         uint32_t lookup_name_type_mask = 0;
349         bool match_name_after_lookup = false;
350         Module::PrepareForFunctionNameLookup (name, name_type_mask,
351                                               eLanguageTypeUnknown, // TODO: add support
352                                               lookup_name,
353                                               lookup_name_type_mask,
354                                               match_name_after_lookup);
355 
356         std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
357         collection::const_iterator pos, end = m_modules.end();
358         for (pos = m_modules.begin(); pos != end; ++pos)
359         {
360             (*pos)->FindFunctions(lookup_name,
361                                   nullptr,
362                                   lookup_name_type_mask,
363                                   include_symbols,
364                                   include_inlines,
365                                   true,
366                                   sc_list);
367         }
368 
369         if (match_name_after_lookup)
370         {
371             SymbolContext sc;
372             size_t i = old_size;
373             while (i < sc_list.GetSize())
374             {
375                 if (sc_list.GetContextAtIndex(i, sc))
376                 {
377                     const char *func_name = sc.GetFunctionName().GetCString();
378                     if (func_name != nullptr && strstr(func_name, name.GetCString()) == nullptr)
379                     {
380                         // Remove the current context
381                         sc_list.RemoveContextAtIndex(i);
382                         // Don't increment i and continue in the loop
383                         continue;
384                     }
385                 }
386                 ++i;
387             }
388         }
389     }
390     else
391     {
392         std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
393         collection::const_iterator pos, end = m_modules.end();
394         for (pos = m_modules.begin(); pos != end; ++pos)
395         {
396             (*pos)->FindFunctions(name, nullptr, name_type_mask, include_symbols, include_inlines, true, sc_list);
397         }
398     }
399     return sc_list.GetSize() - old_size;
400 }
401 
402 size_t
403 ModuleList::FindFunctionSymbols (const ConstString &name,
404                                  uint32_t name_type_mask,
405                                  SymbolContextList& sc_list)
406 {
407     const size_t old_size = sc_list.GetSize();
408 
409     if (name_type_mask & eFunctionNameTypeAuto)
410     {
411         ConstString lookup_name;
412         uint32_t lookup_name_type_mask = 0;
413         bool match_name_after_lookup = false;
414         Module::PrepareForFunctionNameLookup (name, name_type_mask,
415                                               eLanguageTypeUnknown, // TODO: add support
416                                               lookup_name,
417                                               lookup_name_type_mask,
418                                               match_name_after_lookup);
419 
420         std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
421         collection::const_iterator pos, end = m_modules.end();
422         for (pos = m_modules.begin(); pos != end; ++pos)
423         {
424             (*pos)->FindFunctionSymbols (lookup_name,
425                                    lookup_name_type_mask,
426                                    sc_list);
427         }
428 
429         if (match_name_after_lookup)
430         {
431             SymbolContext sc;
432             size_t i = old_size;
433             while (i < sc_list.GetSize())
434             {
435                 if (sc_list.GetContextAtIndex(i, sc))
436                 {
437                     const char *func_name = sc.GetFunctionName().GetCString();
438                     if (func_name != nullptr && strstr(func_name, name.GetCString()) == nullptr)
439                     {
440                         // Remove the current context
441                         sc_list.RemoveContextAtIndex(i);
442                         // Don't increment i and continue in the loop
443                         continue;
444                     }
445                 }
446                 ++i;
447             }
448         }
449     }
450     else
451     {
452         std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
453         collection::const_iterator pos, end = m_modules.end();
454         for (pos = m_modules.begin(); pos != end; ++pos)
455         {
456             (*pos)->FindFunctionSymbols (name, name_type_mask, sc_list);
457         }
458     }
459 
460     return sc_list.GetSize() - old_size;
461 }
462 
463 size_t
464 ModuleList::FindFunctions(const RegularExpression &name,
465                           bool include_symbols,
466                           bool include_inlines,
467                           bool append,
468                           SymbolContextList& sc_list)
469 {
470     const size_t old_size = sc_list.GetSize();
471 
472     std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
473     collection::const_iterator pos, end = m_modules.end();
474     for (pos = m_modules.begin(); pos != end; ++pos)
475     {
476         (*pos)->FindFunctions (name, include_symbols, include_inlines, append, sc_list);
477     }
478 
479     return sc_list.GetSize() - old_size;
480 }
481 
482 size_t
483 ModuleList::FindCompileUnits (const FileSpec &path,
484                               bool append,
485                               SymbolContextList &sc_list) const
486 {
487     if (!append)
488         sc_list.Clear();
489 
490     std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
491     collection::const_iterator pos, end = m_modules.end();
492     for (pos = m_modules.begin(); pos != end; ++pos)
493     {
494         (*pos)->FindCompileUnits (path, true, sc_list);
495     }
496 
497     return sc_list.GetSize();
498 }
499 
500 size_t
501 ModuleList::FindGlobalVariables (const ConstString &name,
502                                  bool append,
503                                  size_t max_matches,
504                                  VariableList& variable_list) const
505 {
506     size_t initial_size = variable_list.GetSize();
507     std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
508     collection::const_iterator pos, end = m_modules.end();
509     for (pos = m_modules.begin(); pos != end; ++pos)
510     {
511         (*pos)->FindGlobalVariables(name, nullptr, append, max_matches, variable_list);
512     }
513     return variable_list.GetSize() - initial_size;
514 }
515 
516 size_t
517 ModuleList::FindGlobalVariables (const RegularExpression& regex,
518                                  bool append,
519                                  size_t max_matches,
520                                  VariableList& variable_list) const
521 {
522     size_t initial_size = variable_list.GetSize();
523     std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
524     collection::const_iterator pos, end = m_modules.end();
525     for (pos = m_modules.begin(); pos != end; ++pos)
526     {
527         (*pos)->FindGlobalVariables (regex, append, max_matches, variable_list);
528     }
529     return variable_list.GetSize() - initial_size;
530 }
531 
532 size_t
533 ModuleList::FindSymbolsWithNameAndType (const ConstString &name,
534                                         SymbolType symbol_type,
535                                         SymbolContextList &sc_list,
536                                         bool append) const
537 {
538     std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
539     if (!append)
540         sc_list.Clear();
541     size_t initial_size = sc_list.GetSize();
542 
543     collection::const_iterator pos, end = m_modules.end();
544     for (pos = m_modules.begin(); pos != end; ++pos)
545         (*pos)->FindSymbolsWithNameAndType (name, symbol_type, sc_list);
546     return sc_list.GetSize() - initial_size;
547 }
548 
549 size_t
550 ModuleList::FindSymbolsMatchingRegExAndType (const RegularExpression &regex,
551                                              lldb::SymbolType symbol_type,
552                                              SymbolContextList &sc_list,
553                                              bool append) const
554 {
555     std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
556     if (!append)
557         sc_list.Clear();
558     size_t initial_size = sc_list.GetSize();
559 
560     collection::const_iterator pos, end = m_modules.end();
561     for (pos = m_modules.begin(); pos != end; ++pos)
562         (*pos)->FindSymbolsMatchingRegExAndType (regex, symbol_type, sc_list);
563     return sc_list.GetSize() - initial_size;
564 }
565 
566 size_t
567 ModuleList::FindModules (const ModuleSpec &module_spec, ModuleList& matching_module_list) const
568 {
569     size_t existing_matches = matching_module_list.GetSize();
570 
571     std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
572     collection::const_iterator pos, end = m_modules.end();
573     for (pos = m_modules.begin(); pos != end; ++pos)
574     {
575         ModuleSP module_sp(*pos);
576         if (module_sp->MatchesModuleSpec (module_spec))
577             matching_module_list.Append(module_sp);
578     }
579     return matching_module_list.GetSize() - existing_matches;
580 }
581 
582 ModuleSP
583 ModuleList::FindModule (const Module *module_ptr) const
584 {
585     ModuleSP module_sp;
586 
587     // Scope for "locker"
588     {
589         std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
590         collection::const_iterator pos, end = m_modules.end();
591 
592         for (pos = m_modules.begin(); pos != end; ++pos)
593         {
594             if ((*pos).get() == module_ptr)
595             {
596                 module_sp = (*pos);
597                 break;
598             }
599         }
600     }
601     return module_sp;
602 }
603 
604 ModuleSP
605 ModuleList::FindModule (const UUID &uuid) const
606 {
607     ModuleSP module_sp;
608 
609     if (uuid.IsValid())
610     {
611         std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
612         collection::const_iterator pos, end = m_modules.end();
613 
614         for (pos = m_modules.begin(); pos != end; ++pos)
615         {
616             if ((*pos)->GetUUID() == uuid)
617             {
618                 module_sp = (*pos);
619                 break;
620             }
621         }
622     }
623     return module_sp;
624 }
625 
626 size_t
627 ModuleList::FindTypes (const SymbolContext& sc, const ConstString &name, bool name_is_fully_qualified, size_t max_matches, llvm::DenseSet<SymbolFile *> &searched_symbol_files, TypeList& types) const
628 {
629     std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
630 
631     size_t total_matches = 0;
632     collection::const_iterator pos, end = m_modules.end();
633     if (sc.module_sp)
634     {
635         // The symbol context "sc" contains a module so we want to search that
636         // one first if it is in our list...
637         for (pos = m_modules.begin(); pos != end; ++pos)
638         {
639             if (sc.module_sp.get() == (*pos).get())
640             {
641                 total_matches += (*pos)->FindTypes (sc, name, name_is_fully_qualified, max_matches, searched_symbol_files, types);
642 
643                 if (total_matches >= max_matches)
644                     break;
645             }
646         }
647     }
648 
649     if (total_matches < max_matches)
650     {
651         SymbolContext world_sc;
652         for (pos = m_modules.begin(); pos != end; ++pos)
653         {
654             // Search the module if the module is not equal to the one in the symbol
655             // context "sc". If "sc" contains a empty module shared pointer, then
656             // the comparison will always be true (valid_module_ptr != nullptr).
657             if (sc.module_sp.get() != (*pos).get())
658                 total_matches += (*pos)->FindTypes (world_sc, name, name_is_fully_qualified, max_matches, searched_symbol_files, types);
659 
660             if (total_matches >= max_matches)
661                 break;
662         }
663     }
664 
665     return total_matches;
666 }
667 
668 bool
669 ModuleList::FindSourceFile (const FileSpec &orig_spec, FileSpec &new_spec) const
670 {
671     std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
672     collection::const_iterator pos, end = m_modules.end();
673     for (pos = m_modules.begin(); pos != end; ++pos)
674     {
675         if ((*pos)->FindSourceFile (orig_spec, new_spec))
676             return true;
677     }
678     return false;
679 }
680 
681 void
682 ModuleList::FindAddressesForLine (const lldb::TargetSP target_sp,
683                                   const FileSpec &file, uint32_t line,
684                                   Function *function,
685                                   std::vector<Address> &output_local, std::vector<Address> &output_extern)
686 {
687     std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
688     collection::const_iterator pos, end = m_modules.end();
689     for (pos = m_modules.begin(); pos != end; ++pos)
690     {
691         (*pos)->FindAddressesForLine(target_sp, file, line, function, output_local, output_extern);
692     }
693 }
694 
695 ModuleSP
696 ModuleList::FindFirstModule (const ModuleSpec &module_spec) const
697 {
698     ModuleSP module_sp;
699     std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
700     collection::const_iterator pos, end = m_modules.end();
701     for (pos = m_modules.begin(); pos != end; ++pos)
702     {
703         ModuleSP module_sp(*pos);
704         if (module_sp->MatchesModuleSpec (module_spec))
705             return module_sp;
706     }
707     return module_sp;
708 
709 }
710 
711 size_t
712 ModuleList::GetSize() const
713 {
714     size_t size = 0;
715     {
716         std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
717         size = m_modules.size();
718     }
719     return size;
720 }
721 
722 void
723 ModuleList::Dump(Stream *s) const
724 {
725     //  s.Printf("%.*p: ", (int)sizeof(void*) * 2, this);
726     //  s.Indent();
727     //  s << "ModuleList\n";
728 
729     std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
730     collection::const_iterator pos, end = m_modules.end();
731     for (pos = m_modules.begin(); pos != end; ++pos)
732     {
733         (*pos)->Dump(s);
734     }
735 }
736 
737 void
738 ModuleList::LogUUIDAndPaths (Log *log, const char *prefix_cstr)
739 {
740     if (log != nullptr)
741     {
742         std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
743         collection::const_iterator pos, begin = m_modules.begin(), end = m_modules.end();
744         for (pos = begin; pos != end; ++pos)
745         {
746             Module *module = pos->get();
747             const FileSpec &module_file_spec = module->GetFileSpec();
748             log->Printf ("%s[%u] %s (%s) \"%s\"",
749                          prefix_cstr ? prefix_cstr : "",
750                          (uint32_t)std::distance (begin, pos),
751                          module->GetUUID().GetAsString().c_str(),
752                          module->GetArchitecture().GetArchitectureName(),
753                          module_file_spec.GetPath().c_str());
754         }
755     }
756 }
757 
758 bool
759 ModuleList::ResolveFileAddress (lldb::addr_t vm_addr, Address& so_addr) const
760 {
761     std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
762     collection::const_iterator pos, end = m_modules.end();
763     for (pos = m_modules.begin(); pos != end; ++pos)
764     {
765         if ((*pos)->ResolveFileAddress (vm_addr, so_addr))
766             return true;
767     }
768 
769     return false;
770 }
771 
772 uint32_t
773 ModuleList::ResolveSymbolContextForAddress (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc) const
774 {
775     // The address is already section offset so it has a module
776     uint32_t resolved_flags = 0;
777     ModuleSP module_sp (so_addr.GetModule());
778     if (module_sp)
779     {
780         resolved_flags = module_sp->ResolveSymbolContextForAddress (so_addr,
781                                                                     resolve_scope,
782                                                                     sc);
783     }
784     else
785     {
786         std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
787         collection::const_iterator pos, end = m_modules.end();
788         for (pos = m_modules.begin(); pos != end; ++pos)
789         {
790             resolved_flags = (*pos)->ResolveSymbolContextForAddress (so_addr,
791                                                                      resolve_scope,
792                                                                      sc);
793             if (resolved_flags != 0)
794                 break;
795         }
796     }
797 
798     return resolved_flags;
799 }
800 
801 uint32_t
802 ModuleList::ResolveSymbolContextForFilePath(const char *file_path,
803                                             uint32_t line,
804                                             bool check_inlines,
805                                             uint32_t resolve_scope,
806                                             SymbolContextList& sc_list) const
807 {
808     FileSpec file_spec(file_path, false);
809     return ResolveSymbolContextsForFileSpec (file_spec, line, check_inlines, resolve_scope, sc_list);
810 }
811 
812 uint32_t
813 ModuleList::ResolveSymbolContextsForFileSpec (const FileSpec &file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list) const
814 {
815     std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
816     collection::const_iterator pos, end = m_modules.end();
817     for (pos = m_modules.begin(); pos != end; ++pos)
818     {
819         (*pos)->ResolveSymbolContextsForFileSpec (file_spec, line, check_inlines, resolve_scope, sc_list);
820     }
821 
822     return sc_list.GetSize();
823 }
824 
825 size_t
826 ModuleList::GetIndexForModule (const Module *module) const
827 {
828     if (module)
829     {
830         std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
831         collection::const_iterator pos;
832         collection::const_iterator begin = m_modules.begin();
833         collection::const_iterator end = m_modules.end();
834         for (pos = begin; pos != end; ++pos)
835         {
836             if ((*pos).get() == module)
837                 return std::distance (begin, pos);
838         }
839     }
840     return LLDB_INVALID_INDEX32;
841 }
842 
843 static ModuleList &
844 GetSharedModuleList ()
845 {
846     static ModuleList *g_shared_module_list = nullptr;
847     static std::once_flag g_once_flag;
848     std::call_once(g_once_flag, [](){
849         // NOTE: Intentionally leak the module list so a program doesn't have to
850         // cleanup all modules and object files as it exits. This just wastes time
851         // doing a bunch of cleanup that isn't required.
852         if (g_shared_module_list == nullptr)
853             g_shared_module_list = new ModuleList(); // <--- Intentional leak!!!
854     });
855     return *g_shared_module_list;
856 }
857 
858 bool
859 ModuleList::ModuleIsInCache (const Module *module_ptr)
860 {
861     if (module_ptr)
862     {
863         ModuleList &shared_module_list = GetSharedModuleList ();
864         return shared_module_list.FindModule(module_ptr).get() != nullptr;
865     }
866     return false;
867 }
868 
869 size_t
870 ModuleList::FindSharedModules (const ModuleSpec &module_spec, ModuleList &matching_module_list)
871 {
872     return GetSharedModuleList ().FindModules (module_spec, matching_module_list);
873 }
874 
875 size_t
876 ModuleList::RemoveOrphanSharedModules (bool mandatory)
877 {
878     return GetSharedModuleList ().RemoveOrphans(mandatory);
879 }
880 
881 Error
882 ModuleList::GetSharedModule(const ModuleSpec &module_spec,
883                             ModuleSP &module_sp,
884                             const FileSpecList *module_search_paths_ptr,
885                             ModuleSP *old_module_sp_ptr,
886                             bool *did_create_ptr,
887                             bool always_create)
888 {
889     ModuleList &shared_module_list = GetSharedModuleList ();
890     std::lock_guard<std::recursive_mutex> guard(shared_module_list.m_modules_mutex);
891     char path[PATH_MAX];
892 
893     Error error;
894 
895     module_sp.reset();
896 
897     if (did_create_ptr)
898         *did_create_ptr = false;
899     if (old_module_sp_ptr)
900         old_module_sp_ptr->reset();
901 
902     const UUID *uuid_ptr = module_spec.GetUUIDPtr();
903     const FileSpec &module_file_spec = module_spec.GetFileSpec();
904     const ArchSpec &arch = module_spec.GetArchitecture();
905 
906     // Make sure no one else can try and get or create a module while this
907     // function is actively working on it by doing an extra lock on the
908     // global mutex list.
909     if (!always_create)
910     {
911         ModuleList matching_module_list;
912         const size_t num_matching_modules = shared_module_list.FindModules (module_spec, matching_module_list);
913         if (num_matching_modules > 0)
914         {
915             for (size_t module_idx = 0; module_idx < num_matching_modules; ++module_idx)
916             {
917                 module_sp = matching_module_list.GetModuleAtIndex(module_idx);
918 
919                 // Make sure the file for the module hasn't been modified
920                 if (module_sp->FileHasChanged())
921                 {
922                     if (old_module_sp_ptr && !*old_module_sp_ptr)
923                         *old_module_sp_ptr = module_sp;
924 
925                     Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_MODULES));
926                     if (log != nullptr)
927                         log->Printf("module changed: %p, removing from global module list",
928                                     static_cast<void*>(module_sp.get()));
929 
930                     shared_module_list.Remove (module_sp);
931                     module_sp.reset();
932                 }
933                 else
934                 {
935                     // The module matches and the module was not modified from
936                     // when it was last loaded.
937                     return error;
938                 }
939             }
940         }
941     }
942 
943     if (module_sp)
944         return error;
945 
946     module_sp.reset (new Module (module_spec));
947     // Make sure there are a module and an object file since we can specify
948     // a valid file path with an architecture that might not be in that file.
949     // By getting the object file we can guarantee that the architecture matches
950     if (module_sp->GetObjectFile())
951     {
952         // If we get in here we got the correct arch, now we just need
953         // to verify the UUID if one was given
954         if (uuid_ptr && *uuid_ptr != module_sp->GetUUID())
955         {
956             module_sp.reset();
957         }
958         else
959         {
960             if (module_sp->GetObjectFile() && module_sp->GetObjectFile()->GetType() == ObjectFile::eTypeStubLibrary)
961             {
962                 module_sp.reset();
963             }
964             else
965             {
966                 if (did_create_ptr)
967                 {
968                     *did_create_ptr = true;
969                 }
970 
971                 shared_module_list.ReplaceEquivalent(module_sp);
972                 return error;
973             }
974         }
975     }
976     else
977     {
978         module_sp.reset();
979     }
980 
981     if (module_search_paths_ptr)
982     {
983         const auto num_directories = module_search_paths_ptr->GetSize();
984         for (size_t idx = 0; idx < num_directories; ++idx)
985         {
986             auto search_path_spec = module_search_paths_ptr->GetFileSpecAtIndex(idx);
987             if (!search_path_spec.ResolvePath())
988                 continue;
989             if (!search_path_spec.Exists() || !search_path_spec.IsDirectory())
990                 continue;
991             search_path_spec.AppendPathComponent(module_spec.GetFileSpec().GetFilename().AsCString());
992             if (!search_path_spec.Exists())
993                 continue;
994 
995             auto resolved_module_spec(module_spec);
996             resolved_module_spec.GetFileSpec() = search_path_spec;
997             module_sp.reset (new Module (resolved_module_spec));
998             if (module_sp->GetObjectFile())
999             {
1000                 // If we get in here we got the correct arch, now we just need
1001                 // to verify the UUID if one was given
1002                 if (uuid_ptr && *uuid_ptr != module_sp->GetUUID())
1003                 {
1004                     module_sp.reset();
1005                 }
1006                 else
1007                 {
1008                     if (module_sp->GetObjectFile()->GetType() == ObjectFile::eTypeStubLibrary)
1009                     {
1010                         module_sp.reset();
1011                     }
1012                     else
1013                     {
1014                         if (did_create_ptr)
1015                             *did_create_ptr = true;
1016 
1017                         shared_module_list.ReplaceEquivalent(module_sp);
1018                         return Error();
1019                     }
1020                 }
1021             }
1022             else
1023             {
1024                 module_sp.reset();
1025             }
1026         }
1027     }
1028 
1029     // Either the file didn't exist where at the path, or no path was given, so
1030     // we now have to use more extreme measures to try and find the appropriate
1031     // module.
1032 
1033     // Fixup the incoming path in case the path points to a valid file, yet
1034     // the arch or UUID (if one was passed in) don't match.
1035     ModuleSpec located_binary_modulespec = Symbols::LocateExecutableObjectFile (module_spec);
1036 
1037     // Don't look for the file if it appears to be the same one we already
1038     // checked for above...
1039     if (located_binary_modulespec.GetFileSpec() != module_file_spec)
1040     {
1041         if (!located_binary_modulespec.GetFileSpec().Exists())
1042         {
1043             located_binary_modulespec.GetFileSpec().GetPath(path, sizeof(path));
1044             if (path[0] == '\0')
1045                 module_file_spec.GetPath(path, sizeof(path));
1046             // How can this check ever be true? This branch it is false, and we haven't modified file_spec.
1047             if (located_binary_modulespec.GetFileSpec().Exists())
1048             {
1049                 std::string uuid_str;
1050                 if (uuid_ptr && uuid_ptr->IsValid())
1051                     uuid_str = uuid_ptr->GetAsString();
1052 
1053                 if (arch.IsValid())
1054                 {
1055                     if (!uuid_str.empty())
1056                         error.SetErrorStringWithFormat("'%s' does not contain the %s architecture and UUID %s", path, arch.GetArchitectureName(), uuid_str.c_str());
1057                     else
1058                         error.SetErrorStringWithFormat("'%s' does not contain the %s architecture.", path, arch.GetArchitectureName());
1059                 }
1060             }
1061             else
1062             {
1063                 error.SetErrorStringWithFormat("'%s' does not exist", path);
1064             }
1065             if (error.Fail())
1066                 module_sp.reset();
1067             return error;
1068         }
1069 
1070         // Make sure no one else can try and get or create a module while this
1071         // function is actively working on it by doing an extra lock on the
1072         // global mutex list.
1073         ModuleSpec platform_module_spec(module_spec);
1074         platform_module_spec.GetFileSpec() = located_binary_modulespec.GetFileSpec();
1075         platform_module_spec.GetPlatformFileSpec() = located_binary_modulespec.GetFileSpec();
1076         platform_module_spec.GetSymbolFileSpec() = located_binary_modulespec.GetSymbolFileSpec();
1077         ModuleList matching_module_list;
1078         if (shared_module_list.FindModules (platform_module_spec, matching_module_list) > 0)
1079         {
1080             module_sp = matching_module_list.GetModuleAtIndex(0);
1081 
1082             // If we didn't have a UUID in mind when looking for the object file,
1083             // then we should make sure the modification time hasn't changed!
1084             if (platform_module_spec.GetUUIDPtr() == nullptr)
1085             {
1086                 TimeValue file_spec_mod_time(located_binary_modulespec.GetFileSpec().GetModificationTime());
1087                 if (file_spec_mod_time.IsValid())
1088                 {
1089                     if (file_spec_mod_time != module_sp->GetModificationTime())
1090                     {
1091                         if (old_module_sp_ptr)
1092                             *old_module_sp_ptr = module_sp;
1093                         shared_module_list.Remove (module_sp);
1094                         module_sp.reset();
1095                     }
1096                 }
1097             }
1098         }
1099 
1100         if (!module_sp)
1101         {
1102             module_sp.reset (new Module (platform_module_spec));
1103             // Make sure there are a module and an object file since we can specify
1104             // a valid file path with an architecture that might not be in that file.
1105             // By getting the object file we can guarantee that the architecture matches
1106             if (module_sp && module_sp->GetObjectFile())
1107             {
1108                 if (module_sp->GetObjectFile()->GetType() == ObjectFile::eTypeStubLibrary)
1109                 {
1110                     module_sp.reset();
1111                 }
1112                 else
1113                 {
1114                     if (did_create_ptr)
1115                         *did_create_ptr = true;
1116 
1117                     shared_module_list.ReplaceEquivalent(module_sp);
1118                 }
1119             }
1120             else
1121             {
1122                 located_binary_modulespec.GetFileSpec().GetPath(path, sizeof(path));
1123 
1124                 if (located_binary_modulespec.GetFileSpec())
1125                 {
1126                     if (arch.IsValid())
1127                         error.SetErrorStringWithFormat("unable to open %s architecture in '%s'", arch.GetArchitectureName(), path);
1128                     else
1129                         error.SetErrorStringWithFormat("unable to open '%s'", path);
1130                 }
1131                 else
1132                 {
1133                     std::string uuid_str;
1134                     if (uuid_ptr && uuid_ptr->IsValid())
1135                         uuid_str = uuid_ptr->GetAsString();
1136 
1137                     if (!uuid_str.empty())
1138                         error.SetErrorStringWithFormat("cannot locate a module for UUID '%s'", uuid_str.c_str());
1139                     else
1140                         error.SetErrorStringWithFormat("cannot locate a module");
1141                 }
1142             }
1143         }
1144     }
1145 
1146     return error;
1147 }
1148 
1149 bool
1150 ModuleList::RemoveSharedModule (lldb::ModuleSP &module_sp)
1151 {
1152     return GetSharedModuleList ().Remove (module_sp);
1153 }
1154 
1155 bool
1156 ModuleList::RemoveSharedModuleIfOrphaned (const Module *module_ptr)
1157 {
1158     return GetSharedModuleList ().RemoveIfOrphaned (module_ptr);
1159 }
1160 
1161 bool
1162 ModuleList::LoadScriptingResourcesInTarget (Target *target,
1163                                             std::list<Error>& errors,
1164                                             Stream *feedback_stream,
1165                                             bool continue_on_error)
1166 {
1167     if (!target)
1168         return false;
1169     std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
1170     for (auto module : m_modules)
1171     {
1172         Error error;
1173         if (module)
1174         {
1175             if (!module->LoadScriptingResourceInTarget(target, error, feedback_stream))
1176             {
1177                 if (error.Fail() && error.AsCString())
1178                 {
1179                     error.SetErrorStringWithFormat("unable to load scripting data for module %s - error reported was %s",
1180                                                    module->GetFileSpec().GetFileNameStrippingExtension().GetCString(),
1181                                                    error.AsCString());
1182                     errors.push_back(error);
1183 
1184                     if (!continue_on_error)
1185                         return false;
1186                 }
1187             }
1188         }
1189     }
1190     return errors.empty();
1191 }
1192 
1193 void
1194 ModuleList::ForEach (std::function <bool (const ModuleSP &module_sp)> const &callback) const
1195 {
1196     std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
1197     for (const auto &module : m_modules)
1198     {
1199         // If the callback returns false, then stop iterating and break out
1200         if (!callback (module))
1201             break;
1202     }
1203 }
1204