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