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