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