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