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