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