1254721Semaste//===-- ModuleList.cpp ------------------------------------------*- C++ -*-===// 2254721Semaste// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6254721Semaste// 7254721Semaste//===----------------------------------------------------------------------===// 8254721Semaste 9254721Semaste#include "lldb/Core/ModuleList.h" 10344779Sdim#include "lldb/Core/FileSpecList.h" 11254721Semaste#include "lldb/Core/Module.h" 12254721Semaste#include "lldb/Core/ModuleSpec.h" 13314564Sdim#include "lldb/Host/FileSystem.h" 14344779Sdim#include "lldb/Interpreter/OptionValueFileSpec.h" 15341825Sdim#include "lldb/Interpreter/OptionValueProperties.h" 16341825Sdim#include "lldb/Interpreter/Property.h" 17353358Sdim#include "lldb/Symbol/LocateSymbolFile.h" 18254721Semaste#include "lldb/Symbol/ObjectFile.h" 19344779Sdim#include "lldb/Symbol/SymbolContext.h" 20360784Sdim#include "lldb/Symbol/TypeList.h" 21254721Semaste#include "lldb/Symbol/VariableList.h" 22344779Sdim#include "lldb/Utility/ArchSpec.h" 23344779Sdim#include "lldb/Utility/ConstString.h" 24321369Sdim#include "lldb/Utility/Log.h" 25344779Sdim#include "lldb/Utility/Logging.h" 26344779Sdim#include "lldb/Utility/UUID.h" 27344779Sdim#include "lldb/lldb-defines.h" 28254721Semaste 29341825Sdim#if defined(_WIN32) 30344779Sdim#include "lldb/Host/windows/PosixApi.h" 31321369Sdim#endif 32321369Sdim 33344779Sdim#include "clang/Driver/Driver.h" 34344779Sdim#include "llvm/ADT/StringRef.h" 35321369Sdim#include "llvm/Support/FileSystem.h" 36321369Sdim#include "llvm/Support/Threading.h" 37344779Sdim#include "llvm/Support/raw_ostream.h" 38321369Sdim 39344779Sdim#include <chrono> 40344779Sdim#include <memory> 41321369Sdim#include <mutex> 42344779Sdim#include <string> 43344779Sdim#include <utility> 44321369Sdim 45321369Sdimnamespace lldb_private { 46321369Sdimclass Function; 47321369Sdim} 48321369Sdimnamespace lldb_private { 49321369Sdimclass RegularExpression; 50321369Sdim} 51321369Sdimnamespace lldb_private { 52321369Sdimclass Stream; 53321369Sdim} 54321369Sdimnamespace lldb_private { 55321369Sdimclass SymbolFile; 56321369Sdim} 57321369Sdimnamespace lldb_private { 58321369Sdimclass Target; 59321369Sdim} 60321369Sdim 61254721Semasteusing namespace lldb; 62254721Semasteusing namespace lldb_private; 63254721Semaste 64341825Sdimnamespace { 65341825Sdim 66360784Sdim#define LLDB_PROPERTIES_modulelist 67360784Sdim#include "CoreProperties.inc" 68341825Sdim 69360784Sdimenum { 70360784Sdim#define LLDB_PROPERTIES_modulelist 71360784Sdim#include "CorePropertiesEnum.inc" 72360784Sdim}; 73341825Sdim 74341825Sdim} // namespace 75341825Sdim 76341825SdimModuleListProperties::ModuleListProperties() { 77353358Sdim m_collection_sp = 78353358Sdim std::make_shared<OptionValueProperties>(ConstString("symbols")); 79360784Sdim m_collection_sp->Initialize(g_modulelist_properties); 80341825Sdim 81341825Sdim llvm::SmallString<128> path; 82341825Sdim clang::driver::Driver::getDefaultModuleCachePath(path); 83341825Sdim SetClangModulesCachePath(path); 84341825Sdim} 85341825Sdim 86341825Sdimbool ModuleListProperties::GetEnableExternalLookup() const { 87341825Sdim const uint32_t idx = ePropertyEnableExternalLookup; 88341825Sdim return m_collection_sp->GetPropertyAtIndexAsBoolean( 89360784Sdim nullptr, idx, g_modulelist_properties[idx].default_uint_value != 0); 90341825Sdim} 91341825Sdim 92353358Sdimbool ModuleListProperties::SetEnableExternalLookup(bool new_value) { 93353358Sdim return m_collection_sp->SetPropertyAtIndexAsBoolean( 94353358Sdim nullptr, ePropertyEnableExternalLookup, new_value); 95353358Sdim} 96353358Sdim 97341825SdimFileSpec ModuleListProperties::GetClangModulesCachePath() const { 98341825Sdim return m_collection_sp 99341825Sdim ->GetPropertyAtIndexAsOptionValueFileSpec(nullptr, false, 100341825Sdim ePropertyClangModulesCachePath) 101341825Sdim ->GetCurrentValue(); 102341825Sdim} 103341825Sdim 104341825Sdimbool ModuleListProperties::SetClangModulesCachePath(llvm::StringRef path) { 105341825Sdim return m_collection_sp->SetPropertyAtIndexAsString( 106341825Sdim nullptr, ePropertyClangModulesCachePath, path); 107341825Sdim} 108341825Sdim 109314564SdimModuleList::ModuleList() 110314564Sdim : m_modules(), m_modules_mutex(), m_notifier(nullptr) {} 111254721Semaste 112314564SdimModuleList::ModuleList(const ModuleList &rhs) 113314564Sdim : m_modules(), m_modules_mutex(), m_notifier(nullptr) { 114314564Sdim std::lock_guard<std::recursive_mutex> lhs_guard(m_modules_mutex); 115314564Sdim std::lock_guard<std::recursive_mutex> rhs_guard(rhs.m_modules_mutex); 116314564Sdim m_modules = rhs.m_modules; 117254721Semaste} 118254721Semaste 119314564SdimModuleList::ModuleList(ModuleList::Notifier *notifier) 120314564Sdim : m_modules(), m_modules_mutex(), m_notifier(notifier) {} 121254721Semaste 122314564Sdimconst ModuleList &ModuleList::operator=(const ModuleList &rhs) { 123314564Sdim if (this != &rhs) { 124353358Sdim std::lock(m_modules_mutex, rhs.m_modules_mutex); 125360784Sdim std::lock_guard<std::recursive_mutex> lhs_guard(m_modules_mutex, 126353358Sdim std::adopt_lock); 127360784Sdim std::lock_guard<std::recursive_mutex> rhs_guard(rhs.m_modules_mutex, 128353358Sdim std::adopt_lock); 129353358Sdim m_modules = rhs.m_modules; 130314564Sdim } 131314564Sdim return *this; 132254721Semaste} 133254721Semaste 134309124SdimModuleList::~ModuleList() = default; 135254721Semaste 136314564Sdimvoid ModuleList::AppendImpl(const ModuleSP &module_sp, bool use_notifier) { 137314564Sdim if (module_sp) { 138314564Sdim std::lock_guard<std::recursive_mutex> guard(m_modules_mutex); 139314564Sdim m_modules.push_back(module_sp); 140314564Sdim if (use_notifier && m_notifier) 141353358Sdim m_notifier->NotifyModuleAdded(*this, module_sp); 142314564Sdim } 143254721Semaste} 144254721Semaste 145360784Sdimvoid ModuleList::Append(const ModuleSP &module_sp, bool notify) { 146360784Sdim AppendImpl(module_sp, notify); 147353358Sdim} 148254721Semaste 149314564Sdimvoid ModuleList::ReplaceEquivalent(const ModuleSP &module_sp) { 150314564Sdim if (module_sp) { 151314564Sdim std::lock_guard<std::recursive_mutex> guard(m_modules_mutex); 152254721Semaste 153314564Sdim // First remove any equivalent modules. Equivalent modules are modules 154314564Sdim // whose path, platform path and architecture match. 155314564Sdim ModuleSpec equivalent_module_spec(module_sp->GetFileSpec(), 156314564Sdim module_sp->GetArchitecture()); 157314564Sdim equivalent_module_spec.GetPlatformFileSpec() = 158314564Sdim module_sp->GetPlatformFileSpec(); 159254721Semaste 160314564Sdim size_t idx = 0; 161314564Sdim while (idx < m_modules.size()) { 162314564Sdim ModuleSP module_sp(m_modules[idx]); 163314564Sdim if (module_sp->MatchesModuleSpec(equivalent_module_spec)) 164314564Sdim RemoveImpl(m_modules.begin() + idx); 165314564Sdim else 166314564Sdim ++idx; 167254721Semaste } 168314564Sdim // Now add the new module to the list 169314564Sdim Append(module_sp); 170314564Sdim } 171254721Semaste} 172254721Semaste 173353358Sdimbool ModuleList::AppendIfNeeded(const ModuleSP &module_sp, bool notify) { 174314564Sdim if (module_sp) { 175314564Sdim std::lock_guard<std::recursive_mutex> guard(m_modules_mutex); 176314564Sdim collection::iterator pos, end = m_modules.end(); 177314564Sdim for (pos = m_modules.begin(); pos != end; ++pos) { 178314564Sdim if (pos->get() == module_sp.get()) 179314564Sdim return false; // Already in the list 180254721Semaste } 181314564Sdim // Only push module_sp on the list if it wasn't already in there. 182353358Sdim Append(module_sp, notify); 183314564Sdim return true; 184314564Sdim } 185314564Sdim return false; 186254721Semaste} 187254721Semaste 188314564Sdimvoid ModuleList::Append(const ModuleList &module_list) { 189314564Sdim for (auto pos : module_list.m_modules) 190314564Sdim Append(pos); 191254721Semaste} 192254721Semaste 193314564Sdimbool ModuleList::AppendIfNeeded(const ModuleList &module_list) { 194314564Sdim bool any_in = false; 195314564Sdim for (auto pos : module_list.m_modules) { 196314564Sdim if (AppendIfNeeded(pos)) 197314564Sdim any_in = true; 198314564Sdim } 199314564Sdim return any_in; 200254721Semaste} 201254721Semaste 202314564Sdimbool ModuleList::RemoveImpl(const ModuleSP &module_sp, bool use_notifier) { 203314564Sdim if (module_sp) { 204314564Sdim std::lock_guard<std::recursive_mutex> guard(m_modules_mutex); 205314564Sdim collection::iterator pos, end = m_modules.end(); 206314564Sdim for (pos = m_modules.begin(); pos != end; ++pos) { 207314564Sdim if (pos->get() == module_sp.get()) { 208314564Sdim m_modules.erase(pos); 209314564Sdim if (use_notifier && m_notifier) 210353358Sdim m_notifier->NotifyModuleRemoved(*this, module_sp); 211314564Sdim return true; 212314564Sdim } 213254721Semaste } 214314564Sdim } 215314564Sdim return false; 216254721Semaste} 217254721Semaste 218254721SemasteModuleList::collection::iterator 219314564SdimModuleList::RemoveImpl(ModuleList::collection::iterator pos, 220314564Sdim bool use_notifier) { 221314564Sdim ModuleSP module_sp(*pos); 222314564Sdim collection::iterator retval = m_modules.erase(pos); 223314564Sdim if (use_notifier && m_notifier) 224353358Sdim m_notifier->NotifyModuleRemoved(*this, module_sp); 225314564Sdim return retval; 226254721Semaste} 227254721Semaste 228353358Sdimbool ModuleList::Remove(const ModuleSP &module_sp, bool notify) { 229353358Sdim return RemoveImpl(module_sp, notify); 230254721Semaste} 231254721Semaste 232314564Sdimbool ModuleList::ReplaceModule(const lldb::ModuleSP &old_module_sp, 233314564Sdim const lldb::ModuleSP &new_module_sp) { 234314564Sdim if (!RemoveImpl(old_module_sp, false)) 235314564Sdim return false; 236314564Sdim AppendImpl(new_module_sp, false); 237314564Sdim if (m_notifier) 238353358Sdim m_notifier->NotifyModuleUpdated(*this, old_module_sp, new_module_sp); 239314564Sdim return true; 240254721Semaste} 241254721Semaste 242314564Sdimbool ModuleList::RemoveIfOrphaned(const Module *module_ptr) { 243314564Sdim if (module_ptr) { 244314564Sdim std::lock_guard<std::recursive_mutex> guard(m_modules_mutex); 245314564Sdim collection::iterator pos, end = m_modules.end(); 246314564Sdim for (pos = m_modules.begin(); pos != end; ++pos) { 247314564Sdim if (pos->get() == module_ptr) { 248314564Sdim if (pos->unique()) { 249314564Sdim pos = RemoveImpl(pos); 250314564Sdim return true; 251314564Sdim } else 252314564Sdim return false; 253314564Sdim } 254254721Semaste } 255314564Sdim } 256314564Sdim return false; 257254721Semaste} 258254721Semaste 259314564Sdimsize_t ModuleList::RemoveOrphans(bool mandatory) { 260314564Sdim std::unique_lock<std::recursive_mutex> lock(m_modules_mutex, std::defer_lock); 261309124Sdim 262314564Sdim if (mandatory) { 263314564Sdim lock.lock(); 264314564Sdim } else { 265314564Sdim // Not mandatory, remove orphans if we can get the mutex 266314564Sdim if (!lock.try_lock()) 267314564Sdim return 0; 268314564Sdim } 269314564Sdim collection::iterator pos = m_modules.begin(); 270314564Sdim size_t remove_count = 0; 271314564Sdim while (pos != m_modules.end()) { 272314564Sdim if (pos->unique()) { 273314564Sdim pos = RemoveImpl(pos); 274314564Sdim ++remove_count; 275314564Sdim } else { 276314564Sdim ++pos; 277254721Semaste } 278314564Sdim } 279314564Sdim return remove_count; 280254721Semaste} 281254721Semaste 282314564Sdimsize_t ModuleList::Remove(ModuleList &module_list) { 283314564Sdim std::lock_guard<std::recursive_mutex> guard(m_modules_mutex); 284314564Sdim size_t num_removed = 0; 285314564Sdim collection::iterator pos, end = module_list.m_modules.end(); 286314564Sdim for (pos = module_list.m_modules.begin(); pos != end; ++pos) { 287353358Sdim if (Remove(*pos, false /* notify */)) 288314564Sdim ++num_removed; 289314564Sdim } 290353358Sdim if (m_notifier) 291353358Sdim m_notifier->NotifyModulesRemoved(module_list); 292314564Sdim return num_removed; 293254721Semaste} 294254721Semaste 295314564Sdimvoid ModuleList::Clear() { ClearImpl(); } 296254721Semaste 297314564Sdimvoid ModuleList::Destroy() { ClearImpl(); } 298254721Semaste 299314564Sdimvoid ModuleList::ClearImpl(bool use_notifier) { 300314564Sdim std::lock_guard<std::recursive_mutex> guard(m_modules_mutex); 301314564Sdim if (use_notifier && m_notifier) 302353358Sdim m_notifier->NotifyWillClearList(*this); 303314564Sdim m_modules.clear(); 304254721Semaste} 305254721Semaste 306314564SdimModule *ModuleList::GetModulePointerAtIndex(size_t idx) const { 307314564Sdim std::lock_guard<std::recursive_mutex> guard(m_modules_mutex); 308314564Sdim return GetModulePointerAtIndexUnlocked(idx); 309254721Semaste} 310254721Semaste 311314564SdimModule *ModuleList::GetModulePointerAtIndexUnlocked(size_t idx) const { 312314564Sdim if (idx < m_modules.size()) 313314564Sdim return m_modules[idx].get(); 314314564Sdim return nullptr; 315254721Semaste} 316254721Semaste 317314564SdimModuleSP ModuleList::GetModuleAtIndex(size_t idx) const { 318314564Sdim std::lock_guard<std::recursive_mutex> guard(m_modules_mutex); 319314564Sdim return GetModuleAtIndexUnlocked(idx); 320254721Semaste} 321254721Semaste 322314564SdimModuleSP ModuleList::GetModuleAtIndexUnlocked(size_t idx) const { 323314564Sdim ModuleSP module_sp; 324314564Sdim if (idx < m_modules.size()) 325314564Sdim module_sp = m_modules[idx]; 326314564Sdim return module_sp; 327254721Semaste} 328254721Semaste 329360784Sdimvoid ModuleList::FindFunctions(ConstString name, 330360784Sdim FunctionNameType name_type_mask, 331360784Sdim bool include_symbols, bool include_inlines, 332360784Sdim SymbolContextList &sc_list) const { 333314564Sdim const size_t old_size = sc_list.GetSize(); 334309124Sdim 335314564Sdim if (name_type_mask & eFunctionNameTypeAuto) { 336314564Sdim Module::LookupInfo lookup_info(name, name_type_mask, eLanguageTypeUnknown); 337254721Semaste 338314564Sdim std::lock_guard<std::recursive_mutex> guard(m_modules_mutex); 339314564Sdim collection::const_iterator pos, end = m_modules.end(); 340314564Sdim for (pos = m_modules.begin(); pos != end; ++pos) { 341314564Sdim (*pos)->FindFunctions(lookup_info.GetLookupName(), nullptr, 342314564Sdim lookup_info.GetNameTypeMask(), include_symbols, 343360784Sdim include_inlines, sc_list); 344254721Semaste } 345254721Semaste 346314564Sdim const size_t new_size = sc_list.GetSize(); 347254721Semaste 348314564Sdim if (old_size < new_size) 349314564Sdim lookup_info.Prune(sc_list, old_size); 350314564Sdim } else { 351314564Sdim std::lock_guard<std::recursive_mutex> guard(m_modules_mutex); 352314564Sdim collection::const_iterator pos, end = m_modules.end(); 353314564Sdim for (pos = m_modules.begin(); pos != end; ++pos) { 354314564Sdim (*pos)->FindFunctions(name, nullptr, name_type_mask, include_symbols, 355360784Sdim include_inlines, sc_list); 356254721Semaste } 357314564Sdim } 358254721Semaste} 359254721Semaste 360360784Sdimvoid ModuleList::FindFunctionSymbols(ConstString name, 361360784Sdim lldb::FunctionNameType name_type_mask, 362360784Sdim SymbolContextList &sc_list) { 363314564Sdim const size_t old_size = sc_list.GetSize(); 364280031Sdim 365314564Sdim if (name_type_mask & eFunctionNameTypeAuto) { 366314564Sdim Module::LookupInfo lookup_info(name, name_type_mask, eLanguageTypeUnknown); 367314564Sdim 368309124Sdim std::lock_guard<std::recursive_mutex> guard(m_modules_mutex); 369280031Sdim collection::const_iterator pos, end = m_modules.end(); 370314564Sdim for (pos = m_modules.begin(); pos != end; ++pos) { 371314564Sdim (*pos)->FindFunctionSymbols(lookup_info.GetLookupName(), 372314564Sdim lookup_info.GetNameTypeMask(), sc_list); 373280031Sdim } 374280031Sdim 375314564Sdim const size_t new_size = sc_list.GetSize(); 376280031Sdim 377314564Sdim if (old_size < new_size) 378314564Sdim lookup_info.Prune(sc_list, old_size); 379314564Sdim } else { 380309124Sdim std::lock_guard<std::recursive_mutex> guard(m_modules_mutex); 381254721Semaste collection::const_iterator pos, end = m_modules.end(); 382314564Sdim for (pos = m_modules.begin(); pos != end; ++pos) { 383314564Sdim (*pos)->FindFunctionSymbols(name, name_type_mask, sc_list); 384254721Semaste } 385314564Sdim } 386254721Semaste} 387254721Semaste 388360784Sdimvoid ModuleList::FindFunctions(const RegularExpression &name, 389360784Sdim bool include_symbols, bool include_inlines, 390360784Sdim SymbolContextList &sc_list) { 391314564Sdim std::lock_guard<std::recursive_mutex> guard(m_modules_mutex); 392314564Sdim collection::const_iterator pos, end = m_modules.end(); 393314564Sdim for (pos = m_modules.begin(); pos != end; ++pos) { 394360784Sdim (*pos)->FindFunctions(name, include_symbols, include_inlines, sc_list); 395314564Sdim } 396254721Semaste} 397254721Semaste 398360784Sdimvoid ModuleList::FindCompileUnits(const FileSpec &path, 399360784Sdim SymbolContextList &sc_list) const { 400314564Sdim std::lock_guard<std::recursive_mutex> guard(m_modules_mutex); 401314564Sdim collection::const_iterator pos, end = m_modules.end(); 402314564Sdim for (pos = m_modules.begin(); pos != end; ++pos) { 403360784Sdim (*pos)->FindCompileUnits(path, sc_list); 404314564Sdim } 405254721Semaste} 406254721Semaste 407360784Sdimvoid ModuleList::FindGlobalVariables(ConstString name, size_t max_matches, 408360784Sdim VariableList &variable_list) const { 409314564Sdim std::lock_guard<std::recursive_mutex> guard(m_modules_mutex); 410314564Sdim collection::const_iterator pos, end = m_modules.end(); 411314564Sdim for (pos = m_modules.begin(); pos != end; ++pos) { 412341825Sdim (*pos)->FindGlobalVariables(name, nullptr, max_matches, variable_list); 413314564Sdim } 414254721Semaste} 415254721Semaste 416360784Sdimvoid ModuleList::FindGlobalVariables(const RegularExpression ®ex, 417360784Sdim size_t max_matches, 418360784Sdim VariableList &variable_list) const { 419314564Sdim std::lock_guard<std::recursive_mutex> guard(m_modules_mutex); 420314564Sdim collection::const_iterator pos, end = m_modules.end(); 421314564Sdim for (pos = m_modules.begin(); pos != end; ++pos) { 422341825Sdim (*pos)->FindGlobalVariables(regex, max_matches, variable_list); 423314564Sdim } 424254721Semaste} 425254721Semaste 426360784Sdimvoid ModuleList::FindSymbolsWithNameAndType(ConstString name, 427360784Sdim SymbolType symbol_type, 428360784Sdim SymbolContextList &sc_list) const { 429314564Sdim std::lock_guard<std::recursive_mutex> guard(m_modules_mutex); 430314564Sdim collection::const_iterator pos, end = m_modules.end(); 431314564Sdim for (pos = m_modules.begin(); pos != end; ++pos) 432314564Sdim (*pos)->FindSymbolsWithNameAndType(name, symbol_type, sc_list); 433254721Semaste} 434254721Semaste 435360784Sdimvoid ModuleList::FindSymbolsMatchingRegExAndType( 436314564Sdim const RegularExpression ®ex, lldb::SymbolType symbol_type, 437360784Sdim SymbolContextList &sc_list) const { 438314564Sdim std::lock_guard<std::recursive_mutex> guard(m_modules_mutex); 439314564Sdim collection::const_iterator pos, end = m_modules.end(); 440314564Sdim for (pos = m_modules.begin(); pos != end; ++pos) 441314564Sdim (*pos)->FindSymbolsMatchingRegExAndType(regex, symbol_type, sc_list); 442254721Semaste} 443254721Semaste 444360784Sdimvoid ModuleList::FindModules(const ModuleSpec &module_spec, 445360784Sdim ModuleList &matching_module_list) const { 446314564Sdim std::lock_guard<std::recursive_mutex> guard(m_modules_mutex); 447314564Sdim collection::const_iterator pos, end = m_modules.end(); 448314564Sdim for (pos = m_modules.begin(); pos != end; ++pos) { 449314564Sdim ModuleSP module_sp(*pos); 450314564Sdim if (module_sp->MatchesModuleSpec(module_spec)) 451314564Sdim matching_module_list.Append(module_sp); 452314564Sdim } 453254721Semaste} 454254721Semaste 455314564SdimModuleSP ModuleList::FindModule(const Module *module_ptr) const { 456314564Sdim ModuleSP module_sp; 457314564Sdim 458314564Sdim // Scope for "locker" 459314564Sdim { 460309124Sdim std::lock_guard<std::recursive_mutex> guard(m_modules_mutex); 461254721Semaste collection::const_iterator pos, end = m_modules.end(); 462254721Semaste 463314564Sdim for (pos = m_modules.begin(); pos != end; ++pos) { 464314564Sdim if ((*pos).get() == module_ptr) { 465314564Sdim module_sp = (*pos); 466314564Sdim break; 467314564Sdim } 468254721Semaste } 469314564Sdim } 470314564Sdim return module_sp; 471254721Semaste} 472254721Semaste 473314564SdimModuleSP ModuleList::FindModule(const UUID &uuid) const { 474314564Sdim ModuleSP module_sp; 475314564Sdim 476314564Sdim if (uuid.IsValid()) { 477309124Sdim std::lock_guard<std::recursive_mutex> guard(m_modules_mutex); 478254721Semaste collection::const_iterator pos, end = m_modules.end(); 479314564Sdim 480314564Sdim for (pos = m_modules.begin(); pos != end; ++pos) { 481314564Sdim if ((*pos)->GetUUID() == uuid) { 482314564Sdim module_sp = (*pos); 483314564Sdim break; 484314564Sdim } 485254721Semaste } 486314564Sdim } 487314564Sdim return module_sp; 488254721Semaste} 489254721Semaste 490360784Sdimvoid ModuleList::FindTypes(Module *search_first, ConstString name, 491360784Sdim bool name_is_fully_qualified, size_t max_matches, 492360784Sdim llvm::DenseSet<SymbolFile *> &searched_symbol_files, 493360784Sdim TypeList &types) const { 494314564Sdim std::lock_guard<std::recursive_mutex> guard(m_modules_mutex); 495314564Sdim 496314564Sdim collection::const_iterator pos, end = m_modules.end(); 497344779Sdim if (search_first) { 498314564Sdim for (pos = m_modules.begin(); pos != end; ++pos) { 499344779Sdim if (search_first == pos->get()) { 500360784Sdim search_first->FindTypes(name, name_is_fully_qualified, max_matches, 501360784Sdim searched_symbol_files, types); 502314564Sdim 503360784Sdim if (types.GetSize() >= max_matches) 504360784Sdim return; 505314564Sdim } 506258054Semaste } 507314564Sdim } 508254721Semaste 509360784Sdim for (pos = m_modules.begin(); pos != end; ++pos) { 510360784Sdim // Search the module if the module is not equal to the one in the symbol 511360784Sdim // context "sc". If "sc" contains a empty module shared pointer, then the 512360784Sdim // comparison will always be true (valid_module_ptr != nullptr). 513360784Sdim if (search_first != pos->get()) 514360784Sdim (*pos)->FindTypes(name, name_is_fully_qualified, max_matches, 515360784Sdim searched_symbol_files, types); 516314564Sdim 517360784Sdim if (types.GetSize() >= max_matches) 518360784Sdim return; 519314564Sdim } 520254721Semaste} 521254721Semaste 522314564Sdimbool ModuleList::FindSourceFile(const FileSpec &orig_spec, 523314564Sdim FileSpec &new_spec) const { 524314564Sdim std::lock_guard<std::recursive_mutex> guard(m_modules_mutex); 525314564Sdim collection::const_iterator pos, end = m_modules.end(); 526314564Sdim for (pos = m_modules.begin(); pos != end; ++pos) { 527314564Sdim if ((*pos)->FindSourceFile(orig_spec, new_spec)) 528314564Sdim return true; 529314564Sdim } 530314564Sdim return false; 531254721Semaste} 532254721Semaste 533314564Sdimvoid ModuleList::FindAddressesForLine(const lldb::TargetSP target_sp, 534314564Sdim const FileSpec &file, uint32_t line, 535314564Sdim Function *function, 536314564Sdim std::vector<Address> &output_local, 537314564Sdim std::vector<Address> &output_extern) { 538314564Sdim std::lock_guard<std::recursive_mutex> guard(m_modules_mutex); 539314564Sdim collection::const_iterator pos, end = m_modules.end(); 540314564Sdim for (pos = m_modules.begin(); pos != end; ++pos) { 541314564Sdim (*pos)->FindAddressesForLine(target_sp, file, line, function, output_local, 542314564Sdim output_extern); 543314564Sdim } 544314564Sdim} 545254721Semaste 546314564SdimModuleSP ModuleList::FindFirstModule(const ModuleSpec &module_spec) const { 547314564Sdim ModuleSP module_sp; 548314564Sdim std::lock_guard<std::recursive_mutex> guard(m_modules_mutex); 549314564Sdim collection::const_iterator pos, end = m_modules.end(); 550314564Sdim for (pos = m_modules.begin(); pos != end; ++pos) { 551314564Sdim ModuleSP module_sp(*pos); 552314564Sdim if (module_sp->MatchesModuleSpec(module_spec)) 553314564Sdim return module_sp; 554314564Sdim } 555314564Sdim return module_sp; 556314564Sdim} 557314564Sdim 558314564Sdimsize_t ModuleList::GetSize() const { 559314564Sdim size_t size = 0; 560314564Sdim { 561309124Sdim std::lock_guard<std::recursive_mutex> guard(m_modules_mutex); 562314564Sdim size = m_modules.size(); 563314564Sdim } 564314564Sdim return size; 565254721Semaste} 566254721Semaste 567314564Sdimvoid ModuleList::Dump(Stream *s) const { 568314564Sdim // s.Printf("%.*p: ", (int)sizeof(void*) * 2, this); 569314564Sdim // s.Indent(); 570314564Sdim // s << "ModuleList\n"; 571314564Sdim 572314564Sdim std::lock_guard<std::recursive_mutex> guard(m_modules_mutex); 573314564Sdim collection::const_iterator pos, end = m_modules.end(); 574314564Sdim for (pos = m_modules.begin(); pos != end; ++pos) { 575314564Sdim (*pos)->Dump(s); 576314564Sdim } 577254721Semaste} 578254721Semaste 579314564Sdimvoid ModuleList::LogUUIDAndPaths(Log *log, const char *prefix_cstr) { 580314564Sdim if (log != nullptr) { 581309124Sdim std::lock_guard<std::recursive_mutex> guard(m_modules_mutex); 582314564Sdim collection::const_iterator pos, begin = m_modules.begin(), 583314564Sdim end = m_modules.end(); 584314564Sdim for (pos = begin; pos != end; ++pos) { 585314564Sdim Module *module = pos->get(); 586314564Sdim const FileSpec &module_file_spec = module->GetFileSpec(); 587360784Sdim LLDB_LOGF(log, "%s[%u] %s (%s) \"%s\"", prefix_cstr ? prefix_cstr : "", 588360784Sdim (uint32_t)std::distance(begin, pos), 589360784Sdim module->GetUUID().GetAsString().c_str(), 590360784Sdim module->GetArchitecture().GetArchitectureName(), 591360784Sdim module_file_spec.GetPath().c_str()); 592254721Semaste } 593314564Sdim } 594314564Sdim} 595254721Semaste 596314564Sdimbool ModuleList::ResolveFileAddress(lldb::addr_t vm_addr, 597314564Sdim Address &so_addr) const { 598314564Sdim std::lock_guard<std::recursive_mutex> guard(m_modules_mutex); 599314564Sdim collection::const_iterator pos, end = m_modules.end(); 600314564Sdim for (pos = m_modules.begin(); pos != end; ++pos) { 601314564Sdim if ((*pos)->ResolveFileAddress(vm_addr, so_addr)) 602314564Sdim return true; 603314564Sdim } 604314564Sdim 605314564Sdim return false; 606254721Semaste} 607254721Semaste 608344779Sdimuint32_t 609344779SdimModuleList::ResolveSymbolContextForAddress(const Address &so_addr, 610344779Sdim SymbolContextItem resolve_scope, 611344779Sdim SymbolContext &sc) const { 612314564Sdim // The address is already section offset so it has a module 613314564Sdim uint32_t resolved_flags = 0; 614314564Sdim ModuleSP module_sp(so_addr.GetModule()); 615314564Sdim if (module_sp) { 616314564Sdim resolved_flags = 617314564Sdim module_sp->ResolveSymbolContextForAddress(so_addr, resolve_scope, sc); 618314564Sdim } else { 619314564Sdim std::lock_guard<std::recursive_mutex> guard(m_modules_mutex); 620314564Sdim collection::const_iterator pos, end = m_modules.end(); 621314564Sdim for (pos = m_modules.begin(); pos != end; ++pos) { 622314564Sdim resolved_flags = 623314564Sdim (*pos)->ResolveSymbolContextForAddress(so_addr, resolve_scope, sc); 624314564Sdim if (resolved_flags != 0) 625314564Sdim break; 626254721Semaste } 627314564Sdim } 628254721Semaste 629314564Sdim return resolved_flags; 630254721Semaste} 631254721Semaste 632314564Sdimuint32_t ModuleList::ResolveSymbolContextForFilePath( 633314564Sdim const char *file_path, uint32_t line, bool check_inlines, 634344779Sdim SymbolContextItem resolve_scope, SymbolContextList &sc_list) const { 635344779Sdim FileSpec file_spec(file_path); 636314564Sdim return ResolveSymbolContextsForFileSpec(file_spec, line, check_inlines, 637314564Sdim resolve_scope, sc_list); 638254721Semaste} 639254721Semaste 640314564Sdimuint32_t ModuleList::ResolveSymbolContextsForFileSpec( 641314564Sdim const FileSpec &file_spec, uint32_t line, bool check_inlines, 642344779Sdim SymbolContextItem resolve_scope, SymbolContextList &sc_list) const { 643314564Sdim std::lock_guard<std::recursive_mutex> guard(m_modules_mutex); 644314564Sdim collection::const_iterator pos, end = m_modules.end(); 645314564Sdim for (pos = m_modules.begin(); pos != end; ++pos) { 646314564Sdim (*pos)->ResolveSymbolContextsForFileSpec(file_spec, line, check_inlines, 647314564Sdim resolve_scope, sc_list); 648314564Sdim } 649254721Semaste 650314564Sdim return sc_list.GetSize(); 651254721Semaste} 652254721Semaste 653314564Sdimsize_t ModuleList::GetIndexForModule(const Module *module) const { 654314564Sdim if (module) { 655314564Sdim std::lock_guard<std::recursive_mutex> guard(m_modules_mutex); 656314564Sdim collection::const_iterator pos; 657314564Sdim collection::const_iterator begin = m_modules.begin(); 658314564Sdim collection::const_iterator end = m_modules.end(); 659314564Sdim for (pos = begin; pos != end; ++pos) { 660314564Sdim if ((*pos).get() == module) 661314564Sdim return std::distance(begin, pos); 662254721Semaste } 663314564Sdim } 664314564Sdim return LLDB_INVALID_INDEX32; 665254721Semaste} 666254721Semaste 667341825Sdimnamespace { 668341825Sdimstruct SharedModuleListInfo { 669341825Sdim ModuleList module_list; 670341825Sdim ModuleListProperties module_list_properties; 671341825Sdim}; 672341825Sdim} 673341825Sdimstatic SharedModuleListInfo &GetSharedModuleListInfo() 674341825Sdim{ 675341825Sdim static SharedModuleListInfo *g_shared_module_list_info = nullptr; 676321369Sdim static llvm::once_flag g_once_flag; 677321369Sdim llvm::call_once(g_once_flag, []() { 678314564Sdim // NOTE: Intentionally leak the module list so a program doesn't have to 679314564Sdim // cleanup all modules and object files as it exits. This just wastes time 680314564Sdim // doing a bunch of cleanup that isn't required. 681341825Sdim if (g_shared_module_list_info == nullptr) 682341825Sdim g_shared_module_list_info = new SharedModuleListInfo(); 683314564Sdim }); 684341825Sdim return *g_shared_module_list_info; 685254721Semaste} 686254721Semaste 687341825Sdimstatic ModuleList &GetSharedModuleList() { 688341825Sdim return GetSharedModuleListInfo().module_list; 689341825Sdim} 690341825Sdim 691341825SdimModuleListProperties &ModuleList::GetGlobalModuleListProperties() { 692341825Sdim return GetSharedModuleListInfo().module_list_properties; 693341825Sdim} 694341825Sdim 695314564Sdimbool ModuleList::ModuleIsInCache(const Module *module_ptr) { 696314564Sdim if (module_ptr) { 697314564Sdim ModuleList &shared_module_list = GetSharedModuleList(); 698314564Sdim return shared_module_list.FindModule(module_ptr).get() != nullptr; 699314564Sdim } 700314564Sdim return false; 701254721Semaste} 702254721Semaste 703360784Sdimvoid ModuleList::FindSharedModules(const ModuleSpec &module_spec, 704360784Sdim ModuleList &matching_module_list) { 705360784Sdim GetSharedModuleList().FindModules(module_spec, matching_module_list); 706254721Semaste} 707254721Semaste 708314564Sdimsize_t ModuleList::RemoveOrphanSharedModules(bool mandatory) { 709314564Sdim return GetSharedModuleList().RemoveOrphans(mandatory); 710254721Semaste} 711254721Semaste 712321369SdimStatus ModuleList::GetSharedModule(const ModuleSpec &module_spec, 713321369Sdim ModuleSP &module_sp, 714321369Sdim const FileSpecList *module_search_paths_ptr, 715321369Sdim ModuleSP *old_module_sp_ptr, 716321369Sdim bool *did_create_ptr, bool always_create) { 717314564Sdim ModuleList &shared_module_list = GetSharedModuleList(); 718314564Sdim std::lock_guard<std::recursive_mutex> guard( 719314564Sdim shared_module_list.m_modules_mutex); 720314564Sdim char path[PATH_MAX]; 721254721Semaste 722321369Sdim Status error; 723254721Semaste 724314564Sdim module_sp.reset(); 725254721Semaste 726314564Sdim if (did_create_ptr) 727314564Sdim *did_create_ptr = false; 728314564Sdim if (old_module_sp_ptr) 729314564Sdim old_module_sp_ptr->reset(); 730254721Semaste 731314564Sdim const UUID *uuid_ptr = module_spec.GetUUIDPtr(); 732314564Sdim const FileSpec &module_file_spec = module_spec.GetFileSpec(); 733314564Sdim const ArchSpec &arch = module_spec.GetArchitecture(); 734254721Semaste 735314564Sdim // Make sure no one else can try and get or create a module while this 736341825Sdim // function is actively working on it by doing an extra lock on the global 737341825Sdim // mutex list. 738314564Sdim if (!always_create) { 739314564Sdim ModuleList matching_module_list; 740360784Sdim shared_module_list.FindModules(module_spec, matching_module_list); 741360784Sdim const size_t num_matching_modules = matching_module_list.GetSize(); 742360784Sdim 743314564Sdim if (num_matching_modules > 0) { 744314564Sdim for (size_t module_idx = 0; module_idx < num_matching_modules; 745314564Sdim ++module_idx) { 746314564Sdim module_sp = matching_module_list.GetModuleAtIndex(module_idx); 747276479Sdim 748314564Sdim // Make sure the file for the module hasn't been modified 749314564Sdim if (module_sp->FileHasChanged()) { 750314564Sdim if (old_module_sp_ptr && !*old_module_sp_ptr) 751314564Sdim *old_module_sp_ptr = module_sp; 752254721Semaste 753314564Sdim Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_MODULES)); 754314564Sdim if (log != nullptr) 755360784Sdim LLDB_LOGF( 756360784Sdim log, "%p '%s' module changed: removing from global module list", 757360784Sdim static_cast<void *>(module_sp.get()), 758360784Sdim module_sp->GetFileSpec().GetFilename().GetCString()); 759254721Semaste 760314564Sdim shared_module_list.Remove(module_sp); 761314564Sdim module_sp.reset(); 762314564Sdim } else { 763341825Sdim // The module matches and the module was not modified from when it 764341825Sdim // was last loaded. 765314564Sdim return error; 766254721Semaste } 767314564Sdim } 768254721Semaste } 769314564Sdim } 770254721Semaste 771314564Sdim if (module_sp) 772314564Sdim return error; 773314564Sdim 774353358Sdim module_sp = std::make_shared<Module>(module_spec); 775341825Sdim // Make sure there are a module and an object file since we can specify a 776341825Sdim // valid file path with an architecture that might not be in that file. By 777341825Sdim // getting the object file we can guarantee that the architecture matches 778314564Sdim if (module_sp->GetObjectFile()) { 779341825Sdim // If we get in here we got the correct arch, now we just need to verify 780341825Sdim // the UUID if one was given 781314564Sdim if (uuid_ptr && *uuid_ptr != module_sp->GetUUID()) { 782314564Sdim module_sp.reset(); 783314564Sdim } else { 784314564Sdim if (module_sp->GetObjectFile() && 785314564Sdim module_sp->GetObjectFile()->GetType() == 786314564Sdim ObjectFile::eTypeStubLibrary) { 787314564Sdim module_sp.reset(); 788314564Sdim } else { 789314564Sdim if (did_create_ptr) { 790314564Sdim *did_create_ptr = true; 791314564Sdim } 792314564Sdim 793314564Sdim shared_module_list.ReplaceEquivalent(module_sp); 794254721Semaste return error; 795314564Sdim } 796314564Sdim } 797314564Sdim } else { 798314564Sdim module_sp.reset(); 799314564Sdim } 800288943Sdim 801314564Sdim if (module_search_paths_ptr) { 802314564Sdim const auto num_directories = module_search_paths_ptr->GetSize(); 803314564Sdim for (size_t idx = 0; idx < num_directories; ++idx) { 804314564Sdim auto search_path_spec = module_search_paths_ptr->GetFileSpecAtIndex(idx); 805344779Sdim FileSystem::Instance().Resolve(search_path_spec); 806321369Sdim namespace fs = llvm::sys::fs; 807344779Sdim if (!FileSystem::Instance().IsDirectory(search_path_spec)) 808314564Sdim continue; 809314564Sdim search_path_spec.AppendPathComponent( 810314564Sdim module_spec.GetFileSpec().GetFilename().AsCString()); 811344779Sdim if (!FileSystem::Instance().Exists(search_path_spec)) 812314564Sdim continue; 813314564Sdim 814314564Sdim auto resolved_module_spec(module_spec); 815314564Sdim resolved_module_spec.GetFileSpec() = search_path_spec; 816353358Sdim module_sp = std::make_shared<Module>(resolved_module_spec); 817314564Sdim if (module_sp->GetObjectFile()) { 818341825Sdim // If we get in here we got the correct arch, now we just need to 819341825Sdim // verify the UUID if one was given 820314564Sdim if (uuid_ptr && *uuid_ptr != module_sp->GetUUID()) { 821314564Sdim module_sp.reset(); 822314564Sdim } else { 823314564Sdim if (module_sp->GetObjectFile()->GetType() == 824314564Sdim ObjectFile::eTypeStubLibrary) { 825288943Sdim module_sp.reset(); 826314564Sdim } else { 827314564Sdim if (did_create_ptr) 828314564Sdim *did_create_ptr = true; 829288943Sdim 830314564Sdim shared_module_list.ReplaceEquivalent(module_sp); 831321369Sdim return Status(); 832314564Sdim } 833288943Sdim } 834314564Sdim } else { 835288943Sdim module_sp.reset(); 836314564Sdim } 837296417Sdim } 838314564Sdim } 839288943Sdim 840314564Sdim // Either the file didn't exist where at the path, or no path was given, so 841314564Sdim // we now have to use more extreme measures to try and find the appropriate 842314564Sdim // module. 843288943Sdim 844341825Sdim // Fixup the incoming path in case the path points to a valid file, yet the 845341825Sdim // arch or UUID (if one was passed in) don't match. 846314564Sdim ModuleSpec located_binary_modulespec = 847314564Sdim Symbols::LocateExecutableObjectFile(module_spec); 848314564Sdim 849314564Sdim // Don't look for the file if it appears to be the same one we already 850314564Sdim // checked for above... 851314564Sdim if (located_binary_modulespec.GetFileSpec() != module_file_spec) { 852344779Sdim if (!FileSystem::Instance().Exists( 853344779Sdim located_binary_modulespec.GetFileSpec())) { 854314564Sdim located_binary_modulespec.GetFileSpec().GetPath(path, sizeof(path)); 855314564Sdim if (path[0] == '\0') 856314564Sdim module_file_spec.GetPath(path, sizeof(path)); 857314564Sdim // How can this check ever be true? This branch it is false, and we 858314564Sdim // haven't modified file_spec. 859344779Sdim if (FileSystem::Instance().Exists( 860344779Sdim located_binary_modulespec.GetFileSpec())) { 861314564Sdim std::string uuid_str; 862314564Sdim if (uuid_ptr && uuid_ptr->IsValid()) 863314564Sdim uuid_str = uuid_ptr->GetAsString(); 864314564Sdim 865314564Sdim if (arch.IsValid()) { 866314564Sdim if (!uuid_str.empty()) 867314564Sdim error.SetErrorStringWithFormat( 868314564Sdim "'%s' does not contain the %s architecture and UUID %s", path, 869314564Sdim arch.GetArchitectureName(), uuid_str.c_str()); 870314564Sdim else 871314564Sdim error.SetErrorStringWithFormat( 872314564Sdim "'%s' does not contain the %s architecture.", path, 873314564Sdim arch.GetArchitectureName()); 874254721Semaste } 875314564Sdim } else { 876314564Sdim error.SetErrorStringWithFormat("'%s' does not exist", path); 877314564Sdim } 878314564Sdim if (error.Fail()) 879314564Sdim module_sp.reset(); 880314564Sdim return error; 881254721Semaste } 882254721Semaste 883314564Sdim // Make sure no one else can try and get or create a module while this 884341825Sdim // function is actively working on it by doing an extra lock on the global 885341825Sdim // mutex list. 886314564Sdim ModuleSpec platform_module_spec(module_spec); 887314564Sdim platform_module_spec.GetFileSpec() = 888314564Sdim located_binary_modulespec.GetFileSpec(); 889314564Sdim platform_module_spec.GetPlatformFileSpec() = 890314564Sdim located_binary_modulespec.GetFileSpec(); 891314564Sdim platform_module_spec.GetSymbolFileSpec() = 892314564Sdim located_binary_modulespec.GetSymbolFileSpec(); 893314564Sdim ModuleList matching_module_list; 894360784Sdim shared_module_list.FindModules(platform_module_spec, matching_module_list); 895360784Sdim if (!matching_module_list.IsEmpty()) { 896314564Sdim module_sp = matching_module_list.GetModuleAtIndex(0); 897254721Semaste 898314564Sdim // If we didn't have a UUID in mind when looking for the object file, 899314564Sdim // then we should make sure the modification time hasn't changed! 900314564Sdim if (platform_module_spec.GetUUIDPtr() == nullptr) { 901344779Sdim auto file_spec_mod_time = FileSystem::Instance().GetModificationTime( 902314564Sdim located_binary_modulespec.GetFileSpec()); 903314564Sdim if (file_spec_mod_time != llvm::sys::TimePoint<>()) { 904314564Sdim if (file_spec_mod_time != module_sp->GetModificationTime()) { 905314564Sdim if (old_module_sp_ptr) 906314564Sdim *old_module_sp_ptr = module_sp; 907314564Sdim shared_module_list.Remove(module_sp); 908314564Sdim module_sp.reset(); 909314564Sdim } 910254721Semaste } 911314564Sdim } 912314564Sdim } 913254721Semaste 914314564Sdim if (!module_sp) { 915353358Sdim module_sp = std::make_shared<Module>(platform_module_spec); 916341825Sdim // Make sure there are a module and an object file since we can specify a 917341825Sdim // valid file path with an architecture that might not be in that file. 918314564Sdim // By getting the object file we can guarantee that the architecture 919314564Sdim // matches 920314564Sdim if (module_sp && module_sp->GetObjectFile()) { 921314564Sdim if (module_sp->GetObjectFile()->GetType() == 922314564Sdim ObjectFile::eTypeStubLibrary) { 923314564Sdim module_sp.reset(); 924314564Sdim } else { 925314564Sdim if (did_create_ptr) 926314564Sdim *did_create_ptr = true; 927254721Semaste 928314564Sdim shared_module_list.ReplaceEquivalent(module_sp); 929254721Semaste } 930314564Sdim } else { 931314564Sdim located_binary_modulespec.GetFileSpec().GetPath(path, sizeof(path)); 932254721Semaste 933314564Sdim if (located_binary_modulespec.GetFileSpec()) { 934314564Sdim if (arch.IsValid()) 935314564Sdim error.SetErrorStringWithFormat( 936314564Sdim "unable to open %s architecture in '%s'", 937314564Sdim arch.GetArchitectureName(), path); 938314564Sdim else 939314564Sdim error.SetErrorStringWithFormat("unable to open '%s'", path); 940314564Sdim } else { 941314564Sdim std::string uuid_str; 942314564Sdim if (uuid_ptr && uuid_ptr->IsValid()) 943314564Sdim uuid_str = uuid_ptr->GetAsString(); 944254721Semaste 945314564Sdim if (!uuid_str.empty()) 946314564Sdim error.SetErrorStringWithFormat( 947314564Sdim "cannot locate a module for UUID '%s'", uuid_str.c_str()); 948314564Sdim else 949314564Sdim error.SetErrorStringWithFormat("cannot locate a module"); 950254721Semaste } 951314564Sdim } 952254721Semaste } 953314564Sdim } 954254721Semaste 955314564Sdim return error; 956254721Semaste} 957254721Semaste 958314564Sdimbool ModuleList::RemoveSharedModule(lldb::ModuleSP &module_sp) { 959314564Sdim return GetSharedModuleList().Remove(module_sp); 960254721Semaste} 961254721Semaste 962314564Sdimbool ModuleList::RemoveSharedModuleIfOrphaned(const Module *module_ptr) { 963314564Sdim return GetSharedModuleList().RemoveIfOrphaned(module_ptr); 964254721Semaste} 965254721Semaste 966314564Sdimbool ModuleList::LoadScriptingResourcesInTarget(Target *target, 967321369Sdim std::list<Status> &errors, 968314564Sdim Stream *feedback_stream, 969314564Sdim bool continue_on_error) { 970314564Sdim if (!target) 971314564Sdim return false; 972314564Sdim std::lock_guard<std::recursive_mutex> guard(m_modules_mutex); 973314564Sdim for (auto module : m_modules) { 974321369Sdim Status error; 975314564Sdim if (module) { 976314564Sdim if (!module->LoadScriptingResourceInTarget(target, error, 977314564Sdim feedback_stream)) { 978314564Sdim if (error.Fail() && error.AsCString()) { 979314564Sdim error.SetErrorStringWithFormat("unable to load scripting data for " 980314564Sdim "module %s - error reported was %s", 981314564Sdim module->GetFileSpec() 982314564Sdim .GetFileNameStrippingExtension() 983314564Sdim .GetCString(), 984314564Sdim error.AsCString()); 985314564Sdim errors.push_back(error); 986276479Sdim 987314564Sdim if (!continue_on_error) 988314564Sdim return false; 989254721Semaste } 990314564Sdim } 991254721Semaste } 992314564Sdim } 993314564Sdim return errors.empty(); 994254721Semaste} 995288943Sdim 996314564Sdimvoid ModuleList::ForEach( 997314564Sdim std::function<bool(const ModuleSP &module_sp)> const &callback) const { 998314564Sdim std::lock_guard<std::recursive_mutex> guard(m_modules_mutex); 999314564Sdim for (const auto &module : m_modules) { 1000314564Sdim // If the callback returns false, then stop iterating and break out 1001314564Sdim if (!callback(module)) 1002314564Sdim break; 1003314564Sdim } 1004288943Sdim} 1005