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