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