1 //===-- TargetList.cpp ----------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "lldb/Target/TargetList.h" 10 #include "lldb/Core/Debugger.h" 11 #include "lldb/Core/Module.h" 12 #include "lldb/Core/ModuleSpec.h" 13 #include "lldb/Host/Host.h" 14 #include "lldb/Host/HostInfo.h" 15 #include "lldb/Interpreter/CommandInterpreter.h" 16 #include "lldb/Interpreter/OptionGroupPlatform.h" 17 #include "lldb/Symbol/ObjectFile.h" 18 #include "lldb/Target/Platform.h" 19 #include "lldb/Target/Process.h" 20 #include "lldb/Utility/Broadcaster.h" 21 #include "lldb/Utility/Event.h" 22 #include "lldb/Utility/State.h" 23 #include "lldb/Utility/TildeExpressionResolver.h" 24 #include "lldb/Utility/Timer.h" 25 26 #include "llvm/ADT/SmallString.h" 27 #include "llvm/Support/FileSystem.h" 28 29 using namespace lldb; 30 using namespace lldb_private; 31 32 ConstString &TargetList::GetStaticBroadcasterClass() { 33 static ConstString class_name("lldb.targetList"); 34 return class_name; 35 } 36 37 // TargetList constructor 38 TargetList::TargetList(Debugger &debugger) 39 : Broadcaster(debugger.GetBroadcasterManager(), 40 TargetList::GetStaticBroadcasterClass().AsCString()), 41 m_target_list(), m_target_list_mutex(), m_selected_target_idx(0) { 42 CheckInWithManager(); 43 } 44 45 // Destructor 46 TargetList::~TargetList() { 47 std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); 48 m_target_list.clear(); 49 } 50 51 Status TargetList::CreateTarget(Debugger &debugger, 52 llvm::StringRef user_exe_path, 53 llvm::StringRef triple_str, 54 LoadDependentFiles load_dependent_files, 55 const OptionGroupPlatform *platform_options, 56 TargetSP &target_sp) { 57 return CreateTargetInternal(debugger, user_exe_path, triple_str, 58 load_dependent_files, platform_options, target_sp, 59 false); 60 } 61 62 Status TargetList::CreateTarget(Debugger &debugger, 63 llvm::StringRef user_exe_path, 64 const ArchSpec &specified_arch, 65 LoadDependentFiles load_dependent_files, 66 PlatformSP &platform_sp, TargetSP &target_sp) { 67 return CreateTargetInternal(debugger, user_exe_path, specified_arch, 68 load_dependent_files, platform_sp, target_sp, 69 false); 70 } 71 72 Status TargetList::CreateTargetInternal( 73 Debugger &debugger, llvm::StringRef user_exe_path, 74 llvm::StringRef triple_str, LoadDependentFiles load_dependent_files, 75 const OptionGroupPlatform *platform_options, TargetSP &target_sp, 76 bool is_dummy_target) { 77 Status error; 78 79 // Let's start by looking at the selected platform. 80 PlatformSP platform_sp = debugger.GetPlatformList().GetSelectedPlatform(); 81 82 // This variable corresponds to the architecture specified by the triple 83 // string. If that string was empty the currently selected platform will 84 // determine the architecture. 85 const ArchSpec arch(triple_str); 86 if (!triple_str.empty() && !arch.IsValid()) { 87 error.SetErrorStringWithFormat("invalid triple '%s'", 88 triple_str.str().c_str()); 89 return error; 90 } 91 92 ArchSpec platform_arch(arch); 93 94 // Create a new platform if a platform was specified in the platform options 95 // and doesn't match the selected platform. 96 if (platform_options && platform_options->PlatformWasSpecified() && 97 !platform_options->PlatformMatches(platform_sp)) { 98 const bool select_platform = true; 99 platform_sp = platform_options->CreatePlatformWithOptions( 100 debugger.GetCommandInterpreter(), arch, select_platform, error, 101 platform_arch); 102 if (!platform_sp) 103 return error; 104 } 105 106 bool prefer_platform_arch = false; 107 108 if (!user_exe_path.empty()) { 109 ModuleSpec module_spec(FileSpec(user_exe_path, FileSpec::Style::native)); 110 FileSystem::Instance().Resolve(module_spec.GetFileSpec()); 111 // Resolve the executable in case we are given a path to a application 112 // bundle 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 ModuleSpecList module_specs; 118 const size_t num_specs = ObjectFile::GetModuleSpecifications( 119 module_spec.GetFileSpec(), file_offset, file_size, module_specs); 120 121 if (num_specs > 0) { 122 ModuleSpec matching_module_spec; 123 124 if (num_specs == 1) { 125 if (module_specs.GetModuleSpecAtIndex(0, matching_module_spec)) { 126 if (platform_arch.IsValid()) { 127 if (platform_arch.IsCompatibleMatch( 128 matching_module_spec.GetArchitecture())) { 129 // If the OS or vendor weren't specified, then adopt the module's 130 // architecture so that the platform matching can be more 131 // accurate. 132 if (!platform_arch.TripleOSWasSpecified() || 133 !platform_arch.TripleVendorWasSpecified()) { 134 prefer_platform_arch = true; 135 platform_arch = matching_module_spec.GetArchitecture(); 136 } 137 } else { 138 StreamString platform_arch_strm; 139 StreamString module_arch_strm; 140 141 platform_arch.DumpTriple(platform_arch_strm.AsRawOstream()); 142 matching_module_spec.GetArchitecture().DumpTriple( 143 module_arch_strm.AsRawOstream()); 144 error.SetErrorStringWithFormat( 145 "the specified architecture '%s' is not compatible with '%s' " 146 "in '%s'", 147 platform_arch_strm.GetData(), module_arch_strm.GetData(), 148 module_spec.GetFileSpec().GetPath().c_str()); 149 return error; 150 } 151 } else { 152 // Only one arch and none was specified. 153 prefer_platform_arch = true; 154 platform_arch = matching_module_spec.GetArchitecture(); 155 } 156 } 157 } else if (arch.IsValid()) { 158 // A (valid) architecture was specified. 159 module_spec.GetArchitecture() = arch; 160 if (module_specs.FindMatchingModuleSpec(module_spec, 161 matching_module_spec)) { 162 prefer_platform_arch = true; 163 platform_arch = matching_module_spec.GetArchitecture(); 164 } 165 } else { 166 // No architecture specified, check if there is only one platform for 167 // all of the architectures. 168 PlatformSP host_platform_sp = Platform::GetHostPlatform(); 169 std::vector<PlatformSP> platforms; 170 for (size_t i = 0; i < num_specs; ++i) { 171 ModuleSpec module_spec; 172 if (module_specs.GetModuleSpecAtIndex(i, module_spec)) { 173 // First consider the platform specified by the user, if any, and 174 // the selected platform otherwise. 175 if (platform_sp) { 176 if (platform_sp->IsCompatibleArchitecture( 177 module_spec.GetArchitecture(), false, nullptr)) { 178 platforms.push_back(platform_sp); 179 continue; 180 } 181 } 182 183 // Now consider the host platform if it is different from the 184 // specified/selected platform. 185 if (host_platform_sp && 186 (!platform_sp || 187 host_platform_sp->GetName() != platform_sp->GetName())) { 188 if (host_platform_sp->IsCompatibleArchitecture( 189 module_spec.GetArchitecture(), false, nullptr)) { 190 platforms.push_back(host_platform_sp); 191 continue; 192 } 193 } 194 195 // Finally find a platform that matches the architecture in the 196 // executable file. 197 PlatformSP fallback_platform_sp( 198 Platform::GetPlatformForArchitecture( 199 module_spec.GetArchitecture(), nullptr)); 200 if (fallback_platform_sp) { 201 platforms.push_back(fallback_platform_sp); 202 } 203 } 204 } 205 206 Platform *platform_ptr = nullptr; 207 bool more_than_one_platforms = false; 208 for (const auto &the_platform_sp : platforms) { 209 if (platform_ptr) { 210 if (platform_ptr->GetName() != the_platform_sp->GetName()) { 211 more_than_one_platforms = true; 212 platform_ptr = nullptr; 213 break; 214 } 215 } else { 216 platform_ptr = the_platform_sp.get(); 217 } 218 } 219 220 if (platform_ptr) { 221 // All platforms for all modules in the executable match, so we can 222 // select this platform. 223 platform_sp = platforms.front(); 224 } else if (!more_than_one_platforms) { 225 // No platforms claim to support this file. 226 error.SetErrorString("no matching platforms found for this file"); 227 return error; 228 } else { 229 // More than one platform claims to support this file. 230 StreamString error_strm; 231 std::set<Platform *> platform_set; 232 error_strm.Printf( 233 "more than one platform supports this executable ("); 234 for (const auto &the_platform_sp : platforms) { 235 if (platform_set.find(the_platform_sp.get()) == 236 platform_set.end()) { 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("), specify an architecture to disambiguate"); 244 error.SetErrorString(error_strm.GetString()); 245 return error; 246 } 247 } 248 } 249 } 250 251 // If we have a valid architecture, make sure the current platform is 252 // compatible with that architecture. 253 if (!prefer_platform_arch && arch.IsValid()) { 254 if (!platform_sp->IsCompatibleArchitecture(arch, false, &platform_arch)) { 255 platform_sp = Platform::GetPlatformForArchitecture(arch, &platform_arch); 256 if (!is_dummy_target && platform_sp) 257 debugger.GetPlatformList().SetSelectedPlatform(platform_sp); 258 } 259 } else if (platform_arch.IsValid()) { 260 // If "arch" isn't valid, yet "platform_arch" is, it means we have an 261 // executable file with a single architecture which should be used. 262 ArchSpec fixed_platform_arch; 263 if (!platform_sp->IsCompatibleArchitecture(platform_arch, false, 264 &fixed_platform_arch)) { 265 platform_sp = Platform::GetPlatformForArchitecture(platform_arch, 266 &fixed_platform_arch); 267 if (!is_dummy_target && platform_sp) 268 debugger.GetPlatformList().SetSelectedPlatform(platform_sp); 269 } 270 } 271 272 if (!platform_arch.IsValid()) 273 platform_arch = arch; 274 275 return TargetList::CreateTargetInternal( 276 debugger, user_exe_path, platform_arch, load_dependent_files, platform_sp, 277 target_sp, is_dummy_target); 278 } 279 280 lldb::TargetSP TargetList::GetDummyTarget(lldb_private::Debugger &debugger) { 281 // FIXME: Maybe the dummy target should be per-Debugger 282 if (!m_dummy_target_sp || !m_dummy_target_sp->IsValid()) { 283 ArchSpec arch(Target::GetDefaultArchitecture()); 284 if (!arch.IsValid()) 285 arch = HostInfo::GetArchitecture(); 286 Status err = CreateDummyTarget( 287 debugger, arch.GetTriple().getTriple().c_str(), m_dummy_target_sp); 288 } 289 290 return m_dummy_target_sp; 291 } 292 293 Status TargetList::CreateDummyTarget(Debugger &debugger, 294 llvm::StringRef specified_arch_name, 295 lldb::TargetSP &target_sp) { 296 PlatformSP host_platform_sp(Platform::GetHostPlatform()); 297 return CreateTargetInternal( 298 debugger, (const char *)nullptr, specified_arch_name, eLoadDependentsNo, 299 (const OptionGroupPlatform *)nullptr, target_sp, true); 300 } 301 302 Status TargetList::CreateTargetInternal(Debugger &debugger, 303 llvm::StringRef user_exe_path, 304 const ArchSpec &specified_arch, 305 LoadDependentFiles load_dependent_files, 306 lldb::PlatformSP &platform_sp, 307 lldb::TargetSP &target_sp, 308 bool is_dummy_target) { 309 static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); 310 Timer scoped_timer( 311 func_cat, "TargetList::CreateTarget (file = '%s', arch = '%s')", 312 user_exe_path.str().c_str(), specified_arch.GetArchitectureName()); 313 Status error; 314 315 ArchSpec arch(specified_arch); 316 317 if (arch.IsValid()) { 318 if (!platform_sp || 319 !platform_sp->IsCompatibleArchitecture(arch, false, nullptr)) 320 platform_sp = Platform::GetPlatformForArchitecture(specified_arch, &arch); 321 } 322 323 if (!platform_sp) 324 platform_sp = debugger.GetPlatformList().GetSelectedPlatform(); 325 326 if (!arch.IsValid()) 327 arch = specified_arch; 328 329 FileSpec file(user_exe_path); 330 if (!FileSystem::Instance().Exists(file) && user_exe_path.startswith("~")) { 331 // we want to expand the tilde but we don't want to resolve any symbolic 332 // links so we can't use the FileSpec constructor's resolve flag 333 llvm::SmallString<64> unglobbed_path; 334 StandardTildeExpressionResolver Resolver; 335 Resolver.ResolveFullPath(user_exe_path, unglobbed_path); 336 337 if (unglobbed_path.empty()) 338 file = FileSpec(user_exe_path); 339 else 340 file = FileSpec(unglobbed_path.c_str()); 341 } 342 343 bool user_exe_path_is_bundle = false; 344 char resolved_bundle_exe_path[PATH_MAX]; 345 resolved_bundle_exe_path[0] = '\0'; 346 if (file) { 347 if (FileSystem::Instance().IsDirectory(file)) 348 user_exe_path_is_bundle = true; 349 350 if (file.IsRelative() && !user_exe_path.empty()) { 351 llvm::SmallString<64> cwd; 352 if (! llvm::sys::fs::current_path(cwd)) { 353 FileSpec cwd_file(cwd.c_str()); 354 cwd_file.AppendPathComponent(file); 355 if (FileSystem::Instance().Exists(cwd_file)) 356 file = cwd_file; 357 } 358 } 359 360 ModuleSP exe_module_sp; 361 if (platform_sp) { 362 FileSpecList executable_search_paths( 363 Target::GetDefaultExecutableSearchPaths()); 364 ModuleSpec module_spec(file, arch); 365 error = platform_sp->ResolveExecutable(module_spec, exe_module_sp, 366 executable_search_paths.GetSize() 367 ? &executable_search_paths 368 : nullptr); 369 } 370 371 if (error.Success() && exe_module_sp) { 372 if (exe_module_sp->GetObjectFile() == nullptr) { 373 if (arch.IsValid()) { 374 error.SetErrorStringWithFormat( 375 "\"%s\" doesn't contain architecture %s", file.GetPath().c_str(), 376 arch.GetArchitectureName()); 377 } else { 378 error.SetErrorStringWithFormat("unsupported file type \"%s\"", 379 file.GetPath().c_str()); 380 } 381 return error; 382 } 383 target_sp.reset(new Target(debugger, arch, platform_sp, is_dummy_target)); 384 target_sp->SetExecutableModule(exe_module_sp, load_dependent_files); 385 if (user_exe_path_is_bundle) 386 exe_module_sp->GetFileSpec().GetPath(resolved_bundle_exe_path, 387 sizeof(resolved_bundle_exe_path)); 388 if (target_sp->GetPreloadSymbols()) 389 exe_module_sp->PreloadSymbols(); 390 } 391 } else { 392 // No file was specified, just create an empty target with any arch if a 393 // valid arch was specified 394 target_sp.reset(new Target(debugger, arch, platform_sp, is_dummy_target)); 395 } 396 397 if (!target_sp) 398 return error; 399 400 // Set argv0 with what the user typed, unless the user specified a 401 // directory. If the user specified a directory, then it is probably a 402 // bundle that was resolved and we need to use the resolved bundle path 403 if (!user_exe_path.empty()) { 404 // Use exactly what the user typed as the first argument when we exec or 405 // posix_spawn 406 if (user_exe_path_is_bundle && resolved_bundle_exe_path[0]) { 407 target_sp->SetArg0(resolved_bundle_exe_path); 408 } else { 409 // Use resolved path 410 target_sp->SetArg0(file.GetPath().c_str()); 411 } 412 } 413 if (file.GetDirectory()) { 414 FileSpec file_dir; 415 file_dir.GetDirectory() = file.GetDirectory(); 416 target_sp->AppendExecutableSearchPaths(file_dir); 417 } 418 419 // Don't put the dummy target in the target list, it's held separately. 420 if (!is_dummy_target) { 421 std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); 422 m_selected_target_idx = m_target_list.size(); 423 m_target_list.push_back(target_sp); 424 // Now prime this from the dummy target: 425 target_sp->PrimeFromDummyTarget(debugger.GetDummyTarget()); 426 } else { 427 m_dummy_target_sp = target_sp; 428 } 429 430 return error; 431 } 432 433 bool TargetList::DeleteTarget(TargetSP &target_sp) { 434 std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); 435 collection::iterator pos, end = m_target_list.end(); 436 437 for (pos = m_target_list.begin(); pos != end; ++pos) { 438 if (pos->get() == target_sp.get()) { 439 m_target_list.erase(pos); 440 return true; 441 } 442 } 443 return false; 444 } 445 446 TargetSP TargetList::FindTargetWithExecutableAndArchitecture( 447 const FileSpec &exe_file_spec, const ArchSpec *exe_arch_ptr) const { 448 std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); 449 TargetSP target_sp; 450 collection::const_iterator pos, end = m_target_list.end(); 451 for (pos = m_target_list.begin(); pos != end; ++pos) { 452 Module *exe_module = (*pos)->GetExecutableModulePointer(); 453 454 if (exe_module) { 455 if (FileSpec::Match(exe_file_spec, exe_module->GetFileSpec())) { 456 if (exe_arch_ptr) { 457 if (!exe_arch_ptr->IsCompatibleMatch(exe_module->GetArchitecture())) 458 continue; 459 } 460 target_sp = *pos; 461 break; 462 } 463 } 464 } 465 return target_sp; 466 } 467 468 TargetSP TargetList::FindTargetWithProcessID(lldb::pid_t pid) const { 469 std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); 470 TargetSP target_sp; 471 collection::const_iterator pos, end = m_target_list.end(); 472 for (pos = m_target_list.begin(); pos != end; ++pos) { 473 Process *process = (*pos)->GetProcessSP().get(); 474 if (process && process->GetID() == pid) { 475 target_sp = *pos; 476 break; 477 } 478 } 479 return target_sp; 480 } 481 482 TargetSP TargetList::FindTargetWithProcess(Process *process) const { 483 TargetSP target_sp; 484 if (process) { 485 std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); 486 collection::const_iterator pos, end = m_target_list.end(); 487 for (pos = m_target_list.begin(); pos != end; ++pos) { 488 if (process == (*pos)->GetProcessSP().get()) { 489 target_sp = *pos; 490 break; 491 } 492 } 493 } 494 return target_sp; 495 } 496 497 TargetSP TargetList::GetTargetSP(Target *target) const { 498 TargetSP target_sp; 499 if (target) { 500 std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); 501 collection::const_iterator pos, end = m_target_list.end(); 502 for (pos = m_target_list.begin(); pos != end; ++pos) { 503 if (target == (*pos).get()) { 504 target_sp = *pos; 505 break; 506 } 507 } 508 } 509 return target_sp; 510 } 511 512 uint32_t TargetList::SendAsyncInterrupt(lldb::pid_t pid) { 513 uint32_t num_async_interrupts_sent = 0; 514 515 if (pid != LLDB_INVALID_PROCESS_ID) { 516 TargetSP target_sp(FindTargetWithProcessID(pid)); 517 if (target_sp) { 518 Process *process = target_sp->GetProcessSP().get(); 519 if (process) { 520 process->SendAsyncInterrupt(); 521 ++num_async_interrupts_sent; 522 } 523 } 524 } else { 525 // We don't have a valid pid to broadcast to, so broadcast to the target 526 // list's async broadcaster... 527 BroadcastEvent(Process::eBroadcastBitInterrupt, nullptr); 528 } 529 530 return num_async_interrupts_sent; 531 } 532 533 uint32_t TargetList::SignalIfRunning(lldb::pid_t pid, int signo) { 534 uint32_t num_signals_sent = 0; 535 Process *process = nullptr; 536 if (pid == LLDB_INVALID_PROCESS_ID) { 537 // Signal all processes with signal 538 std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); 539 collection::iterator pos, end = m_target_list.end(); 540 for (pos = m_target_list.begin(); pos != end; ++pos) { 541 process = (*pos)->GetProcessSP().get(); 542 if (process) { 543 if (process->IsAlive()) { 544 ++num_signals_sent; 545 process->Signal(signo); 546 } 547 } 548 } 549 } else { 550 // Signal a specific process with signal 551 TargetSP target_sp(FindTargetWithProcessID(pid)); 552 if (target_sp) { 553 process = target_sp->GetProcessSP().get(); 554 if (process) { 555 if (process->IsAlive()) { 556 ++num_signals_sent; 557 process->Signal(signo); 558 } 559 } 560 } 561 } 562 return num_signals_sent; 563 } 564 565 int TargetList::GetNumTargets() const { 566 std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); 567 return m_target_list.size(); 568 } 569 570 lldb::TargetSP TargetList::GetTargetAtIndex(uint32_t idx) const { 571 TargetSP target_sp; 572 std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); 573 if (idx < m_target_list.size()) 574 target_sp = m_target_list[idx]; 575 return target_sp; 576 } 577 578 uint32_t TargetList::GetIndexOfTarget(lldb::TargetSP target_sp) const { 579 std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); 580 size_t num_targets = m_target_list.size(); 581 for (size_t idx = 0; idx < num_targets; idx++) { 582 if (target_sp == m_target_list[idx]) 583 return idx; 584 } 585 return UINT32_MAX; 586 } 587 588 uint32_t TargetList::SetSelectedTarget(Target *target) { 589 std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); 590 collection::const_iterator pos, begin = m_target_list.begin(), 591 end = m_target_list.end(); 592 for (pos = begin; pos != end; ++pos) { 593 if (pos->get() == target) { 594 m_selected_target_idx = std::distance(begin, pos); 595 return m_selected_target_idx; 596 } 597 } 598 m_selected_target_idx = 0; 599 return m_selected_target_idx; 600 } 601 602 lldb::TargetSP TargetList::GetSelectedTarget() { 603 std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); 604 if (m_selected_target_idx >= m_target_list.size()) 605 m_selected_target_idx = 0; 606 return GetTargetAtIndex(m_selected_target_idx); 607 } 608