1 //===-- PlatformAppleSimulator.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 "PlatformAppleSimulator.h" 10 11 #if defined(__APPLE__) 12 #include <dlfcn.h> 13 #endif 14 15 #include "lldb/Core/Debugger.h" 16 #include "lldb/Core/Module.h" 17 #include "lldb/Core/PluginManager.h" 18 #include "lldb/Host/HostInfo.h" 19 #include "lldb/Host/PseudoTerminal.h" 20 #include "lldb/Target/Process.h" 21 #include "lldb/Utility/LLDBAssert.h" 22 #include "lldb/Utility/LLDBLog.h" 23 #include "lldb/Utility/Log.h" 24 #include "lldb/Utility/Status.h" 25 #include "lldb/Utility/StreamString.h" 26 27 #include "llvm/Support/Threading.h" 28 29 #include <mutex> 30 #include <thread> 31 32 using namespace lldb; 33 using namespace lldb_private; 34 35 #if !defined(__APPLE__) 36 #define UNSUPPORTED_ERROR ("Apple simulators aren't supported on this platform") 37 #endif 38 39 /// Default Constructor 40 PlatformAppleSimulator::PlatformAppleSimulator( 41 const char *class_name, const char *description, ConstString plugin_name, 42 llvm::Triple::OSType preferred_os, 43 llvm::SmallVector<llvm::StringRef, 4> supported_triples, 44 std::string sdk_name_primary, std::string sdk_name_secondary, 45 lldb_private::XcodeSDK::Type sdk_type, 46 CoreSimulatorSupport::DeviceType::ProductFamilyID kind) 47 : PlatformDarwin(true), m_class_name(class_name), 48 m_description(description), m_plugin_name(plugin_name), m_kind(kind), 49 m_os_type(preferred_os), m_supported_triples(supported_triples), 50 m_sdk_name_primary(std::move(sdk_name_primary)), 51 m_sdk_name_secondary(std::move(sdk_name_secondary)), 52 m_sdk_type(sdk_type) {} 53 54 /// Destructor. 55 /// 56 /// The destructor is virtual since this class is designed to be 57 /// inherited from by the plug-in instance. 58 PlatformAppleSimulator::~PlatformAppleSimulator() = default; 59 60 lldb_private::Status PlatformAppleSimulator::LaunchProcess( 61 lldb_private::ProcessLaunchInfo &launch_info) { 62 #if defined(__APPLE__) 63 LoadCoreSimulator(); 64 CoreSimulatorSupport::Device device(GetSimulatorDevice()); 65 66 if (device.GetState() != CoreSimulatorSupport::Device::State::Booted) { 67 Status boot_err; 68 device.Boot(boot_err); 69 if (boot_err.Fail()) 70 return boot_err; 71 } 72 73 auto spawned = device.Spawn(launch_info); 74 75 if (spawned) { 76 launch_info.SetProcessID(spawned.GetPID()); 77 return Status(); 78 } else 79 return spawned.GetError(); 80 #else 81 Status err; 82 err = Status::FromErrorString(UNSUPPORTED_ERROR); 83 return err; 84 #endif 85 } 86 87 void PlatformAppleSimulator::GetStatus(Stream &strm) { 88 Platform::GetStatus(strm); 89 llvm::StringRef sdk = GetSDKFilepath(); 90 if (!sdk.empty()) 91 strm << " SDK Path: \"" << sdk << "\"\n"; 92 else 93 strm << " SDK Path: error: unable to locate SDK\n"; 94 95 #if defined(__APPLE__) 96 // This will get called by subclasses, so just output status on the current 97 // simulator 98 PlatformAppleSimulator::LoadCoreSimulator(); 99 100 std::string developer_dir = HostInfo::GetXcodeDeveloperDirectory().GetPath(); 101 CoreSimulatorSupport::DeviceSet devices = 102 CoreSimulatorSupport::DeviceSet::GetAvailableDevices( 103 developer_dir.c_str()); 104 const size_t num_devices = devices.GetNumDevices(); 105 if (num_devices) { 106 strm.Printf("Available devices:\n"); 107 for (size_t i = 0; i < num_devices; ++i) { 108 CoreSimulatorSupport::Device device = devices.GetDeviceAtIndex(i); 109 strm << " " << device.GetUDID() << ": " << device.GetName() << "\n"; 110 } 111 112 if (m_device.has_value() && m_device->operator bool()) { 113 strm << "Current device: " << m_device->GetUDID() << ": " 114 << m_device->GetName(); 115 if (m_device->GetState() == CoreSimulatorSupport::Device::State::Booted) { 116 strm << " state = booted"; 117 } 118 strm << "\nType \"platform connect <ARG>\" where <ARG> is a device " 119 "UDID or a device name to disconnect and connect to a " 120 "different device.\n"; 121 122 } else { 123 strm << "No current device is selected, \"platform connect <ARG>\" " 124 "where <ARG> is a device UDID or a device name to connect to " 125 "a specific device.\n"; 126 } 127 128 } else { 129 strm << "No devices are available.\n"; 130 } 131 #else 132 strm << UNSUPPORTED_ERROR; 133 #endif 134 } 135 136 Status PlatformAppleSimulator::ConnectRemote(Args &args) { 137 #if defined(__APPLE__) 138 Status error; 139 if (args.GetArgumentCount() == 1) { 140 if (m_device) 141 DisconnectRemote(); 142 PlatformAppleSimulator::LoadCoreSimulator(); 143 const char *arg_cstr = args.GetArgumentAtIndex(0); 144 if (arg_cstr) { 145 std::string arg_str(arg_cstr); 146 std::string developer_dir = HostInfo::GetXcodeDeveloperDirectory().GetPath(); 147 CoreSimulatorSupport::DeviceSet devices = 148 CoreSimulatorSupport::DeviceSet::GetAvailableDevices( 149 developer_dir.c_str()); 150 devices.ForEach( 151 [this, &arg_str](const CoreSimulatorSupport::Device &device) -> bool { 152 if (arg_str == device.GetUDID() || arg_str == device.GetName()) { 153 m_device = device; 154 return false; // Stop iterating 155 } else { 156 return true; // Keep iterating 157 } 158 }); 159 if (!m_device) 160 error = Status::FromErrorStringWithFormat( 161 "no device with UDID or name '%s' was found", arg_cstr); 162 } 163 } else { 164 error = Status::FromErrorString( 165 "this command take a single UDID argument of the " 166 "device you want to connect to."); 167 } 168 return error; 169 #else 170 Status err; 171 err = Status::FromErrorString(UNSUPPORTED_ERROR); 172 return err; 173 #endif 174 } 175 176 Status PlatformAppleSimulator::DisconnectRemote() { 177 #if defined(__APPLE__) 178 m_device.reset(); 179 return Status(); 180 #else 181 Status err; 182 err = Status::FromErrorString(UNSUPPORTED_ERROR); 183 return err; 184 #endif 185 } 186 187 lldb::ProcessSP 188 PlatformAppleSimulator::DebugProcess(ProcessLaunchInfo &launch_info, 189 Debugger &debugger, Target &target, 190 Status &error) { 191 #if defined(__APPLE__) 192 ProcessSP process_sp; 193 // Make sure we stop at the entry point 194 launch_info.GetFlags().Set(eLaunchFlagDebug); 195 // We always launch the process we are going to debug in a separate process 196 // group, since then we can handle ^C interrupts ourselves w/o having to 197 // worry about the target getting them as well. 198 launch_info.SetLaunchInSeparateProcessGroup(true); 199 200 error = LaunchProcess(launch_info); 201 if (error.Success()) { 202 if (launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID) { 203 ProcessAttachInfo attach_info(launch_info); 204 process_sp = Attach(attach_info, debugger, &target, error); 205 if (process_sp) { 206 launch_info.SetHijackListener(attach_info.GetHijackListener()); 207 208 // Since we attached to the process, it will think it needs to detach 209 // if the process object just goes away without an explicit call to 210 // Process::Kill() or Process::Detach(), so let it know to kill the 211 // process if this happens. 212 process_sp->SetShouldDetach(false); 213 214 // If we didn't have any file actions, the pseudo terminal might have 215 // been used where the secondary side was given as the file to open for 216 // stdin/out/err after we have already opened the primary so we can 217 // read/write stdin/out/err. 218 int pty_fd = launch_info.GetPTY().ReleasePrimaryFileDescriptor(); 219 if (pty_fd != PseudoTerminal::invalid_fd) { 220 process_sp->SetSTDIOFileDescriptor(pty_fd); 221 } 222 } 223 } 224 } 225 226 return process_sp; 227 #else 228 return ProcessSP(); 229 #endif 230 } 231 232 FileSpec PlatformAppleSimulator::GetCoreSimulatorPath() { 233 #if defined(__APPLE__) 234 std::lock_guard<std::mutex> guard(m_core_sim_path_mutex); 235 if (!m_core_simulator_framework_path.has_value()) { 236 m_core_simulator_framework_path = 237 FileSpec("/Library/Developer/PrivateFrameworks/CoreSimulator.framework/" 238 "CoreSimulator"); 239 FileSystem::Instance().Resolve(*m_core_simulator_framework_path); 240 } 241 return m_core_simulator_framework_path.value(); 242 #else 243 return FileSpec(); 244 #endif 245 } 246 247 void PlatformAppleSimulator::LoadCoreSimulator() { 248 #if defined(__APPLE__) 249 static llvm::once_flag g_load_core_sim_flag; 250 llvm::call_once(g_load_core_sim_flag, [this] { 251 const std::string core_sim_path(GetCoreSimulatorPath().GetPath()); 252 if (core_sim_path.size()) 253 dlopen(core_sim_path.c_str(), RTLD_LAZY); 254 }); 255 #endif 256 } 257 258 #if defined(__APPLE__) 259 CoreSimulatorSupport::Device PlatformAppleSimulator::GetSimulatorDevice() { 260 if (!m_device.has_value()) { 261 const CoreSimulatorSupport::DeviceType::ProductFamilyID dev_id = m_kind; 262 std::string developer_dir = 263 HostInfo::GetXcodeDeveloperDirectory().GetPath(); 264 m_device = CoreSimulatorSupport::DeviceSet::GetAvailableDevices( 265 developer_dir.c_str()) 266 .GetFanciest(dev_id); 267 } 268 269 if (m_device.has_value()) 270 return m_device.value(); 271 else 272 return CoreSimulatorSupport::Device(); 273 } 274 #endif 275 276 std::vector<ArchSpec> PlatformAppleSimulator::GetSupportedArchitectures( 277 const ArchSpec &process_host_arch) { 278 std::vector<ArchSpec> result(m_supported_triples.size()); 279 llvm::transform(m_supported_triples, result.begin(), 280 [](llvm::StringRef triple) { return ArchSpec(triple); }); 281 return result; 282 } 283 284 static llvm::StringRef GetXcodeSDKDir(std::string preferred, 285 std::string secondary) { 286 llvm::StringRef sdk; 287 auto get_sdk = [&](std::string sdk) -> llvm::StringRef { 288 auto sdk_path_or_err = 289 HostInfo::GetSDKRoot(HostInfo::SDKOptions{XcodeSDK(std::move(sdk))}); 290 if (!sdk_path_or_err) { 291 Debugger::ReportError("Error while searching for Xcode SDK: " + 292 toString(sdk_path_or_err.takeError())); 293 return {}; 294 } 295 return *sdk_path_or_err; 296 }; 297 298 sdk = get_sdk(preferred); 299 if (sdk.empty()) 300 sdk = get_sdk(secondary); 301 return sdk; 302 } 303 304 llvm::StringRef PlatformAppleSimulator::GetSDKFilepath() { 305 if (!m_have_searched_for_sdk) { 306 m_sdk = GetXcodeSDKDir(m_sdk_name_primary, m_sdk_name_secondary); 307 m_have_searched_for_sdk = true; 308 } 309 return m_sdk; 310 } 311 312 PlatformSP PlatformAppleSimulator::CreateInstance( 313 const char *class_name, const char *description, ConstString plugin_name, 314 llvm::SmallVector<llvm::Triple::ArchType, 4> supported_arch, 315 llvm::Triple::OSType preferred_os, 316 llvm::SmallVector<llvm::Triple::OSType, 4> supported_os, 317 llvm::SmallVector<llvm::StringRef, 4> supported_triples, 318 std::string sdk_name_primary, std::string sdk_name_secondary, 319 lldb_private::XcodeSDK::Type sdk_type, 320 CoreSimulatorSupport::DeviceType::ProductFamilyID kind, bool force, 321 const ArchSpec *arch) { 322 Log *log = GetLog(LLDBLog::Platform); 323 if (log) { 324 const char *arch_name; 325 if (arch && arch->GetArchitectureName()) 326 arch_name = arch->GetArchitectureName(); 327 else 328 arch_name = "<null>"; 329 330 const char *triple_cstr = 331 arch ? arch->GetTriple().getTriple().c_str() : "<null>"; 332 333 LLDB_LOGF(log, "%s::%s(force=%s, arch={%s,%s})", class_name, __FUNCTION__, 334 force ? "true" : "false", arch_name, triple_cstr); 335 } 336 337 bool create = force; 338 if (!create && arch && arch->IsValid()) { 339 if (llvm::is_contained(supported_arch, arch->GetMachine())) { 340 const llvm::Triple &triple = arch->GetTriple(); 341 switch (triple.getVendor()) { 342 case llvm::Triple::Apple: 343 create = true; 344 break; 345 346 #if defined(__APPLE__) 347 // Only accept "unknown" for the vendor if the host is Apple and if 348 // "unknown" wasn't specified (it was just returned because it was NOT 349 // specified) 350 case llvm::Triple::UnknownVendor: 351 create = !arch->TripleVendorWasSpecified(); 352 break; 353 #endif 354 default: 355 break; 356 } 357 358 if (create) { 359 if (llvm::is_contained(supported_os, triple.getOS())) 360 create = true; 361 #if defined(__APPLE__) 362 // Only accept "unknown" for the OS if the host is Apple and it 363 // "unknown" wasn't specified (it was just returned because it was NOT 364 // specified) 365 else if (triple.getOS() == llvm::Triple::UnknownOS) 366 create = !arch->TripleOSWasSpecified(); 367 #endif 368 else 369 create = false; 370 } 371 } 372 } 373 if (create) { 374 LLDB_LOGF(log, "%s::%s() creating platform", class_name, __FUNCTION__); 375 376 return PlatformSP(new PlatformAppleSimulator( 377 class_name, description, plugin_name, preferred_os, supported_triples, 378 sdk_name_primary, sdk_name_secondary, sdk_type, kind)); 379 } 380 381 LLDB_LOGF(log, "%s::%s() aborting creation of platform", class_name, 382 __FUNCTION__); 383 384 return PlatformSP(); 385 } 386 387 Status PlatformAppleSimulator::GetSymbolFile(const FileSpec &platform_file, 388 const UUID *uuid_ptr, 389 FileSpec &local_file) { 390 Status error; 391 char platform_file_path[PATH_MAX]; 392 if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) { 393 char resolved_path[PATH_MAX]; 394 395 llvm::StringRef sdk = GetSDKFilepath(); 396 if (!sdk.empty()) { 397 ::snprintf(resolved_path, sizeof(resolved_path), "%s/%s", 398 sdk.str().c_str(), platform_file_path); 399 400 // First try in the SDK and see if the file is in there 401 local_file.SetFile(resolved_path, FileSpec::Style::native); 402 FileSystem::Instance().Resolve(local_file); 403 if (FileSystem::Instance().Exists(local_file)) 404 return error; 405 406 // Else fall back to the actual path itself 407 local_file.SetFile(platform_file_path, FileSpec::Style::native); 408 FileSystem::Instance().Resolve(local_file); 409 if (FileSystem::Instance().Exists(local_file)) 410 return error; 411 } 412 error = Status::FromErrorStringWithFormatv( 413 "unable to locate a platform file for '{0}' in platform '{1}'", 414 platform_file_path, GetPluginName()); 415 } else { 416 error = Status::FromErrorString("invalid platform file argument"); 417 } 418 return error; 419 } 420 421 Status PlatformAppleSimulator::GetSharedModule( 422 const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp, 423 const FileSpecList *module_search_paths_ptr, 424 llvm::SmallVectorImpl<lldb::ModuleSP> *old_modules, bool *did_create_ptr) { 425 // For iOS/tvOS/watchOS, the SDK files are all cached locally on the 426 // host system. So first we ask for the file in the cached SDK, then 427 // we attempt to get a shared module for the right architecture with 428 // the right UUID. 429 Status error; 430 ModuleSpec platform_module_spec(module_spec); 431 const FileSpec &platform_file = module_spec.GetFileSpec(); 432 error = GetSymbolFile(platform_file, module_spec.GetUUIDPtr(), 433 platform_module_spec.GetFileSpec()); 434 if (error.Success()) { 435 error = ResolveExecutable(platform_module_spec, module_sp, 436 module_search_paths_ptr); 437 } else { 438 const bool always_create = false; 439 error = ModuleList::GetSharedModule(module_spec, module_sp, 440 module_search_paths_ptr, old_modules, 441 did_create_ptr, always_create); 442 } 443 if (module_sp) 444 module_sp->SetPlatformFileSpec(platform_file); 445 446 return error; 447 } 448 449 uint32_t PlatformAppleSimulator::FindProcesses( 450 const ProcessInstanceInfoMatch &match_info, 451 ProcessInstanceInfoList &process_infos) { 452 ProcessInstanceInfoList all_osx_process_infos; 453 // First we get all OSX processes 454 const uint32_t n = Host::FindProcesses(match_info, all_osx_process_infos); 455 456 // Now we filter them down to only the matching triples. 457 for (uint32_t i = 0; i < n; ++i) { 458 const ProcessInstanceInfo &proc_info = all_osx_process_infos[i]; 459 const llvm::Triple &triple = proc_info.GetArchitecture().GetTriple(); 460 if (triple.getOS() == m_os_type && 461 triple.getEnvironment() == llvm::Triple::Simulator) { 462 process_infos.push_back(proc_info); 463 } 464 } 465 return process_infos.size(); 466 } 467 468 /// Whether to skip creating a simulator platform. 469 static bool shouldSkipSimulatorPlatform(bool force, const ArchSpec *arch) { 470 // If the arch is known not to specify a simulator environment, skip creating 471 // the simulator platform (we can create it later if there's a matching arch). 472 // This avoids very slow xcrun queries for non-simulator archs (the slowness 473 // is due to xcrun not caching negative queries. 474 return !force && arch && arch->IsValid() && 475 !arch->TripleEnvironmentWasSpecified(); 476 } 477 478 static const char *g_ios_plugin_name = "ios-simulator"; 479 static const char *g_ios_description = "iPhone simulator platform plug-in."; 480 481 /// IPhone Simulator Plugin. 482 struct PlatformiOSSimulator { 483 static void Initialize() { 484 PluginManager::RegisterPlugin(g_ios_plugin_name, g_ios_description, 485 PlatformiOSSimulator::CreateInstance); 486 } 487 488 static void Terminate() { 489 PluginManager::UnregisterPlugin(PlatformiOSSimulator::CreateInstance); 490 } 491 492 static PlatformSP CreateInstance(bool force, const ArchSpec *arch) { 493 if (shouldSkipSimulatorPlatform(force, arch)) 494 return nullptr; 495 496 return PlatformAppleSimulator::CreateInstance( 497 "PlatformiOSSimulator", g_ios_description, 498 ConstString(g_ios_plugin_name), 499 {llvm::Triple::aarch64, llvm::Triple::x86_64, llvm::Triple::x86}, 500 llvm::Triple::IOS, 501 {// Deprecated, but still support Darwin for historical reasons. 502 llvm::Triple::Darwin, llvm::Triple::MacOSX, 503 // IOS is not used for simulator triples, but accept it just in 504 // case. 505 llvm::Triple::IOS}, 506 { 507 #ifdef __APPLE__ 508 #if __arm64__ 509 "arm64e-apple-ios-simulator", "arm64-apple-ios-simulator", 510 "x86_64-apple-ios-simulator", "x86_64h-apple-ios-simulator", 511 #else 512 "x86_64h-apple-ios-simulator", "x86_64-apple-ios-simulator", 513 "i386-apple-ios-simulator", 514 #endif 515 #endif 516 }, 517 "iPhoneSimulator.Internal.sdk", "iPhoneSimulator.sdk", 518 XcodeSDK::Type::iPhoneSimulator, 519 CoreSimulatorSupport::DeviceType::ProductFamilyID::iPhone, force, arch); 520 } 521 }; 522 523 static const char *g_tvos_plugin_name = "tvos-simulator"; 524 static const char *g_tvos_description = "tvOS simulator platform plug-in."; 525 526 /// Apple TV Simulator Plugin. 527 struct PlatformAppleTVSimulator { 528 static void Initialize() { 529 PluginManager::RegisterPlugin(g_tvos_plugin_name, g_tvos_description, 530 PlatformAppleTVSimulator::CreateInstance); 531 } 532 533 static void Terminate() { 534 PluginManager::UnregisterPlugin(PlatformAppleTVSimulator::CreateInstance); 535 } 536 537 static PlatformSP CreateInstance(bool force, const ArchSpec *arch) { 538 if (shouldSkipSimulatorPlatform(force, arch)) 539 return nullptr; 540 return PlatformAppleSimulator::CreateInstance( 541 "PlatformAppleTVSimulator", g_tvos_description, 542 ConstString(g_tvos_plugin_name), 543 {llvm::Triple::aarch64, llvm::Triple::x86_64}, llvm::Triple::TvOS, 544 {llvm::Triple::TvOS}, 545 { 546 #ifdef __APPLE__ 547 #if __arm64__ 548 "arm64e-apple-tvos-simulator", "arm64-apple-tvos-simulator", 549 "x86_64h-apple-tvos-simulator", "x86_64-apple-tvos-simulator", 550 #else 551 "x86_64h-apple-tvos-simulator", "x86_64-apple-tvos-simulator", 552 #endif 553 #endif 554 }, 555 "AppleTVSimulator.Internal.sdk", "AppleTVSimulator.sdk", 556 XcodeSDK::Type::AppleTVSimulator, 557 CoreSimulatorSupport::DeviceType::ProductFamilyID::appleTV, force, 558 arch); 559 } 560 }; 561 562 563 static const char *g_watchos_plugin_name = "watchos-simulator"; 564 static const char *g_watchos_description = 565 "Apple Watch simulator platform plug-in."; 566 567 /// Apple Watch Simulator Plugin. 568 struct PlatformAppleWatchSimulator { 569 static void Initialize() { 570 PluginManager::RegisterPlugin(g_watchos_plugin_name, g_watchos_description, 571 PlatformAppleWatchSimulator::CreateInstance); 572 } 573 574 static void Terminate() { 575 PluginManager::UnregisterPlugin( 576 PlatformAppleWatchSimulator::CreateInstance); 577 } 578 579 static PlatformSP CreateInstance(bool force, const ArchSpec *arch) { 580 if (shouldSkipSimulatorPlatform(force, arch)) 581 return nullptr; 582 return PlatformAppleSimulator::CreateInstance( 583 "PlatformAppleWatchSimulator", g_watchos_description, 584 ConstString(g_watchos_plugin_name), 585 {llvm::Triple::aarch64, llvm::Triple::x86_64, llvm::Triple::x86}, 586 llvm::Triple::WatchOS, {llvm::Triple::WatchOS}, 587 { 588 #ifdef __APPLE__ 589 #if __arm64__ 590 "arm64e-apple-watchos-simulator", "arm64-apple-watchos-simulator", 591 #else 592 "x86_64-apple-watchos-simulator", "x86_64h-apple-watchos-simulator", 593 "i386-apple-watchos-simulator", 594 #endif 595 #endif 596 }, 597 "WatchSimulator.Internal.sdk", "WatchSimulator.sdk", 598 XcodeSDK::Type::WatchSimulator, 599 CoreSimulatorSupport::DeviceType::ProductFamilyID::appleWatch, force, 600 arch); 601 } 602 }; 603 604 static const char *g_xros_plugin_name = "xros-simulator"; 605 static const char *g_xros_description = "XROS simulator platform plug-in."; 606 607 /// XRSimulator Plugin. 608 struct PlatformXRSimulator { 609 static void Initialize() { 610 PluginManager::RegisterPlugin(g_xros_plugin_name, g_xros_description, 611 PlatformXRSimulator::CreateInstance); 612 } 613 614 static void Terminate() { 615 PluginManager::UnregisterPlugin(PlatformXRSimulator::CreateInstance); 616 } 617 618 static PlatformSP CreateInstance(bool force, const ArchSpec *arch) { 619 return PlatformAppleSimulator::CreateInstance( 620 "PlatformXRSimulator", g_xros_description, 621 ConstString(g_xros_plugin_name), 622 {llvm::Triple::aarch64, llvm::Triple::x86_64, llvm::Triple::x86}, 623 llvm::Triple::XROS, {llvm::Triple::XROS}, 624 { 625 #ifdef __APPLE__ 626 #if __arm64__ 627 "arm64e-apple-xros-simulator", "arm64-apple-xros-simulator", 628 #else 629 "x86_64-apple-xros-simulator", "x86_64h-apple-xros-simulator", 630 #endif 631 #endif 632 }, 633 "XRSimulator.Internal.sdk", "XRSimulator.sdk", 634 XcodeSDK::Type::XRSimulator, 635 CoreSimulatorSupport::DeviceType::ProductFamilyID::appleXR, force, 636 arch); 637 } 638 }; 639 640 static unsigned g_initialize_count = 0; 641 642 // Static Functions 643 void PlatformAppleSimulator::Initialize() { 644 if (g_initialize_count++ == 0) { 645 PlatformDarwin::Initialize(); 646 PlatformiOSSimulator::Initialize(); 647 PlatformAppleTVSimulator::Initialize(); 648 PlatformAppleWatchSimulator::Initialize(); 649 PlatformXRSimulator::Initialize(); 650 } 651 } 652 653 void PlatformAppleSimulator::Terminate() { 654 if (g_initialize_count > 0) 655 if (--g_initialize_count == 0) { 656 PlatformXRSimulator::Terminate(); 657 PlatformAppleWatchSimulator::Terminate(); 658 PlatformAppleTVSimulator::Terminate(); 659 PlatformiOSSimulator::Terminate(); 660 PlatformDarwin::Terminate(); 661 } 662 } 663 664