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