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