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/Interpreter/CommandInterpreter.h" 25 #include "lldb/Interpreter/OptionGroupPlatform.h" 26 #include "lldb/Symbol/ObjectFile.h" 27 #include "lldb/Target/Platform.h" 28 #include "lldb/Target/Process.h" 29 #include "lldb/Target/TargetList.h" 30 31 #include "llvm/ADT/SmallString.h" 32 33 using namespace lldb; 34 using namespace lldb_private; 35 36 ConstString & 37 TargetList::GetStaticBroadcasterClass () 38 { 39 static ConstString class_name ("lldb.targetList"); 40 return class_name; 41 } 42 43 //---------------------------------------------------------------------- 44 // TargetList constructor 45 //---------------------------------------------------------------------- 46 TargetList::TargetList(Debugger &debugger) : 47 Broadcaster(&debugger, TargetList::GetStaticBroadcasterClass().AsCString()), 48 m_target_list(), 49 m_target_list_mutex (Mutex::eMutexTypeRecursive), 50 m_selected_target_idx (0) 51 { 52 CheckInWithManager(); 53 } 54 55 //---------------------------------------------------------------------- 56 // Destructor 57 //---------------------------------------------------------------------- 58 TargetList::~TargetList() 59 { 60 Mutex::Locker locker(m_target_list_mutex); 61 m_target_list.clear(); 62 } 63 64 Error 65 TargetList::CreateTarget (Debugger &debugger, 66 const char *user_exe_path, 67 const char *triple_cstr, 68 bool get_dependent_files, 69 const OptionGroupPlatform *platform_options, 70 TargetSP &target_sp) 71 { 72 Error error; 73 PlatformSP platform_sp; 74 75 // This is purposely left empty unless it is specified by triple_cstr. 76 // If not initialized via triple_cstr, then the currently selected platform 77 // will set the architecture correctly. 78 const ArchSpec arch(triple_cstr); 79 if (triple_cstr && triple_cstr[0]) 80 { 81 if (!arch.IsValid()) 82 { 83 error.SetErrorStringWithFormat("invalid triple '%s'", triple_cstr); 84 return error; 85 } 86 } 87 88 ArchSpec platform_arch(arch); 89 90 bool prefer_platform_arch = false; 91 92 CommandInterpreter &interpreter = debugger.GetCommandInterpreter(); 93 if (platform_options && platform_options->PlatformWasSpecified ()) 94 { 95 const bool select_platform = true; 96 platform_sp = platform_options->CreatePlatformWithOptions (interpreter, 97 arch, 98 select_platform, 99 error, 100 platform_arch); 101 if (!platform_sp) 102 return error; 103 } 104 105 if (user_exe_path && user_exe_path[0]) 106 { 107 ModuleSpecList module_specs; 108 ModuleSpec module_spec; 109 module_spec.GetFileSpec().SetFile(user_exe_path, true); 110 111 // Resolve the executable in case we are given a path to a application bundle 112 // like a .app bundle on MacOSX 113 Host::ResolveExecutableInBundle (module_spec.GetFileSpec()); 114 115 lldb::offset_t file_offset = 0; 116 lldb::offset_t file_size = 0; 117 const size_t num_specs = ObjectFile::GetModuleSpecifications (module_spec.GetFileSpec(), file_offset, file_size, module_specs); 118 if (num_specs > 0) 119 { 120 ModuleSpec matching_module_spec; 121 122 if (num_specs == 1) 123 { 124 if (module_specs.GetModuleSpecAtIndex(0, matching_module_spec)) 125 { 126 if (platform_arch.IsValid()) 127 { 128 if (platform_arch.IsCompatibleMatch(matching_module_spec.GetArchitecture())) 129 { 130 // If the OS or vendor weren't specified, then adopt the module's 131 // architecture so that the platform matching can be more accurate 132 if (!platform_arch.TripleOSWasSpecified() || !platform_arch.TripleVendorWasSpecified()) 133 { 134 prefer_platform_arch = true; 135 platform_arch = matching_module_spec.GetArchitecture(); 136 } 137 } 138 else 139 { 140 error.SetErrorStringWithFormat("the specified architecture '%s' is not compatible with '%s' in '%s'", 141 platform_arch.GetTriple().str().c_str(), 142 matching_module_spec.GetArchitecture().GetTriple().str().c_str(), 143 module_spec.GetFileSpec().GetPath().c_str()); 144 return error; 145 } 146 } 147 else 148 { 149 // Only one arch and none was specified 150 prefer_platform_arch = true; 151 platform_arch = matching_module_spec.GetArchitecture(); 152 } 153 } 154 } 155 else 156 { 157 if (arch.IsValid()) 158 { 159 module_spec.GetArchitecture() = arch; 160 if (module_specs.FindMatchingModuleSpec(module_spec, matching_module_spec)) 161 { 162 prefer_platform_arch = true; 163 platform_arch = matching_module_spec.GetArchitecture(); 164 } 165 } 166 else 167 { 168 // No architecture specified, check if there is only one platform for 169 // all of the architectures. 170 171 typedef std::vector<PlatformSP> PlatformList; 172 PlatformList platforms; 173 PlatformSP host_platform_sp = Platform::GetHostPlatform(); 174 for (size_t i=0; i<num_specs; ++i) 175 { 176 ModuleSpec module_spec; 177 if (module_specs.GetModuleSpecAtIndex(i, module_spec)) 178 { 179 // See if there was a selected platform and check that first 180 // since the user may have specified it. 181 if (platform_sp) 182 { 183 if (platform_sp->IsCompatibleArchitecture(module_spec.GetArchitecture(), false, NULL)) 184 { 185 platforms.push_back(platform_sp); 186 continue; 187 } 188 } 189 190 // Next check the host platform it if wasn't already checked above 191 if (host_platform_sp && (!platform_sp || host_platform_sp->GetName() != platform_sp->GetName())) 192 { 193 if (host_platform_sp->IsCompatibleArchitecture(module_spec.GetArchitecture(), false, NULL)) 194 { 195 platforms.push_back(host_platform_sp); 196 continue; 197 } 198 } 199 200 // Just find a platform that matches the architecture in the executable file 201 platforms.push_back(Platform::GetPlatformForArchitecture(module_spec.GetArchitecture(), nullptr)); 202 } 203 } 204 205 Platform *platform_ptr = NULL; 206 for (const auto &the_platform_sp : platforms) 207 { 208 if (platform_ptr) 209 { 210 if (platform_ptr->GetName() != the_platform_sp->GetName()) 211 { 212 platform_ptr = NULL; 213 break; 214 } 215 } 216 else 217 { 218 platform_ptr = the_platform_sp.get(); 219 } 220 } 221 222 if (platform_ptr) 223 { 224 // All platforms for all modules in the exectuable match, so we can select this platform 225 platform_sp = platforms.front(); 226 } 227 else 228 { 229 // More than one platform claims to support this file, so the --platform option must be specified 230 StreamString error_strm; 231 std::set<Platform *> platform_set; 232 error_strm.Printf ("more than one platform supports this executable ("); 233 for (const auto &the_platform_sp : platforms) 234 { 235 if (platform_set.find(the_platform_sp.get()) == platform_set.end()) 236 { 237 if (!platform_set.empty()) 238 error_strm.PutCString(", "); 239 error_strm.PutCString(the_platform_sp->GetName().GetCString()); 240 platform_set.insert(the_platform_sp.get()); 241 } 242 } 243 error_strm.Printf("), use the --platform option to specify a platform"); 244 error.SetErrorString(error_strm.GetString().c_str()); 245 return error; 246 } 247 } 248 } 249 } 250 } 251 252 if (!platform_sp) 253 { 254 // Get the current platform and make sure it is compatible with the 255 // current architecture if we have a valid architecture. 256 platform_sp = debugger.GetPlatformList().GetSelectedPlatform (); 257 258 if (!prefer_platform_arch && arch.IsValid()) 259 { 260 if (!platform_sp->IsCompatibleArchitecture(arch, false, &platform_arch)) 261 { 262 platform_sp = Platform::GetPlatformForArchitecture(arch, &platform_arch); 263 if (platform_sp) 264 debugger.GetPlatformList().SetSelectedPlatform(platform_sp); 265 } 266 } 267 else if (platform_arch.IsValid()) 268 { 269 // if "arch" isn't valid, yet "platform_arch" is, it means we have an executable file with 270 // a single architecture which should be used 271 ArchSpec fixed_platform_arch; 272 if (!platform_sp->IsCompatibleArchitecture(platform_arch, false, &fixed_platform_arch)) 273 { 274 platform_sp = Platform::GetPlatformForArchitecture(platform_arch, &fixed_platform_arch); 275 if (platform_sp) 276 debugger.GetPlatformList().SetSelectedPlatform(platform_sp); 277 } 278 } 279 } 280 281 if (!platform_arch.IsValid()) 282 platform_arch = arch; 283 284 error = TargetList::CreateTarget (debugger, 285 user_exe_path, 286 platform_arch, 287 get_dependent_files, 288 platform_sp, 289 target_sp); 290 return error; 291 } 292 293 Error 294 TargetList::CreateTarget (Debugger &debugger, 295 const char *user_exe_path, 296 const ArchSpec& specified_arch, 297 bool get_dependent_files, 298 PlatformSP &platform_sp, 299 TargetSP &target_sp) 300 { 301 Timer scoped_timer (__PRETTY_FUNCTION__, 302 "TargetList::CreateTarget (file = '%s', arch = '%s')", 303 user_exe_path, 304 specified_arch.GetArchitectureName()); 305 Error error; 306 307 ArchSpec arch(specified_arch); 308 309 if (arch.IsValid()) 310 { 311 if (!platform_sp || !platform_sp->IsCompatibleArchitecture(arch, false, NULL)) 312 platform_sp = Platform::GetPlatformForArchitecture(specified_arch, &arch); 313 } 314 315 if (!platform_sp) 316 platform_sp = debugger.GetPlatformList().GetSelectedPlatform(); 317 318 if (!arch.IsValid()) 319 arch = specified_arch; 320 321 FileSpec file (user_exe_path, false); 322 if (!file.Exists() && user_exe_path && user_exe_path[0] == '~') 323 { 324 // we want to expand the tilde but we don't want to resolve any symbolic links 325 // so we can't use the FileSpec constructor's resolve flag 326 llvm::SmallString<64> unglobbed_path(user_exe_path); 327 FileSpec::ResolveUsername(unglobbed_path); 328 329 if (unglobbed_path.empty()) 330 file = FileSpec(user_exe_path, false); 331 else 332 file = FileSpec(unglobbed_path.c_str(), false); 333 } 334 335 bool user_exe_path_is_bundle = false; 336 char resolved_bundle_exe_path[PATH_MAX]; 337 resolved_bundle_exe_path[0] = '\0'; 338 if (file) 339 { 340 if (file.GetFileType() == FileSpec::eFileTypeDirectory) 341 user_exe_path_is_bundle = true; 342 343 if (file.IsRelativeToCurrentWorkingDirectory() && user_exe_path) 344 { 345 // Ignore paths that start with "./" and "../" 346 if (!((user_exe_path[0] == '.' && user_exe_path[1] == '/') || 347 (user_exe_path[0] == '.' && user_exe_path[1] == '.' && user_exe_path[2] == '/'))) 348 { 349 char cwd[PATH_MAX]; 350 if (getcwd (cwd, sizeof(cwd))) 351 { 352 std::string cwd_user_exe_path (cwd); 353 cwd_user_exe_path += '/'; 354 cwd_user_exe_path += user_exe_path; 355 FileSpec cwd_file (cwd_user_exe_path.c_str(), false); 356 if (cwd_file.Exists()) 357 file = cwd_file; 358 } 359 } 360 } 361 362 ModuleSP exe_module_sp; 363 if (platform_sp) 364 { 365 FileSpecList executable_search_paths (Target::GetDefaultExecutableSearchPaths()); 366 error = platform_sp->ResolveExecutable (file, 367 arch, 368 exe_module_sp, 369 executable_search_paths.GetSize() ? &executable_search_paths : NULL); 370 } 371 372 if (error.Success() && exe_module_sp) 373 { 374 if (exe_module_sp->GetObjectFile() == NULL) 375 { 376 if (arch.IsValid()) 377 { 378 error.SetErrorStringWithFormat("\"%s\" doesn't contain architecture %s", 379 file.GetPath().c_str(), 380 arch.GetArchitectureName()); 381 } 382 else 383 { 384 error.SetErrorStringWithFormat("unsupported file type \"%s\"", 385 file.GetPath().c_str()); 386 } 387 return error; 388 } 389 target_sp.reset(new Target(debugger, arch, platform_sp)); 390 target_sp->SetExecutableModule (exe_module_sp, get_dependent_files); 391 if (user_exe_path_is_bundle) 392 exe_module_sp->GetFileSpec().GetPath(resolved_bundle_exe_path, sizeof(resolved_bundle_exe_path)); 393 } 394 } 395 else 396 { 397 // No file was specified, just create an empty target with any arch 398 // if a valid arch was specified 399 target_sp.reset(new Target(debugger, arch, platform_sp)); 400 } 401 402 if (target_sp) 403 { 404 // Set argv0 with what the user typed, unless the user specified a 405 // directory. If the user specified a directory, then it is probably a 406 // bundle that was resolved and we need to use the resolved bundle path 407 if (user_exe_path) 408 { 409 // Use exactly what the user typed as the first argument when we exec or posix_spawn 410 if (user_exe_path_is_bundle && resolved_bundle_exe_path[0]) 411 { 412 target_sp->SetArg0 (resolved_bundle_exe_path); 413 } 414 else 415 { 416 // Use resolved path 417 target_sp->SetArg0 (file.GetPath().c_str()); 418 } 419 } 420 if (file.GetDirectory()) 421 { 422 FileSpec file_dir; 423 file_dir.GetDirectory() = file.GetDirectory(); 424 target_sp->GetExecutableSearchPaths ().Append (file_dir); 425 } 426 Mutex::Locker locker(m_target_list_mutex); 427 m_selected_target_idx = m_target_list.size(); 428 m_target_list.push_back(target_sp); 429 430 431 } 432 433 return error; 434 } 435 436 bool 437 TargetList::DeleteTarget (TargetSP &target_sp) 438 { 439 Mutex::Locker locker(m_target_list_mutex); 440 collection::iterator pos, end = m_target_list.end(); 441 442 for (pos = m_target_list.begin(); pos != end; ++pos) 443 { 444 if (pos->get() == target_sp.get()) 445 { 446 m_target_list.erase(pos); 447 return true; 448 } 449 } 450 return false; 451 } 452 453 454 TargetSP 455 TargetList::FindTargetWithExecutableAndArchitecture 456 ( 457 const FileSpec &exe_file_spec, 458 const ArchSpec *exe_arch_ptr 459 ) const 460 { 461 Mutex::Locker locker (m_target_list_mutex); 462 TargetSP target_sp; 463 bool full_match = (bool)exe_file_spec.GetDirectory(); 464 465 collection::const_iterator pos, end = m_target_list.end(); 466 for (pos = m_target_list.begin(); pos != end; ++pos) 467 { 468 Module *exe_module = (*pos)->GetExecutableModulePointer(); 469 470 if (exe_module) 471 { 472 if (FileSpec::Equal (exe_file_spec, exe_module->GetFileSpec(), full_match)) 473 { 474 if (exe_arch_ptr) 475 { 476 if (!exe_arch_ptr->IsCompatibleMatch(exe_module->GetArchitecture())) 477 continue; 478 } 479 target_sp = *pos; 480 break; 481 } 482 } 483 } 484 return target_sp; 485 } 486 487 TargetSP 488 TargetList::FindTargetWithProcessID (lldb::pid_t pid) const 489 { 490 Mutex::Locker locker(m_target_list_mutex); 491 TargetSP target_sp; 492 collection::const_iterator pos, end = m_target_list.end(); 493 for (pos = m_target_list.begin(); pos != end; ++pos) 494 { 495 Process* process = (*pos)->GetProcessSP().get(); 496 if (process && process->GetID() == pid) 497 { 498 target_sp = *pos; 499 break; 500 } 501 } 502 return target_sp; 503 } 504 505 506 TargetSP 507 TargetList::FindTargetWithProcess (Process *process) const 508 { 509 TargetSP target_sp; 510 if (process) 511 { 512 Mutex::Locker locker(m_target_list_mutex); 513 collection::const_iterator pos, end = m_target_list.end(); 514 for (pos = m_target_list.begin(); pos != end; ++pos) 515 { 516 if (process == (*pos)->GetProcessSP().get()) 517 { 518 target_sp = *pos; 519 break; 520 } 521 } 522 } 523 return target_sp; 524 } 525 526 TargetSP 527 TargetList::GetTargetSP (Target *target) const 528 { 529 TargetSP target_sp; 530 if (target) 531 { 532 Mutex::Locker locker(m_target_list_mutex); 533 collection::const_iterator pos, end = m_target_list.end(); 534 for (pos = m_target_list.begin(); pos != end; ++pos) 535 { 536 if (target == (*pos).get()) 537 { 538 target_sp = *pos; 539 break; 540 } 541 } 542 } 543 return target_sp; 544 } 545 546 uint32_t 547 TargetList::SendAsyncInterrupt (lldb::pid_t pid) 548 { 549 uint32_t num_async_interrupts_sent = 0; 550 551 if (pid != LLDB_INVALID_PROCESS_ID) 552 { 553 TargetSP target_sp(FindTargetWithProcessID (pid)); 554 if (target_sp.get()) 555 { 556 Process* process = target_sp->GetProcessSP().get(); 557 if (process) 558 { 559 process->SendAsyncInterrupt(); 560 ++num_async_interrupts_sent; 561 } 562 } 563 } 564 else 565 { 566 // We don't have a valid pid to broadcast to, so broadcast to the target 567 // list's async broadcaster... 568 BroadcastEvent (Process::eBroadcastBitInterrupt, NULL); 569 } 570 571 return num_async_interrupts_sent; 572 } 573 574 uint32_t 575 TargetList::SignalIfRunning (lldb::pid_t pid, int signo) 576 { 577 uint32_t num_signals_sent = 0; 578 Process *process = NULL; 579 if (pid == LLDB_INVALID_PROCESS_ID) 580 { 581 // Signal all processes with signal 582 Mutex::Locker locker(m_target_list_mutex); 583 collection::iterator pos, end = m_target_list.end(); 584 for (pos = m_target_list.begin(); pos != end; ++pos) 585 { 586 process = (*pos)->GetProcessSP().get(); 587 if (process) 588 { 589 if (process->IsAlive()) 590 { 591 ++num_signals_sent; 592 process->Signal (signo); 593 } 594 } 595 } 596 } 597 else 598 { 599 // Signal a specific process with signal 600 TargetSP target_sp(FindTargetWithProcessID (pid)); 601 if (target_sp.get()) 602 { 603 process = target_sp->GetProcessSP().get(); 604 if (process) 605 { 606 if (process->IsAlive()) 607 { 608 ++num_signals_sent; 609 process->Signal (signo); 610 } 611 } 612 } 613 } 614 return num_signals_sent; 615 } 616 617 int 618 TargetList::GetNumTargets () const 619 { 620 Mutex::Locker locker (m_target_list_mutex); 621 return m_target_list.size(); 622 } 623 624 lldb::TargetSP 625 TargetList::GetTargetAtIndex (uint32_t idx) const 626 { 627 TargetSP target_sp; 628 Mutex::Locker locker (m_target_list_mutex); 629 if (idx < m_target_list.size()) 630 target_sp = m_target_list[idx]; 631 return target_sp; 632 } 633 634 uint32_t 635 TargetList::GetIndexOfTarget (lldb::TargetSP target_sp) const 636 { 637 Mutex::Locker locker (m_target_list_mutex); 638 size_t num_targets = m_target_list.size(); 639 for (size_t idx = 0; idx < num_targets; idx++) 640 { 641 if (target_sp == m_target_list[idx]) 642 return idx; 643 } 644 return UINT32_MAX; 645 } 646 647 uint32_t 648 TargetList::SetSelectedTarget (Target* target) 649 { 650 Mutex::Locker locker (m_target_list_mutex); 651 collection::const_iterator pos, 652 begin = m_target_list.begin(), 653 end = m_target_list.end(); 654 for (pos = begin; pos != end; ++pos) 655 { 656 if (pos->get() == target) 657 { 658 m_selected_target_idx = std::distance (begin, pos); 659 return m_selected_target_idx; 660 } 661 } 662 m_selected_target_idx = 0; 663 return m_selected_target_idx; 664 } 665 666 lldb::TargetSP 667 TargetList::GetSelectedTarget () 668 { 669 Mutex::Locker locker (m_target_list_mutex); 670 if (m_selected_target_idx >= m_target_list.size()) 671 m_selected_target_idx = 0; 672 return GetTargetAtIndex (m_selected_target_idx); 673 } 674