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
32using namespace lldb;
33using 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
40PlatformAppleSimulator::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.
58PlatformAppleSimulator::~PlatformAppleSimulator() = default;
59
60lldb_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.SetErrorString(UNSUPPORTED_ERROR);
83 return err;
84#endif
85}
86
87void 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
136Status 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.SetErrorStringWithFormat(
161 "no device with UDID or name '%s' was found", arg_cstr);
162 }
163 } else {
164 error.SetErrorString("this command take a single UDID argument of the "
165 "device you want to connect to.");
166 }
167 return error;
168#else
169 Status err;
170 err.SetErrorString(UNSUPPORTED_ERROR);
171 return err;
172#endif
173}
174
175Status PlatformAppleSimulator::DisconnectRemote() {
176#if defined(__APPLE__)
177 m_device.reset();
178 return Status();
179#else
180 Status err;
181 err.SetErrorString(UNSUPPORTED_ERROR);
182 return err;
183#endif
184}
185
186lldb::ProcessSP
187PlatformAppleSimulator::DebugProcess(ProcessLaunchInfo &launch_info,
188 Debugger &debugger, Target &target,
189 Status &error) {
190#if defined(__APPLE__)
191 ProcessSP process_sp;
192 // Make sure we stop at the entry point
193 launch_info.GetFlags().Set(eLaunchFlagDebug);
194 // We always launch the process we are going to debug in a separate process
195 // group, since then we can handle ^C interrupts ourselves w/o having to
196 // worry about the target getting them as well.
197 launch_info.SetLaunchInSeparateProcessGroup(true);
198
199 error = LaunchProcess(launch_info);
200 if (error.Success()) {
201 if (launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID) {
202 ProcessAttachInfo attach_info(launch_info);
203 process_sp = Attach(attach_info, debugger, &target, error);
204 if (process_sp) {
205 launch_info.SetHijackListener(attach_info.GetHijackListener());
206
207 // Since we attached to the process, it will think it needs to detach
208 // if the process object just goes away without an explicit call to
209 // Process::Kill() or Process::Detach(), so let it know to kill the
210 // process if this happens.
211 process_sp->SetShouldDetach(false);
212
213 // If we didn't have any file actions, the pseudo terminal might have
214 // been used where the secondary side was given as the file to open for
215 // stdin/out/err after we have already opened the primary so we can
216 // read/write stdin/out/err.
217 int pty_fd = launch_info.GetPTY().ReleasePrimaryFileDescriptor();
218 if (pty_fd != PseudoTerminal::invalid_fd) {
219 process_sp->SetSTDIOFileDescriptor(pty_fd);
220 }
221 }
222 }
223 }
224
225 return process_sp;
226#else
227 return ProcessSP();
228#endif
229}
230
231FileSpec PlatformAppleSimulator::GetCoreSimulatorPath() {
232#if defined(__APPLE__)
233 std::lock_guard<std::mutex> guard(m_core_sim_path_mutex);
234 if (!m_core_simulator_framework_path.has_value()) {
235 m_core_simulator_framework_path =
236 FileSpec("/Library/Developer/PrivateFrameworks/CoreSimulator.framework/"
237 "CoreSimulator");
238 FileSystem::Instance().Resolve(*m_core_simulator_framework_path);
239 }
240 return m_core_simulator_framework_path.value();
241#else
242 return FileSpec();
243#endif
244}
245
246void PlatformAppleSimulator::LoadCoreSimulator() {
247#if defined(__APPLE__)
248 static llvm::once_flag g_load_core_sim_flag;
249 llvm::call_once(g_load_core_sim_flag, [this] {
250 const std::string core_sim_path(GetCoreSimulatorPath().GetPath());
251 if (core_sim_path.size())
252 dlopen(core_sim_path.c_str(), RTLD_LAZY);
253 });
254#endif
255}
256
257#if defined(__APPLE__)
258CoreSimulatorSupport::Device PlatformAppleSimulator::GetSimulatorDevice() {
259 if (!m_device.has_value()) {
260 const CoreSimulatorSupport::DeviceType::ProductFamilyID dev_id = m_kind;
261 std::string developer_dir =
262 HostInfo::GetXcodeDeveloperDirectory().GetPath();
263 m_device = CoreSimulatorSupport::DeviceSet::GetAvailableDevices(
264 developer_dir.c_str())
265 .GetFanciest(dev_id);
266 }
267
268 if (m_device.has_value())
269 return m_device.value();
270 else
271 return CoreSimulatorSupport::Device();
272}
273#endif
274
275std::vector<ArchSpec> PlatformAppleSimulator::GetSupportedArchitectures(
276 const ArchSpec &process_host_arch) {
277 std::vector<ArchSpec> result(m_supported_triples.size());
278 llvm::transform(Range&: m_supported_triples, d_first: result.begin(),
279 F: [](llvm::StringRef triple) { return ArchSpec(triple); });
280 return result;
281}
282
283static llvm::StringRef GetXcodeSDKDir(std::string preferred,
284 std::string secondary) {
285 llvm::StringRef sdk;
286 auto get_sdk = [&](std::string sdk) -> llvm::StringRef {
287 auto sdk_path_or_err =
288 HostInfo::GetSDKRoot(options: HostInfo::SDKOptions{.XcodeSDKSelection: XcodeSDK(std::move(sdk))});
289 if (!sdk_path_or_err) {
290 Debugger::ReportError(message: "Error while searching for Xcode SDK: " +
291 toString(E: sdk_path_or_err.takeError()));
292 return {};
293 }
294 return *sdk_path_or_err;
295 };
296
297 sdk = get_sdk(preferred);
298 if (sdk.empty())
299 sdk = get_sdk(secondary);
300 return sdk;
301}
302
303llvm::StringRef PlatformAppleSimulator::GetSDKFilepath() {
304 if (!m_have_searched_for_sdk) {
305 m_sdk = GetXcodeSDKDir(preferred: m_sdk_name_primary, secondary: m_sdk_name_secondary);
306 m_have_searched_for_sdk = true;
307 }
308 return m_sdk;
309}
310
311PlatformSP PlatformAppleSimulator::CreateInstance(
312 const char *class_name, const char *description, ConstString plugin_name,
313 llvm::SmallVector<llvm::Triple::ArchType, 4> supported_arch,
314 llvm::Triple::OSType preferred_os,
315 llvm::SmallVector<llvm::Triple::OSType, 4> supported_os,
316 llvm::SmallVector<llvm::StringRef, 4> supported_triples,
317 std::string sdk_name_primary, std::string sdk_name_secondary,
318 lldb_private::XcodeSDK::Type sdk_type,
319 CoreSimulatorSupport::DeviceType::ProductFamilyID kind, bool force,
320 const ArchSpec *arch) {
321 Log *log = GetLog(mask: LLDBLog::Platform);
322 if (log) {
323 const char *arch_name;
324 if (arch && arch->GetArchitectureName())
325 arch_name = arch->GetArchitectureName();
326 else
327 arch_name = "<null>";
328
329 const char *triple_cstr =
330 arch ? arch->GetTriple().getTriple().c_str() : "<null>";
331
332 LLDB_LOGF(log, "%s::%s(force=%s, arch={%s,%s})", class_name, __FUNCTION__,
333 force ? "true" : "false", arch_name, triple_cstr);
334 }
335
336 bool create = force;
337 if (!create && arch && arch->IsValid()) {
338 if (llvm::is_contained(Range&: supported_arch, Element: arch->GetMachine())) {
339 const llvm::Triple &triple = arch->GetTriple();
340 switch (triple.getVendor()) {
341 case llvm::Triple::Apple:
342 create = true;
343 break;
344
345#if defined(__APPLE__)
346 // Only accept "unknown" for the vendor if the host is Apple and if
347 // "unknown" wasn't specified (it was just returned because it was NOT
348 // specified)
349 case llvm::Triple::UnknownVendor:
350 create = !arch->TripleVendorWasSpecified();
351 break;
352#endif
353 default:
354 break;
355 }
356
357 if (create) {
358 if (llvm::is_contained(Range&: supported_os, Element: triple.getOS()))
359 create = true;
360#if defined(__APPLE__)
361 // Only accept "unknown" for the OS if the host is Apple and it
362 // "unknown" wasn't specified (it was just returned because it was NOT
363 // specified)
364 else if (triple.getOS() == llvm::Triple::UnknownOS)
365 create = !arch->TripleOSWasSpecified();
366#endif
367 else
368 create = false;
369 }
370 }
371 }
372 if (create) {
373 LLDB_LOGF(log, "%s::%s() creating platform", class_name, __FUNCTION__);
374
375 return PlatformSP(new PlatformAppleSimulator(
376 class_name, description, plugin_name, preferred_os, supported_triples,
377 sdk_name_primary, sdk_name_secondary, sdk_type, kind));
378 }
379
380 LLDB_LOGF(log, "%s::%s() aborting creation of platform", class_name,
381 __FUNCTION__);
382
383 return PlatformSP();
384}
385
386Status PlatformAppleSimulator::ResolveExecutable(
387 const ModuleSpec &module_spec, lldb::ModuleSP &exe_module_sp,
388 const FileSpecList *module_search_paths_ptr) {
389 Status error;
390 // Nothing special to do here, just use the actual file and architecture
391
392 ModuleSpec resolved_module_spec(module_spec);
393
394 // If we have "ls" as the exe_file, resolve the executable loation based on
395 // the current path variables
396 // TODO: resolve bare executables in the Platform SDK
397 // if (!resolved_exe_file.Exists())
398 // resolved_exe_file.ResolveExecutableLocation ();
399
400 // Resolve any executable within a bundle on MacOSX
401 // TODO: verify that this handles shallow bundles, if not then implement one
402 // ourselves
403 Host::ResolveExecutableInBundle(file&: resolved_module_spec.GetFileSpec());
404
405 if (FileSystem::Instance().Exists(file_spec: resolved_module_spec.GetFileSpec())) {
406 if (resolved_module_spec.GetArchitecture().IsValid()) {
407 error = ModuleList::GetSharedModule(module_spec: resolved_module_spec, module_sp&: exe_module_sp,
408 NULL, NULL, NULL);
409
410 if (exe_module_sp && exe_module_sp->GetObjectFile())
411 return error;
412 exe_module_sp.reset();
413 }
414 // No valid architecture was specified or the exact ARM slice wasn't found
415 // so ask the platform for the architectures that we should be using (in
416 // the correct order) and see if we can find a match that way
417 StreamString arch_names;
418 llvm::ListSeparator LS;
419 ArchSpec platform_arch;
420 for (const ArchSpec &arch : GetSupportedArchitectures(process_host_arch: {})) {
421 resolved_module_spec.GetArchitecture() = arch;
422
423 // Only match x86 with x86 and x86_64 with x86_64...
424 if (!module_spec.GetArchitecture().IsValid() ||
425 module_spec.GetArchitecture().GetCore() ==
426 resolved_module_spec.GetArchitecture().GetCore()) {
427 error = ModuleList::GetSharedModule(module_spec: resolved_module_spec, module_sp&: exe_module_sp,
428 NULL, NULL, NULL);
429 // Did we find an executable using one of the
430 if (error.Success()) {
431 if (exe_module_sp && exe_module_sp->GetObjectFile())
432 break;
433 else
434 error.SetErrorToGenericError();
435 }
436
437 arch_names << LS << platform_arch.GetArchitectureName();
438 }
439 }
440
441 if (error.Fail() || !exe_module_sp) {
442 if (FileSystem::Instance().Readable(file_spec: resolved_module_spec.GetFileSpec())) {
443 error.SetErrorStringWithFormatv(
444 format: "'{0}' doesn't contain any '{1}' platform architectures: {2}",
445 args&: resolved_module_spec.GetFileSpec(), args: GetPluginName(),
446 args: arch_names.GetString());
447 } else {
448 error.SetErrorStringWithFormat(
449 "'%s' is not readable",
450 resolved_module_spec.GetFileSpec().GetPath().c_str());
451 }
452 }
453 } else {
454 error.SetErrorStringWithFormat("'%s' does not exist",
455 module_spec.GetFileSpec().GetPath().c_str());
456 }
457
458 return error;
459}
460
461Status PlatformAppleSimulator::GetSymbolFile(const FileSpec &platform_file,
462 const UUID *uuid_ptr,
463 FileSpec &local_file) {
464 Status error;
465 char platform_file_path[PATH_MAX];
466 if (platform_file.GetPath(path: platform_file_path, max_path_length: sizeof(platform_file_path))) {
467 char resolved_path[PATH_MAX];
468
469 llvm::StringRef sdk = GetSDKFilepath();
470 if (!sdk.empty()) {
471 ::snprintf(s: resolved_path, maxlen: sizeof(resolved_path), format: "%s/%s",
472 sdk.str().c_str(), platform_file_path);
473
474 // First try in the SDK and see if the file is in there
475 local_file.SetFile(path: resolved_path, style: FileSpec::Style::native);
476 FileSystem::Instance().Resolve(file_spec&: local_file);
477 if (FileSystem::Instance().Exists(file_spec: local_file))
478 return error;
479
480 // Else fall back to the actual path itself
481 local_file.SetFile(path: platform_file_path, style: FileSpec::Style::native);
482 FileSystem::Instance().Resolve(file_spec&: local_file);
483 if (FileSystem::Instance().Exists(file_spec: local_file))
484 return error;
485 }
486 error.SetErrorStringWithFormatv(
487 format: "unable to locate a platform file for '{0}' in platform '{1}'",
488 args&: platform_file_path, args: GetPluginName());
489 } else {
490 error.SetErrorString("invalid platform file argument");
491 }
492 return error;
493}
494
495Status PlatformAppleSimulator::GetSharedModule(
496 const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp,
497 const FileSpecList *module_search_paths_ptr,
498 llvm::SmallVectorImpl<lldb::ModuleSP> *old_modules, bool *did_create_ptr) {
499 // For iOS/tvOS/watchOS, the SDK files are all cached locally on the
500 // host system. So first we ask for the file in the cached SDK, then
501 // we attempt to get a shared module for the right architecture with
502 // the right UUID.
503 Status error;
504 ModuleSpec platform_module_spec(module_spec);
505 const FileSpec &platform_file = module_spec.GetFileSpec();
506 error = GetSymbolFile(platform_file, uuid_ptr: module_spec.GetUUIDPtr(),
507 local_file&: platform_module_spec.GetFileSpec());
508 if (error.Success()) {
509 error = ResolveExecutable(module_spec: platform_module_spec, exe_module_sp&: module_sp,
510 module_search_paths_ptr);
511 } else {
512 const bool always_create = false;
513 error = ModuleList::GetSharedModule(module_spec, module_sp,
514 module_search_paths_ptr, old_modules,
515 did_create_ptr, always_create);
516 }
517 if (module_sp)
518 module_sp->SetPlatformFileSpec(platform_file);
519
520 return error;
521}
522
523uint32_t PlatformAppleSimulator::FindProcesses(
524 const ProcessInstanceInfoMatch &match_info,
525 ProcessInstanceInfoList &process_infos) {
526 ProcessInstanceInfoList all_osx_process_infos;
527 // First we get all OSX processes
528 const uint32_t n = Host::FindProcesses(match_info, proc_infos&: all_osx_process_infos);
529
530 // Now we filter them down to only the matching triples.
531 for (uint32_t i = 0; i < n; ++i) {
532 const ProcessInstanceInfo &proc_info = all_osx_process_infos[i];
533 const llvm::Triple &triple = proc_info.GetArchitecture().GetTriple();
534 if (triple.getOS() == m_os_type &&
535 triple.getEnvironment() == llvm::Triple::Simulator) {
536 process_infos.push_back(x: proc_info);
537 }
538 }
539 return process_infos.size();
540}
541
542/// Whether to skip creating a simulator platform.
543static bool shouldSkipSimulatorPlatform(bool force, const ArchSpec *arch) {
544 // If the arch is known not to specify a simulator environment, skip creating
545 // the simulator platform (we can create it later if there's a matching arch).
546 // This avoids very slow xcrun queries for non-simulator archs (the slowness
547 // is due to xcrun not caching negative queries.
548 return !force && arch && arch->IsValid() &&
549 !arch->TripleEnvironmentWasSpecified();
550}
551
552static const char *g_ios_plugin_name = "ios-simulator";
553static const char *g_ios_description = "iPhone simulator platform plug-in.";
554
555/// IPhone Simulator Plugin.
556struct PlatformiOSSimulator {
557 static void Initialize() {
558 PluginManager::RegisterPlugin(name: g_ios_plugin_name, description: g_ios_description,
559 create_callback: PlatformiOSSimulator::CreateInstance);
560 }
561
562 static void Terminate() {
563 PluginManager::UnregisterPlugin(create_callback: PlatformiOSSimulator::CreateInstance);
564 }
565
566 static PlatformSP CreateInstance(bool force, const ArchSpec *arch) {
567 if (shouldSkipSimulatorPlatform(force, arch))
568 return nullptr;
569
570 return PlatformAppleSimulator::CreateInstance(
571 class_name: "PlatformiOSSimulator", description: g_ios_description,
572 plugin_name: ConstString(g_ios_plugin_name),
573 supported_arch: {llvm::Triple::aarch64, llvm::Triple::x86_64, llvm::Triple::x86},
574 preferred_os: llvm::Triple::IOS,
575 supported_os: {// Deprecated, but still support Darwin for historical reasons.
576 llvm::Triple::Darwin, llvm::Triple::MacOSX,
577 // IOS is not used for simulator triples, but accept it just in
578 // case.
579 llvm::Triple::IOS},
580 supported_triples: {
581#ifdef __APPLE__
582#if __arm64__
583 "arm64e-apple-ios-simulator", "arm64-apple-ios-simulator",
584 "x86_64-apple-ios-simulator", "x86_64h-apple-ios-simulator",
585#else
586 "x86_64h-apple-ios-simulator", "x86_64-apple-ios-simulator",
587 "i386-apple-ios-simulator",
588#endif
589#endif
590 },
591 sdk_name_primary: "iPhoneSimulator.Internal.sdk", sdk_name_secondary: "iPhoneSimulator.sdk",
592 sdk_type: XcodeSDK::Type::iPhoneSimulator,
593 kind: CoreSimulatorSupport::DeviceType::ProductFamilyID::iPhone, force, arch);
594 }
595};
596
597static const char *g_tvos_plugin_name = "tvos-simulator";
598static const char *g_tvos_description = "tvOS simulator platform plug-in.";
599
600/// Apple TV Simulator Plugin.
601struct PlatformAppleTVSimulator {
602 static void Initialize() {
603 PluginManager::RegisterPlugin(name: g_tvos_plugin_name, description: g_tvos_description,
604 create_callback: PlatformAppleTVSimulator::CreateInstance);
605 }
606
607 static void Terminate() {
608 PluginManager::UnregisterPlugin(create_callback: PlatformAppleTVSimulator::CreateInstance);
609 }
610
611 static PlatformSP CreateInstance(bool force, const ArchSpec *arch) {
612 if (shouldSkipSimulatorPlatform(force, arch))
613 return nullptr;
614 return PlatformAppleSimulator::CreateInstance(
615 class_name: "PlatformAppleTVSimulator", description: g_tvos_description,
616 plugin_name: ConstString(g_tvos_plugin_name),
617 supported_arch: {llvm::Triple::aarch64, llvm::Triple::x86_64}, preferred_os: llvm::Triple::TvOS,
618 supported_os: {llvm::Triple::TvOS},
619 supported_triples: {
620#ifdef __APPLE__
621#if __arm64__
622 "arm64e-apple-tvos-simulator", "arm64-apple-tvos-simulator",
623 "x86_64h-apple-tvos-simulator", "x86_64-apple-tvos-simulator",
624#else
625 "x86_64h-apple-tvos-simulator", "x86_64-apple-tvos-simulator",
626#endif
627#endif
628 },
629 sdk_name_primary: "AppleTVSimulator.Internal.sdk", sdk_name_secondary: "AppleTVSimulator.sdk",
630 sdk_type: XcodeSDK::Type::AppleTVSimulator,
631 kind: CoreSimulatorSupport::DeviceType::ProductFamilyID::appleTV, force,
632 arch);
633 }
634};
635
636
637static const char *g_watchos_plugin_name = "watchos-simulator";
638static const char *g_watchos_description =
639 "Apple Watch simulator platform plug-in.";
640
641/// Apple Watch Simulator Plugin.
642struct PlatformAppleWatchSimulator {
643 static void Initialize() {
644 PluginManager::RegisterPlugin(name: g_watchos_plugin_name, description: g_watchos_description,
645 create_callback: PlatformAppleWatchSimulator::CreateInstance);
646 }
647
648 static void Terminate() {
649 PluginManager::UnregisterPlugin(
650 create_callback: PlatformAppleWatchSimulator::CreateInstance);
651 }
652
653 static PlatformSP CreateInstance(bool force, const ArchSpec *arch) {
654 if (shouldSkipSimulatorPlatform(force, arch))
655 return nullptr;
656 return PlatformAppleSimulator::CreateInstance(
657 class_name: "PlatformAppleWatchSimulator", description: g_watchos_description,
658 plugin_name: ConstString(g_watchos_plugin_name),
659 supported_arch: {llvm::Triple::aarch64, llvm::Triple::x86_64, llvm::Triple::x86},
660 preferred_os: llvm::Triple::WatchOS, supported_os: {llvm::Triple::WatchOS},
661 supported_triples: {
662#ifdef __APPLE__
663#if __arm64__
664 "arm64e-apple-watchos-simulator", "arm64-apple-watchos-simulator",
665#else
666 "x86_64-apple-watchos-simulator", "x86_64h-apple-watchos-simulator",
667 "i386-apple-watchos-simulator",
668#endif
669#endif
670 },
671 sdk_name_primary: "WatchSimulator.Internal.sdk", sdk_name_secondary: "WatchSimulator.sdk",
672 sdk_type: XcodeSDK::Type::WatchSimulator,
673 kind: CoreSimulatorSupport::DeviceType::ProductFamilyID::appleWatch, force,
674 arch);
675 }
676};
677
678static const char *g_xros_plugin_name = "xros-simulator";
679static const char *g_xros_description = "XROS simulator platform plug-in.";
680
681/// XRSimulator Plugin.
682struct PlatformXRSimulator {
683 static void Initialize() {
684 PluginManager::RegisterPlugin(name: g_xros_plugin_name, description: g_xros_description,
685 create_callback: PlatformXRSimulator::CreateInstance);
686 }
687
688 static void Terminate() {
689 PluginManager::UnregisterPlugin(create_callback: PlatformXRSimulator::CreateInstance);
690 }
691
692 static PlatformSP CreateInstance(bool force, const ArchSpec *arch) {
693 return PlatformAppleSimulator::CreateInstance(
694 class_name: "PlatformXRSimulator", description: g_xros_description,
695 plugin_name: ConstString(g_xros_plugin_name),
696 supported_arch: {llvm::Triple::aarch64, llvm::Triple::x86_64, llvm::Triple::x86},
697 preferred_os: llvm::Triple::XROS, supported_os: {llvm::Triple::XROS},
698 supported_triples: {
699#ifdef __APPLE__
700#if __arm64__
701 "arm64e-apple-xros-simulator", "arm64-apple-xros-simulator",
702#else
703 "x86_64-apple-xros-simulator", "x86_64h-apple-xros-simulator",
704#endif
705#endif
706 },
707 sdk_name_primary: "XRSimulator.Internal.sdk", sdk_name_secondary: "XRSimulator.sdk",
708 sdk_type: XcodeSDK::Type::XRSimulator,
709 kind: CoreSimulatorSupport::DeviceType::ProductFamilyID::appleXR, force,
710 arch);
711 }
712};
713
714static unsigned g_initialize_count = 0;
715
716// Static Functions
717void PlatformAppleSimulator::Initialize() {
718 if (g_initialize_count++ == 0) {
719 PlatformDarwin::Initialize();
720 PlatformiOSSimulator::Initialize();
721 PlatformAppleTVSimulator::Initialize();
722 PlatformAppleWatchSimulator::Initialize();
723 PlatformXRSimulator::Initialize();
724 }
725}
726
727void PlatformAppleSimulator::Terminate() {
728 if (g_initialize_count > 0)
729 if (--g_initialize_count == 0) {
730 PlatformXRSimulator::Terminate();
731 PlatformAppleWatchSimulator::Terminate();
732 PlatformAppleTVSimulator::Terminate();
733 PlatformiOSSimulator::Terminate();
734 PlatformDarwin::Terminate();
735 }
736}
737
738

source code of lldb/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp