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::GetDefaultPlatform(); 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 platform_sp = Platform::GetPlatformForArchitecture(arch, &platform_arch); 262 } 263 else if (platform_arch.IsValid()) 264 { 265 // if "arch" isn't valid, yet "platform_arch" is, it means we have an executable file with 266 // a single architecture which should be used 267 ArchSpec fixed_platform_arch; 268 if (!platform_sp->IsCompatibleArchitecture(platform_arch, false, &fixed_platform_arch)) 269 platform_sp = Platform::GetPlatformForArchitecture(platform_arch, &fixed_platform_arch); 270 } 271 } 272 273 if (!platform_arch.IsValid()) 274 platform_arch = arch; 275 276 error = TargetList::CreateTarget (debugger, 277 user_exe_path, 278 platform_arch, 279 get_dependent_files, 280 platform_sp, 281 target_sp); 282 return error; 283 } 284 285 Error 286 TargetList::CreateTarget (Debugger &debugger, 287 const char *user_exe_path, 288 const ArchSpec& specified_arch, 289 bool get_dependent_files, 290 PlatformSP &platform_sp, 291 TargetSP &target_sp) 292 { 293 Timer scoped_timer (__PRETTY_FUNCTION__, 294 "TargetList::CreateTarget (file = '%s', arch = '%s')", 295 user_exe_path, 296 specified_arch.GetArchitectureName()); 297 Error error; 298 299 ArchSpec arch(specified_arch); 300 301 if (arch.IsValid()) 302 { 303 if (!platform_sp || !platform_sp->IsCompatibleArchitecture(arch, false, NULL)) 304 platform_sp = Platform::GetPlatformForArchitecture(specified_arch, &arch); 305 } 306 307 if (!platform_sp) 308 platform_sp = debugger.GetPlatformList().GetSelectedPlatform(); 309 310 if (!arch.IsValid()) 311 arch = specified_arch; 312 313 FileSpec file (user_exe_path, false); 314 if (!file.Exists() && user_exe_path && user_exe_path[0] == '~') 315 { 316 // we want to expand the tilde but we don't want to resolve any symbolic links 317 // so we can't use the FileSpec constructor's resolve flag 318 llvm::SmallString<64> unglobbed_path(user_exe_path); 319 FileSpec::ResolveUsername(unglobbed_path); 320 321 if (unglobbed_path.empty()) 322 file = FileSpec(user_exe_path, false); 323 else 324 file = FileSpec(unglobbed_path.c_str(), false); 325 } 326 327 bool user_exe_path_is_bundle = false; 328 char resolved_bundle_exe_path[PATH_MAX]; 329 resolved_bundle_exe_path[0] = '\0'; 330 if (file) 331 { 332 if (file.GetFileType() == FileSpec::eFileTypeDirectory) 333 user_exe_path_is_bundle = true; 334 335 if (file.IsRelativeToCurrentWorkingDirectory()) 336 { 337 // Ignore paths that start with "./" and "../" 338 if (!((user_exe_path[0] == '.' && user_exe_path[1] == '/') || 339 (user_exe_path[0] == '.' && user_exe_path[1] == '.' && user_exe_path[2] == '/'))) 340 { 341 char cwd[PATH_MAX]; 342 if (getcwd (cwd, sizeof(cwd))) 343 { 344 std::string cwd_user_exe_path (cwd); 345 cwd_user_exe_path += '/'; 346 cwd_user_exe_path += user_exe_path; 347 FileSpec cwd_file (cwd_user_exe_path.c_str(), false); 348 if (cwd_file.Exists()) 349 file = cwd_file; 350 } 351 } 352 } 353 354 ModuleSP exe_module_sp; 355 if (platform_sp) 356 { 357 FileSpecList executable_search_paths (Target::GetDefaultExecutableSearchPaths()); 358 error = platform_sp->ResolveExecutable (file, 359 arch, 360 exe_module_sp, 361 executable_search_paths.GetSize() ? &executable_search_paths : NULL); 362 } 363 364 if (error.Success() && exe_module_sp) 365 { 366 if (exe_module_sp->GetObjectFile() == NULL) 367 { 368 if (arch.IsValid()) 369 { 370 error.SetErrorStringWithFormat("\"%s\" doesn't contain architecture %s", 371 file.GetPath().c_str(), 372 arch.GetArchitectureName()); 373 } 374 else 375 { 376 error.SetErrorStringWithFormat("unsupported file type \"%s\"", 377 file.GetPath().c_str()); 378 } 379 return error; 380 } 381 target_sp.reset(new Target(debugger, arch, platform_sp)); 382 target_sp->SetExecutableModule (exe_module_sp, get_dependent_files); 383 if (user_exe_path_is_bundle) 384 exe_module_sp->GetFileSpec().GetPath(resolved_bundle_exe_path, sizeof(resolved_bundle_exe_path)); 385 } 386 } 387 else 388 { 389 // No file was specified, just create an empty target with any arch 390 // if a valid arch was specified 391 target_sp.reset(new Target(debugger, arch, platform_sp)); 392 } 393 394 if (target_sp) 395 { 396 // Set argv0 with what the user typed, unless the user specified a 397 // directory. If the user specified a directory, then it is probably a 398 // bundle that was resolved and we need to use the resolved bundle path 399 if (user_exe_path) 400 { 401 // Use exactly what the user typed as the first argument when we exec or posix_spawn 402 if (user_exe_path_is_bundle && resolved_bundle_exe_path[0]) 403 { 404 target_sp->SetArg0 (resolved_bundle_exe_path); 405 } 406 else 407 { 408 // Use resolved path 409 target_sp->SetArg0 (file.GetPath().c_str()); 410 } 411 } 412 if (file.GetDirectory()) 413 { 414 FileSpec file_dir; 415 file_dir.GetDirectory() = file.GetDirectory(); 416 target_sp->GetExecutableSearchPaths ().Append (file_dir); 417 } 418 Mutex::Locker locker(m_target_list_mutex); 419 m_selected_target_idx = m_target_list.size(); 420 m_target_list.push_back(target_sp); 421 422 423 } 424 425 return error; 426 } 427 428 bool 429 TargetList::DeleteTarget (TargetSP &target_sp) 430 { 431 Mutex::Locker locker(m_target_list_mutex); 432 collection::iterator pos, end = m_target_list.end(); 433 434 for (pos = m_target_list.begin(); pos != end; ++pos) 435 { 436 if (pos->get() == target_sp.get()) 437 { 438 m_target_list.erase(pos); 439 return true; 440 } 441 } 442 return false; 443 } 444 445 446 TargetSP 447 TargetList::FindTargetWithExecutableAndArchitecture 448 ( 449 const FileSpec &exe_file_spec, 450 const ArchSpec *exe_arch_ptr 451 ) const 452 { 453 Mutex::Locker locker (m_target_list_mutex); 454 TargetSP target_sp; 455 bool full_match = (bool)exe_file_spec.GetDirectory(); 456 457 collection::const_iterator pos, end = m_target_list.end(); 458 for (pos = m_target_list.begin(); pos != end; ++pos) 459 { 460 Module *exe_module = (*pos)->GetExecutableModulePointer(); 461 462 if (exe_module) 463 { 464 if (FileSpec::Equal (exe_file_spec, exe_module->GetFileSpec(), full_match)) 465 { 466 if (exe_arch_ptr) 467 { 468 if (!exe_arch_ptr->IsCompatibleMatch(exe_module->GetArchitecture())) 469 continue; 470 } 471 target_sp = *pos; 472 break; 473 } 474 } 475 } 476 return target_sp; 477 } 478 479 TargetSP 480 TargetList::FindTargetWithProcessID (lldb::pid_t pid) const 481 { 482 Mutex::Locker locker(m_target_list_mutex); 483 TargetSP target_sp; 484 collection::const_iterator pos, end = m_target_list.end(); 485 for (pos = m_target_list.begin(); pos != end; ++pos) 486 { 487 Process* process = (*pos)->GetProcessSP().get(); 488 if (process && process->GetID() == pid) 489 { 490 target_sp = *pos; 491 break; 492 } 493 } 494 return target_sp; 495 } 496 497 498 TargetSP 499 TargetList::FindTargetWithProcess (Process *process) const 500 { 501 TargetSP target_sp; 502 if (process) 503 { 504 Mutex::Locker locker(m_target_list_mutex); 505 collection::const_iterator pos, end = m_target_list.end(); 506 for (pos = m_target_list.begin(); pos != end; ++pos) 507 { 508 if (process == (*pos)->GetProcessSP().get()) 509 { 510 target_sp = *pos; 511 break; 512 } 513 } 514 } 515 return target_sp; 516 } 517 518 TargetSP 519 TargetList::GetTargetSP (Target *target) const 520 { 521 TargetSP target_sp; 522 if (target) 523 { 524 Mutex::Locker locker(m_target_list_mutex); 525 collection::const_iterator pos, end = m_target_list.end(); 526 for (pos = m_target_list.begin(); pos != end; ++pos) 527 { 528 if (target == (*pos).get()) 529 { 530 target_sp = *pos; 531 break; 532 } 533 } 534 } 535 return target_sp; 536 } 537 538 uint32_t 539 TargetList::SendAsyncInterrupt (lldb::pid_t pid) 540 { 541 uint32_t num_async_interrupts_sent = 0; 542 543 if (pid != LLDB_INVALID_PROCESS_ID) 544 { 545 TargetSP target_sp(FindTargetWithProcessID (pid)); 546 if (target_sp.get()) 547 { 548 Process* process = target_sp->GetProcessSP().get(); 549 if (process) 550 { 551 process->SendAsyncInterrupt(); 552 ++num_async_interrupts_sent; 553 } 554 } 555 } 556 else 557 { 558 // We don't have a valid pid to broadcast to, so broadcast to the target 559 // list's async broadcaster... 560 BroadcastEvent (Process::eBroadcastBitInterrupt, NULL); 561 } 562 563 return num_async_interrupts_sent; 564 } 565 566 uint32_t 567 TargetList::SignalIfRunning (lldb::pid_t pid, int signo) 568 { 569 uint32_t num_signals_sent = 0; 570 Process *process = NULL; 571 if (pid == LLDB_INVALID_PROCESS_ID) 572 { 573 // Signal all processes with signal 574 Mutex::Locker locker(m_target_list_mutex); 575 collection::iterator pos, end = m_target_list.end(); 576 for (pos = m_target_list.begin(); pos != end; ++pos) 577 { 578 process = (*pos)->GetProcessSP().get(); 579 if (process) 580 { 581 if (process->IsAlive()) 582 { 583 ++num_signals_sent; 584 process->Signal (signo); 585 } 586 } 587 } 588 } 589 else 590 { 591 // Signal a specific process with signal 592 TargetSP target_sp(FindTargetWithProcessID (pid)); 593 if (target_sp.get()) 594 { 595 process = target_sp->GetProcessSP().get(); 596 if (process) 597 { 598 if (process->IsAlive()) 599 { 600 ++num_signals_sent; 601 process->Signal (signo); 602 } 603 } 604 } 605 } 606 return num_signals_sent; 607 } 608 609 int 610 TargetList::GetNumTargets () const 611 { 612 Mutex::Locker locker (m_target_list_mutex); 613 return m_target_list.size(); 614 } 615 616 lldb::TargetSP 617 TargetList::GetTargetAtIndex (uint32_t idx) const 618 { 619 TargetSP target_sp; 620 Mutex::Locker locker (m_target_list_mutex); 621 if (idx < m_target_list.size()) 622 target_sp = m_target_list[idx]; 623 return target_sp; 624 } 625 626 uint32_t 627 TargetList::GetIndexOfTarget (lldb::TargetSP target_sp) const 628 { 629 Mutex::Locker locker (m_target_list_mutex); 630 size_t num_targets = m_target_list.size(); 631 for (size_t idx = 0; idx < num_targets; idx++) 632 { 633 if (target_sp == m_target_list[idx]) 634 return idx; 635 } 636 return UINT32_MAX; 637 } 638 639 uint32_t 640 TargetList::SetSelectedTarget (Target* target) 641 { 642 Mutex::Locker locker (m_target_list_mutex); 643 collection::const_iterator pos, 644 begin = m_target_list.begin(), 645 end = m_target_list.end(); 646 for (pos = begin; pos != end; ++pos) 647 { 648 if (pos->get() == target) 649 { 650 m_selected_target_idx = std::distance (begin, pos); 651 return m_selected_target_idx; 652 } 653 } 654 m_selected_target_idx = 0; 655 return m_selected_target_idx; 656 } 657 658 lldb::TargetSP 659 TargetList::GetSelectedTarget () 660 { 661 Mutex::Locker locker (m_target_list_mutex); 662 if (m_selected_target_idx >= m_target_list.size()) 663 m_selected_target_idx = 0; 664 return GetTargetAtIndex (m_selected_target_idx); 665 } 666