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