1254721Semaste//===-- ModuleList.cpp ------------------------------------------*- C++ -*-===//
2254721Semaste//
3254721Semaste//                     The LLVM Compiler Infrastructure
4254721Semaste//
5254721Semaste// This file is distributed under the University of Illinois Open Source
6254721Semaste// License. See LICENSE.TXT for details.
7254721Semaste//
8254721Semaste//===----------------------------------------------------------------------===//
9254721Semaste
10254721Semaste#include "lldb/Core/ModuleList.h"
11254721Semaste
12254721Semaste// C Includes
13276479Sdim#include <stdint.h>
14276479Sdim
15254721Semaste// C++ Includes
16276479Sdim#include <mutex> // std::once
17276479Sdim
18254721Semaste// Other libraries and framework includes
19254721Semaste// Project includes
20254721Semaste#include "lldb/Core/Log.h"
21254721Semaste#include "lldb/Core/Module.h"
22254721Semaste#include "lldb/Core/ModuleSpec.h"
23254721Semaste#include "lldb/Host/Host.h"
24254721Semaste#include "lldb/Host/Symbols.h"
25254721Semaste#include "lldb/Symbol/ObjectFile.h"
26254721Semaste#include "lldb/Symbol/VariableList.h"
27254721Semaste
28254721Semasteusing namespace lldb;
29254721Semasteusing namespace lldb_private;
30254721Semaste
31254721Semaste//----------------------------------------------------------------------
32254721Semaste// ModuleList constructor
33254721Semaste//----------------------------------------------------------------------
34254721SemasteModuleList::ModuleList() :
35254721Semaste    m_modules(),
36254721Semaste    m_modules_mutex (Mutex::eMutexTypeRecursive),
37254721Semaste    m_notifier(NULL)
38254721Semaste{
39254721Semaste}
40254721Semaste
41254721Semaste//----------------------------------------------------------------------
42254721Semaste// Copy constructor
43254721Semaste//----------------------------------------------------------------------
44254721SemasteModuleList::ModuleList(const ModuleList& rhs) :
45254721Semaste    m_modules(),
46276479Sdim    m_modules_mutex (Mutex::eMutexTypeRecursive),
47276479Sdim    m_notifier(NULL)
48254721Semaste{
49254721Semaste    Mutex::Locker lhs_locker(m_modules_mutex);
50254721Semaste    Mutex::Locker rhs_locker(rhs.m_modules_mutex);
51254721Semaste    m_modules = rhs.m_modules;
52254721Semaste}
53254721Semaste
54254721SemasteModuleList::ModuleList (ModuleList::Notifier* notifier) :
55254721Semaste    m_modules(),
56254721Semaste    m_modules_mutex (Mutex::eMutexTypeRecursive),
57254721Semaste    m_notifier(notifier)
58254721Semaste{
59254721Semaste}
60254721Semaste
61254721Semaste//----------------------------------------------------------------------
62254721Semaste// Assignment operator
63254721Semaste//----------------------------------------------------------------------
64254721Semasteconst ModuleList&
65254721SemasteModuleList::operator= (const ModuleList& rhs)
66254721Semaste{
67254721Semaste    if (this != &rhs)
68254721Semaste    {
69276479Sdim        // That's probably me nit-picking, but in theoretical situation:
70276479Sdim        //
71276479Sdim        // * that two threads A B and
72296417Sdim        // * two ModuleList's x y do opposite assignments ie.:
73276479Sdim        //
74276479Sdim        //  in thread A: | in thread B:
75276479Sdim        //    x = y;     |   y = x;
76276479Sdim        //
77276479Sdim        // This establishes correct(same) lock taking order and thus
78276479Sdim        // avoids priority inversion.
79276479Sdim        if (uintptr_t(this) > uintptr_t(&rhs))
80276479Sdim        {
81276479Sdim            Mutex::Locker lhs_locker(m_modules_mutex);
82276479Sdim            Mutex::Locker rhs_locker(rhs.m_modules_mutex);
83276479Sdim            m_modules = rhs.m_modules;
84276479Sdim        }
85276479Sdim        else
86276479Sdim        {
87276479Sdim            Mutex::Locker rhs_locker(rhs.m_modules_mutex);
88276479Sdim            Mutex::Locker lhs_locker(m_modules_mutex);
89276479Sdim            m_modules = rhs.m_modules;
90276479Sdim        }
91254721Semaste    }
92254721Semaste    return *this;
93254721Semaste}
94254721Semaste
95254721Semaste//----------------------------------------------------------------------
96254721Semaste// Destructor
97254721Semaste//----------------------------------------------------------------------
98254721SemasteModuleList::~ModuleList()
99254721Semaste{
100254721Semaste}
101254721Semaste
102254721Semastevoid
103254721SemasteModuleList::AppendImpl (const ModuleSP &module_sp, bool use_notifier)
104254721Semaste{
105254721Semaste    if (module_sp)
106254721Semaste    {
107254721Semaste        Mutex::Locker locker(m_modules_mutex);
108254721Semaste        m_modules.push_back(module_sp);
109254721Semaste        if (use_notifier && m_notifier)
110254721Semaste            m_notifier->ModuleAdded(*this, module_sp);
111254721Semaste    }
112254721Semaste}
113254721Semaste
114254721Semastevoid
115254721SemasteModuleList::Append (const ModuleSP &module_sp)
116254721Semaste{
117254721Semaste    AppendImpl (module_sp);
118254721Semaste}
119254721Semaste
120254721Semastevoid
121254721SemasteModuleList::ReplaceEquivalent (const ModuleSP &module_sp)
122254721Semaste{
123254721Semaste    if (module_sp)
124254721Semaste    {
125254721Semaste        Mutex::Locker locker(m_modules_mutex);
126254721Semaste
127254721Semaste        // First remove any equivalent modules. Equivalent modules are modules
128254721Semaste        // whose path, platform path and architecture match.
129254721Semaste        ModuleSpec equivalent_module_spec (module_sp->GetFileSpec(), module_sp->GetArchitecture());
130254721Semaste        equivalent_module_spec.GetPlatformFileSpec() = module_sp->GetPlatformFileSpec();
131254721Semaste
132254721Semaste        size_t idx = 0;
133254721Semaste        while (idx < m_modules.size())
134254721Semaste        {
135254721Semaste            ModuleSP module_sp (m_modules[idx]);
136254721Semaste            if (module_sp->MatchesModuleSpec (equivalent_module_spec))
137254721Semaste                RemoveImpl(m_modules.begin() + idx);
138254721Semaste            else
139254721Semaste                ++idx;
140254721Semaste        }
141254721Semaste        // Now add the new module to the list
142254721Semaste        Append(module_sp);
143254721Semaste    }
144254721Semaste}
145254721Semaste
146254721Semastebool
147254721SemasteModuleList::AppendIfNeeded (const ModuleSP &module_sp)
148254721Semaste{
149254721Semaste    if (module_sp)
150254721Semaste    {
151254721Semaste        Mutex::Locker locker(m_modules_mutex);
152254721Semaste        collection::iterator pos, end = m_modules.end();
153254721Semaste        for (pos = m_modules.begin(); pos != end; ++pos)
154254721Semaste        {
155254721Semaste            if (pos->get() == module_sp.get())
156254721Semaste                return false; // Already in the list
157254721Semaste        }
158254721Semaste        // Only push module_sp on the list if it wasn't already in there.
159254721Semaste        Append(module_sp);
160254721Semaste        return true;
161254721Semaste    }
162254721Semaste    return false;
163254721Semaste}
164254721Semaste
165254721Semastevoid
166254721SemasteModuleList::Append (const ModuleList& module_list)
167254721Semaste{
168254721Semaste    for (auto pos : module_list.m_modules)
169254721Semaste        Append(pos);
170254721Semaste}
171254721Semaste
172254721Semastebool
173254721SemasteModuleList::AppendIfNeeded (const ModuleList& module_list)
174254721Semaste{
175254721Semaste    bool any_in = false;
176254721Semaste    for (auto pos : module_list.m_modules)
177254721Semaste    {
178254721Semaste        if (AppendIfNeeded(pos))
179254721Semaste            any_in = true;
180254721Semaste    }
181254721Semaste    return any_in;
182254721Semaste}
183254721Semaste
184254721Semastebool
185254721SemasteModuleList::RemoveImpl (const ModuleSP &module_sp, bool use_notifier)
186254721Semaste{
187254721Semaste    if (module_sp)
188254721Semaste    {
189254721Semaste        Mutex::Locker locker(m_modules_mutex);
190254721Semaste        collection::iterator pos, end = m_modules.end();
191254721Semaste        for (pos = m_modules.begin(); pos != end; ++pos)
192254721Semaste        {
193254721Semaste            if (pos->get() == module_sp.get())
194254721Semaste            {
195254721Semaste                m_modules.erase (pos);
196254721Semaste                if (use_notifier && m_notifier)
197254721Semaste                    m_notifier->ModuleRemoved(*this, module_sp);
198254721Semaste                return true;
199254721Semaste            }
200254721Semaste        }
201254721Semaste    }
202254721Semaste    return false;
203254721Semaste}
204254721Semaste
205254721SemasteModuleList::collection::iterator
206254721SemasteModuleList::RemoveImpl (ModuleList::collection::iterator pos, bool use_notifier)
207254721Semaste{
208254721Semaste    ModuleSP module_sp(*pos);
209254721Semaste    collection::iterator retval = m_modules.erase(pos);
210254721Semaste    if (use_notifier && m_notifier)
211254721Semaste        m_notifier->ModuleRemoved(*this, module_sp);
212254721Semaste    return retval;
213254721Semaste}
214254721Semaste
215254721Semastebool
216254721SemasteModuleList::Remove (const ModuleSP &module_sp)
217254721Semaste{
218254721Semaste    return RemoveImpl (module_sp);
219254721Semaste}
220254721Semaste
221254721Semastebool
222254721SemasteModuleList::ReplaceModule (const lldb::ModuleSP &old_module_sp, const lldb::ModuleSP &new_module_sp)
223254721Semaste{
224254721Semaste    if (!RemoveImpl(old_module_sp, false))
225254721Semaste        return false;
226254721Semaste    AppendImpl (new_module_sp, false);
227254721Semaste    if (m_notifier)
228254721Semaste        m_notifier->ModuleUpdated(*this, old_module_sp,new_module_sp);
229254721Semaste    return true;
230254721Semaste}
231254721Semaste
232254721Semastebool
233254721SemasteModuleList::RemoveIfOrphaned (const Module *module_ptr)
234254721Semaste{
235254721Semaste    if (module_ptr)
236254721Semaste    {
237254721Semaste        Mutex::Locker locker(m_modules_mutex);
238254721Semaste        collection::iterator pos, end = m_modules.end();
239254721Semaste        for (pos = m_modules.begin(); pos != end; ++pos)
240254721Semaste        {
241254721Semaste            if (pos->get() == module_ptr)
242254721Semaste            {
243254721Semaste                if (pos->unique())
244254721Semaste                {
245254721Semaste                    pos = RemoveImpl(pos);
246254721Semaste                    return true;
247254721Semaste                }
248254721Semaste                else
249254721Semaste                    return false;
250254721Semaste            }
251254721Semaste        }
252254721Semaste    }
253254721Semaste    return false;
254254721Semaste}
255254721Semaste
256254721Semastesize_t
257254721SemasteModuleList::RemoveOrphans (bool mandatory)
258254721Semaste{
259254721Semaste    Mutex::Locker locker;
260254721Semaste
261254721Semaste    if (mandatory)
262254721Semaste    {
263254721Semaste        locker.Lock (m_modules_mutex);
264254721Semaste    }
265254721Semaste    else
266254721Semaste    {
267254721Semaste        // Not mandatory, remove orphans if we can get the mutex
268254721Semaste        if (!locker.TryLock(m_modules_mutex))
269254721Semaste            return 0;
270254721Semaste    }
271254721Semaste    collection::iterator pos = m_modules.begin();
272254721Semaste    size_t remove_count = 0;
273254721Semaste    while (pos != m_modules.end())
274254721Semaste    {
275254721Semaste        if (pos->unique())
276254721Semaste        {
277254721Semaste            pos = RemoveImpl(pos);
278254721Semaste            ++remove_count;
279254721Semaste        }
280254721Semaste        else
281254721Semaste        {
282254721Semaste            ++pos;
283254721Semaste        }
284254721Semaste    }
285254721Semaste    return remove_count;
286254721Semaste}
287254721Semaste
288254721Semastesize_t
289254721SemasteModuleList::Remove (ModuleList &module_list)
290254721Semaste{
291254721Semaste    Mutex::Locker locker(m_modules_mutex);
292254721Semaste    size_t num_removed = 0;
293254721Semaste    collection::iterator pos, end = module_list.m_modules.end();
294254721Semaste    for (pos = module_list.m_modules.begin(); pos != end; ++pos)
295254721Semaste    {
296254721Semaste        if (Remove (*pos))
297254721Semaste            ++num_removed;
298254721Semaste    }
299254721Semaste    return num_removed;
300254721Semaste}
301254721Semaste
302254721Semaste
303254721Semastevoid
304254721SemasteModuleList::Clear()
305254721Semaste{
306254721Semaste    ClearImpl();
307254721Semaste}
308254721Semaste
309254721Semastevoid
310254721SemasteModuleList::Destroy()
311254721Semaste{
312254721Semaste    ClearImpl();
313254721Semaste}
314254721Semaste
315254721Semastevoid
316254721SemasteModuleList::ClearImpl (bool use_notifier)
317254721Semaste{
318254721Semaste    Mutex::Locker locker(m_modules_mutex);
319254721Semaste    if (use_notifier && m_notifier)
320254721Semaste        m_notifier->WillClearList(*this);
321254721Semaste    m_modules.clear();
322254721Semaste}
323254721Semaste
324254721SemasteModule*
325254721SemasteModuleList::GetModulePointerAtIndex (size_t idx) const
326254721Semaste{
327254721Semaste    Mutex::Locker locker(m_modules_mutex);
328254721Semaste    return GetModulePointerAtIndexUnlocked(idx);
329254721Semaste}
330254721Semaste
331254721SemasteModule*
332254721SemasteModuleList::GetModulePointerAtIndexUnlocked (size_t idx) const
333254721Semaste{
334254721Semaste    if (idx < m_modules.size())
335254721Semaste        return m_modules[idx].get();
336254721Semaste    return NULL;
337254721Semaste}
338254721Semaste
339254721SemasteModuleSP
340254721SemasteModuleList::GetModuleAtIndex(size_t idx) const
341254721Semaste{
342254721Semaste    Mutex::Locker locker(m_modules_mutex);
343254721Semaste    return GetModuleAtIndexUnlocked(idx);
344254721Semaste}
345254721Semaste
346254721SemasteModuleSP
347254721SemasteModuleList::GetModuleAtIndexUnlocked(size_t idx) const
348254721Semaste{
349254721Semaste    ModuleSP module_sp;
350254721Semaste    if (idx < m_modules.size())
351254721Semaste        module_sp = m_modules[idx];
352254721Semaste    return module_sp;
353254721Semaste}
354254721Semaste
355254721Semastesize_t
356254721SemasteModuleList::FindFunctions (const ConstString &name,
357254721Semaste                           uint32_t name_type_mask,
358254721Semaste                           bool include_symbols,
359254721Semaste                           bool include_inlines,
360254721Semaste                           bool append,
361254721Semaste                           SymbolContextList &sc_list) const
362254721Semaste{
363254721Semaste    if (!append)
364254721Semaste        sc_list.Clear();
365254721Semaste
366254721Semaste    const size_t old_size = sc_list.GetSize();
367254721Semaste
368254721Semaste    if (name_type_mask & eFunctionNameTypeAuto)
369254721Semaste    {
370254721Semaste        ConstString lookup_name;
371254721Semaste        uint32_t lookup_name_type_mask = 0;
372254721Semaste        bool match_name_after_lookup = false;
373254721Semaste        Module::PrepareForFunctionNameLookup (name, name_type_mask,
374296417Sdim                                              eLanguageTypeUnknown, // TODO: add support
375254721Semaste                                              lookup_name,
376254721Semaste                                              lookup_name_type_mask,
377254721Semaste                                              match_name_after_lookup);
378254721Semaste
379254721Semaste        Mutex::Locker locker(m_modules_mutex);
380254721Semaste        collection::const_iterator pos, end = m_modules.end();
381254721Semaste        for (pos = m_modules.begin(); pos != end; ++pos)
382254721Semaste        {
383254721Semaste            (*pos)->FindFunctions (lookup_name,
384254721Semaste                                   NULL,
385254721Semaste                                   lookup_name_type_mask,
386254721Semaste                                   include_symbols,
387254721Semaste                                   include_inlines,
388254721Semaste                                   true,
389254721Semaste                                   sc_list);
390254721Semaste        }
391254721Semaste
392254721Semaste        if (match_name_after_lookup)
393254721Semaste        {
394254721Semaste            SymbolContext sc;
395254721Semaste            size_t i = old_size;
396254721Semaste            while (i<sc_list.GetSize())
397254721Semaste            {
398254721Semaste                if (sc_list.GetContextAtIndex(i, sc))
399254721Semaste                {
400254721Semaste                    const char *func_name = sc.GetFunctionName().GetCString();
401254721Semaste                    if (func_name && strstr (func_name, name.GetCString()) == NULL)
402254721Semaste                    {
403254721Semaste                        // Remove the current context
404254721Semaste                        sc_list.RemoveContextAtIndex(i);
405254721Semaste                        // Don't increment i and continue in the loop
406254721Semaste                        continue;
407254721Semaste                    }
408254721Semaste                }
409254721Semaste                ++i;
410254721Semaste            }
411254721Semaste        }
412254721Semaste
413254721Semaste    }
414254721Semaste    else
415254721Semaste    {
416254721Semaste        Mutex::Locker locker(m_modules_mutex);
417254721Semaste        collection::const_iterator pos, end = m_modules.end();
418254721Semaste        for (pos = m_modules.begin(); pos != end; ++pos)
419254721Semaste        {
420254721Semaste            (*pos)->FindFunctions (name, NULL, name_type_mask, include_symbols, include_inlines, true, sc_list);
421254721Semaste        }
422254721Semaste    }
423254721Semaste    return sc_list.GetSize() - old_size;
424254721Semaste}
425254721Semaste
426254721Semastesize_t
427254721SemasteModuleList::FindFunctionSymbols (const ConstString &name,
428254721Semaste                                 uint32_t name_type_mask,
429254721Semaste                                 SymbolContextList& sc_list)
430254721Semaste{
431254721Semaste    const size_t old_size = sc_list.GetSize();
432254721Semaste
433254721Semaste    if (name_type_mask & eFunctionNameTypeAuto)
434254721Semaste    {
435254721Semaste        ConstString lookup_name;
436254721Semaste        uint32_t lookup_name_type_mask = 0;
437254721Semaste        bool match_name_after_lookup = false;
438254721Semaste        Module::PrepareForFunctionNameLookup (name, name_type_mask,
439296417Sdim                                              eLanguageTypeUnknown, // TODO: add support
440254721Semaste                                              lookup_name,
441254721Semaste                                              lookup_name_type_mask,
442254721Semaste                                              match_name_after_lookup);
443254721Semaste
444254721Semaste        Mutex::Locker locker(m_modules_mutex);
445254721Semaste        collection::const_iterator pos, end = m_modules.end();
446254721Semaste        for (pos = m_modules.begin(); pos != end; ++pos)
447254721Semaste        {
448254721Semaste            (*pos)->FindFunctionSymbols (lookup_name,
449254721Semaste                                   lookup_name_type_mask,
450254721Semaste                                   sc_list);
451254721Semaste        }
452254721Semaste
453254721Semaste        if (match_name_after_lookup)
454254721Semaste        {
455254721Semaste            SymbolContext sc;
456254721Semaste            size_t i = old_size;
457254721Semaste            while (i<sc_list.GetSize())
458254721Semaste            {
459254721Semaste                if (sc_list.GetContextAtIndex(i, sc))
460254721Semaste                {
461254721Semaste                    const char *func_name = sc.GetFunctionName().GetCString();
462254721Semaste                    if (func_name && strstr (func_name, name.GetCString()) == NULL)
463254721Semaste                    {
464254721Semaste                        // Remove the current context
465254721Semaste                        sc_list.RemoveContextAtIndex(i);
466254721Semaste                        // Don't increment i and continue in the loop
467254721Semaste                        continue;
468254721Semaste                    }
469254721Semaste                }
470254721Semaste                ++i;
471254721Semaste            }
472254721Semaste        }
473254721Semaste
474254721Semaste    }
475254721Semaste    else
476254721Semaste    {
477254721Semaste        Mutex::Locker locker(m_modules_mutex);
478254721Semaste        collection::const_iterator pos, end = m_modules.end();
479254721Semaste        for (pos = m_modules.begin(); pos != end; ++pos)
480254721Semaste        {
481254721Semaste            (*pos)->FindFunctionSymbols (name, name_type_mask, sc_list);
482254721Semaste        }
483254721Semaste    }
484254721Semaste
485254721Semaste    return sc_list.GetSize() - old_size;
486254721Semaste}
487254721Semaste
488280031Sdim
489254721Semastesize_t
490280031SdimModuleList::FindFunctions(const RegularExpression &name,
491280031Sdim                          bool include_symbols,
492280031Sdim                          bool include_inlines,
493280031Sdim                          bool append,
494280031Sdim                          SymbolContextList& sc_list)
495280031Sdim{
496280031Sdim    const size_t old_size = sc_list.GetSize();
497280031Sdim
498280031Sdim    Mutex::Locker locker(m_modules_mutex);
499280031Sdim    collection::const_iterator pos, end = m_modules.end();
500280031Sdim    for (pos = m_modules.begin(); pos != end; ++pos)
501280031Sdim    {
502280031Sdim        (*pos)->FindFunctions (name, include_symbols, include_inlines, append, sc_list);
503280031Sdim    }
504280031Sdim
505280031Sdim    return sc_list.GetSize() - old_size;
506280031Sdim}
507280031Sdim
508280031Sdimsize_t
509254721SemasteModuleList::FindCompileUnits (const FileSpec &path,
510254721Semaste                              bool append,
511254721Semaste                              SymbolContextList &sc_list) const
512254721Semaste{
513254721Semaste    if (!append)
514254721Semaste        sc_list.Clear();
515254721Semaste
516254721Semaste    Mutex::Locker locker(m_modules_mutex);
517254721Semaste    collection::const_iterator pos, end = m_modules.end();
518254721Semaste    for (pos = m_modules.begin(); pos != end; ++pos)
519254721Semaste    {
520254721Semaste        (*pos)->FindCompileUnits (path, true, sc_list);
521254721Semaste    }
522254721Semaste
523254721Semaste    return sc_list.GetSize();
524254721Semaste}
525254721Semaste
526254721Semastesize_t
527254721SemasteModuleList::FindGlobalVariables (const ConstString &name,
528254721Semaste                                 bool append,
529254721Semaste                                 size_t max_matches,
530254721Semaste                                 VariableList& variable_list) const
531254721Semaste{
532254721Semaste    size_t initial_size = variable_list.GetSize();
533254721Semaste    Mutex::Locker locker(m_modules_mutex);
534254721Semaste    collection::const_iterator pos, end = m_modules.end();
535254721Semaste    for (pos = m_modules.begin(); pos != end; ++pos)
536254721Semaste    {
537254721Semaste        (*pos)->FindGlobalVariables (name, NULL, append, max_matches, variable_list);
538254721Semaste    }
539254721Semaste    return variable_list.GetSize() - initial_size;
540254721Semaste}
541254721Semaste
542254721Semaste
543254721Semastesize_t
544254721SemasteModuleList::FindGlobalVariables (const RegularExpression& regex,
545254721Semaste                                 bool append,
546254721Semaste                                 size_t max_matches,
547254721Semaste                                 VariableList& variable_list) const
548254721Semaste{
549254721Semaste    size_t initial_size = variable_list.GetSize();
550254721Semaste    Mutex::Locker locker(m_modules_mutex);
551254721Semaste    collection::const_iterator pos, end = m_modules.end();
552254721Semaste    for (pos = m_modules.begin(); pos != end; ++pos)
553254721Semaste    {
554254721Semaste        (*pos)->FindGlobalVariables (regex, append, max_matches, variable_list);
555254721Semaste    }
556254721Semaste    return variable_list.GetSize() - initial_size;
557254721Semaste}
558254721Semaste
559254721Semaste
560254721Semastesize_t
561254721SemasteModuleList::FindSymbolsWithNameAndType (const ConstString &name,
562254721Semaste                                        SymbolType symbol_type,
563254721Semaste                                        SymbolContextList &sc_list,
564254721Semaste                                        bool append) const
565254721Semaste{
566254721Semaste    Mutex::Locker locker(m_modules_mutex);
567254721Semaste    if (!append)
568254721Semaste        sc_list.Clear();
569254721Semaste    size_t initial_size = sc_list.GetSize();
570254721Semaste
571254721Semaste    collection::const_iterator pos, end = m_modules.end();
572254721Semaste    for (pos = m_modules.begin(); pos != end; ++pos)
573254721Semaste        (*pos)->FindSymbolsWithNameAndType (name, symbol_type, sc_list);
574254721Semaste    return sc_list.GetSize() - initial_size;
575254721Semaste}
576254721Semaste
577254721Semastesize_t
578254721SemasteModuleList::FindSymbolsMatchingRegExAndType (const RegularExpression &regex,
579254721Semaste                                             lldb::SymbolType symbol_type,
580254721Semaste                                             SymbolContextList &sc_list,
581254721Semaste                                             bool append) const
582254721Semaste{
583254721Semaste    Mutex::Locker locker(m_modules_mutex);
584254721Semaste    if (!append)
585254721Semaste        sc_list.Clear();
586254721Semaste    size_t initial_size = sc_list.GetSize();
587254721Semaste
588254721Semaste    collection::const_iterator pos, end = m_modules.end();
589254721Semaste    for (pos = m_modules.begin(); pos != end; ++pos)
590254721Semaste        (*pos)->FindSymbolsMatchingRegExAndType (regex, symbol_type, sc_list);
591254721Semaste    return sc_list.GetSize() - initial_size;
592254721Semaste}
593254721Semaste
594254721Semastesize_t
595254721SemasteModuleList::FindModules (const ModuleSpec &module_spec, ModuleList& matching_module_list) const
596254721Semaste{
597254721Semaste    size_t existing_matches = matching_module_list.GetSize();
598254721Semaste
599254721Semaste    Mutex::Locker locker(m_modules_mutex);
600254721Semaste    collection::const_iterator pos, end = m_modules.end();
601254721Semaste    for (pos = m_modules.begin(); pos != end; ++pos)
602254721Semaste    {
603254721Semaste        ModuleSP module_sp(*pos);
604254721Semaste        if (module_sp->MatchesModuleSpec (module_spec))
605254721Semaste            matching_module_list.Append(module_sp);
606254721Semaste    }
607254721Semaste    return matching_module_list.GetSize() - existing_matches;
608254721Semaste}
609254721Semaste
610254721SemasteModuleSP
611254721SemasteModuleList::FindModule (const Module *module_ptr) const
612254721Semaste{
613254721Semaste    ModuleSP module_sp;
614254721Semaste
615254721Semaste    // Scope for "locker"
616254721Semaste    {
617254721Semaste        Mutex::Locker locker(m_modules_mutex);
618254721Semaste        collection::const_iterator pos, end = m_modules.end();
619254721Semaste
620254721Semaste        for (pos = m_modules.begin(); pos != end; ++pos)
621254721Semaste        {
622254721Semaste            if ((*pos).get() == module_ptr)
623254721Semaste            {
624254721Semaste                module_sp = (*pos);
625254721Semaste                break;
626254721Semaste            }
627254721Semaste        }
628254721Semaste    }
629254721Semaste    return module_sp;
630254721Semaste
631254721Semaste}
632254721Semaste
633254721SemasteModuleSP
634254721SemasteModuleList::FindModule (const UUID &uuid) const
635254721Semaste{
636254721Semaste    ModuleSP module_sp;
637254721Semaste
638254721Semaste    if (uuid.IsValid())
639254721Semaste    {
640254721Semaste        Mutex::Locker locker(m_modules_mutex);
641254721Semaste        collection::const_iterator pos, end = m_modules.end();
642254721Semaste
643254721Semaste        for (pos = m_modules.begin(); pos != end; ++pos)
644254721Semaste        {
645254721Semaste            if ((*pos)->GetUUID() == uuid)
646254721Semaste            {
647254721Semaste                module_sp = (*pos);
648254721Semaste                break;
649254721Semaste            }
650254721Semaste        }
651254721Semaste    }
652254721Semaste    return module_sp;
653254721Semaste}
654254721Semaste
655254721Semaste
656254721Semastesize_t
657254721SemasteModuleList::FindTypes (const SymbolContext& sc, const ConstString &name, bool name_is_fully_qualified, size_t max_matches, TypeList& types) const
658254721Semaste{
659254721Semaste    Mutex::Locker locker(m_modules_mutex);
660254721Semaste
661254721Semaste    size_t total_matches = 0;
662254721Semaste    collection::const_iterator pos, end = m_modules.end();
663254721Semaste    if (sc.module_sp)
664254721Semaste    {
665254721Semaste        // The symbol context "sc" contains a module so we want to search that
666254721Semaste        // one first if it is in our list...
667254721Semaste        for (pos = m_modules.begin(); pos != end; ++pos)
668254721Semaste        {
669254721Semaste            if (sc.module_sp.get() == (*pos).get())
670254721Semaste            {
671254721Semaste                total_matches += (*pos)->FindTypes (sc, name, name_is_fully_qualified, max_matches, types);
672254721Semaste
673254721Semaste                if (total_matches >= max_matches)
674254721Semaste                    break;
675254721Semaste            }
676254721Semaste        }
677254721Semaste    }
678254721Semaste
679254721Semaste    if (total_matches < max_matches)
680254721Semaste    {
681254721Semaste        SymbolContext world_sc;
682254721Semaste        for (pos = m_modules.begin(); pos != end; ++pos)
683254721Semaste        {
684254721Semaste            // Search the module if the module is not equal to the one in the symbol
685254721Semaste            // context "sc". If "sc" contains a empty module shared pointer, then
686296417Sdim            // the comparison will always be true (valid_module_ptr != NULL).
687254721Semaste            if (sc.module_sp.get() != (*pos).get())
688254721Semaste                total_matches += (*pos)->FindTypes (world_sc, name, name_is_fully_qualified, max_matches, types);
689254721Semaste
690254721Semaste            if (total_matches >= max_matches)
691254721Semaste                break;
692254721Semaste        }
693254721Semaste    }
694254721Semaste
695254721Semaste    return total_matches;
696254721Semaste}
697254721Semaste
698254721Semastebool
699254721SemasteModuleList::FindSourceFile (const FileSpec &orig_spec, FileSpec &new_spec) const
700254721Semaste{
701254721Semaste    Mutex::Locker locker(m_modules_mutex);
702254721Semaste    collection::const_iterator pos, end = m_modules.end();
703254721Semaste    for (pos = m_modules.begin(); pos != end; ++pos)
704254721Semaste    {
705254721Semaste        if ((*pos)->FindSourceFile (orig_spec, new_spec))
706254721Semaste            return true;
707254721Semaste    }
708254721Semaste    return false;
709254721Semaste}
710254721Semaste
711258054Semastevoid
712258054SemasteModuleList::FindAddressesForLine (const lldb::TargetSP target_sp,
713258054Semaste                                  const FileSpec &file, uint32_t line,
714258054Semaste                                  Function *function,
715258054Semaste                                  std::vector<Address> &output_local, std::vector<Address> &output_extern)
716258054Semaste{
717258054Semaste    Mutex::Locker locker(m_modules_mutex);
718258054Semaste    collection::const_iterator pos, end = m_modules.end();
719258054Semaste    for (pos = m_modules.begin(); pos != end; ++pos)
720258054Semaste    {
721258054Semaste        (*pos)->FindAddressesForLine(target_sp, file, line, function, output_local, output_extern);
722258054Semaste    }
723258054Semaste}
724254721Semaste
725254721SemasteModuleSP
726254721SemasteModuleList::FindFirstModule (const ModuleSpec &module_spec) const
727254721Semaste{
728254721Semaste    ModuleSP module_sp;
729254721Semaste    Mutex::Locker locker(m_modules_mutex);
730254721Semaste    collection::const_iterator pos, end = m_modules.end();
731254721Semaste    for (pos = m_modules.begin(); pos != end; ++pos)
732254721Semaste    {
733254721Semaste        ModuleSP module_sp(*pos);
734254721Semaste        if (module_sp->MatchesModuleSpec (module_spec))
735254721Semaste            return module_sp;
736254721Semaste    }
737254721Semaste    return module_sp;
738254721Semaste
739254721Semaste}
740254721Semaste
741254721Semastesize_t
742254721SemasteModuleList::GetSize() const
743254721Semaste{
744254721Semaste    size_t size = 0;
745254721Semaste    {
746254721Semaste        Mutex::Locker locker(m_modules_mutex);
747254721Semaste        size = m_modules.size();
748254721Semaste    }
749254721Semaste    return size;
750254721Semaste}
751254721Semaste
752254721Semaste
753254721Semastevoid
754254721SemasteModuleList::Dump(Stream *s) const
755254721Semaste{
756254721Semaste//  s.Printf("%.*p: ", (int)sizeof(void*) * 2, this);
757254721Semaste//  s.Indent();
758254721Semaste//  s << "ModuleList\n";
759254721Semaste
760254721Semaste    Mutex::Locker locker(m_modules_mutex);
761254721Semaste    collection::const_iterator pos, end = m_modules.end();
762254721Semaste    for (pos = m_modules.begin(); pos != end; ++pos)
763254721Semaste    {
764254721Semaste        (*pos)->Dump(s);
765254721Semaste    }
766254721Semaste}
767254721Semaste
768254721Semastevoid
769254721SemasteModuleList::LogUUIDAndPaths (Log *log, const char *prefix_cstr)
770254721Semaste{
771254721Semaste    if (log)
772254721Semaste    {
773254721Semaste        Mutex::Locker locker(m_modules_mutex);
774254721Semaste        collection::const_iterator pos, begin = m_modules.begin(), end = m_modules.end();
775254721Semaste        for (pos = begin; pos != end; ++pos)
776254721Semaste        {
777254721Semaste            Module *module = pos->get();
778254721Semaste            const FileSpec &module_file_spec = module->GetFileSpec();
779254721Semaste            log->Printf ("%s[%u] %s (%s) \"%s\"",
780254721Semaste                         prefix_cstr ? prefix_cstr : "",
781254721Semaste                         (uint32_t)std::distance (begin, pos),
782254721Semaste                         module->GetUUID().GetAsString().c_str(),
783254721Semaste                         module->GetArchitecture().GetArchitectureName(),
784254721Semaste                         module_file_spec.GetPath().c_str());
785254721Semaste        }
786254721Semaste    }
787254721Semaste}
788254721Semaste
789254721Semastebool
790254721SemasteModuleList::ResolveFileAddress (lldb::addr_t vm_addr, Address& so_addr) const
791254721Semaste{
792254721Semaste    Mutex::Locker locker(m_modules_mutex);
793254721Semaste    collection::const_iterator pos, end = m_modules.end();
794254721Semaste    for (pos = m_modules.begin(); pos != end; ++pos)
795254721Semaste    {
796254721Semaste        if ((*pos)->ResolveFileAddress (vm_addr, so_addr))
797254721Semaste            return true;
798254721Semaste    }
799254721Semaste
800254721Semaste    return false;
801254721Semaste}
802254721Semaste
803254721Semasteuint32_t
804254721SemasteModuleList::ResolveSymbolContextForAddress (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc) const
805254721Semaste{
806254721Semaste    // The address is already section offset so it has a module
807254721Semaste    uint32_t resolved_flags = 0;
808254721Semaste    ModuleSP module_sp (so_addr.GetModule());
809254721Semaste    if (module_sp)
810254721Semaste    {
811254721Semaste        resolved_flags = module_sp->ResolveSymbolContextForAddress (so_addr,
812254721Semaste                                                                    resolve_scope,
813254721Semaste                                                                    sc);
814254721Semaste    }
815254721Semaste    else
816254721Semaste    {
817254721Semaste        Mutex::Locker locker(m_modules_mutex);
818254721Semaste        collection::const_iterator pos, end = m_modules.end();
819254721Semaste        for (pos = m_modules.begin(); pos != end; ++pos)
820254721Semaste        {
821254721Semaste            resolved_flags = (*pos)->ResolveSymbolContextForAddress (so_addr,
822254721Semaste                                                                     resolve_scope,
823254721Semaste                                                                     sc);
824254721Semaste            if (resolved_flags != 0)
825254721Semaste                break;
826254721Semaste        }
827254721Semaste    }
828254721Semaste
829254721Semaste    return resolved_flags;
830254721Semaste}
831254721Semaste
832254721Semasteuint32_t
833254721SemasteModuleList::ResolveSymbolContextForFilePath
834254721Semaste(
835254721Semaste    const char *file_path,
836254721Semaste    uint32_t line,
837254721Semaste    bool check_inlines,
838254721Semaste    uint32_t resolve_scope,
839254721Semaste    SymbolContextList& sc_list
840254721Semaste)  const
841254721Semaste{
842254721Semaste    FileSpec file_spec(file_path, false);
843254721Semaste    return ResolveSymbolContextsForFileSpec (file_spec, line, check_inlines, resolve_scope, sc_list);
844254721Semaste}
845254721Semaste
846254721Semasteuint32_t
847254721SemasteModuleList::ResolveSymbolContextsForFileSpec (const FileSpec &file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list) const
848254721Semaste{
849254721Semaste    Mutex::Locker locker(m_modules_mutex);
850254721Semaste    collection::const_iterator pos, end = m_modules.end();
851254721Semaste    for (pos = m_modules.begin(); pos != end; ++pos)
852254721Semaste    {
853254721Semaste        (*pos)->ResolveSymbolContextsForFileSpec (file_spec, line, check_inlines, resolve_scope, sc_list);
854254721Semaste    }
855254721Semaste
856254721Semaste    return sc_list.GetSize();
857254721Semaste}
858254721Semaste
859254721Semastesize_t
860254721SemasteModuleList::GetIndexForModule (const Module *module) const
861254721Semaste{
862254721Semaste    if (module)
863254721Semaste    {
864254721Semaste        Mutex::Locker locker(m_modules_mutex);
865254721Semaste        collection::const_iterator pos;
866254721Semaste        collection::const_iterator begin = m_modules.begin();
867254721Semaste        collection::const_iterator end = m_modules.end();
868254721Semaste        for (pos = begin; pos != end; ++pos)
869254721Semaste        {
870254721Semaste            if ((*pos).get() == module)
871254721Semaste                return std::distance (begin, pos);
872254721Semaste        }
873254721Semaste    }
874254721Semaste    return LLDB_INVALID_INDEX32;
875254721Semaste}
876254721Semaste
877254721Semastestatic ModuleList &
878254721SemasteGetSharedModuleList ()
879254721Semaste{
880254721Semaste    static ModuleList *g_shared_module_list = NULL;
881276479Sdim    static std::once_flag g_once_flag;
882276479Sdim    std::call_once(g_once_flag, [](){
883276479Sdim        // NOTE: Intentionally leak the module list so a program doesn't have to
884276479Sdim        // cleanup all modules and object files as it exits. This just wastes time
885276479Sdim        // doing a bunch of cleanup that isn't required.
886276479Sdim        if (g_shared_module_list == NULL)
887276479Sdim            g_shared_module_list = new ModuleList(); // <--- Intentional leak!!!
888276479Sdim    });
889254721Semaste    return *g_shared_module_list;
890254721Semaste}
891254721Semaste
892254721Semastebool
893254721SemasteModuleList::ModuleIsInCache (const Module *module_ptr)
894254721Semaste{
895254721Semaste    if (module_ptr)
896254721Semaste    {
897254721Semaste        ModuleList &shared_module_list = GetSharedModuleList ();
898254721Semaste        return shared_module_list.FindModule (module_ptr).get() != NULL;
899254721Semaste    }
900254721Semaste    return false;
901254721Semaste}
902254721Semaste
903254721Semastesize_t
904254721SemasteModuleList::FindSharedModules (const ModuleSpec &module_spec, ModuleList &matching_module_list)
905254721Semaste{
906254721Semaste    return GetSharedModuleList ().FindModules (module_spec, matching_module_list);
907254721Semaste}
908254721Semaste
909254721Semastesize_t
910254721SemasteModuleList::RemoveOrphanSharedModules (bool mandatory)
911254721Semaste{
912254721Semaste    return GetSharedModuleList ().RemoveOrphans(mandatory);
913254721Semaste}
914254721Semaste
915254721SemasteError
916254721SemasteModuleList::GetSharedModule
917254721Semaste(
918254721Semaste    const ModuleSpec &module_spec,
919254721Semaste    ModuleSP &module_sp,
920254721Semaste    const FileSpecList *module_search_paths_ptr,
921254721Semaste    ModuleSP *old_module_sp_ptr,
922254721Semaste    bool *did_create_ptr,
923254721Semaste    bool always_create
924254721Semaste)
925254721Semaste{
926254721Semaste    ModuleList &shared_module_list = GetSharedModuleList ();
927254721Semaste    Mutex::Locker locker(shared_module_list.m_modules_mutex);
928254721Semaste    char path[PATH_MAX];
929254721Semaste
930254721Semaste    Error error;
931254721Semaste
932254721Semaste    module_sp.reset();
933254721Semaste
934254721Semaste    if (did_create_ptr)
935254721Semaste        *did_create_ptr = false;
936254721Semaste    if (old_module_sp_ptr)
937254721Semaste        old_module_sp_ptr->reset();
938254721Semaste
939254721Semaste    const UUID *uuid_ptr = module_spec.GetUUIDPtr();
940254721Semaste    const FileSpec &module_file_spec = module_spec.GetFileSpec();
941254721Semaste    const ArchSpec &arch = module_spec.GetArchitecture();
942254721Semaste
943254721Semaste    // Make sure no one else can try and get or create a module while this
944254721Semaste    // function is actively working on it by doing an extra lock on the
945254721Semaste    // global mutex list.
946254721Semaste    if (always_create == false)
947254721Semaste    {
948254721Semaste        ModuleList matching_module_list;
949254721Semaste        const size_t num_matching_modules = shared_module_list.FindModules (module_spec, matching_module_list);
950254721Semaste        if (num_matching_modules > 0)
951254721Semaste        {
952254721Semaste            for (size_t module_idx = 0; module_idx < num_matching_modules; ++module_idx)
953254721Semaste            {
954254721Semaste                module_sp = matching_module_list.GetModuleAtIndex(module_idx);
955276479Sdim
956254721Semaste                // Make sure the file for the module hasn't been modified
957254721Semaste                if (module_sp->FileHasChanged())
958254721Semaste                {
959254721Semaste                    if (old_module_sp_ptr && !old_module_sp_ptr->get())
960254721Semaste                        *old_module_sp_ptr = module_sp;
961254721Semaste
962254721Semaste                    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_MODULES));
963254721Semaste                    if (log)
964276479Sdim                        log->Printf("module changed: %p, removing from global module list",
965276479Sdim                                    static_cast<void*>(module_sp.get()));
966254721Semaste
967254721Semaste                    shared_module_list.Remove (module_sp);
968254721Semaste                    module_sp.reset();
969254721Semaste                }
970254721Semaste                else
971254721Semaste                {
972254721Semaste                    // The module matches and the module was not modified from
973254721Semaste                    // when it was last loaded.
974254721Semaste                    return error;
975254721Semaste                }
976254721Semaste            }
977254721Semaste        }
978254721Semaste    }
979254721Semaste
980254721Semaste    if (module_sp)
981254721Semaste        return error;
982288943Sdim
983288943Sdim    module_sp.reset (new Module (module_spec));
984288943Sdim    // Make sure there are a module and an object file since we can specify
985288943Sdim    // a valid file path with an architecture that might not be in that file.
986288943Sdim    // By getting the object file we can guarantee that the architecture matches
987288943Sdim    if (module_sp->GetObjectFile())
988288943Sdim    {
989288943Sdim        // If we get in here we got the correct arch, now we just need
990288943Sdim        // to verify the UUID if one was given
991288943Sdim        if (uuid_ptr && *uuid_ptr != module_sp->GetUUID())
992296417Sdim        {
993288943Sdim            module_sp.reset();
994296417Sdim        }
995288943Sdim        else
996288943Sdim        {
997296417Sdim            if (module_sp->GetObjectFile() && module_sp->GetObjectFile()->GetType() == ObjectFile::eTypeStubLibrary)
998296417Sdim            {
999296417Sdim                module_sp.reset();
1000296417Sdim            }
1001296417Sdim            else
1002296417Sdim            {
1003296417Sdim                if (did_create_ptr)
1004296417Sdim                {
1005296417Sdim                    *did_create_ptr = true;
1006296417Sdim                }
1007288943Sdim
1008296417Sdim                shared_module_list.ReplaceEquivalent(module_sp);
1009296417Sdim                return error;
1010296417Sdim            }
1011288943Sdim        }
1012288943Sdim    }
1013254721Semaste    else
1014296417Sdim    {
1015288943Sdim        module_sp.reset();
1016296417Sdim    }
1017288943Sdim
1018288943Sdim    if (module_search_paths_ptr)
1019254721Semaste    {
1020288943Sdim        const auto num_directories = module_search_paths_ptr->GetSize();
1021288943Sdim        for (size_t idx = 0; idx < num_directories; ++idx)
1022254721Semaste        {
1023288943Sdim            auto search_path_spec = module_search_paths_ptr->GetFileSpecAtIndex(idx);
1024288943Sdim            if (!search_path_spec.ResolvePath())
1025288943Sdim                continue;
1026288943Sdim            if (!search_path_spec.Exists() || !search_path_spec.IsDirectory())
1027288943Sdim                continue;
1028288943Sdim            search_path_spec.AppendPathComponent(module_spec.GetFileSpec().GetFilename().AsCString());
1029288943Sdim            if (!search_path_spec.Exists())
1030288943Sdim                continue;
1031288943Sdim
1032288943Sdim            auto resolved_module_spec(module_spec);
1033288943Sdim            resolved_module_spec.GetFileSpec() = search_path_spec;
1034288943Sdim            module_sp.reset (new Module (resolved_module_spec));
1035254721Semaste            if (module_sp->GetObjectFile())
1036254721Semaste            {
1037254721Semaste                // If we get in here we got the correct arch, now we just need
1038254721Semaste                // to verify the UUID if one was given
1039254721Semaste                if (uuid_ptr && *uuid_ptr != module_sp->GetUUID())
1040296417Sdim                {
1041254721Semaste                    module_sp.reset();
1042296417Sdim                }
1043254721Semaste                else
1044254721Semaste                {
1045296417Sdim                    if (module_sp->GetObjectFile()->GetType() == ObjectFile::eTypeStubLibrary)
1046296417Sdim                    {
1047296417Sdim                        module_sp.reset();
1048296417Sdim                    }
1049296417Sdim                    else
1050296417Sdim                    {
1051296417Sdim                        if (did_create_ptr)
1052296417Sdim                            *did_create_ptr = true;
1053296417Sdim
1054296417Sdim                        shared_module_list.ReplaceEquivalent(module_sp);
1055296417Sdim                        return Error();
1056296417Sdim                    }
1057254721Semaste                }
1058254721Semaste            }
1059254721Semaste            else
1060296417Sdim            {
1061254721Semaste                module_sp.reset();
1062296417Sdim            }
1063254721Semaste        }
1064254721Semaste    }
1065254721Semaste
1066254721Semaste    // Either the file didn't exist where at the path, or no path was given, so
1067254721Semaste    // we now have to use more extreme measures to try and find the appropriate
1068254721Semaste    // module.
1069254721Semaste
1070254721Semaste    // Fixup the incoming path in case the path points to a valid file, yet
1071254721Semaste    // the arch or UUID (if one was passed in) don't match.
1072296417Sdim    ModuleSpec located_binary_modulespec = Symbols::LocateExecutableObjectFile (module_spec);
1073254721Semaste
1074254721Semaste    // Don't look for the file if it appears to be the same one we already
1075254721Semaste    // checked for above...
1076296417Sdim    if (located_binary_modulespec.GetFileSpec() != module_file_spec)
1077254721Semaste    {
1078296417Sdim        if (!located_binary_modulespec.GetFileSpec().Exists())
1079254721Semaste        {
1080296417Sdim            located_binary_modulespec.GetFileSpec().GetPath(path, sizeof(path));
1081254721Semaste            if (path[0] == '\0')
1082254721Semaste                module_file_spec.GetPath(path, sizeof(path));
1083276479Sdim            // How can this check ever be true? This branch it is false, and we haven't modified file_spec.
1084296417Sdim            if (located_binary_modulespec.GetFileSpec().Exists())
1085254721Semaste            {
1086254721Semaste                std::string uuid_str;
1087254721Semaste                if (uuid_ptr && uuid_ptr->IsValid())
1088254721Semaste                    uuid_str = uuid_ptr->GetAsString();
1089254721Semaste
1090254721Semaste                if (arch.IsValid())
1091254721Semaste                {
1092254721Semaste                    if (!uuid_str.empty())
1093254721Semaste                        error.SetErrorStringWithFormat("'%s' does not contain the %s architecture and UUID %s", path, arch.GetArchitectureName(), uuid_str.c_str());
1094254721Semaste                    else
1095254721Semaste                        error.SetErrorStringWithFormat("'%s' does not contain the %s architecture.", path, arch.GetArchitectureName());
1096254721Semaste                }
1097254721Semaste            }
1098254721Semaste            else
1099254721Semaste            {
1100254721Semaste                error.SetErrorStringWithFormat("'%s' does not exist", path);
1101254721Semaste            }
1102254721Semaste            if (error.Fail())
1103254721Semaste                module_sp.reset();
1104254721Semaste            return error;
1105254721Semaste        }
1106254721Semaste
1107254721Semaste
1108254721Semaste        // Make sure no one else can try and get or create a module while this
1109254721Semaste        // function is actively working on it by doing an extra lock on the
1110254721Semaste        // global mutex list.
1111254721Semaste        ModuleSpec platform_module_spec(module_spec);
1112296417Sdim        platform_module_spec.GetFileSpec() = located_binary_modulespec.GetFileSpec();
1113296417Sdim        platform_module_spec.GetPlatformFileSpec() = located_binary_modulespec.GetFileSpec();
1114296417Sdim        platform_module_spec.GetSymbolFileSpec() = located_binary_modulespec.GetSymbolFileSpec();
1115254721Semaste        ModuleList matching_module_list;
1116254721Semaste        if (shared_module_list.FindModules (platform_module_spec, matching_module_list) > 0)
1117254721Semaste        {
1118254721Semaste            module_sp = matching_module_list.GetModuleAtIndex(0);
1119254721Semaste
1120254721Semaste            // If we didn't have a UUID in mind when looking for the object file,
1121254721Semaste            // then we should make sure the modification time hasn't changed!
1122254721Semaste            if (platform_module_spec.GetUUIDPtr() == NULL)
1123254721Semaste            {
1124296417Sdim                TimeValue file_spec_mod_time(located_binary_modulespec.GetFileSpec().GetModificationTime());
1125254721Semaste                if (file_spec_mod_time.IsValid())
1126254721Semaste                {
1127254721Semaste                    if (file_spec_mod_time != module_sp->GetModificationTime())
1128254721Semaste                    {
1129254721Semaste                        if (old_module_sp_ptr)
1130254721Semaste                            *old_module_sp_ptr = module_sp;
1131254721Semaste                        shared_module_list.Remove (module_sp);
1132254721Semaste                        module_sp.reset();
1133254721Semaste                    }
1134254721Semaste                }
1135254721Semaste            }
1136254721Semaste        }
1137254721Semaste
1138254721Semaste        if (module_sp.get() == NULL)
1139254721Semaste        {
1140254721Semaste            module_sp.reset (new Module (platform_module_spec));
1141254721Semaste            // Make sure there are a module and an object file since we can specify
1142254721Semaste            // a valid file path with an architecture that might not be in that file.
1143254721Semaste            // By getting the object file we can guarantee that the architecture matches
1144254721Semaste            if (module_sp && module_sp->GetObjectFile())
1145254721Semaste            {
1146296417Sdim                if (module_sp->GetObjectFile()->GetType() == ObjectFile::eTypeStubLibrary)
1147296417Sdim                {
1148296417Sdim                    module_sp.reset();
1149296417Sdim                }
1150296417Sdim                else
1151296417Sdim                {
1152296417Sdim                    if (did_create_ptr)
1153296417Sdim                        *did_create_ptr = true;
1154254721Semaste
1155296417Sdim                    shared_module_list.ReplaceEquivalent(module_sp);
1156296417Sdim                }
1157254721Semaste            }
1158254721Semaste            else
1159254721Semaste            {
1160296417Sdim                located_binary_modulespec.GetFileSpec().GetPath(path, sizeof(path));
1161254721Semaste
1162296417Sdim                if (located_binary_modulespec.GetFileSpec())
1163254721Semaste                {
1164254721Semaste                    if (arch.IsValid())
1165254721Semaste                        error.SetErrorStringWithFormat("unable to open %s architecture in '%s'", arch.GetArchitectureName(), path);
1166254721Semaste                    else
1167254721Semaste                        error.SetErrorStringWithFormat("unable to open '%s'", path);
1168254721Semaste                }
1169254721Semaste                else
1170254721Semaste                {
1171254721Semaste                    std::string uuid_str;
1172254721Semaste                    if (uuid_ptr && uuid_ptr->IsValid())
1173254721Semaste                        uuid_str = uuid_ptr->GetAsString();
1174254721Semaste
1175254721Semaste                    if (!uuid_str.empty())
1176254721Semaste                        error.SetErrorStringWithFormat("cannot locate a module for UUID '%s'", uuid_str.c_str());
1177254721Semaste                    else
1178254721Semaste                        error.SetErrorStringWithFormat("cannot locate a module");
1179254721Semaste                }
1180254721Semaste            }
1181254721Semaste        }
1182254721Semaste    }
1183254721Semaste
1184254721Semaste    return error;
1185254721Semaste}
1186254721Semaste
1187254721Semastebool
1188254721SemasteModuleList::RemoveSharedModule (lldb::ModuleSP &module_sp)
1189254721Semaste{
1190254721Semaste    return GetSharedModuleList ().Remove (module_sp);
1191254721Semaste}
1192254721Semaste
1193254721Semastebool
1194254721SemasteModuleList::RemoveSharedModuleIfOrphaned (const Module *module_ptr)
1195254721Semaste{
1196254721Semaste    return GetSharedModuleList ().RemoveIfOrphaned (module_ptr);
1197254721Semaste}
1198254721Semaste
1199254721Semastebool
1200254721SemasteModuleList::LoadScriptingResourcesInTarget (Target *target,
1201254721Semaste                                            std::list<Error>& errors,
1202254721Semaste                                            Stream *feedback_stream,
1203254721Semaste                                            bool continue_on_error)
1204254721Semaste{
1205254721Semaste    if (!target)
1206254721Semaste        return false;
1207254721Semaste    Mutex::Locker locker(m_modules_mutex);
1208254721Semaste    for (auto module : m_modules)
1209254721Semaste    {
1210254721Semaste        Error error;
1211254721Semaste        if (module)
1212254721Semaste        {
1213254721Semaste            if (!module->LoadScriptingResourceInTarget(target, error, feedback_stream))
1214254721Semaste            {
1215254721Semaste                if (error.Fail() && error.AsCString())
1216254721Semaste                {
1217254721Semaste                    error.SetErrorStringWithFormat("unable to load scripting data for module %s - error reported was %s",
1218254721Semaste                                                   module->GetFileSpec().GetFileNameStrippingExtension().GetCString(),
1219254721Semaste                                                   error.AsCString());
1220254721Semaste                    errors.push_back(error);
1221276479Sdim
1222276479Sdim                    if (!continue_on_error)
1223276479Sdim                        return false;
1224254721Semaste                }
1225254721Semaste            }
1226254721Semaste        }
1227254721Semaste    }
1228254721Semaste    return errors.size() == 0;
1229254721Semaste}
1230288943Sdim
1231288943Sdimvoid
1232288943SdimModuleList::ForEach (std::function <bool (const ModuleSP &module_sp)> const &callback) const
1233288943Sdim{
1234288943Sdim    Mutex::Locker locker(m_modules_mutex);
1235288943Sdim    for (const auto &module : m_modules)
1236288943Sdim    {
1237288943Sdim        // If the callback returns false, then stop iterating and break out
1238288943Sdim        if (!callback (module))
1239288943Sdim            break;
1240288943Sdim    }
1241288943Sdim}
1242