1 //===-- ModuleList.cpp ------------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "lldb/Core/ModuleList.h" 11 12 // C Includes 13 // C++ Includes 14 // Other libraries and framework includes 15 // Project includes 16 #include "lldb/Core/Log.h" 17 #include "lldb/Core/Module.h" 18 #include "lldb/Host/Host.h" 19 #include "lldb/Host/Symbols.h" 20 #include "lldb/Symbol/ClangNamespaceDecl.h" 21 #include "lldb/Symbol/ObjectFile.h" 22 #include "lldb/Symbol/VariableList.h" 23 24 using namespace lldb; 25 using namespace lldb_private; 26 27 //---------------------------------------------------------------------- 28 // ModuleList constructor 29 //---------------------------------------------------------------------- 30 ModuleList::ModuleList() : 31 m_modules(), 32 m_modules_mutex (Mutex::eMutexTypeRecursive) 33 { 34 } 35 36 //---------------------------------------------------------------------- 37 // Copy constructor 38 //---------------------------------------------------------------------- 39 ModuleList::ModuleList(const ModuleList& rhs) : 40 m_modules(rhs.m_modules) 41 { 42 } 43 44 //---------------------------------------------------------------------- 45 // Assignment operator 46 //---------------------------------------------------------------------- 47 const ModuleList& 48 ModuleList::operator= (const ModuleList& rhs) 49 { 50 if (this != &rhs) 51 { 52 Mutex::Locker locker(m_modules_mutex); 53 m_modules = rhs.m_modules; 54 } 55 return *this; 56 } 57 58 //---------------------------------------------------------------------- 59 // Destructor 60 //---------------------------------------------------------------------- 61 ModuleList::~ModuleList() 62 { 63 } 64 65 void 66 ModuleList::Append (const ModuleSP &module_sp) 67 { 68 if (module_sp) 69 { 70 Mutex::Locker locker(m_modules_mutex); 71 m_modules.push_back(module_sp); 72 } 73 } 74 75 bool 76 ModuleList::AppendIfNeeded (const ModuleSP &module_sp) 77 { 78 if (module_sp) 79 { 80 Mutex::Locker locker(m_modules_mutex); 81 collection::iterator pos, end = m_modules.end(); 82 for (pos = m_modules.begin(); pos != end; ++pos) 83 { 84 if (pos->get() == module_sp.get()) 85 return false; // Already in the list 86 } 87 // Only push module_sp on the list if it wasn't already in there. 88 m_modules.push_back(module_sp); 89 return true; 90 } 91 return false; 92 } 93 94 bool 95 ModuleList::Remove (const ModuleSP &module_sp) 96 { 97 if (module_sp) 98 { 99 Mutex::Locker locker(m_modules_mutex); 100 collection::iterator pos, end = m_modules.end(); 101 for (pos = m_modules.begin(); pos != end; ++pos) 102 { 103 if (pos->get() == module_sp.get()) 104 { 105 m_modules.erase (pos); 106 return true; 107 } 108 } 109 } 110 return false; 111 } 112 113 114 size_t 115 ModuleList::RemoveOrphans () 116 { 117 Mutex::Locker locker(m_modules_mutex); 118 collection::iterator pos = m_modules.begin(); 119 size_t remove_count = 0; 120 while (pos != m_modules.end()) 121 { 122 if (pos->unique()) 123 { 124 pos = m_modules.erase (pos); 125 ++remove_count; 126 } 127 else 128 { 129 ++pos; 130 } 131 } 132 return remove_count; 133 } 134 135 size_t 136 ModuleList::Remove (ModuleList &module_list) 137 { 138 Mutex::Locker locker(m_modules_mutex); 139 size_t num_removed = 0; 140 collection::iterator pos, end = module_list.m_modules.end(); 141 for (pos = module_list.m_modules.begin(); pos != end; ++pos) 142 { 143 if (Remove (*pos)) 144 ++num_removed; 145 } 146 return num_removed; 147 } 148 149 150 151 void 152 ModuleList::Clear() 153 { 154 Mutex::Locker locker(m_modules_mutex); 155 m_modules.clear(); 156 } 157 158 void 159 ModuleList::Destroy() 160 { 161 Mutex::Locker locker(m_modules_mutex); 162 collection empty; 163 m_modules.swap(empty); 164 } 165 166 Module* 167 ModuleList::GetModulePointerAtIndex (uint32_t idx) const 168 { 169 Mutex::Locker locker(m_modules_mutex); 170 if (idx < m_modules.size()) 171 return m_modules[idx].get(); 172 return NULL; 173 } 174 175 ModuleSP 176 ModuleList::GetModuleAtIndex(uint32_t idx) 177 { 178 Mutex::Locker locker(m_modules_mutex); 179 ModuleSP module_sp; 180 if (idx < m_modules.size()) 181 module_sp = m_modules[idx]; 182 return module_sp; 183 } 184 185 uint32_t 186 ModuleList::FindFunctions (const ConstString &name, 187 uint32_t name_type_mask, 188 bool include_symbols, 189 bool include_inlines, 190 bool append, 191 SymbolContextList &sc_list) 192 { 193 if (!append) 194 sc_list.Clear(); 195 196 Mutex::Locker locker(m_modules_mutex); 197 collection::const_iterator pos, end = m_modules.end(); 198 for (pos = m_modules.begin(); pos != end; ++pos) 199 { 200 (*pos)->FindFunctions (name, NULL, name_type_mask, include_symbols, include_inlines, true, sc_list); 201 } 202 203 return sc_list.GetSize(); 204 } 205 206 uint32_t 207 ModuleList::FindCompileUnits (const FileSpec &path, 208 bool append, 209 SymbolContextList &sc_list) 210 { 211 if (!append) 212 sc_list.Clear(); 213 214 Mutex::Locker locker(m_modules_mutex); 215 collection::const_iterator pos, end = m_modules.end(); 216 for (pos = m_modules.begin(); pos != end; ++pos) 217 { 218 (*pos)->FindCompileUnits (path, true, sc_list); 219 } 220 221 return sc_list.GetSize(); 222 } 223 224 uint32_t 225 ModuleList::FindGlobalVariables (const ConstString &name, 226 bool append, 227 uint32_t max_matches, 228 VariableList& variable_list) 229 { 230 size_t initial_size = variable_list.GetSize(); 231 Mutex::Locker locker(m_modules_mutex); 232 collection::iterator pos, end = m_modules.end(); 233 for (pos = m_modules.begin(); pos != end; ++pos) 234 { 235 (*pos)->FindGlobalVariables (name, NULL, append, max_matches, variable_list); 236 } 237 return variable_list.GetSize() - initial_size; 238 } 239 240 241 uint32_t 242 ModuleList::FindGlobalVariables (const RegularExpression& regex, 243 bool append, 244 uint32_t max_matches, 245 VariableList& variable_list) 246 { 247 size_t initial_size = variable_list.GetSize(); 248 Mutex::Locker locker(m_modules_mutex); 249 collection::iterator pos, end = m_modules.end(); 250 for (pos = m_modules.begin(); pos != end; ++pos) 251 { 252 (*pos)->FindGlobalVariables (regex, append, max_matches, variable_list); 253 } 254 return variable_list.GetSize() - initial_size; 255 } 256 257 258 size_t 259 ModuleList::FindSymbolsWithNameAndType (const ConstString &name, 260 SymbolType symbol_type, 261 SymbolContextList &sc_list, 262 bool append) 263 { 264 Mutex::Locker locker(m_modules_mutex); 265 if (!append) 266 sc_list.Clear(); 267 size_t initial_size = sc_list.GetSize(); 268 269 collection::iterator pos, end = m_modules.end(); 270 for (pos = m_modules.begin(); pos != end; ++pos) 271 (*pos)->FindSymbolsWithNameAndType (name, symbol_type, sc_list); 272 return sc_list.GetSize() - initial_size; 273 } 274 275 size_t 276 ModuleList::FindSymbolsMatchingRegExAndType (const RegularExpression ®ex, 277 lldb::SymbolType symbol_type, 278 SymbolContextList &sc_list, 279 bool append) 280 { 281 Mutex::Locker locker(m_modules_mutex); 282 if (!append) 283 sc_list.Clear(); 284 size_t initial_size = sc_list.GetSize(); 285 286 collection::iterator pos, end = m_modules.end(); 287 for (pos = m_modules.begin(); pos != end; ++pos) 288 (*pos)->FindSymbolsMatchingRegExAndType (regex, symbol_type, sc_list); 289 return sc_list.GetSize() - initial_size; 290 } 291 292 class ModuleMatches 293 { 294 public: 295 //-------------------------------------------------------------- 296 /// Construct with the user ID to look for. 297 //-------------------------------------------------------------- 298 ModuleMatches (const FileSpec *file_spec_ptr, 299 const ArchSpec *arch_ptr, 300 const lldb_private::UUID *uuid_ptr, 301 const ConstString *object_name, 302 bool file_spec_is_platform) : 303 m_file_spec_ptr (file_spec_ptr), 304 m_arch_ptr (arch_ptr), 305 m_uuid_ptr (uuid_ptr), 306 m_object_name (object_name), 307 m_file_spec_compare_basename_only (false), 308 m_file_spec_is_platform (file_spec_is_platform) 309 { 310 if (file_spec_ptr) 311 m_file_spec_compare_basename_only = file_spec_ptr->GetDirectory(); 312 } 313 314 315 //-------------------------------------------------------------- 316 /// Unary predicate function object callback. 317 //-------------------------------------------------------------- 318 bool 319 operator () (const ModuleSP& module_sp) const 320 { 321 if (m_file_spec_ptr) 322 { 323 if (m_file_spec_is_platform) 324 { 325 if (!FileSpec::Equal (*m_file_spec_ptr, 326 module_sp->GetPlatformFileSpec(), 327 m_file_spec_compare_basename_only)) 328 return false; 329 330 } 331 else 332 { 333 if (!FileSpec::Equal (*m_file_spec_ptr, 334 module_sp->GetFileSpec(), 335 m_file_spec_compare_basename_only)) 336 return false; 337 } 338 } 339 340 if (m_arch_ptr && m_arch_ptr->IsValid()) 341 { 342 if (module_sp->GetArchitecture() != *m_arch_ptr) 343 return false; 344 } 345 346 if (m_uuid_ptr && m_uuid_ptr->IsValid()) 347 { 348 if (module_sp->GetUUID() != *m_uuid_ptr) 349 return false; 350 } 351 352 if (m_object_name) 353 { 354 if (module_sp->GetObjectName() != *m_object_name) 355 return false; 356 } 357 return true; 358 } 359 360 private: 361 //-------------------------------------------------------------- 362 // Member variables. 363 //-------------------------------------------------------------- 364 const FileSpec * m_file_spec_ptr; 365 const ArchSpec * m_arch_ptr; 366 const lldb_private::UUID * m_uuid_ptr; 367 const ConstString * m_object_name; 368 bool m_file_spec_compare_basename_only; 369 bool m_file_spec_is_platform; 370 }; 371 372 size_t 373 ModuleList::FindModules 374 ( 375 const FileSpec *file_spec_ptr, 376 const ArchSpec *arch_ptr, 377 const lldb_private::UUID *uuid_ptr, 378 const ConstString *object_name, 379 ModuleList& matching_module_list 380 ) const 381 { 382 size_t existing_matches = matching_module_list.GetSize(); 383 ModuleMatches matcher (file_spec_ptr, arch_ptr, uuid_ptr, object_name, false); 384 385 Mutex::Locker locker(m_modules_mutex); 386 collection::const_iterator end = m_modules.end(); 387 collection::const_iterator pos; 388 389 for (pos = std::find_if (m_modules.begin(), end, matcher); 390 pos != end; 391 pos = std::find_if (++pos, end, matcher)) 392 { 393 ModuleSP module_sp(*pos); 394 matching_module_list.Append(module_sp); 395 } 396 return matching_module_list.GetSize() - existing_matches; 397 } 398 399 ModuleSP 400 ModuleList::FindModule (const Module *module_ptr) 401 { 402 ModuleSP module_sp; 403 404 // Scope for "locker" 405 { 406 Mutex::Locker locker(m_modules_mutex); 407 collection::const_iterator pos, end = m_modules.end(); 408 409 for (pos = m_modules.begin(); pos != end; ++pos) 410 { 411 if ((*pos).get() == module_ptr) 412 { 413 module_sp = (*pos); 414 break; 415 } 416 } 417 } 418 return module_sp; 419 420 } 421 422 ModuleSP 423 ModuleList::FindModule (const UUID &uuid) 424 { 425 ModuleSP module_sp; 426 427 if (uuid.IsValid()) 428 { 429 Mutex::Locker locker(m_modules_mutex); 430 collection::const_iterator pos, end = m_modules.end(); 431 432 for (pos = m_modules.begin(); pos != end; ++pos) 433 { 434 if ((*pos)->GetUUID() == uuid) 435 { 436 module_sp = (*pos); 437 break; 438 } 439 } 440 } 441 return module_sp; 442 } 443 444 445 uint32_t 446 ModuleList::FindTypes (const SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, TypeList& types) 447 { 448 Mutex::Locker locker(m_modules_mutex); 449 450 if (!append) 451 types.Clear(); 452 453 uint32_t total_matches = 0; 454 collection::const_iterator pos, end = m_modules.end(); 455 for (pos = m_modules.begin(); pos != end; ++pos) 456 { 457 if (sc.module_sp.get() == NULL || sc.module_sp.get() == (*pos).get()) 458 total_matches += (*pos)->FindTypes (sc, name, NULL, true, max_matches, types); 459 460 if (total_matches >= max_matches) 461 break; 462 } 463 return total_matches; 464 } 465 466 ModuleSP 467 ModuleList::FindFirstModuleForFileSpec (const FileSpec &file_spec, 468 const ArchSpec *arch_ptr, 469 const ConstString *object_name) 470 { 471 ModuleSP module_sp; 472 ModuleMatches matcher (&file_spec, 473 arch_ptr, 474 NULL, 475 object_name, 476 false); 477 478 // Scope for "locker" 479 { 480 Mutex::Locker locker(m_modules_mutex); 481 collection::const_iterator end = m_modules.end(); 482 collection::const_iterator pos = m_modules.begin(); 483 484 pos = std::find_if (pos, end, matcher); 485 if (pos != end) 486 module_sp = (*pos); 487 } 488 return module_sp; 489 490 } 491 492 ModuleSP 493 ModuleList::FindFirstModuleForPlatormFileSpec (const FileSpec &file_spec, 494 const ArchSpec *arch_ptr, 495 const ConstString *object_name) 496 { 497 ModuleSP module_sp; 498 ModuleMatches matcher (&file_spec, 499 arch_ptr, 500 NULL, 501 object_name, 502 true); 503 504 // Scope for "locker" 505 { 506 Mutex::Locker locker(m_modules_mutex); 507 collection::const_iterator end = m_modules.end(); 508 collection::const_iterator pos = m_modules.begin(); 509 510 pos = std::find_if (pos, end, matcher); 511 if (pos != end) 512 module_sp = (*pos); 513 } 514 return module_sp; 515 516 } 517 518 519 size_t 520 ModuleList::GetSize() const 521 { 522 size_t size = 0; 523 { 524 Mutex::Locker locker(m_modules_mutex); 525 size = m_modules.size(); 526 } 527 return size; 528 } 529 530 531 void 532 ModuleList::Dump(Stream *s) const 533 { 534 // s.Printf("%.*p: ", (int)sizeof(void*) * 2, this); 535 // s.Indent(); 536 // s << "ModuleList\n"; 537 538 Mutex::Locker locker(m_modules_mutex); 539 collection::const_iterator pos, end = m_modules.end(); 540 for (pos = m_modules.begin(); pos != end; ++pos) 541 { 542 (*pos)->Dump(s); 543 } 544 } 545 546 void 547 ModuleList::LogUUIDAndPaths (LogSP &log_sp, const char *prefix_cstr) 548 { 549 if (log_sp) 550 { 551 Mutex::Locker locker(m_modules_mutex); 552 char uuid_cstr[256]; 553 collection::const_iterator pos, begin = m_modules.begin(), end = m_modules.end(); 554 for (pos = begin; pos != end; ++pos) 555 { 556 Module *module = pos->get(); 557 module->GetUUID().GetAsCString (uuid_cstr, sizeof(uuid_cstr)); 558 const FileSpec &module_file_spec = module->GetFileSpec(); 559 log_sp->Printf ("%s[%u] %s (%s) \"%s/%s\"", 560 prefix_cstr ? prefix_cstr : "", 561 (uint32_t)std::distance (begin, pos), 562 uuid_cstr, 563 module->GetArchitecture().GetArchitectureName(), 564 module_file_spec.GetDirectory().GetCString(), 565 module_file_spec.GetFilename().GetCString()); 566 } 567 } 568 } 569 570 bool 571 ModuleList::ResolveFileAddress (lldb::addr_t vm_addr, Address& so_addr) 572 { 573 Mutex::Locker locker(m_modules_mutex); 574 collection::const_iterator pos, end = m_modules.end(); 575 for (pos = m_modules.begin(); pos != end; ++pos) 576 { 577 if ((*pos)->ResolveFileAddress (vm_addr, so_addr)) 578 return true; 579 } 580 581 return false; 582 } 583 584 uint32_t 585 ModuleList::ResolveSymbolContextForAddress (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc) 586 { 587 // The address is already section offset so it has a module 588 uint32_t resolved_flags = 0; 589 Module *module = so_addr.GetModulePtr(); 590 if (module) 591 { 592 resolved_flags = module->ResolveSymbolContextForAddress (so_addr, 593 resolve_scope, 594 sc); 595 } 596 else 597 { 598 Mutex::Locker locker(m_modules_mutex); 599 collection::const_iterator pos, end = m_modules.end(); 600 for (pos = m_modules.begin(); pos != end; ++pos) 601 { 602 resolved_flags = (*pos)->ResolveSymbolContextForAddress (so_addr, 603 resolve_scope, 604 sc); 605 if (resolved_flags != 0) 606 break; 607 } 608 } 609 610 return resolved_flags; 611 } 612 613 uint32_t 614 ModuleList::ResolveSymbolContextForFilePath 615 ( 616 const char *file_path, 617 uint32_t line, 618 bool check_inlines, 619 uint32_t resolve_scope, 620 SymbolContextList& sc_list 621 ) 622 { 623 FileSpec file_spec(file_path, false); 624 return ResolveSymbolContextsForFileSpec (file_spec, line, check_inlines, resolve_scope, sc_list); 625 } 626 627 uint32_t 628 ModuleList::ResolveSymbolContextsForFileSpec (const FileSpec &file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list) 629 { 630 Mutex::Locker locker(m_modules_mutex); 631 collection::const_iterator pos, end = m_modules.end(); 632 for (pos = m_modules.begin(); pos != end; ++pos) 633 { 634 (*pos)->ResolveSymbolContextsForFileSpec (file_spec, line, check_inlines, resolve_scope, sc_list); 635 } 636 637 return sc_list.GetSize(); 638 } 639 640 uint32_t 641 ModuleList::GetIndexForModule (const Module *module) const 642 { 643 if (module) 644 { 645 Mutex::Locker locker(m_modules_mutex); 646 collection::const_iterator pos; 647 collection::const_iterator begin = m_modules.begin(); 648 collection::const_iterator end = m_modules.end(); 649 for (pos = begin; pos != end; ++pos) 650 { 651 if ((*pos).get() == module) 652 return std::distance (begin, pos); 653 } 654 } 655 return LLDB_INVALID_INDEX32; 656 } 657 658 static ModuleList & 659 GetSharedModuleList () 660 { 661 static ModuleList g_shared_module_list; 662 return g_shared_module_list; 663 } 664 665 bool 666 ModuleList::ModuleIsInCache (const Module *module_ptr) 667 { 668 if (module_ptr) 669 { 670 ModuleList &shared_module_list = GetSharedModuleList (); 671 return shared_module_list.FindModule (module_ptr).get() != NULL; 672 } 673 return false; 674 } 675 676 size_t 677 ModuleList::FindSharedModules 678 ( 679 const FileSpec& in_file_spec, 680 const ArchSpec& arch, 681 const lldb_private::UUID *uuid_ptr, 682 const ConstString *object_name_ptr, 683 ModuleList &matching_module_list 684 ) 685 { 686 ModuleList &shared_module_list = GetSharedModuleList (); 687 return shared_module_list.FindModules (&in_file_spec, &arch, uuid_ptr, object_name_ptr, matching_module_list); 688 } 689 690 uint32_t 691 ModuleList::RemoveOrphanSharedModules () 692 { 693 return GetSharedModuleList ().RemoveOrphans(); 694 } 695 //#define ENABLE_MODULE_SP_LOGGING 696 #if defined (ENABLE_MODULE_SP_LOGGING) 697 #include "lldb/Core/StreamFile.h" 698 #include "lldb/Host/Host.h" 699 static void 700 ModuleSharedPtrLogger(void* p, const ModuleSP& sp, bool will_decrement) 701 { 702 if (sp.get()) 703 { 704 const char *module_basename = sp->GetFileSpec().GetFilename().GetCString(); 705 // If "p" is set, then it is the basename of a module to watch for. This 706 // basename MUST be uniqued first by getting it from a ConstString or this 707 // won't work. 708 if (p && p != module_basename) 709 { 710 return; 711 } 712 long use_count = sp.use_count(); 713 if (will_decrement) 714 --use_count; 715 716 printf("\nModuleSP(%p): %c %p {%lu} %s/%s\n", &sp, will_decrement ? '-' : '+', sp.get(), use_count, sp->GetFileSpec().GetDirectory().GetCString(), module_basename); 717 StreamFile stdout_strm(stdout, false); 718 Host::Backtrace (stdout_strm, 512); 719 } 720 } 721 #endif 722 723 Error 724 ModuleList::GetSharedModule 725 ( 726 const FileSpec& in_file_spec, 727 const ArchSpec& arch, 728 const lldb_private::UUID *uuid_ptr, 729 const ConstString *object_name_ptr, 730 off_t object_offset, 731 ModuleSP &module_sp, 732 const FileSpecList *module_search_paths_ptr, 733 ModuleSP *old_module_sp_ptr, 734 bool *did_create_ptr, 735 bool always_create 736 ) 737 { 738 ModuleList &shared_module_list = GetSharedModuleList (); 739 Mutex::Locker locker(shared_module_list.m_modules_mutex); 740 char path[PATH_MAX]; 741 char uuid_cstr[64]; 742 743 Error error; 744 745 module_sp.reset(); 746 747 if (did_create_ptr) 748 *did_create_ptr = false; 749 if (old_module_sp_ptr) 750 old_module_sp_ptr->reset(); 751 752 753 // First just try and get the file where it purports to be (path in 754 // in_file_spec), then check and uuid. 755 756 if (in_file_spec) 757 { 758 // Make sure no one else can try and get or create a module while this 759 // function is actively working on it by doing an extra lock on the 760 // global mutex list. 761 if (always_create == false) 762 { 763 ModuleList matching_module_list; 764 const size_t num_matching_modules = shared_module_list.FindModules (&in_file_spec, &arch, NULL, object_name_ptr, matching_module_list); 765 if (num_matching_modules > 0) 766 { 767 for (uint32_t module_idx = 0; module_idx < num_matching_modules; ++module_idx) 768 { 769 module_sp = matching_module_list.GetModuleAtIndex(module_idx); 770 if (uuid_ptr && uuid_ptr->IsValid()) 771 { 772 // We found the module we were looking for. 773 if (module_sp->GetUUID() == *uuid_ptr) 774 return error; 775 } 776 else 777 { 778 // If we didn't have a UUID in mind when looking for the object file, 779 // then we should make sure the modification time hasn't changed! 780 TimeValue file_spec_mod_time(in_file_spec.GetModificationTime()); 781 if (file_spec_mod_time.IsValid()) 782 { 783 if (file_spec_mod_time == module_sp->GetModificationTime()) 784 return error; 785 } 786 } 787 if (old_module_sp_ptr && !old_module_sp_ptr->get()) 788 *old_module_sp_ptr = module_sp; 789 shared_module_list.Remove (module_sp); 790 module_sp.reset(); 791 } 792 } 793 } 794 795 if (module_sp) 796 return error; 797 else 798 { 799 #if defined ENABLE_MODULE_SP_LOGGING 800 ModuleSP logging_module_sp (new Module (in_file_spec, arch, object_name_ptr, object_offset), ModuleSharedPtrLogger, (void *)ConstString("a.out").GetCString()); 801 module_sp = logging_module_sp; 802 #else 803 module_sp.reset (new Module (in_file_spec, arch, object_name_ptr, object_offset)); 804 #endif 805 // Make sure there are a module and an object file since we can specify 806 // a valid file path with an architecture that might not be in that file. 807 // By getting the object file we can guarantee that the architecture matches 808 if (module_sp) 809 { 810 if (module_sp->GetObjectFile()) 811 { 812 // If we get in here we got the correct arch, now we just need 813 // to verify the UUID if one was given 814 if (uuid_ptr && *uuid_ptr != module_sp->GetUUID()) 815 module_sp.reset(); 816 else 817 { 818 if (did_create_ptr) 819 *did_create_ptr = true; 820 821 shared_module_list.Append(module_sp); 822 return error; 823 } 824 } 825 else 826 module_sp.reset(); 827 } 828 } 829 } 830 831 // Either the file didn't exist where at the path, or no path was given, so 832 // we now have to use more extreme measures to try and find the appropriate 833 // module. 834 835 // Fixup the incoming path in case the path points to a valid file, yet 836 // the arch or UUID (if one was passed in) don't match. 837 FileSpec file_spec = Symbols::LocateExecutableObjectFile (in_file_spec ? &in_file_spec : NULL, 838 arch.IsValid() ? &arch : NULL, 839 uuid_ptr); 840 841 // Don't look for the file if it appears to be the same one we already 842 // checked for above... 843 if (file_spec != in_file_spec) 844 { 845 if (!file_spec.Exists()) 846 { 847 file_spec.GetPath(path, sizeof(path)); 848 if (path[0] == '\0') 849 in_file_spec.GetPath(path, sizeof(path)); 850 if (file_spec.Exists()) 851 { 852 if (uuid_ptr && uuid_ptr->IsValid()) 853 uuid_ptr->GetAsCString(uuid_cstr, sizeof (uuid_cstr)); 854 else 855 uuid_cstr[0] = '\0'; 856 857 858 if (arch.IsValid()) 859 { 860 if (uuid_cstr[0]) 861 error.SetErrorStringWithFormat("'%s' does not contain the %s architecture and UUID %s", path, arch.GetArchitectureName(), uuid_cstr); 862 else 863 error.SetErrorStringWithFormat("'%s' does not contain the %s architecture.", path, arch.GetArchitectureName()); 864 } 865 } 866 else 867 { 868 error.SetErrorStringWithFormat("'%s' does not exist", path); 869 } 870 if (error.Fail()) 871 module_sp.reset(); 872 return error; 873 } 874 875 876 // Make sure no one else can try and get or create a module while this 877 // function is actively working on it by doing an extra lock on the 878 // global mutex list. 879 ModuleList matching_module_list; 880 if (shared_module_list.FindModules (&file_spec, &arch, uuid_ptr, object_name_ptr, matching_module_list) > 0) 881 { 882 module_sp = matching_module_list.GetModuleAtIndex(0); 883 884 // If we didn't have a UUID in mind when looking for the object file, 885 // then we should make sure the modification time hasn't changed! 886 if (uuid_ptr == NULL) 887 { 888 TimeValue file_spec_mod_time(file_spec.GetModificationTime()); 889 if (file_spec_mod_time.IsValid()) 890 { 891 if (file_spec_mod_time != module_sp->GetModificationTime()) 892 { 893 if (old_module_sp_ptr) 894 *old_module_sp_ptr = module_sp; 895 shared_module_list.Remove (module_sp); 896 module_sp.reset(); 897 } 898 } 899 } 900 } 901 902 if (module_sp.get() == NULL) 903 { 904 #if defined ENABLE_MODULE_SP_LOGGING 905 ModuleSP logging_module_sp (new Module (file_spec, arch, object_name_ptr, object_offset), ModuleSharedPtrLogger, 0); 906 module_sp = logging_module_sp; 907 #else 908 module_sp.reset (new Module (file_spec, arch, object_name_ptr, object_offset)); 909 #endif 910 // Make sure there are a module and an object file since we can specify 911 // a valid file path with an architecture that might not be in that file. 912 // By getting the object file we can guarantee that the architecture matches 913 if (module_sp && module_sp->GetObjectFile()) 914 { 915 if (did_create_ptr) 916 *did_create_ptr = true; 917 918 shared_module_list.Append(module_sp); 919 } 920 else 921 { 922 file_spec.GetPath(path, sizeof(path)); 923 924 if (file_spec) 925 { 926 if (arch.IsValid()) 927 error.SetErrorStringWithFormat("unable to open %s architecture in '%s'", arch.GetArchitectureName(), path); 928 else 929 error.SetErrorStringWithFormat("unable to open '%s'", path); 930 } 931 else 932 { 933 if (uuid_ptr && uuid_ptr->IsValid()) 934 uuid_ptr->GetAsCString(uuid_cstr, sizeof (uuid_cstr)); 935 else 936 uuid_cstr[0] = '\0'; 937 938 if (uuid_cstr[0]) 939 error.SetErrorStringWithFormat("cannot locate a module for UUID '%s'", uuid_cstr); 940 else 941 error.SetErrorStringWithFormat("cannot locate a module"); 942 } 943 } 944 } 945 } 946 947 return error; 948 } 949 950 bool 951 ModuleList::RemoveSharedModule (lldb::ModuleSP &module_sp) 952 { 953 return GetSharedModuleList ().Remove (module_sp); 954 } 955 956 957