180814287SRaphael Isemann //===-- ModuleList.cpp ----------------------------------------------------===//
230fdc8d8SChris Lattner //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
630fdc8d8SChris Lattner //
730fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
830fdc8d8SChris Lattner 
930fdc8d8SChris Lattner #include "lldb/Core/ModuleList.h"
10672d2c12SJonas Devlieghere #include "lldb/Core/FileSpecList.h"
1130fdc8d8SChris Lattner #include "lldb/Core/Module.h"
121f746071SGreg Clayton #include "lldb/Core/ModuleSpec.h"
131408bf72SPavel Labath #include "lldb/Host/FileSystem.h"
14235354beSAdrian Prantl #include "lldb/Interpreter/OptionValueFileSpec.h"
1527df2d9fSPavel Labath #include "lldb/Interpreter/OptionValueFileSpecList.h"
16672d2c12SJonas Devlieghere #include "lldb/Interpreter/OptionValueProperties.h"
17235354beSAdrian Prantl #include "lldb/Interpreter/Property.h"
1880552918SZachary Turner #include "lldb/Symbol/LocateSymbolFile.h"
1930fdc8d8SChris Lattner #include "lldb/Symbol/ObjectFile.h"
20672d2c12SJonas Devlieghere #include "lldb/Symbol/SymbolContext.h"
21bf9d84c0SAdrian Prantl #include "lldb/Symbol/TypeList.h"
2230fdc8d8SChris Lattner #include "lldb/Symbol/VariableList.h"
23672d2c12SJonas Devlieghere #include "lldb/Utility/ArchSpec.h"
24672d2c12SJonas Devlieghere #include "lldb/Utility/ConstString.h"
25c34698a8SPavel Labath #include "lldb/Utility/LLDBLog.h"
266f9e6901SZachary Turner #include "lldb/Utility/Log.h"
27672d2c12SJonas Devlieghere #include "lldb/Utility/UUID.h"
28672d2c12SJonas Devlieghere #include "lldb/lldb-defines.h"
2930fdc8d8SChris Lattner 
30b1cb0b79SNico Weber #if defined(_WIN32)
31672d2c12SJonas Devlieghere #include "lldb/Host/windows/PosixApi.h"
322f3df613SZachary Turner #endif
332f3df613SZachary Turner 
34672d2c12SJonas Devlieghere #include "clang/Driver/Driver.h"
35672d2c12SJonas Devlieghere #include "llvm/ADT/StringRef.h"
367d86ee5aSZachary Turner #include "llvm/Support/FileSystem.h"
37c5f28e2aSKamil Rytarowski #include "llvm/Support/Threading.h"
38672d2c12SJonas Devlieghere #include "llvm/Support/raw_ostream.h"
392f3df613SZachary Turner 
40672d2c12SJonas Devlieghere #include <chrono>
41672d2c12SJonas Devlieghere #include <memory>
422f3df613SZachary Turner #include <mutex>
43672d2c12SJonas Devlieghere #include <string>
44672d2c12SJonas Devlieghere #include <utility>
452f3df613SZachary Turner 
462f3df613SZachary Turner namespace lldb_private {
472f3df613SZachary Turner class Function;
482f3df613SZachary Turner }
492f3df613SZachary Turner namespace lldb_private {
502f3df613SZachary Turner class RegularExpression;
512f3df613SZachary Turner }
522f3df613SZachary Turner namespace lldb_private {
532f3df613SZachary Turner class Stream;
542f3df613SZachary Turner }
552f3df613SZachary Turner namespace lldb_private {
562f3df613SZachary Turner class SymbolFile;
572f3df613SZachary Turner }
582f3df613SZachary Turner namespace lldb_private {
592f3df613SZachary Turner class Target;
602f3df613SZachary Turner }
61c5f28e2aSKamil Rytarowski 
6230fdc8d8SChris Lattner using namespace lldb;
6330fdc8d8SChris Lattner using namespace lldb_private;
6430fdc8d8SChris Lattner 
65235354beSAdrian Prantl namespace {
66235354beSAdrian Prantl 
67971f9ca6SJonas Devlieghere #define LLDB_PROPERTIES_modulelist
686a253d37SJordan Rupprecht #include "CoreProperties.inc"
69235354beSAdrian Prantl 
70971f9ca6SJonas Devlieghere enum {
71971f9ca6SJonas Devlieghere #define LLDB_PROPERTIES_modulelist
726a253d37SJordan Rupprecht #include "CorePropertiesEnum.inc"
73971f9ca6SJonas Devlieghere };
74235354beSAdrian Prantl 
75235354beSAdrian Prantl } // namespace
76235354beSAdrian Prantl 
ModuleListProperties()77235354beSAdrian Prantl ModuleListProperties::ModuleListProperties() {
78796ac80bSJonas Devlieghere   m_collection_sp =
79796ac80bSJonas Devlieghere       std::make_shared<OptionValueProperties>(ConstString("symbols"));
80a8ea5955SJonas Devlieghere   m_collection_sp->Initialize(g_modulelist_properties);
8127df2d9fSPavel Labath   m_collection_sp->SetValueChangedCallback(ePropertySymLinkPaths,
8227df2d9fSPavel Labath                                            [this] { UpdateSymlinkMappings(); });
83235354beSAdrian Prantl 
84235354beSAdrian Prantl   llvm::SmallString<128> path;
85208e3f5dSRaphael Isemann   if (clang::driver::Driver::getDefaultModuleCachePath(path)) {
86208e3f5dSRaphael Isemann     lldbassert(SetClangModulesCachePath(FileSpec(path)));
87208e3f5dSRaphael Isemann   }
88da816ca0SGreg Clayton 
89da816ca0SGreg Clayton   path.clear();
90da816ca0SGreg Clayton   if (llvm::sys::path::cache_directory(path)) {
91da816ca0SGreg Clayton     llvm::sys::path::append(path, "lldb");
92da816ca0SGreg Clayton     llvm::sys::path::append(path, "IndexCache");
93da816ca0SGreg Clayton     lldbassert(SetLLDBIndexCachePath(FileSpec(path)));
94da816ca0SGreg Clayton   }
95da816ca0SGreg Clayton 
96235354beSAdrian Prantl }
97235354beSAdrian Prantl 
GetEnableExternalLookup() const981cc1c5f2SAdrian Prantl bool ModuleListProperties::GetEnableExternalLookup() const {
991cc1c5f2SAdrian Prantl   const uint32_t idx = ePropertyEnableExternalLookup;
1001cc1c5f2SAdrian Prantl   return m_collection_sp->GetPropertyAtIndexAsBoolean(
101a8ea5955SJonas Devlieghere       nullptr, idx, g_modulelist_properties[idx].default_uint_value != 0);
1021cc1c5f2SAdrian Prantl }
1031cc1c5f2SAdrian Prantl 
SetEnableExternalLookup(bool new_value)1048c82c412SJan Kratochvil bool ModuleListProperties::SetEnableExternalLookup(bool new_value) {
1058c82c412SJan Kratochvil   return m_collection_sp->SetPropertyAtIndexAsBoolean(
1068c82c412SJan Kratochvil       nullptr, ePropertyEnableExternalLookup, new_value);
1078c82c412SJan Kratochvil }
1088c82c412SJan Kratochvil 
GetClangModulesCachePath() const109235354beSAdrian Prantl FileSpec ModuleListProperties::GetClangModulesCachePath() const {
110235354beSAdrian Prantl   return m_collection_sp
111235354beSAdrian Prantl       ->GetPropertyAtIndexAsOptionValueFileSpec(nullptr, false,
112235354beSAdrian Prantl                                                 ePropertyClangModulesCachePath)
113235354beSAdrian Prantl       ->GetCurrentValue();
114235354beSAdrian Prantl }
115235354beSAdrian Prantl 
SetClangModulesCachePath(const FileSpec & path)116208e3f5dSRaphael Isemann bool ModuleListProperties::SetClangModulesCachePath(const FileSpec &path) {
117208e3f5dSRaphael Isemann   return m_collection_sp->SetPropertyAtIndexAsFileSpec(
118235354beSAdrian Prantl       nullptr, ePropertyClangModulesCachePath, path);
119235354beSAdrian Prantl }
120235354beSAdrian Prantl 
GetLLDBIndexCachePath() const121da816ca0SGreg Clayton FileSpec ModuleListProperties::GetLLDBIndexCachePath() const {
122da816ca0SGreg Clayton   return m_collection_sp
123da816ca0SGreg Clayton       ->GetPropertyAtIndexAsOptionValueFileSpec(nullptr, false,
124da816ca0SGreg Clayton                                                 ePropertyLLDBIndexCachePath)
125da816ca0SGreg Clayton       ->GetCurrentValue();
126da816ca0SGreg Clayton }
127da816ca0SGreg Clayton 
SetLLDBIndexCachePath(const FileSpec & path)128da816ca0SGreg Clayton bool ModuleListProperties::SetLLDBIndexCachePath(const FileSpec &path) {
129da816ca0SGreg Clayton   return m_collection_sp->SetPropertyAtIndexAsFileSpec(
130da816ca0SGreg Clayton       nullptr, ePropertyLLDBIndexCachePath, path);
131da816ca0SGreg Clayton }
132da816ca0SGreg Clayton 
GetEnableLLDBIndexCache() const133da816ca0SGreg Clayton bool ModuleListProperties::GetEnableLLDBIndexCache() const {
134da816ca0SGreg Clayton   const uint32_t idx = ePropertyEnableLLDBIndexCache;
135da816ca0SGreg Clayton   return m_collection_sp->GetPropertyAtIndexAsBoolean(
136da816ca0SGreg Clayton       nullptr, idx, g_modulelist_properties[idx].default_uint_value != 0);
137da816ca0SGreg Clayton }
138da816ca0SGreg Clayton 
SetEnableLLDBIndexCache(bool new_value)139da816ca0SGreg Clayton bool ModuleListProperties::SetEnableLLDBIndexCache(bool new_value) {
140da816ca0SGreg Clayton   return m_collection_sp->SetPropertyAtIndexAsBoolean(
141da816ca0SGreg Clayton       nullptr, ePropertyEnableLLDBIndexCache, new_value);
142da816ca0SGreg Clayton }
143da816ca0SGreg Clayton 
GetLLDBIndexCacheMaxByteSize()144da816ca0SGreg Clayton uint64_t ModuleListProperties::GetLLDBIndexCacheMaxByteSize() {
145da816ca0SGreg Clayton   const uint32_t idx = ePropertyLLDBIndexCacheMaxByteSize;
146da816ca0SGreg Clayton   return m_collection_sp->GetPropertyAtIndexAsUInt64(
147da816ca0SGreg Clayton       nullptr, idx, g_modulelist_properties[idx].default_uint_value);
148da816ca0SGreg Clayton }
149da816ca0SGreg Clayton 
GetLLDBIndexCacheMaxPercent()150da816ca0SGreg Clayton uint64_t ModuleListProperties::GetLLDBIndexCacheMaxPercent() {
151da816ca0SGreg Clayton   const uint32_t idx = ePropertyLLDBIndexCacheMaxPercent;
152da816ca0SGreg Clayton   return m_collection_sp->GetPropertyAtIndexAsUInt64(
153da816ca0SGreg Clayton       nullptr, idx, g_modulelist_properties[idx].default_uint_value);
154da816ca0SGreg Clayton }
155da816ca0SGreg Clayton 
GetLLDBIndexCacheExpirationDays()156da816ca0SGreg Clayton uint64_t ModuleListProperties::GetLLDBIndexCacheExpirationDays() {
157da816ca0SGreg Clayton   const uint32_t idx = ePropertyLLDBIndexCacheExpirationDays;
158da816ca0SGreg Clayton   return m_collection_sp->GetPropertyAtIndexAsUInt64(
159da816ca0SGreg Clayton       nullptr, idx, g_modulelist_properties[idx].default_uint_value);
160da816ca0SGreg Clayton }
161da816ca0SGreg Clayton 
UpdateSymlinkMappings()16227df2d9fSPavel Labath void ModuleListProperties::UpdateSymlinkMappings() {
16327df2d9fSPavel Labath   FileSpecList list = m_collection_sp
16427df2d9fSPavel Labath                           ->GetPropertyAtIndexAsOptionValueFileSpecList(
16527df2d9fSPavel Labath                               nullptr, false, ePropertySymLinkPaths)
16627df2d9fSPavel Labath                           ->GetCurrentValue();
16727df2d9fSPavel Labath   llvm::sys::ScopedWriter lock(m_symlink_paths_mutex);
16827df2d9fSPavel Labath   const bool notify = false;
16927df2d9fSPavel Labath   m_symlink_paths.Clear(notify);
17027df2d9fSPavel Labath   for (FileSpec symlink : list) {
17127df2d9fSPavel Labath     FileSpec resolved;
17227df2d9fSPavel Labath     Status status = FileSystem::Instance().Readlink(symlink, resolved);
17327df2d9fSPavel Labath     if (status.Success())
174dfd499a6SXu Jun       m_symlink_paths.Append(symlink.GetPath(), resolved.GetPath(), notify);
17527df2d9fSPavel Labath   }
17627df2d9fSPavel Labath }
17727df2d9fSPavel Labath 
GetSymlinkMappings() const17827df2d9fSPavel Labath PathMappingList ModuleListProperties::GetSymlinkMappings() const {
17927df2d9fSPavel Labath   llvm::sys::ScopedReader lock(m_symlink_paths_mutex);
18027df2d9fSPavel Labath   return m_symlink_paths;
18127df2d9fSPavel Labath }
18227df2d9fSPavel Labath 
GetLoadSymbolOnDemand()183*7b81192dSJeffrey Tan bool ModuleListProperties::GetLoadSymbolOnDemand() {
184*7b81192dSJeffrey Tan   const uint32_t idx = ePropertyLoadSymbolOnDemand;
185*7b81192dSJeffrey Tan   return m_collection_sp->GetPropertyAtIndexAsBoolean(
186*7b81192dSJeffrey Tan       nullptr, idx, g_modulelist_properties[idx].default_uint_value != 0);
187*7b81192dSJeffrey Tan }
188*7b81192dSJeffrey Tan 
ModuleList()1899494c510SJonas Devlieghere ModuleList::ModuleList() : m_modules(), m_modules_mutex() {}
19030fdc8d8SChris Lattner 
ModuleList(const ModuleList & rhs)19128c878aeSShafik Yaghmour ModuleList::ModuleList(const ModuleList &rhs) : m_modules(), m_modules_mutex() {
192bb19a13cSSaleem Abdulrasool   std::lock_guard<std::recursive_mutex> lhs_guard(m_modules_mutex);
193bb19a13cSSaleem Abdulrasool   std::lock_guard<std::recursive_mutex> rhs_guard(rhs.m_modules_mutex);
1948921ce83SGreg Clayton   m_modules = rhs.m_modules;
1951759848bSEnrico Granata }
1961759848bSEnrico Granata 
ModuleList(ModuleList::Notifier * notifier)197b9c1b51eSKate Stone ModuleList::ModuleList(ModuleList::Notifier *notifier)
198b9c1b51eSKate Stone     : m_modules(), m_modules_mutex(), m_notifier(notifier) {}
19930fdc8d8SChris Lattner 
operator =(const ModuleList & rhs)200b9c1b51eSKate Stone const ModuleList &ModuleList::operator=(const ModuleList &rhs) {
201b9c1b51eSKate Stone   if (this != &rhs) {
202cdd4892fSJim Ingham     std::lock(m_modules_mutex, rhs.m_modules_mutex);
203cdd4892fSJim Ingham     std::lock_guard<std::recursive_mutex> lhs_guard(m_modules_mutex,
204cdd4892fSJim Ingham                                                     std::adopt_lock);
205cdd4892fSJim Ingham     std::lock_guard<std::recursive_mutex> rhs_guard(rhs.m_modules_mutex,
206cdd4892fSJim Ingham                                                     std::adopt_lock);
20730fdc8d8SChris Lattner     m_modules = rhs.m_modules;
2081d77a820SGreg Clayton   }
20930fdc8d8SChris Lattner   return *this;
21030fdc8d8SChris Lattner }
21130fdc8d8SChris Lattner 
212c5dac77aSEugene Zelenko ModuleList::~ModuleList() = default;
21330fdc8d8SChris Lattner 
AppendImpl(const ModuleSP & module_sp,bool use_notifier)214b9c1b51eSKate Stone void ModuleList::AppendImpl(const ModuleSP &module_sp, bool use_notifier) {
215b9c1b51eSKate Stone   if (module_sp) {
216bb19a13cSSaleem Abdulrasool     std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
21730fdc8d8SChris Lattner     m_modules.push_back(module_sp);
2181759848bSEnrico Granata     if (use_notifier && m_notifier)
2191724a179SJason Molenda       m_notifier->NotifyModuleAdded(*this, module_sp);
22030fdc8d8SChris Lattner   }
2218b82f087SGreg Clayton }
22230fdc8d8SChris Lattner 
Append(const ModuleSP & module_sp,bool notify)2231724a179SJason Molenda void ModuleList::Append(const ModuleSP &module_sp, bool notify) {
2241724a179SJason Molenda   AppendImpl(module_sp, notify);
2251724a179SJason Molenda }
2261759848bSEnrico Granata 
ReplaceEquivalent(const ModuleSP & module_sp,llvm::SmallVectorImpl<lldb::ModuleSP> * old_modules)227d20aa7caSJoseph Tremoulet void ModuleList::ReplaceEquivalent(
228d20aa7caSJoseph Tremoulet     const ModuleSP &module_sp,
229d20aa7caSJoseph Tremoulet     llvm::SmallVectorImpl<lldb::ModuleSP> *old_modules) {
230b9c1b51eSKate Stone   if (module_sp) {
231bb19a13cSSaleem Abdulrasool     std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
2324e0fe8abSGreg Clayton 
2334e0fe8abSGreg Clayton     // First remove any equivalent modules. Equivalent modules are modules
2344e0fe8abSGreg Clayton     // whose path, platform path and architecture match.
235b9c1b51eSKate Stone     ModuleSpec equivalent_module_spec(module_sp->GetFileSpec(),
236b9c1b51eSKate Stone                                       module_sp->GetArchitecture());
237b9c1b51eSKate Stone     equivalent_module_spec.GetPlatformFileSpec() =
238b9c1b51eSKate Stone         module_sp->GetPlatformFileSpec();
2394e0fe8abSGreg Clayton 
2404e0fe8abSGreg Clayton     size_t idx = 0;
241b9c1b51eSKate Stone     while (idx < m_modules.size()) {
242d20aa7caSJoseph Tremoulet       ModuleSP test_module_sp(m_modules[idx]);
243d20aa7caSJoseph Tremoulet       if (test_module_sp->MatchesModuleSpec(equivalent_module_spec)) {
244d20aa7caSJoseph Tremoulet         if (old_modules)
245d20aa7caSJoseph Tremoulet           old_modules->push_back(test_module_sp);
2461759848bSEnrico Granata         RemoveImpl(m_modules.begin() + idx);
247d20aa7caSJoseph Tremoulet       } else {
2484e0fe8abSGreg Clayton         ++idx;
2494e0fe8abSGreg Clayton       }
250d20aa7caSJoseph Tremoulet     }
2514e0fe8abSGreg Clayton     // Now add the new module to the list
2521759848bSEnrico Granata     Append(module_sp);
2534e0fe8abSGreg Clayton   }
2544e0fe8abSGreg Clayton }
2554e0fe8abSGreg Clayton 
AppendIfNeeded(const ModuleSP & new_module,bool notify)2564cf9d1e4SRaphael Isemann bool ModuleList::AppendIfNeeded(const ModuleSP &new_module, bool notify) {
2574cf9d1e4SRaphael Isemann   if (new_module) {
258bb19a13cSSaleem Abdulrasool     std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
2594cf9d1e4SRaphael Isemann     for (const ModuleSP &module_sp : m_modules) {
2604cf9d1e4SRaphael Isemann       if (module_sp.get() == new_module.get())
26130fdc8d8SChris Lattner         return false; // Already in the list
26230fdc8d8SChris Lattner     }
26330fdc8d8SChris Lattner     // Only push module_sp on the list if it wasn't already in there.
2644cf9d1e4SRaphael Isemann     Append(new_module, notify);
26530fdc8d8SChris Lattner     return true;
26630fdc8d8SChris Lattner   }
2678b82f087SGreg Clayton   return false;
2688b82f087SGreg Clayton }
26930fdc8d8SChris Lattner 
Append(const ModuleList & module_list)270b9c1b51eSKate Stone void ModuleList::Append(const ModuleList &module_list) {
2711759848bSEnrico Granata   for (auto pos : module_list.m_modules)
2721759848bSEnrico Granata     Append(pos);
2731759848bSEnrico Granata }
2741759848bSEnrico Granata 
AppendIfNeeded(const ModuleList & module_list)275b9c1b51eSKate Stone bool ModuleList::AppendIfNeeded(const ModuleList &module_list) {
2761759848bSEnrico Granata   bool any_in = false;
277b9c1b51eSKate Stone   for (auto pos : module_list.m_modules) {
278fd814c5aSGreg Clayton     if (AppendIfNeeded(pos))
279fd814c5aSGreg Clayton       any_in = true;
280fd814c5aSGreg Clayton   }
2811759848bSEnrico Granata   return any_in;
2821759848bSEnrico Granata }
2831759848bSEnrico Granata 
RemoveImpl(const ModuleSP & module_sp,bool use_notifier)284b9c1b51eSKate Stone bool ModuleList::RemoveImpl(const ModuleSP &module_sp, bool use_notifier) {
285b9c1b51eSKate Stone   if (module_sp) {
286bb19a13cSSaleem Abdulrasool     std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
28730fdc8d8SChris Lattner     collection::iterator pos, end = m_modules.end();
288b9c1b51eSKate Stone     for (pos = m_modules.begin(); pos != end; ++pos) {
289b9c1b51eSKate Stone       if (pos->get() == module_sp.get()) {
29030fdc8d8SChris Lattner         m_modules.erase(pos);
2911759848bSEnrico Granata         if (use_notifier && m_notifier)
2921724a179SJason Molenda           m_notifier->NotifyModuleRemoved(*this, module_sp);
29330fdc8d8SChris Lattner         return true;
29430fdc8d8SChris Lattner       }
29530fdc8d8SChris Lattner     }
2968b82f087SGreg Clayton   }
29730fdc8d8SChris Lattner   return false;
29830fdc8d8SChris Lattner }
29930fdc8d8SChris Lattner 
3001759848bSEnrico Granata ModuleList::collection::iterator
RemoveImpl(ModuleList::collection::iterator pos,bool use_notifier)301b9c1b51eSKate Stone ModuleList::RemoveImpl(ModuleList::collection::iterator pos,
302b9c1b51eSKate Stone                        bool use_notifier) {
3031759848bSEnrico Granata   ModuleSP module_sp(*pos);
3041759848bSEnrico Granata   collection::iterator retval = m_modules.erase(pos);
3051759848bSEnrico Granata   if (use_notifier && m_notifier)
3061724a179SJason Molenda     m_notifier->NotifyModuleRemoved(*this, module_sp);
3071759848bSEnrico Granata   return retval;
3081759848bSEnrico Granata }
3091759848bSEnrico Granata 
Remove(const ModuleSP & module_sp,bool notify)3101724a179SJason Molenda bool ModuleList::Remove(const ModuleSP &module_sp, bool notify) {
3111724a179SJason Molenda   return RemoveImpl(module_sp, notify);
3121759848bSEnrico Granata }
3131759848bSEnrico Granata 
ReplaceModule(const lldb::ModuleSP & old_module_sp,const lldb::ModuleSP & new_module_sp)314b9c1b51eSKate Stone bool ModuleList::ReplaceModule(const lldb::ModuleSP &old_module_sp,
315b9c1b51eSKate Stone                                const lldb::ModuleSP &new_module_sp) {
3161759848bSEnrico Granata   if (!RemoveImpl(old_module_sp, false))
3171759848bSEnrico Granata     return false;
3181759848bSEnrico Granata   AppendImpl(new_module_sp, false);
3191759848bSEnrico Granata   if (m_notifier)
3201724a179SJason Molenda     m_notifier->NotifyModuleUpdated(*this, old_module_sp, new_module_sp);
3211759848bSEnrico Granata   return true;
3221759848bSEnrico Granata }
3231759848bSEnrico Granata 
RemoveIfOrphaned(const Module * module_ptr)324b9c1b51eSKate Stone bool ModuleList::RemoveIfOrphaned(const Module *module_ptr) {
325b9c1b51eSKate Stone   if (module_ptr) {
326bb19a13cSSaleem Abdulrasool     std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
3274a94c910SJim Ingham     collection::iterator pos, end = m_modules.end();
328b9c1b51eSKate Stone     for (pos = m_modules.begin(); pos != end; ++pos) {
329b9c1b51eSKate Stone       if (pos->get() == module_ptr) {
330b9c1b51eSKate Stone         if (pos->unique()) {
3311759848bSEnrico Granata           pos = RemoveImpl(pos);
3324a94c910SJim Ingham           return true;
333b9c1b51eSKate Stone         } else
3344a94c910SJim Ingham           return false;
3354a94c910SJim Ingham       }
3364a94c910SJim Ingham     }
3374a94c910SJim Ingham   }
3384a94c910SJim Ingham   return false;
3394a94c910SJim Ingham }
340aa149cbdSGreg Clayton 
RemoveOrphans(bool mandatory)341b9c1b51eSKate Stone size_t ModuleList::RemoveOrphans(bool mandatory) {
342bb19a13cSSaleem Abdulrasool   std::unique_lock<std::recursive_mutex> lock(m_modules_mutex, std::defer_lock);
3430cd70866SGreg Clayton 
344b9c1b51eSKate Stone   if (mandatory) {
345bb19a13cSSaleem Abdulrasool     lock.lock();
346b9c1b51eSKate Stone   } else {
3470cd70866SGreg Clayton     // Not mandatory, remove orphans if we can get the mutex
348bb19a13cSSaleem Abdulrasool     if (!lock.try_lock())
3490cd70866SGreg Clayton       return 0;
3500cd70866SGreg Clayton   }
351aa149cbdSGreg Clayton   size_t remove_count = 0;
352139e2a3fSRaphael Isemann   // Modules might hold shared pointers to other modules, so removing one
353139e2a3fSRaphael Isemann   // module might make other other modules orphans. Keep removing modules until
354139e2a3fSRaphael Isemann   // there are no further modules that can be removed.
355139e2a3fSRaphael Isemann   bool made_progress = true;
356139e2a3fSRaphael Isemann   while (made_progress) {
357139e2a3fSRaphael Isemann     // Keep track if we make progress this iteration.
358139e2a3fSRaphael Isemann     made_progress = false;
359139e2a3fSRaphael Isemann     collection::iterator pos = m_modules.begin();
360b9c1b51eSKate Stone     while (pos != m_modules.end()) {
361b9c1b51eSKate Stone       if (pos->unique()) {
3621759848bSEnrico Granata         pos = RemoveImpl(pos);
363aa149cbdSGreg Clayton         ++remove_count;
364139e2a3fSRaphael Isemann         // We did make progress.
365139e2a3fSRaphael Isemann         made_progress = true;
366b9c1b51eSKate Stone       } else {
367aa149cbdSGreg Clayton         ++pos;
368aa149cbdSGreg Clayton       }
369aa149cbdSGreg Clayton     }
370139e2a3fSRaphael Isemann   }
371aa149cbdSGreg Clayton   return remove_count;
372aa149cbdSGreg Clayton }
373aa149cbdSGreg Clayton 
Remove(ModuleList & module_list)374b9c1b51eSKate Stone size_t ModuleList::Remove(ModuleList &module_list) {
375bb19a13cSSaleem Abdulrasool   std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
376a4d78300SGreg Clayton   size_t num_removed = 0;
377a4d78300SGreg Clayton   collection::iterator pos, end = module_list.m_modules.end();
378b9c1b51eSKate Stone   for (pos = module_list.m_modules.begin(); pos != end; ++pos) {
3791724a179SJason Molenda     if (Remove(*pos, false /* notify */))
380a4d78300SGreg Clayton       ++num_removed;
381a4d78300SGreg Clayton   }
3821724a179SJason Molenda   if (m_notifier)
3831724a179SJason Molenda     m_notifier->NotifyModulesRemoved(module_list);
384a4d78300SGreg Clayton   return num_removed;
385a4d78300SGreg Clayton }
386a4d78300SGreg Clayton 
Clear()387b9c1b51eSKate Stone void ModuleList::Clear() { ClearImpl(); }
38830fdc8d8SChris Lattner 
Destroy()389b9c1b51eSKate Stone void ModuleList::Destroy() { ClearImpl(); }
39030fdc8d8SChris Lattner 
ClearImpl(bool use_notifier)391b9c1b51eSKate Stone void ModuleList::ClearImpl(bool use_notifier) {
392bb19a13cSSaleem Abdulrasool   std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
3931759848bSEnrico Granata   if (use_notifier && m_notifier)
3941724a179SJason Molenda     m_notifier->NotifyWillClearList(*this);
3951759848bSEnrico Granata   m_modules.clear();
39629ad7b91SGreg Clayton }
39729ad7b91SGreg Clayton 
GetModulePointerAtIndex(size_t idx) const398b9c1b51eSKate Stone Module *ModuleList::GetModulePointerAtIndex(size_t idx) const {
399bb19a13cSSaleem Abdulrasool   std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
40030fdc8d8SChris Lattner   if (idx < m_modules.size())
40130fdc8d8SChris Lattner     return m_modules[idx].get();
402c5dac77aSEugene Zelenko   return nullptr;
40330fdc8d8SChris Lattner }
40430fdc8d8SChris Lattner 
GetModuleAtIndex(size_t idx) const405b9c1b51eSKate Stone ModuleSP ModuleList::GetModuleAtIndex(size_t idx) const {
406bb19a13cSSaleem Abdulrasool   std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
4073ee12ef2SJim Ingham   return GetModuleAtIndexUnlocked(idx);
4083ee12ef2SJim Ingham }
4093ee12ef2SJim Ingham 
GetModuleAtIndexUnlocked(size_t idx) const410b9c1b51eSKate Stone ModuleSP ModuleList::GetModuleAtIndexUnlocked(size_t idx) const {
41130fdc8d8SChris Lattner   ModuleSP module_sp;
41230fdc8d8SChris Lattner   if (idx < m_modules.size())
41330fdc8d8SChris Lattner     module_sp = m_modules[idx];
41430fdc8d8SChris Lattner   return module_sp;
41530fdc8d8SChris Lattner }
41630fdc8d8SChris Lattner 
FindFunctions(ConstString name,FunctionNameType name_type_mask,const ModuleFunctionSearchOptions & options,SymbolContextList & sc_list) const4171ad655e2SAdrian Prantl void ModuleList::FindFunctions(ConstString name,
418117b1fa1SZachary Turner                                FunctionNameType name_type_mask,
419c020be17SJonas Devlieghere                                const ModuleFunctionSearchOptions &options,
420b9c1b51eSKate Stone                                SymbolContextList &sc_list) const {
42143fe217bSGreg Clayton   const size_t old_size = sc_list.GetSize();
42243fe217bSGreg Clayton 
423b9c1b51eSKate Stone   if (name_type_mask & eFunctionNameTypeAuto) {
4246234a5c8SGreg Clayton     Module::LookupInfo lookup_info(name, name_type_mask, eLanguageTypeUnknown);
42543fe217bSGreg Clayton 
426bb19a13cSSaleem Abdulrasool     std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
4274cf9d1e4SRaphael Isemann     for (const ModuleSP &module_sp : m_modules) {
4284cf9d1e4SRaphael Isemann       module_sp->FindFunctions(lookup_info.GetLookupName(),
4294cf9d1e4SRaphael Isemann                                CompilerDeclContext(),
430c020be17SJonas Devlieghere                                lookup_info.GetNameTypeMask(), options, sc_list);
43143fe217bSGreg Clayton     }
43243fe217bSGreg Clayton 
4336234a5c8SGreg Clayton     const size_t new_size = sc_list.GetSize();
4346234a5c8SGreg Clayton 
4356234a5c8SGreg Clayton     if (old_size < new_size)
4366234a5c8SGreg Clayton       lookup_info.Prune(sc_list, old_size);
437b9c1b51eSKate Stone   } else {
438bb19a13cSSaleem Abdulrasool     std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
4394cf9d1e4SRaphael Isemann     for (const ModuleSP &module_sp : m_modules) {
4404cf9d1e4SRaphael Isemann       module_sp->FindFunctions(name, CompilerDeclContext(), name_type_mask,
441c020be17SJonas Devlieghere                                options, sc_list);
44230fdc8d8SChris Lattner     }
44343fe217bSGreg Clayton   }
44430fdc8d8SChris Lattner }
44530fdc8d8SChris Lattner 
FindFunctionSymbols(ConstString name,lldb::FunctionNameType name_type_mask,SymbolContextList & sc_list)4461ad655e2SAdrian Prantl void ModuleList::FindFunctionSymbols(ConstString name,
447117b1fa1SZachary Turner                                      lldb::FunctionNameType name_type_mask,
448b9c1b51eSKate Stone                                      SymbolContextList &sc_list) {
449cc791bbfSMichael Sartain   const size_t old_size = sc_list.GetSize();
450cc791bbfSMichael Sartain 
451b9c1b51eSKate Stone   if (name_type_mask & eFunctionNameTypeAuto) {
4526234a5c8SGreg Clayton     Module::LookupInfo lookup_info(name, name_type_mask, eLanguageTypeUnknown);
453cc791bbfSMichael Sartain 
454bb19a13cSSaleem Abdulrasool     std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
4554cf9d1e4SRaphael Isemann     for (const ModuleSP &module_sp : m_modules) {
4564cf9d1e4SRaphael Isemann       module_sp->FindFunctionSymbols(lookup_info.GetLookupName(),
457b9c1b51eSKate Stone                                      lookup_info.GetNameTypeMask(), sc_list);
458cc791bbfSMichael Sartain     }
459cc791bbfSMichael Sartain 
4606234a5c8SGreg Clayton     const size_t new_size = sc_list.GetSize();
4616234a5c8SGreg Clayton 
4626234a5c8SGreg Clayton     if (old_size < new_size)
4636234a5c8SGreg Clayton       lookup_info.Prune(sc_list, old_size);
464b9c1b51eSKate Stone   } else {
465bb19a13cSSaleem Abdulrasool     std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
4664cf9d1e4SRaphael Isemann     for (const ModuleSP &module_sp : m_modules) {
4674cf9d1e4SRaphael Isemann       module_sp->FindFunctionSymbols(name, name_type_mask, sc_list);
468cc791bbfSMichael Sartain     }
469cc791bbfSMichael Sartain   }
470cc791bbfSMichael Sartain }
471cc791bbfSMichael Sartain 
FindFunctions(const RegularExpression & name,const ModuleFunctionSearchOptions & options,SymbolContextList & sc_list)4721ad655e2SAdrian Prantl void ModuleList::FindFunctions(const RegularExpression &name,
473c020be17SJonas Devlieghere                                const ModuleFunctionSearchOptions &options,
4741ad655e2SAdrian Prantl                                SymbolContextList &sc_list) {
475bb19a13cSSaleem Abdulrasool   std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
4764cf9d1e4SRaphael Isemann   for (const ModuleSP &module_sp : m_modules)
4774cf9d1e4SRaphael Isemann     module_sp->FindFunctions(name, options, sc_list);
4780fd6fd4fSCarlo Kok }
4790fd6fd4fSCarlo Kok 
FindCompileUnits(const FileSpec & path,SymbolContextList & sc_list) const4801ad655e2SAdrian Prantl void ModuleList::FindCompileUnits(const FileSpec &path,
481b9c1b51eSKate Stone                                   SymbolContextList &sc_list) const {
482bb19a13cSSaleem Abdulrasool   std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
4834cf9d1e4SRaphael Isemann   for (const ModuleSP &module_sp : m_modules)
4844cf9d1e4SRaphael Isemann     module_sp->FindCompileUnits(path, sc_list);
485644247c1SGreg Clayton }
486644247c1SGreg Clayton 
FindGlobalVariables(ConstString name,size_t max_matches,VariableList & variable_list) const4871ad655e2SAdrian Prantl void ModuleList::FindGlobalVariables(ConstString name, size_t max_matches,
488b9c1b51eSKate Stone                                      VariableList &variable_list) const {
489bb19a13cSSaleem Abdulrasool   std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
4904cf9d1e4SRaphael Isemann   for (const ModuleSP &module_sp : m_modules) {
4914cf9d1e4SRaphael Isemann     module_sp->FindGlobalVariables(name, CompilerDeclContext(), max_matches,
492f9568a95SRaphael Isemann                                    variable_list);
49330fdc8d8SChris Lattner   }
49430fdc8d8SChris Lattner }
49530fdc8d8SChris Lattner 
FindGlobalVariables(const RegularExpression & regex,size_t max_matches,VariableList & variable_list) const4961ad655e2SAdrian Prantl void ModuleList::FindGlobalVariables(const RegularExpression &regex,
49734cda14bSPavel Labath                                      size_t max_matches,
498b9c1b51eSKate Stone                                      VariableList &variable_list) const {
499bb19a13cSSaleem Abdulrasool   std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
5004cf9d1e4SRaphael Isemann   for (const ModuleSP &module_sp : m_modules)
5014cf9d1e4SRaphael Isemann     module_sp->FindGlobalVariables(regex, max_matches, variable_list);
50230fdc8d8SChris Lattner }
50330fdc8d8SChris Lattner 
FindSymbolsWithNameAndType(ConstString name,SymbolType symbol_type,SymbolContextList & sc_list) const5041ad655e2SAdrian Prantl void ModuleList::FindSymbolsWithNameAndType(ConstString name,
505931180e6SGreg Clayton                                             SymbolType symbol_type,
5061ad655e2SAdrian Prantl                                             SymbolContextList &sc_list) const {
507bb19a13cSSaleem Abdulrasool   std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
5084cf9d1e4SRaphael Isemann   for (const ModuleSP &module_sp : m_modules)
5094cf9d1e4SRaphael Isemann     module_sp->FindSymbolsWithNameAndType(name, symbol_type, sc_list);
5109683ff12SJim Ingham }
5119683ff12SJim Ingham 
FindSymbolsMatchingRegExAndType(const RegularExpression & regex,lldb::SymbolType symbol_type,SymbolContextList & sc_list) const5121ad655e2SAdrian Prantl void ModuleList::FindSymbolsMatchingRegExAndType(
513b9c1b51eSKate Stone     const RegularExpression &regex, lldb::SymbolType symbol_type,
5141ad655e2SAdrian Prantl     SymbolContextList &sc_list) const {
515bb19a13cSSaleem Abdulrasool   std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
5164cf9d1e4SRaphael Isemann   for (const ModuleSP &module_sp : m_modules)
5174cf9d1e4SRaphael Isemann     module_sp->FindSymbolsMatchingRegExAndType(regex, symbol_type, sc_list);
51830fdc8d8SChris Lattner }
51930fdc8d8SChris Lattner 
FindModules(const ModuleSpec & module_spec,ModuleList & matching_module_list) const5201ad655e2SAdrian Prantl void ModuleList::FindModules(const ModuleSpec &module_spec,
521b9c1b51eSKate Stone                              ModuleList &matching_module_list) const {
522bb19a13cSSaleem Abdulrasool   std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
5234cf9d1e4SRaphael Isemann   for (const ModuleSP &module_sp : m_modules) {
524b9a01b39SGreg Clayton     if (module_sp->MatchesModuleSpec(module_spec))
52530fdc8d8SChris Lattner       matching_module_list.Append(module_sp);
52630fdc8d8SChris Lattner   }
52730fdc8d8SChris Lattner }
52830fdc8d8SChris Lattner 
FindModule(const Module * module_ptr) const529b9c1b51eSKate Stone ModuleSP ModuleList::FindModule(const Module *module_ptr) const {
53030fdc8d8SChris Lattner   ModuleSP module_sp;
53130fdc8d8SChris Lattner 
53230fdc8d8SChris Lattner   // Scope for "locker"
53330fdc8d8SChris Lattner   {
534bb19a13cSSaleem Abdulrasool     std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
53530fdc8d8SChris Lattner     collection::const_iterator pos, end = m_modules.end();
53630fdc8d8SChris Lattner 
537b9c1b51eSKate Stone     for (pos = m_modules.begin(); pos != end; ++pos) {
538b9c1b51eSKate Stone       if ((*pos).get() == module_ptr) {
53930fdc8d8SChris Lattner         module_sp = (*pos);
54030fdc8d8SChris Lattner         break;
54130fdc8d8SChris Lattner       }
54230fdc8d8SChris Lattner     }
54330fdc8d8SChris Lattner   }
54430fdc8d8SChris Lattner   return module_sp;
54530fdc8d8SChris Lattner }
54630fdc8d8SChris Lattner 
FindModule(const UUID & uuid) const547b9c1b51eSKate Stone ModuleSP ModuleList::FindModule(const UUID &uuid) const {
54832e0a750SGreg Clayton   ModuleSP module_sp;
54932e0a750SGreg Clayton 
550b9c1b51eSKate Stone   if (uuid.IsValid()) {
551bb19a13cSSaleem Abdulrasool     std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
55232e0a750SGreg Clayton     collection::const_iterator pos, end = m_modules.end();
55332e0a750SGreg Clayton 
554b9c1b51eSKate Stone     for (pos = m_modules.begin(); pos != end; ++pos) {
555b9c1b51eSKate Stone       if ((*pos)->GetUUID() == uuid) {
55632e0a750SGreg Clayton         module_sp = (*pos);
55732e0a750SGreg Clayton         break;
55832e0a750SGreg Clayton       }
55932e0a750SGreg Clayton     }
56032e0a750SGreg Clayton   }
56132e0a750SGreg Clayton   return module_sp;
56232e0a750SGreg Clayton }
56332e0a750SGreg Clayton 
FindTypes(Module * search_first,ConstString name,bool name_is_fully_qualified,size_t max_matches,llvm::DenseSet<SymbolFile * > & searched_symbol_files,TypeList & types) const564bf9d84c0SAdrian Prantl void ModuleList::FindTypes(Module *search_first, ConstString name,
565b9c1b51eSKate Stone                            bool name_is_fully_qualified, size_t max_matches,
566b9c1b51eSKate Stone                            llvm::DenseSet<SymbolFile *> &searched_symbol_files,
567b9c1b51eSKate Stone                            TypeList &types) const {
568bb19a13cSSaleem Abdulrasool   std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
5693504eee8SGreg Clayton 
5703504eee8SGreg Clayton   collection::const_iterator pos, end = m_modules.end();
571576495e6SZachary Turner   if (search_first) {
572b9c1b51eSKate Stone     for (pos = m_modules.begin(); pos != end; ++pos) {
573576495e6SZachary Turner       if (search_first == pos->get()) {
574576495e6SZachary Turner         search_first->FindTypes(name, name_is_fully_qualified, max_matches,
575b9c1b51eSKate Stone                                 searched_symbol_files, types);
5763504eee8SGreg Clayton 
577bf9d84c0SAdrian Prantl         if (types.GetSize() >= max_matches)
578bf9d84c0SAdrian Prantl           return;
5793504eee8SGreg Clayton       }
580780af515SGreg Clayton     }
581780af515SGreg Clayton   }
582780af515SGreg Clayton 
583b9c1b51eSKate Stone   for (pos = m_modules.begin(); pos != end; ++pos) {
584780af515SGreg Clayton     // Search the module if the module is not equal to the one in the symbol
58505097246SAdrian Prantl     // context "sc". If "sc" contains a empty module shared pointer, then the
58605097246SAdrian Prantl     // comparison will always be true (valid_module_ptr != nullptr).
587576495e6SZachary Turner     if (search_first != pos->get())
588576495e6SZachary Turner       (*pos)->FindTypes(name, name_is_fully_qualified, max_matches,
589576495e6SZachary Turner                         searched_symbol_files, types);
590780af515SGreg Clayton 
591bf9d84c0SAdrian Prantl     if (types.GetSize() >= max_matches)
592bf9d84c0SAdrian Prantl       return;
593780af515SGreg Clayton   }
594780af515SGreg Clayton }
595780af515SGreg Clayton 
FindSourceFile(const FileSpec & orig_spec,FileSpec & new_spec) const596b9c1b51eSKate Stone bool ModuleList::FindSourceFile(const FileSpec &orig_spec,
597b9c1b51eSKate Stone                                 FileSpec &new_spec) const {
598bb19a13cSSaleem Abdulrasool   std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
5994cf9d1e4SRaphael Isemann   for (const ModuleSP &module_sp : m_modules) {
6004cf9d1e4SRaphael Isemann     if (module_sp->FindSourceFile(orig_spec, new_spec))
601d804d285SGreg Clayton       return true;
602d804d285SGreg Clayton   }
603d804d285SGreg Clayton   return false;
604d804d285SGreg Clayton }
605d804d285SGreg Clayton 
FindAddressesForLine(const lldb::TargetSP target_sp,const FileSpec & file,uint32_t line,Function * function,std::vector<Address> & output_local,std::vector<Address> & output_extern)606b9c1b51eSKate Stone void ModuleList::FindAddressesForLine(const lldb::TargetSP target_sp,
607f86248d9SRichard Mitton                                       const FileSpec &file, uint32_t line,
608f86248d9SRichard Mitton                                       Function *function,
609b9c1b51eSKate Stone                                       std::vector<Address> &output_local,
610b9c1b51eSKate Stone                                       std::vector<Address> &output_extern) {
611bb19a13cSSaleem Abdulrasool   std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
6124cf9d1e4SRaphael Isemann   for (const ModuleSP &module_sp : m_modules) {
6134cf9d1e4SRaphael Isemann     module_sp->FindAddressesForLine(target_sp, file, line, function,
6144cf9d1e4SRaphael Isemann                                     output_local, output_extern);
615f86248d9SRichard Mitton   }
616f86248d9SRichard Mitton }
617d804d285SGreg Clayton 
FindFirstModule(const ModuleSpec & module_spec) const618b9c1b51eSKate Stone ModuleSP ModuleList::FindFirstModule(const ModuleSpec &module_spec) const {
61930fdc8d8SChris Lattner   ModuleSP module_sp;
620bb19a13cSSaleem Abdulrasool   std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
621b9a01b39SGreg Clayton   collection::const_iterator pos, end = m_modules.end();
622b9c1b51eSKate Stone   for (pos = m_modules.begin(); pos != end; ++pos) {
623b9a01b39SGreg Clayton     ModuleSP module_sp(*pos);
624b9a01b39SGreg Clayton     if (module_sp->MatchesModuleSpec(module_spec))
625b9a01b39SGreg Clayton       return module_sp;
62632e0a750SGreg Clayton   }
62732e0a750SGreg Clayton   return module_sp;
62832e0a750SGreg Clayton }
62932e0a750SGreg Clayton 
GetSize() const630b9c1b51eSKate Stone size_t ModuleList::GetSize() const {
63130fdc8d8SChris Lattner   size_t size = 0;
63230fdc8d8SChris Lattner   {
633bb19a13cSSaleem Abdulrasool     std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
63430fdc8d8SChris Lattner     size = m_modules.size();
63530fdc8d8SChris Lattner   }
63630fdc8d8SChris Lattner   return size;
63730fdc8d8SChris Lattner }
63830fdc8d8SChris Lattner 
Dump(Stream * s) const639b9c1b51eSKate Stone void ModuleList::Dump(Stream *s) const {
640bb19a13cSSaleem Abdulrasool   std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
6414cf9d1e4SRaphael Isemann   for (const ModuleSP &module_sp : m_modules)
6424cf9d1e4SRaphael Isemann     module_sp->Dump(s);
64330fdc8d8SChris Lattner }
64430fdc8d8SChris Lattner 
LogUUIDAndPaths(Log * log,const char * prefix_cstr)645b9c1b51eSKate Stone void ModuleList::LogUUIDAndPaths(Log *log, const char *prefix_cstr) {
646b9c1b51eSKate Stone   if (log != nullptr) {
647bb19a13cSSaleem Abdulrasool     std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
648b9c1b51eSKate Stone     collection::const_iterator pos, begin = m_modules.begin(),
649b9c1b51eSKate Stone                                     end = m_modules.end();
650b9c1b51eSKate Stone     for (pos = begin; pos != end; ++pos) {
6518b2fe6dcSGreg Clayton       Module *module = pos->get();
6528b2fe6dcSGreg Clayton       const FileSpec &module_file_spec = module->GetFileSpec();
65363e5fb76SJonas Devlieghere       LLDB_LOGF(log, "%s[%u] %s (%s) \"%s\"", prefix_cstr ? prefix_cstr : "",
6548b2fe6dcSGreg Clayton                 (uint32_t)std::distance(begin, pos),
655c16b4af0SJason Molenda                 module->GetUUID().GetAsString().c_str(),
65664195a2cSGreg Clayton                 module->GetArchitecture().GetArchitectureName(),
657b5ad4ec7SGreg Clayton                 module_file_spec.GetPath().c_str());
6588b2fe6dcSGreg Clayton     }
6598b2fe6dcSGreg Clayton   }
6608b2fe6dcSGreg Clayton }
66130fdc8d8SChris Lattner 
ResolveFileAddress(lldb::addr_t vm_addr,Address & so_addr) const662b9c1b51eSKate Stone bool ModuleList::ResolveFileAddress(lldb::addr_t vm_addr,
663b9c1b51eSKate Stone                                     Address &so_addr) const {
664bb19a13cSSaleem Abdulrasool   std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
6654cf9d1e4SRaphael Isemann   for (const ModuleSP &module_sp : m_modules) {
6664cf9d1e4SRaphael Isemann     if (module_sp->ResolveFileAddress(vm_addr, so_addr))
66730fdc8d8SChris Lattner       return true;
66830fdc8d8SChris Lattner   }
66930fdc8d8SChris Lattner 
67030fdc8d8SChris Lattner   return false;
67130fdc8d8SChris Lattner }
67230fdc8d8SChris Lattner 
673991e4453SZachary Turner uint32_t
ResolveSymbolContextForAddress(const Address & so_addr,SymbolContextItem resolve_scope,SymbolContext & sc) const674991e4453SZachary Turner ModuleList::ResolveSymbolContextForAddress(const Address &so_addr,
675991e4453SZachary Turner                                            SymbolContextItem resolve_scope,
676b9c1b51eSKate Stone                                            SymbolContext &sc) const {
67730fdc8d8SChris Lattner   // The address is already section offset so it has a module
67830fdc8d8SChris Lattner   uint32_t resolved_flags = 0;
679e72dfb32SGreg Clayton   ModuleSP module_sp(so_addr.GetModule());
680b9c1b51eSKate Stone   if (module_sp) {
681b9c1b51eSKate Stone     resolved_flags =
682b9c1b51eSKate Stone         module_sp->ResolveSymbolContextForAddress(so_addr, resolve_scope, sc);
683b9c1b51eSKate Stone   } else {
684bb19a13cSSaleem Abdulrasool     std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
68530fdc8d8SChris Lattner     collection::const_iterator pos, end = m_modules.end();
686b9c1b51eSKate Stone     for (pos = m_modules.begin(); pos != end; ++pos) {
687b9c1b51eSKate Stone       resolved_flags =
688b9c1b51eSKate Stone           (*pos)->ResolveSymbolContextForAddress(so_addr, resolve_scope, sc);
68930fdc8d8SChris Lattner       if (resolved_flags != 0)
69030fdc8d8SChris Lattner         break;
69130fdc8d8SChris Lattner     }
69230fdc8d8SChris Lattner   }
69330fdc8d8SChris Lattner 
69430fdc8d8SChris Lattner   return resolved_flags;
69530fdc8d8SChris Lattner }
69630fdc8d8SChris Lattner 
ResolveSymbolContextForFilePath(const char * file_path,uint32_t line,bool check_inlines,SymbolContextItem resolve_scope,SymbolContextList & sc_list) const697b9c1b51eSKate Stone uint32_t ModuleList::ResolveSymbolContextForFilePath(
698b9c1b51eSKate Stone     const char *file_path, uint32_t line, bool check_inlines,
699991e4453SZachary Turner     SymbolContextItem resolve_scope, SymbolContextList &sc_list) const {
7008f3be7a3SJonas Devlieghere   FileSpec file_spec(file_path);
701b9c1b51eSKate Stone   return ResolveSymbolContextsForFileSpec(file_spec, line, check_inlines,
702b9c1b51eSKate Stone                                           resolve_scope, sc_list);
70330fdc8d8SChris Lattner }
70430fdc8d8SChris Lattner 
ResolveSymbolContextsForFileSpec(const FileSpec & file_spec,uint32_t line,bool check_inlines,SymbolContextItem resolve_scope,SymbolContextList & sc_list) const705b9c1b51eSKate Stone uint32_t ModuleList::ResolveSymbolContextsForFileSpec(
706b9c1b51eSKate Stone     const FileSpec &file_spec, uint32_t line, bool check_inlines,
707991e4453SZachary Turner     SymbolContextItem resolve_scope, SymbolContextList &sc_list) const {
708bb19a13cSSaleem Abdulrasool   std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
7094cf9d1e4SRaphael Isemann   for (const ModuleSP &module_sp : m_modules) {
7104cf9d1e4SRaphael Isemann     module_sp->ResolveSymbolContextsForFileSpec(file_spec, line, check_inlines,
711b9c1b51eSKate Stone                                                 resolve_scope, sc_list);
71230fdc8d8SChris Lattner   }
71330fdc8d8SChris Lattner 
71430fdc8d8SChris Lattner   return sc_list.GetSize();
71530fdc8d8SChris Lattner }
71630fdc8d8SChris Lattner 
GetIndexForModule(const Module * module) const717b9c1b51eSKate Stone size_t ModuleList::GetIndexForModule(const Module *module) const {
718b9c1b51eSKate Stone   if (module) {
719bb19a13cSSaleem Abdulrasool     std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
72030fdc8d8SChris Lattner     collection::const_iterator pos;
72130fdc8d8SChris Lattner     collection::const_iterator begin = m_modules.begin();
72230fdc8d8SChris Lattner     collection::const_iterator end = m_modules.end();
723b9c1b51eSKate Stone     for (pos = begin; pos != end; ++pos) {
72430fdc8d8SChris Lattner       if ((*pos).get() == module)
72530fdc8d8SChris Lattner         return std::distance(begin, pos);
72630fdc8d8SChris Lattner     }
72730fdc8d8SChris Lattner   }
72830fdc8d8SChris Lattner   return LLDB_INVALID_INDEX32;
72930fdc8d8SChris Lattner }
73030fdc8d8SChris Lattner 
731235354beSAdrian Prantl namespace {
732235354beSAdrian Prantl struct SharedModuleListInfo {
733235354beSAdrian Prantl   ModuleList module_list;
734235354beSAdrian Prantl   ModuleListProperties module_list_properties;
735235354beSAdrian Prantl };
736235354beSAdrian Prantl }
GetSharedModuleListInfo()737235354beSAdrian Prantl static SharedModuleListInfo &GetSharedModuleListInfo()
738235354beSAdrian Prantl {
739235354beSAdrian Prantl   static SharedModuleListInfo *g_shared_module_list_info = nullptr;
740c5f28e2aSKamil Rytarowski   static llvm::once_flag g_once_flag;
741c5f28e2aSKamil Rytarowski   llvm::call_once(g_once_flag, []() {
7426f4d8af7SGreg Clayton     // NOTE: Intentionally leak the module list so a program doesn't have to
7436f4d8af7SGreg Clayton     // cleanup all modules and object files as it exits. This just wastes time
7446f4d8af7SGreg Clayton     // doing a bunch of cleanup that isn't required.
745235354beSAdrian Prantl     if (g_shared_module_list_info == nullptr)
746235354beSAdrian Prantl       g_shared_module_list_info = new SharedModuleListInfo();
7471d77a820SGreg Clayton   });
748235354beSAdrian Prantl   return *g_shared_module_list_info;
749235354beSAdrian Prantl }
750235354beSAdrian Prantl 
GetSharedModuleList()751235354beSAdrian Prantl static ModuleList &GetSharedModuleList() {
752235354beSAdrian Prantl   return GetSharedModuleListInfo().module_list;
753235354beSAdrian Prantl }
754235354beSAdrian Prantl 
GetGlobalModuleListProperties()755235354beSAdrian Prantl ModuleListProperties &ModuleList::GetGlobalModuleListProperties() {
756235354beSAdrian Prantl   return GetSharedModuleListInfo().module_list_properties;
75730fdc8d8SChris Lattner }
75830fdc8d8SChris Lattner 
ModuleIsInCache(const Module * module_ptr)759b9c1b51eSKate Stone bool ModuleList::ModuleIsInCache(const Module *module_ptr) {
760b9c1b51eSKate Stone   if (module_ptr) {
76130fdc8d8SChris Lattner     ModuleList &shared_module_list = GetSharedModuleList();
762c5dac77aSEugene Zelenko     return shared_module_list.FindModule(module_ptr).get() != nullptr;
763bdea7ceeSGreg Clayton   }
76429ad7b91SGreg Clayton   return false;
76530fdc8d8SChris Lattner }
76630fdc8d8SChris Lattner 
FindSharedModules(const ModuleSpec & module_spec,ModuleList & matching_module_list)7671ad655e2SAdrian Prantl void ModuleList::FindSharedModules(const ModuleSpec &module_spec,
768b9c1b51eSKate Stone                                    ModuleList &matching_module_list) {
7691ad655e2SAdrian Prantl   GetSharedModuleList().FindModules(module_spec, matching_module_list);
7708d38ac45SGreg Clayton }
77130fdc8d8SChris Lattner 
RemoveOrphanSharedModules(bool mandatory)772b9c1b51eSKate Stone size_t ModuleList::RemoveOrphanSharedModules(bool mandatory) {
7730cd70866SGreg Clayton   return GetSharedModuleList().RemoveOrphans(mandatory);
774aa149cbdSGreg Clayton }
775aa149cbdSGreg Clayton 
77661bfc703SJoseph Tremoulet Status
GetSharedModule(const ModuleSpec & module_spec,ModuleSP & module_sp,const FileSpecList * module_search_paths_ptr,llvm::SmallVectorImpl<lldb::ModuleSP> * old_modules,bool * did_create_ptr,bool always_create)77761bfc703SJoseph Tremoulet ModuleList::GetSharedModule(const ModuleSpec &module_spec, ModuleSP &module_sp,
778c859e2d5SGreg Clayton                             const FileSpecList *module_search_paths_ptr,
77961bfc703SJoseph Tremoulet                             llvm::SmallVectorImpl<lldb::ModuleSP> *old_modules,
780b9c1b51eSKate Stone                             bool *did_create_ptr, bool always_create) {
78130fdc8d8SChris Lattner   ModuleList &shared_module_list = GetSharedModuleList();
782b9c1b51eSKate Stone   std::lock_guard<std::recursive_mutex> guard(
783b9c1b51eSKate Stone       shared_module_list.m_modules_mutex);
78430fdc8d8SChris Lattner   char path[PATH_MAX];
78530fdc8d8SChris Lattner 
78697206d57SZachary Turner   Status error;
78730fdc8d8SChris Lattner 
78830fdc8d8SChris Lattner   module_sp.reset();
78930fdc8d8SChris Lattner 
79030fdc8d8SChris Lattner   if (did_create_ptr)
79130fdc8d8SChris Lattner     *did_create_ptr = false;
79230fdc8d8SChris Lattner 
793b9a01b39SGreg Clayton   const UUID *uuid_ptr = module_spec.GetUUIDPtr();
794b9a01b39SGreg Clayton   const FileSpec &module_file_spec = module_spec.GetFileSpec();
795b9a01b39SGreg Clayton   const ArchSpec &arch = module_spec.GetArchitecture();
79630fdc8d8SChris Lattner 
79730fdc8d8SChris Lattner   // Make sure no one else can try and get or create a module while this
79805097246SAdrian Prantl   // function is actively working on it by doing an extra lock on the global
79905097246SAdrian Prantl   // mutex list.
800b9c1b51eSKate Stone   if (!always_create) {
801616f4907SGreg Clayton     ModuleList matching_module_list;
802b9c1b51eSKate Stone     shared_module_list.FindModules(module_spec, matching_module_list);
8031ad655e2SAdrian Prantl     const size_t num_matching_modules = matching_module_list.GetSize();
8041ad655e2SAdrian Prantl 
805b9c1b51eSKate Stone     if (num_matching_modules > 0) {
806b9c1b51eSKate Stone       for (size_t module_idx = 0; module_idx < num_matching_modules;
807b9c1b51eSKate Stone            ++module_idx) {
808616f4907SGreg Clayton         module_sp = matching_module_list.GetModuleAtIndex(module_idx);
8091d60909eSGreg Clayton 
8101d60909eSGreg Clayton         // Make sure the file for the module hasn't been modified
811b9c1b51eSKate Stone         if (module_sp->FileHasChanged()) {
81261bfc703SJoseph Tremoulet           if (old_modules)
81361bfc703SJoseph Tremoulet             old_modules->push_back(module_sp);
8143a18e319SGreg Clayton 
815a007a6d8SPavel Labath           Log *log = GetLog(LLDBLog::Modules);
816c5dac77aSEugene Zelenko           if (log != nullptr)
8170304360aSAdrian Prantl             LLDB_LOGF(
8180304360aSAdrian Prantl                 log, "%p '%s' module changed: removing from global module list",
8190304360aSAdrian Prantl                 static_cast<void *>(module_sp.get()),
8200304360aSAdrian Prantl                 module_sp->GetFileSpec().GetFilename().GetCString());
8213a18e319SGreg Clayton 
82230fdc8d8SChris Lattner           shared_module_list.Remove(module_sp);
82330fdc8d8SChris Lattner           module_sp.reset();
824b9c1b51eSKate Stone         } else {
82505097246SAdrian Prantl           // The module matches and the module was not modified from when it
82605097246SAdrian Prantl           // was last loaded.
8271d60909eSGreg Clayton           return error;
8281d60909eSGreg Clayton         }
8291d60909eSGreg Clayton       }
83030fdc8d8SChris Lattner     }
83130fdc8d8SChris Lattner   }
83230fdc8d8SChris Lattner 
833616f4907SGreg Clayton   if (module_sp)
834616f4907SGreg Clayton     return error;
835933f8530SOleksiy Vyalov 
836796ac80bSJonas Devlieghere   module_sp = std::make_shared<Module>(module_spec);
83705097246SAdrian Prantl   // Make sure there are a module and an object file since we can specify a
83805097246SAdrian Prantl   // valid file path with an architecture that might not be in that file. By
83905097246SAdrian Prantl   // getting the object file we can guarantee that the architecture matches
840b9c1b51eSKate Stone   if (module_sp->GetObjectFile()) {
84105097246SAdrian Prantl     // If we get in here we got the correct arch, now we just need to verify
84205097246SAdrian Prantl     // the UUID if one was given
843b9c1b51eSKate Stone     if (uuid_ptr && *uuid_ptr != module_sp->GetUUID()) {
84430fdc8d8SChris Lattner       module_sp.reset();
845b9c1b51eSKate Stone     } else {
846b9c1b51eSKate Stone       if (module_sp->GetObjectFile() &&
847b9c1b51eSKate Stone           module_sp->GetObjectFile()->GetType() ==
848b9c1b51eSKate Stone               ObjectFile::eTypeStubLibrary) {
8499c077cf3SJason Molenda         module_sp.reset();
850b9c1b51eSKate Stone       } else {
851b9c1b51eSKate Stone         if (did_create_ptr) {
85230fdc8d8SChris Lattner           *did_create_ptr = true;
8539c077cf3SJason Molenda         }
85430fdc8d8SChris Lattner 
855d20aa7caSJoseph Tremoulet         shared_module_list.ReplaceEquivalent(module_sp, old_modules);
85630fdc8d8SChris Lattner         return error;
85730fdc8d8SChris Lattner       }
85830fdc8d8SChris Lattner     }
859b9c1b51eSKate Stone   } else {
860c3776bf2SGreg Clayton     module_sp.reset();
8619c077cf3SJason Molenda   }
862933f8530SOleksiy Vyalov 
863b9c1b51eSKate Stone   if (module_search_paths_ptr) {
864933f8530SOleksiy Vyalov     const auto num_directories = module_search_paths_ptr->GetSize();
865b9c1b51eSKate Stone     for (size_t idx = 0; idx < num_directories; ++idx) {
866933f8530SOleksiy Vyalov       auto search_path_spec = module_search_paths_ptr->GetFileSpecAtIndex(idx);
8678f3be7a3SJonas Devlieghere       FileSystem::Instance().Resolve(search_path_spec);
8687d86ee5aSZachary Turner       namespace fs = llvm::sys::fs;
8693a58d898SJonas Devlieghere       if (!FileSystem::Instance().IsDirectory(search_path_spec))
870933f8530SOleksiy Vyalov         continue;
871b9c1b51eSKate Stone       search_path_spec.AppendPathComponent(
872642bc15dSRaphael Isemann           module_spec.GetFileSpec().GetFilename().GetStringRef());
873dbd7fabaSJonas Devlieghere       if (!FileSystem::Instance().Exists(search_path_spec))
874933f8530SOleksiy Vyalov         continue;
875933f8530SOleksiy Vyalov 
876933f8530SOleksiy Vyalov       auto resolved_module_spec(module_spec);
877933f8530SOleksiy Vyalov       resolved_module_spec.GetFileSpec() = search_path_spec;
878796ac80bSJonas Devlieghere       module_sp = std::make_shared<Module>(resolved_module_spec);
879b9c1b51eSKate Stone       if (module_sp->GetObjectFile()) {
88005097246SAdrian Prantl         // If we get in here we got the correct arch, now we just need to
88105097246SAdrian Prantl         // verify the UUID if one was given
882b9c1b51eSKate Stone         if (uuid_ptr && *uuid_ptr != module_sp->GetUUID()) {
883933f8530SOleksiy Vyalov           module_sp.reset();
884b9c1b51eSKate Stone         } else {
885b9c1b51eSKate Stone           if (module_sp->GetObjectFile()->GetType() ==
886b9c1b51eSKate Stone               ObjectFile::eTypeStubLibrary) {
8879c077cf3SJason Molenda             module_sp.reset();
888b9c1b51eSKate Stone           } else {
889933f8530SOleksiy Vyalov             if (did_create_ptr)
890933f8530SOleksiy Vyalov               *did_create_ptr = true;
891933f8530SOleksiy Vyalov 
892d20aa7caSJoseph Tremoulet             shared_module_list.ReplaceEquivalent(module_sp, old_modules);
89397206d57SZachary Turner             return Status();
894933f8530SOleksiy Vyalov           }
895933f8530SOleksiy Vyalov         }
896b9c1b51eSKate Stone       } else {
897933f8530SOleksiy Vyalov         module_sp.reset();
898c3776bf2SGreg Clayton       }
89930fdc8d8SChris Lattner     }
9009c077cf3SJason Molenda   }
90130fdc8d8SChris Lattner 
90230fdc8d8SChris Lattner   // Either the file didn't exist where at the path, or no path was given, so
90330fdc8d8SChris Lattner   // we now have to use more extreme measures to try and find the appropriate
90430fdc8d8SChris Lattner   // module.
90530fdc8d8SChris Lattner 
90605097246SAdrian Prantl   // Fixup the incoming path in case the path points to a valid file, yet the
90705097246SAdrian Prantl   // arch or UUID (if one was passed in) don't match.
908b9c1b51eSKate Stone   ModuleSpec located_binary_modulespec =
909b9c1b51eSKate Stone       Symbols::LocateExecutableObjectFile(module_spec);
91030fdc8d8SChris Lattner 
91130fdc8d8SChris Lattner   // Don't look for the file if it appears to be the same one we already
91230fdc8d8SChris Lattner   // checked for above...
913b9c1b51eSKate Stone   if (located_binary_modulespec.GetFileSpec() != module_file_spec) {
914dbd7fabaSJonas Devlieghere     if (!FileSystem::Instance().Exists(
915dbd7fabaSJonas Devlieghere             located_binary_modulespec.GetFileSpec())) {
9168825c5c9SJason Molenda       located_binary_modulespec.GetFileSpec().GetPath(path, sizeof(path));
91744435ed0SGreg Clayton       if (path[0] == '\0')
918b9a01b39SGreg Clayton         module_file_spec.GetPath(path, sizeof(path));
919b9c1b51eSKate Stone       // How can this check ever be true? This branch it is false, and we
920b9c1b51eSKate Stone       // haven't modified file_spec.
921dbd7fabaSJonas Devlieghere       if (FileSystem::Instance().Exists(
922dbd7fabaSJonas Devlieghere               located_binary_modulespec.GetFileSpec())) {
923c16b4af0SJason Molenda         std::string uuid_str;
92430fdc8d8SChris Lattner         if (uuid_ptr && uuid_ptr->IsValid())
925c16b4af0SJason Molenda           uuid_str = uuid_ptr->GetAsString();
92630fdc8d8SChris Lattner 
927b9c1b51eSKate Stone         if (arch.IsValid()) {
928c16b4af0SJason Molenda           if (!uuid_str.empty())
929b9c1b51eSKate Stone             error.SetErrorStringWithFormat(
930b9c1b51eSKate Stone                 "'%s' does not contain the %s architecture and UUID %s", path,
931b9c1b51eSKate Stone                 arch.GetArchitectureName(), uuid_str.c_str());
93230fdc8d8SChris Lattner           else
933b9c1b51eSKate Stone             error.SetErrorStringWithFormat(
934b9c1b51eSKate Stone                 "'%s' does not contain the %s architecture.", path,
935b9c1b51eSKate Stone                 arch.GetArchitectureName());
93630fdc8d8SChris Lattner         }
937b9c1b51eSKate Stone       } else {
93886edbf41SGreg Clayton         error.SetErrorStringWithFormat("'%s' does not exist", path);
93930fdc8d8SChris Lattner       }
940c9660546SGreg Clayton       if (error.Fail())
941c9660546SGreg Clayton         module_sp.reset();
94230fdc8d8SChris Lattner       return error;
94330fdc8d8SChris Lattner     }
94430fdc8d8SChris Lattner 
94530fdc8d8SChris Lattner     // Make sure no one else can try and get or create a module while this
94605097246SAdrian Prantl     // function is actively working on it by doing an extra lock on the global
94705097246SAdrian Prantl     // mutex list.
948746ffd69SPavel Labath     ModuleSpec platform_module_spec(module_spec);
949b9c1b51eSKate Stone     platform_module_spec.GetFileSpec() =
950b9c1b51eSKate Stone         located_binary_modulespec.GetFileSpec();
951b9c1b51eSKate Stone     platform_module_spec.GetPlatformFileSpec() =
952b9c1b51eSKate Stone         located_binary_modulespec.GetFileSpec();
953b9c1b51eSKate Stone     platform_module_spec.GetSymbolFileSpec() =
954b9c1b51eSKate Stone         located_binary_modulespec.GetSymbolFileSpec();
95530fdc8d8SChris Lattner     ModuleList matching_module_list;
9561ad655e2SAdrian Prantl     shared_module_list.FindModules(platform_module_spec, matching_module_list);
9571ad655e2SAdrian Prantl     if (!matching_module_list.IsEmpty()) {
95830fdc8d8SChris Lattner       module_sp = matching_module_list.GetModuleAtIndex(0);
95930fdc8d8SChris Lattner 
96030fdc8d8SChris Lattner       // If we didn't have a UUID in mind when looking for the object file,
96130fdc8d8SChris Lattner       // then we should make sure the modification time hasn't changed!
962b9c1b51eSKate Stone       if (platform_module_spec.GetUUIDPtr() == nullptr) {
96346376966SJonas Devlieghere         auto file_spec_mod_time = FileSystem::Instance().GetModificationTime(
9643dc342ebSPavel Labath             located_binary_modulespec.GetFileSpec());
9653dc342ebSPavel Labath         if (file_spec_mod_time != llvm::sys::TimePoint<>()) {
966b9c1b51eSKate Stone           if (file_spec_mod_time != module_sp->GetModificationTime()) {
96761bfc703SJoseph Tremoulet             if (old_modules)
96861bfc703SJoseph Tremoulet               old_modules->push_back(module_sp);
96930fdc8d8SChris Lattner             shared_module_list.Remove(module_sp);
97030fdc8d8SChris Lattner             module_sp.reset();
97130fdc8d8SChris Lattner           }
97230fdc8d8SChris Lattner         }
97330fdc8d8SChris Lattner       }
97430fdc8d8SChris Lattner     }
97530fdc8d8SChris Lattner 
976b9c1b51eSKate Stone     if (!module_sp) {
977796ac80bSJonas Devlieghere       module_sp = std::make_shared<Module>(platform_module_spec);
97805097246SAdrian Prantl       // Make sure there are a module and an object file since we can specify a
97905097246SAdrian Prantl       // valid file path with an architecture that might not be in that file.
980b9c1b51eSKate Stone       // By getting the object file we can guarantee that the architecture
981b9c1b51eSKate Stone       // matches
982b9c1b51eSKate Stone       if (module_sp && module_sp->GetObjectFile()) {
983b9c1b51eSKate Stone         if (module_sp->GetObjectFile()->GetType() ==
984b9c1b51eSKate Stone             ObjectFile::eTypeStubLibrary) {
9859c077cf3SJason Molenda           module_sp.reset();
986b9c1b51eSKate Stone         } else {
98730fdc8d8SChris Lattner           if (did_create_ptr)
98830fdc8d8SChris Lattner             *did_create_ptr = true;
98930fdc8d8SChris Lattner 
990d20aa7caSJoseph Tremoulet           shared_module_list.ReplaceEquivalent(module_sp, old_modules);
99130fdc8d8SChris Lattner         }
992b9c1b51eSKate Stone       } else {
9938825c5c9SJason Molenda         located_binary_modulespec.GetFileSpec().GetPath(path, sizeof(path));
99430fdc8d8SChris Lattner 
995b9c1b51eSKate Stone         if (located_binary_modulespec.GetFileSpec()) {
99630fdc8d8SChris Lattner           if (arch.IsValid())
997b9c1b51eSKate Stone             error.SetErrorStringWithFormat(
998b9c1b51eSKate Stone                 "unable to open %s architecture in '%s'",
999b9c1b51eSKate Stone                 arch.GetArchitectureName(), path);
100030fdc8d8SChris Lattner           else
100186edbf41SGreg Clayton             error.SetErrorStringWithFormat("unable to open '%s'", path);
1002b9c1b51eSKate Stone         } else {
1003c16b4af0SJason Molenda           std::string uuid_str;
100430fdc8d8SChris Lattner           if (uuid_ptr && uuid_ptr->IsValid())
1005c16b4af0SJason Molenda             uuid_str = uuid_ptr->GetAsString();
100630fdc8d8SChris Lattner 
1007c16b4af0SJason Molenda           if (!uuid_str.empty())
1008b9c1b51eSKate Stone             error.SetErrorStringWithFormat(
1009b9c1b51eSKate Stone                 "cannot locate a module for UUID '%s'", uuid_str.c_str());
101030fdc8d8SChris Lattner           else
101189533764SJonas Devlieghere             error.SetErrorString("cannot locate a module");
101230fdc8d8SChris Lattner         }
101330fdc8d8SChris Lattner       }
101430fdc8d8SChris Lattner     }
101530fdc8d8SChris Lattner   }
101630fdc8d8SChris Lattner 
101730fdc8d8SChris Lattner   return error;
101830fdc8d8SChris Lattner }
101930fdc8d8SChris Lattner 
RemoveSharedModule(lldb::ModuleSP & module_sp)1020b9c1b51eSKate Stone bool ModuleList::RemoveSharedModule(lldb::ModuleSP &module_sp) {
1021616f4907SGreg Clayton   return GetSharedModuleList().Remove(module_sp);
1022616f4907SGreg Clayton }
1023616f4907SGreg Clayton 
RemoveSharedModuleIfOrphaned(const Module * module_ptr)1024b9c1b51eSKate Stone bool ModuleList::RemoveSharedModuleIfOrphaned(const Module *module_ptr) {
10254a94c910SJim Ingham   return GetSharedModuleList().RemoveIfOrphaned(module_ptr);
10264a94c910SJim Ingham }
10274a94c910SJim Ingham 
LoadScriptingResourcesInTarget(Target * target,std::list<Status> & errors,Stream * feedback_stream,bool continue_on_error)1028b9c1b51eSKate Stone bool ModuleList::LoadScriptingResourcesInTarget(Target *target,
102997206d57SZachary Turner                                                 std::list<Status> &errors,
10309730339bSEnrico Granata                                                 Stream *feedback_stream,
1031b9c1b51eSKate Stone                                                 bool continue_on_error) {
103284a53dfbSEnrico Granata   if (!target)
103384a53dfbSEnrico Granata     return false;
1034bb19a13cSSaleem Abdulrasool   std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
1035b9c1b51eSKate Stone   for (auto module : m_modules) {
103697206d57SZachary Turner     Status error;
1037b9c1b51eSKate Stone     if (module) {
1038b9c1b51eSKate Stone       if (!module->LoadScriptingResourceInTarget(target, error,
1039b9c1b51eSKate Stone                                                  feedback_stream)) {
1040b9c1b51eSKate Stone         if (error.Fail() && error.AsCString()) {
1041b9c1b51eSKate Stone           error.SetErrorStringWithFormat("unable to load scripting data for "
1042b9c1b51eSKate Stone                                          "module %s - error reported was %s",
1043b9c1b51eSKate Stone                                          module->GetFileSpec()
1044b9c1b51eSKate Stone                                              .GetFileNameStrippingExtension()
1045b9c1b51eSKate Stone                                              .GetCString(),
104684a53dfbSEnrico Granata                                          error.AsCString());
104784a53dfbSEnrico Granata           errors.push_back(error);
1048994740fbSGreg Clayton 
104984a53dfbSEnrico Granata           if (!continue_on_error)
105084a53dfbSEnrico Granata             return false;
105184a53dfbSEnrico Granata         }
105284a53dfbSEnrico Granata       }
10539730339bSEnrico Granata     }
1054994740fbSGreg Clayton   }
1055c5dac77aSEugene Zelenko   return errors.empty();
105684a53dfbSEnrico Granata }
1057d6346e6fSGreg Clayton 
ForEach(std::function<bool (const ModuleSP & module_sp)> const & callback) const1058b9c1b51eSKate Stone void ModuleList::ForEach(
1059b9c1b51eSKate Stone     std::function<bool(const ModuleSP &module_sp)> const &callback) const {
1060bb19a13cSSaleem Abdulrasool   std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
1061b9c1b51eSKate Stone   for (const auto &module : m_modules) {
1062d6346e6fSGreg Clayton     // If the callback returns false, then stop iterating and break out
1063d6346e6fSGreg Clayton     if (!callback(module))
1064d6346e6fSGreg Clayton       break;
1065d6346e6fSGreg Clayton   }
1066d6346e6fSGreg Clayton }
1067