1 //===-- TargetList.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 // C Includes 11 // C++ Includes 12 // Other libraries and framework includes 13 // Project includes 14 #include "lldb/Core/Broadcaster.h" 15 #include "lldb/Core/Debugger.h" 16 #include "lldb/Core/Event.h" 17 #include "lldb/Core/Module.h" 18 #include "lldb/Core/ModuleSpec.h" 19 #include "lldb/Core/State.h" 20 #include "lldb/Core/Timer.h" 21 #include "lldb/Host/Host.h" 22 #include "lldb/Host/HostInfo.h" 23 #include "lldb/Interpreter/CommandInterpreter.h" 24 #include "lldb/Interpreter/OptionGroupPlatform.h" 25 #include "lldb/Symbol/ObjectFile.h" 26 #include "lldb/Target/Platform.h" 27 #include "lldb/Target/Process.h" 28 #include "lldb/Target/TargetList.h" 29 30 #include "llvm/ADT/SmallString.h" 31 32 using namespace lldb; 33 using namespace lldb_private; 34 35 ConstString & 36 TargetList::GetStaticBroadcasterClass () 37 { 38 static ConstString class_name ("lldb.targetList"); 39 return class_name; 40 } 41 42 //---------------------------------------------------------------------- 43 // TargetList constructor 44 //---------------------------------------------------------------------- 45 TargetList::TargetList(Debugger &debugger) : 46 Broadcaster(&debugger, TargetList::GetStaticBroadcasterClass().AsCString()), 47 m_target_list(), 48 m_target_list_mutex (Mutex::eMutexTypeRecursive), 49 m_selected_target_idx (0) 50 { 51 CheckInWithManager(); 52 } 53 54 //---------------------------------------------------------------------- 55 // Destructor 56 //---------------------------------------------------------------------- 57 TargetList::~TargetList() 58 { 59 Mutex::Locker locker(m_target_list_mutex); 60 m_target_list.clear(); 61 } 62 63 Error 64 TargetList::CreateTarget (Debugger &debugger, 65 const char *user_exe_path, 66 const char *triple_cstr, 67 bool get_dependent_files, 68 const OptionGroupPlatform *platform_options, 69 TargetSP &target_sp) 70 { 71 return CreateTargetInternal (debugger, 72 user_exe_path, 73 triple_cstr, 74 get_dependent_files, 75 platform_options, 76 target_sp, 77 false); 78 } 79 80 Error 81 TargetList::CreateTarget (Debugger &debugger, 82 const char *user_exe_path, 83 const ArchSpec& specified_arch, 84 bool get_dependent_files, 85 PlatformSP &platform_sp, 86 TargetSP &target_sp) 87 { 88 return CreateTargetInternal (debugger, 89 user_exe_path, 90 specified_arch, 91 get_dependent_files, 92 platform_sp, 93 target_sp, 94 false); 95 } 96 97 Error 98 TargetList::CreateTargetInternal (Debugger &debugger, 99 const char *user_exe_path, 100 const char *triple_cstr, 101 bool get_dependent_files, 102 const OptionGroupPlatform *platform_options, 103 TargetSP &target_sp, 104 bool is_dummy_target) 105 { 106 Error error; 107 PlatformSP platform_sp; 108 109 // This is purposely left empty unless it is specified by triple_cstr. 110 // If not initialized via triple_cstr, then the currently selected platform 111 // will set the architecture correctly. 112 const ArchSpec arch(triple_cstr); 113 if (triple_cstr && triple_cstr[0]) 114 { 115 if (!arch.IsValid()) 116 { 117 error.SetErrorStringWithFormat("invalid triple '%s'", triple_cstr); 118 return error; 119 } 120 } 121 122 ArchSpec platform_arch(arch); 123 124 bool prefer_platform_arch = false; 125 126 CommandInterpreter &interpreter = debugger.GetCommandInterpreter(); 127 128 // let's see if there is already an existing plaform before we go creating another... 129 platform_sp = debugger.GetPlatformList().GetSelectedPlatform(); 130 131 if (platform_options && platform_options->PlatformWasSpecified ()) 132 { 133 // Create a new platform if it doesn't match the selected platform 134 if (!platform_options->PlatformMatches(platform_sp)) 135 { 136 const bool select_platform = true; 137 platform_sp = platform_options->CreatePlatformWithOptions (interpreter, 138 arch, 139 select_platform, 140 error, 141 platform_arch); 142 if (!platform_sp) 143 return error; 144 } 145 } 146 147 if (user_exe_path && user_exe_path[0]) 148 { 149 ModuleSpecList module_specs; 150 ModuleSpec module_spec; 151 module_spec.GetFileSpec().SetFile(user_exe_path, true); 152 153 // Resolve the executable in case we are given a path to a application bundle 154 // like a .app bundle on MacOSX 155 Host::ResolveExecutableInBundle (module_spec.GetFileSpec()); 156 157 lldb::offset_t file_offset = 0; 158 lldb::offset_t file_size = 0; 159 const size_t num_specs = ObjectFile::GetModuleSpecifications (module_spec.GetFileSpec(), file_offset, file_size, module_specs); 160 if (num_specs > 0) 161 { 162 ModuleSpec matching_module_spec; 163 164 if (num_specs == 1) 165 { 166 if (module_specs.GetModuleSpecAtIndex(0, matching_module_spec)) 167 { 168 if (platform_arch.IsValid()) 169 { 170 if (platform_arch.IsCompatibleMatch(matching_module_spec.GetArchitecture())) 171 { 172 // If the OS or vendor weren't specified, then adopt the module's 173 // architecture so that the platform matching can be more accurate 174 if (!platform_arch.TripleOSWasSpecified() || !platform_arch.TripleVendorWasSpecified()) 175 { 176 prefer_platform_arch = true; 177 platform_arch = matching_module_spec.GetArchitecture(); 178 } 179 } 180 else 181 { 182 StreamString platform_arch_strm; 183 StreamString module_arch_strm; 184 185 platform_arch.DumpTriple(platform_arch_strm); 186 matching_module_spec.GetArchitecture().DumpTriple(module_arch_strm); 187 error.SetErrorStringWithFormat("the specified architecture '%s' is not compatible with '%s' in '%s'", 188 platform_arch_strm.GetString().c_str(), 189 module_arch_strm.GetString().c_str(), 190 module_spec.GetFileSpec().GetPath().c_str()); 191 return error; 192 } 193 } 194 else 195 { 196 // Only one arch and none was specified 197 prefer_platform_arch = true; 198 platform_arch = matching_module_spec.GetArchitecture(); 199 } 200 } 201 } 202 else 203 { 204 if (arch.IsValid()) 205 { 206 module_spec.GetArchitecture() = arch; 207 if (module_specs.FindMatchingModuleSpec(module_spec, matching_module_spec)) 208 { 209 prefer_platform_arch = true; 210 platform_arch = matching_module_spec.GetArchitecture(); 211 } 212 } 213 else 214 { 215 // No architecture specified, check if there is only one platform for 216 // all of the architectures. 217 218 typedef std::vector<PlatformSP> PlatformList; 219 PlatformList platforms; 220 PlatformSP host_platform_sp = Platform::GetHostPlatform(); 221 for (size_t i=0; i<num_specs; ++i) 222 { 223 ModuleSpec module_spec; 224 if (module_specs.GetModuleSpecAtIndex(i, module_spec)) 225 { 226 // See if there was a selected platform and check that first 227 // since the user may have specified it. 228 if (platform_sp) 229 { 230 if (platform_sp->IsCompatibleArchitecture(module_spec.GetArchitecture(), false, NULL)) 231 { 232 platforms.push_back(platform_sp); 233 continue; 234 } 235 } 236 237 // Next check the host platform it if wasn't already checked above 238 if (host_platform_sp && (!platform_sp || host_platform_sp->GetName() != platform_sp->GetName())) 239 { 240 if (host_platform_sp->IsCompatibleArchitecture(module_spec.GetArchitecture(), false, NULL)) 241 { 242 platforms.push_back(host_platform_sp); 243 continue; 244 } 245 } 246 247 // Just find a platform that matches the architecture in the executable file 248 PlatformSP fallback_platform_sp (Platform::GetPlatformForArchitecture(module_spec.GetArchitecture(), nullptr)); 249 if (fallback_platform_sp) 250 { 251 platforms.push_back(fallback_platform_sp); 252 } 253 } 254 } 255 256 Platform *platform_ptr = NULL; 257 bool more_than_one_platforms = false; 258 for (const auto &the_platform_sp : platforms) 259 { 260 if (platform_ptr) 261 { 262 if (platform_ptr->GetName() != the_platform_sp->GetName()) 263 { 264 more_than_one_platforms = true; 265 platform_ptr = NULL; 266 break; 267 } 268 } 269 else 270 { 271 platform_ptr = the_platform_sp.get(); 272 } 273 } 274 275 if (platform_ptr) 276 { 277 // All platforms for all modules in the exectuable match, so we can select this platform 278 platform_sp = platforms.front(); 279 } 280 else if (more_than_one_platforms == false) 281 { 282 // No platforms claim to support this file 283 error.SetErrorString ("No matching platforms found for this file, specify one with the --platform option"); 284 return error; 285 } 286 else 287 { 288 // More than one platform claims to support this file, so the --platform option must be specified 289 StreamString error_strm; 290 std::set<Platform *> platform_set; 291 error_strm.Printf ("more than one platform supports this executable ("); 292 for (const auto &the_platform_sp : platforms) 293 { 294 if (platform_set.find(the_platform_sp.get()) == platform_set.end()) 295 { 296 if (!platform_set.empty()) 297 error_strm.PutCString(", "); 298 error_strm.PutCString(the_platform_sp->GetName().GetCString()); 299 platform_set.insert(the_platform_sp.get()); 300 } 301 } 302 error_strm.Printf("), use the --platform option to specify a platform"); 303 error.SetErrorString(error_strm.GetString().c_str()); 304 return error; 305 } 306 } 307 } 308 } 309 } 310 311 // If we have a valid architecture, make sure the current platform is 312 // compatible with that architecture 313 if (!prefer_platform_arch && arch.IsValid()) 314 { 315 if (!platform_sp->IsCompatibleArchitecture(arch, false, &platform_arch)) 316 { 317 platform_sp = Platform::GetPlatformForArchitecture(arch, &platform_arch); 318 if (!is_dummy_target && platform_sp) 319 debugger.GetPlatformList().SetSelectedPlatform(platform_sp); 320 } 321 } 322 else if (platform_arch.IsValid()) 323 { 324 // if "arch" isn't valid, yet "platform_arch" is, it means we have an executable file with 325 // a single architecture which should be used 326 ArchSpec fixed_platform_arch; 327 if (!platform_sp->IsCompatibleArchitecture(platform_arch, false, &fixed_platform_arch)) 328 { 329 platform_sp = Platform::GetPlatformForArchitecture(platform_arch, &fixed_platform_arch); 330 if (!is_dummy_target && platform_sp) 331 debugger.GetPlatformList().SetSelectedPlatform(platform_sp); 332 } 333 } 334 335 if (!platform_arch.IsValid()) 336 platform_arch = arch; 337 338 error = TargetList::CreateTargetInternal (debugger, 339 user_exe_path, 340 platform_arch, 341 get_dependent_files, 342 platform_sp, 343 target_sp, 344 is_dummy_target); 345 return error; 346 } 347 348 lldb::TargetSP 349 TargetList::GetDummyTarget (lldb_private::Debugger &debugger) 350 { 351 // FIXME: Maybe the dummy target should be per-Debugger 352 if (!m_dummy_target_sp || !m_dummy_target_sp->IsValid()) 353 { 354 ArchSpec arch(Target::GetDefaultArchitecture()); 355 if (!arch.IsValid()) 356 arch = HostInfo::GetArchitecture(); 357 Error err = CreateDummyTarget(debugger, 358 arch.GetTriple().getTriple().c_str(), 359 m_dummy_target_sp); 360 } 361 362 return m_dummy_target_sp; 363 } 364 365 Error 366 TargetList::CreateDummyTarget (Debugger &debugger, 367 const char *specified_arch_name, 368 lldb::TargetSP &target_sp) 369 { 370 PlatformSP host_platform_sp(Platform::GetHostPlatform()); 371 return CreateTargetInternal (debugger, 372 (const char *) nullptr, 373 specified_arch_name, 374 false, 375 (const OptionGroupPlatform *) nullptr, 376 target_sp, 377 true); 378 } 379 380 Error 381 TargetList::CreateTargetInternal (Debugger &debugger, 382 const char *user_exe_path, 383 const ArchSpec& specified_arch, 384 bool get_dependent_files, 385 lldb::PlatformSP &platform_sp, 386 lldb::TargetSP &target_sp, 387 bool is_dummy_target) 388 { 389 390 Timer scoped_timer (__PRETTY_FUNCTION__, 391 "TargetList::CreateTarget (file = '%s', arch = '%s')", 392 user_exe_path, 393 specified_arch.GetArchitectureName()); 394 Error error; 395 396 ArchSpec arch(specified_arch); 397 398 if (arch.IsValid()) 399 { 400 if (!platform_sp || !platform_sp->IsCompatibleArchitecture(arch, false, NULL)) 401 platform_sp = Platform::GetPlatformForArchitecture(specified_arch, &arch); 402 } 403 404 if (!platform_sp) 405 platform_sp = debugger.GetPlatformList().GetSelectedPlatform(); 406 407 if (!arch.IsValid()) 408 arch = specified_arch; 409 410 FileSpec file (user_exe_path, false); 411 if (!file.Exists() && user_exe_path && user_exe_path[0] == '~') 412 { 413 // we want to expand the tilde but we don't want to resolve any symbolic links 414 // so we can't use the FileSpec constructor's resolve flag 415 llvm::SmallString<64> unglobbed_path(user_exe_path); 416 FileSpec::ResolveUsername(unglobbed_path); 417 418 if (unglobbed_path.empty()) 419 file = FileSpec(user_exe_path, false); 420 else 421 file = FileSpec(unglobbed_path.c_str(), false); 422 } 423 424 bool user_exe_path_is_bundle = false; 425 char resolved_bundle_exe_path[PATH_MAX]; 426 resolved_bundle_exe_path[0] = '\0'; 427 if (file) 428 { 429 if (file.GetFileType() == FileSpec::eFileTypeDirectory) 430 user_exe_path_is_bundle = true; 431 432 if (file.IsRelative() && user_exe_path) 433 { 434 // Ignore paths that start with "./" and "../" 435 if (!((user_exe_path[0] == '.' && user_exe_path[1] == '/') || 436 (user_exe_path[0] == '.' && user_exe_path[1] == '.' && user_exe_path[2] == '/'))) 437 { 438 char cwd[PATH_MAX]; 439 if (getcwd (cwd, sizeof(cwd))) 440 { 441 std::string cwd_user_exe_path (cwd); 442 cwd_user_exe_path += '/'; 443 cwd_user_exe_path += user_exe_path; 444 FileSpec cwd_file (cwd_user_exe_path.c_str(), false); 445 if (cwd_file.Exists()) 446 file = cwd_file; 447 } 448 } 449 } 450 451 ModuleSP exe_module_sp; 452 if (platform_sp) 453 { 454 FileSpecList executable_search_paths (Target::GetDefaultExecutableSearchPaths()); 455 ModuleSpec module_spec(file, arch); 456 error = platform_sp->ResolveExecutable (module_spec, 457 exe_module_sp, 458 executable_search_paths.GetSize() ? &executable_search_paths : NULL); 459 } 460 461 if (error.Success() && exe_module_sp) 462 { 463 if (exe_module_sp->GetObjectFile() == NULL) 464 { 465 if (arch.IsValid()) 466 { 467 error.SetErrorStringWithFormat("\"%s\" doesn't contain architecture %s", 468 file.GetPath().c_str(), 469 arch.GetArchitectureName()); 470 } 471 else 472 { 473 error.SetErrorStringWithFormat("unsupported file type \"%s\"", 474 file.GetPath().c_str()); 475 } 476 return error; 477 } 478 target_sp.reset(new Target(debugger, arch, platform_sp, is_dummy_target)); 479 target_sp->SetExecutableModule (exe_module_sp, get_dependent_files); 480 if (user_exe_path_is_bundle) 481 exe_module_sp->GetFileSpec().GetPath(resolved_bundle_exe_path, sizeof(resolved_bundle_exe_path)); 482 } 483 } 484 else 485 { 486 // No file was specified, just create an empty target with any arch 487 // if a valid arch was specified 488 target_sp.reset(new Target(debugger, arch, platform_sp, is_dummy_target)); 489 } 490 491 if (target_sp) 492 { 493 // Set argv0 with what the user typed, unless the user specified a 494 // directory. If the user specified a directory, then it is probably a 495 // bundle that was resolved and we need to use the resolved bundle path 496 if (user_exe_path) 497 { 498 // Use exactly what the user typed as the first argument when we exec or posix_spawn 499 if (user_exe_path_is_bundle && resolved_bundle_exe_path[0]) 500 { 501 target_sp->SetArg0 (resolved_bundle_exe_path); 502 } 503 else 504 { 505 // Use resolved path 506 target_sp->SetArg0 (file.GetPath().c_str()); 507 } 508 } 509 if (file.GetDirectory()) 510 { 511 FileSpec file_dir; 512 file_dir.GetDirectory() = file.GetDirectory(); 513 target_sp->GetExecutableSearchPaths ().Append (file_dir); 514 } 515 516 // Don't put the dummy target in the target list, it's held separately. 517 if (!is_dummy_target) 518 { 519 Mutex::Locker locker(m_target_list_mutex); 520 m_selected_target_idx = m_target_list.size(); 521 m_target_list.push_back(target_sp); 522 // Now prime this from the dummy target: 523 target_sp->PrimeFromDummyTarget(debugger.GetDummyTarget()); 524 } 525 else 526 { 527 m_dummy_target_sp = target_sp; 528 } 529 } 530 531 return error; 532 } 533 534 bool 535 TargetList::DeleteTarget (TargetSP &target_sp) 536 { 537 Mutex::Locker locker(m_target_list_mutex); 538 collection::iterator pos, end = m_target_list.end(); 539 540 for (pos = m_target_list.begin(); pos != end; ++pos) 541 { 542 if (pos->get() == target_sp.get()) 543 { 544 m_target_list.erase(pos); 545 return true; 546 } 547 } 548 return false; 549 } 550 551 552 TargetSP 553 TargetList::FindTargetWithExecutableAndArchitecture 554 ( 555 const FileSpec &exe_file_spec, 556 const ArchSpec *exe_arch_ptr 557 ) const 558 { 559 Mutex::Locker locker (m_target_list_mutex); 560 TargetSP target_sp; 561 bool full_match = (bool)exe_file_spec.GetDirectory(); 562 563 collection::const_iterator pos, end = m_target_list.end(); 564 for (pos = m_target_list.begin(); pos != end; ++pos) 565 { 566 Module *exe_module = (*pos)->GetExecutableModulePointer(); 567 568 if (exe_module) 569 { 570 if (FileSpec::Equal (exe_file_spec, exe_module->GetFileSpec(), full_match)) 571 { 572 if (exe_arch_ptr) 573 { 574 if (!exe_arch_ptr->IsCompatibleMatch(exe_module->GetArchitecture())) 575 continue; 576 } 577 target_sp = *pos; 578 break; 579 } 580 } 581 } 582 return target_sp; 583 } 584 585 TargetSP 586 TargetList::FindTargetWithProcessID (lldb::pid_t pid) const 587 { 588 Mutex::Locker locker(m_target_list_mutex); 589 TargetSP target_sp; 590 collection::const_iterator pos, end = m_target_list.end(); 591 for (pos = m_target_list.begin(); pos != end; ++pos) 592 { 593 Process* process = (*pos)->GetProcessSP().get(); 594 if (process && process->GetID() == pid) 595 { 596 target_sp = *pos; 597 break; 598 } 599 } 600 return target_sp; 601 } 602 603 604 TargetSP 605 TargetList::FindTargetWithProcess (Process *process) const 606 { 607 TargetSP target_sp; 608 if (process) 609 { 610 Mutex::Locker locker(m_target_list_mutex); 611 collection::const_iterator pos, end = m_target_list.end(); 612 for (pos = m_target_list.begin(); pos != end; ++pos) 613 { 614 if (process == (*pos)->GetProcessSP().get()) 615 { 616 target_sp = *pos; 617 break; 618 } 619 } 620 } 621 return target_sp; 622 } 623 624 TargetSP 625 TargetList::GetTargetSP (Target *target) const 626 { 627 TargetSP target_sp; 628 if (target) 629 { 630 Mutex::Locker locker(m_target_list_mutex); 631 collection::const_iterator pos, end = m_target_list.end(); 632 for (pos = m_target_list.begin(); pos != end; ++pos) 633 { 634 if (target == (*pos).get()) 635 { 636 target_sp = *pos; 637 break; 638 } 639 } 640 } 641 return target_sp; 642 } 643 644 uint32_t 645 TargetList::SendAsyncInterrupt (lldb::pid_t pid) 646 { 647 uint32_t num_async_interrupts_sent = 0; 648 649 if (pid != LLDB_INVALID_PROCESS_ID) 650 { 651 TargetSP target_sp(FindTargetWithProcessID (pid)); 652 if (target_sp.get()) 653 { 654 Process* process = target_sp->GetProcessSP().get(); 655 if (process) 656 { 657 process->SendAsyncInterrupt(); 658 ++num_async_interrupts_sent; 659 } 660 } 661 } 662 else 663 { 664 // We don't have a valid pid to broadcast to, so broadcast to the target 665 // list's async broadcaster... 666 BroadcastEvent (Process::eBroadcastBitInterrupt, NULL); 667 } 668 669 return num_async_interrupts_sent; 670 } 671 672 uint32_t 673 TargetList::SignalIfRunning (lldb::pid_t pid, int signo) 674 { 675 uint32_t num_signals_sent = 0; 676 Process *process = NULL; 677 if (pid == LLDB_INVALID_PROCESS_ID) 678 { 679 // Signal all processes with signal 680 Mutex::Locker locker(m_target_list_mutex); 681 collection::iterator pos, end = m_target_list.end(); 682 for (pos = m_target_list.begin(); pos != end; ++pos) 683 { 684 process = (*pos)->GetProcessSP().get(); 685 if (process) 686 { 687 if (process->IsAlive()) 688 { 689 ++num_signals_sent; 690 process->Signal (signo); 691 } 692 } 693 } 694 } 695 else 696 { 697 // Signal a specific process with signal 698 TargetSP target_sp(FindTargetWithProcessID (pid)); 699 if (target_sp.get()) 700 { 701 process = target_sp->GetProcessSP().get(); 702 if (process) 703 { 704 if (process->IsAlive()) 705 { 706 ++num_signals_sent; 707 process->Signal (signo); 708 } 709 } 710 } 711 } 712 return num_signals_sent; 713 } 714 715 int 716 TargetList::GetNumTargets () const 717 { 718 Mutex::Locker locker (m_target_list_mutex); 719 return m_target_list.size(); 720 } 721 722 lldb::TargetSP 723 TargetList::GetTargetAtIndex (uint32_t idx) const 724 { 725 TargetSP target_sp; 726 Mutex::Locker locker (m_target_list_mutex); 727 if (idx < m_target_list.size()) 728 target_sp = m_target_list[idx]; 729 return target_sp; 730 } 731 732 uint32_t 733 TargetList::GetIndexOfTarget (lldb::TargetSP target_sp) const 734 { 735 Mutex::Locker locker (m_target_list_mutex); 736 size_t num_targets = m_target_list.size(); 737 for (size_t idx = 0; idx < num_targets; idx++) 738 { 739 if (target_sp == m_target_list[idx]) 740 return idx; 741 } 742 return UINT32_MAX; 743 } 744 745 uint32_t 746 TargetList::SetSelectedTarget (Target* target) 747 { 748 Mutex::Locker locker (m_target_list_mutex); 749 collection::const_iterator pos, 750 begin = m_target_list.begin(), 751 end = m_target_list.end(); 752 for (pos = begin; pos != end; ++pos) 753 { 754 if (pos->get() == target) 755 { 756 m_selected_target_idx = std::distance (begin, pos); 757 return m_selected_target_idx; 758 } 759 } 760 m_selected_target_idx = 0; 761 return m_selected_target_idx; 762 } 763 764 lldb::TargetSP 765 TargetList::GetSelectedTarget () 766 { 767 Mutex::Locker locker (m_target_list_mutex); 768 if (m_selected_target_idx >= m_target_list.size()) 769 m_selected_target_idx = 0; 770 return GetTargetAtIndex (m_selected_target_idx); 771 } 772