Coverage Report

Created: 2023-09-30 09:22

/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp
Line
Count
Source (jump to first uncovered line)
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
23
    : PlatformDarwin(true), m_class_name(class_name),
48
23
      m_description(description), m_plugin_name(plugin_name), m_kind(kind),
49
23
      m_os_type(preferred_os), m_supported_triples(supported_triples),
50
23
      m_sdk_name_primary(std::move(sdk_name_primary)),
51
23
      m_sdk_name_secondary(std::move(sdk_name_secondary)),
52
23
      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
23
PlatformAppleSimulator::~PlatformAppleSimulator() = default;
59
60
lldb_private::Status PlatformAppleSimulator::LaunchProcess(
61
0
    lldb_private::ProcessLaunchInfo &launch_info) {
62
0
#if defined(__APPLE__)
63
0
  LoadCoreSimulator();
64
0
  CoreSimulatorSupport::Device device(GetSimulatorDevice());
65
66
0
  if (device.GetState() != CoreSimulatorSupport::Device::State::Booted) {
67
0
    Status boot_err;
68
0
    device.Boot(boot_err);
69
0
    if (boot_err.Fail())
70
0
      return boot_err;
71
0
  }
72
73
0
  auto spawned = device.Spawn(launch_info);
74
75
0
  if (spawned) {
76
0
    launch_info.SetProcessID(spawned.GetPID());
77
0
    return Status();
78
0
  } else
79
0
    return spawned.GetError();
80
#else
81
  Status err;
82
  err.SetErrorString(UNSUPPORTED_ERROR);
83
  return err;
84
#endif
85
0
}
86
87
0
void PlatformAppleSimulator::GetStatus(Stream &strm) {
88
0
  Platform::GetStatus(strm);
89
0
  llvm::StringRef sdk = GetSDKFilepath();
90
0
  if (!sdk.empty())
91
0
    strm << "  SDK Path: \"" << sdk << "\"\n";
92
0
  else
93
0
    strm << "  SDK Path: error: unable to locate SDK\n";
94
95
0
#if defined(__APPLE__)
96
  // This will get called by subclasses, so just output status on the current
97
  // simulator
98
0
  PlatformAppleSimulator::LoadCoreSimulator();
99
100
0
  std::string developer_dir = HostInfo::GetXcodeDeveloperDirectory().GetPath();
101
0
  CoreSimulatorSupport::DeviceSet devices =
102
0
      CoreSimulatorSupport::DeviceSet::GetAvailableDevices(
103
0
          developer_dir.c_str());
104
0
  const size_t num_devices = devices.GetNumDevices();
105
0
  if (num_devices) {
106
0
    strm.Printf("Available devices:\n");
107
0
    for (size_t i = 0; i < num_devices; ++i) {
108
0
      CoreSimulatorSupport::Device device = devices.GetDeviceAtIndex(i);
109
0
      strm << "   " << device.GetUDID() << ": " << device.GetName() << "\n";
110
0
    }
111
112
0
    if (m_device.has_value() && m_device->operator bool()) {
113
0
      strm << "Current device: " << m_device->GetUDID() << ": "
114
0
           << m_device->GetName();
115
0
      if (m_device->GetState() == CoreSimulatorSupport::Device::State::Booted) {
116
0
        strm << " state = booted";
117
0
      }
118
0
      strm << "\nType \"platform connect <ARG>\" where <ARG> is a device "
119
0
              "UDID or a device name to disconnect and connect to a "
120
0
              "different device.\n";
121
122
0
    } else {
123
0
      strm << "No current device is selected, \"platform connect <ARG>\" "
124
0
              "where <ARG> is a device UDID or a device name to connect to "
125
0
              "a specific device.\n";
126
0
    }
127
128
0
  } else {
129
0
    strm << "No devices are available.\n";
130
0
  }
131
#else
132
  strm << UNSUPPORTED_ERROR;
133
#endif
134
0
}
135
136
0
Status PlatformAppleSimulator::ConnectRemote(Args &args) {
137
0
#if defined(__APPLE__)
138
0
  Status error;
139
0
  if (args.GetArgumentCount() == 1) {
140
0
    if (m_device)
141
0
      DisconnectRemote();
142
0
    PlatformAppleSimulator::LoadCoreSimulator();
143
0
    const char *arg_cstr = args.GetArgumentAtIndex(0);
144
0
    if (arg_cstr) {
145
0
      std::string arg_str(arg_cstr);
146
0
      std::string developer_dir = HostInfo::GetXcodeDeveloperDirectory().GetPath();
147
0
      CoreSimulatorSupport::DeviceSet devices =
148
0
          CoreSimulatorSupport::DeviceSet::GetAvailableDevices(
149
0
              developer_dir.c_str());
150
0
      devices.ForEach(
151
0
          [this, &arg_str](const CoreSimulatorSupport::Device &device) -> bool {
152
0
            if (arg_str == device.GetUDID() || arg_str == device.GetName()) {
153
0
              m_device = device;
154
0
              return false; // Stop iterating
155
0
            } else {
156
0
              return true; // Keep iterating
157
0
            }
158
0
          });
159
0
      if (!m_device)
160
0
        error.SetErrorStringWithFormat(
161
0
            "no device with UDID or name '%s' was found", arg_cstr);
162
0
    }
163
0
  } else {
164
0
    error.SetErrorString("this command take a single UDID argument of the "
165
0
                         "device you want to connect to.");
166
0
  }
167
0
  return error;
168
#else
169
  Status err;
170
  err.SetErrorString(UNSUPPORTED_ERROR);
171
  return err;
172
#endif
173
0
}
174
175
0
Status PlatformAppleSimulator::DisconnectRemote() {
176
0
#if defined(__APPLE__)
177
0
  m_device.reset();
178
0
  return Status();
179
#else
180
  Status err;
181
  err.SetErrorString(UNSUPPORTED_ERROR);
182
  return err;
183
#endif
184
0
}
185
186
lldb::ProcessSP
187
PlatformAppleSimulator::DebugProcess(ProcessLaunchInfo &launch_info,
188
                                     Debugger &debugger, Target &target,
189
0
                                     Status &error) {
190
0
#if defined(__APPLE__)
191
0
  ProcessSP process_sp;
192
  // Make sure we stop at the entry point
193
0
  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
0
  launch_info.SetLaunchInSeparateProcessGroup(true);
198
199
0
  error = LaunchProcess(launch_info);
200
0
  if (error.Success()) {
201
0
    if (launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID) {
202
0
      ProcessAttachInfo attach_info(launch_info);
203
0
      process_sp = Attach(attach_info, debugger, &target, error);
204
0
      if (process_sp) {
205
0
        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
0
        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
0
        int pty_fd = launch_info.GetPTY().ReleasePrimaryFileDescriptor();
218
0
        if (pty_fd != PseudoTerminal::invalid_fd) {
219
0
          process_sp->SetSTDIOFileDescriptor(pty_fd);
220
0
        }
221
0
      }
222
0
    }
223
0
  }
224
225
0
  return process_sp;
226
#else
227
  return ProcessSP();
228
#endif
229
0
}
230
231
0
FileSpec PlatformAppleSimulator::GetCoreSimulatorPath() {
232
0
#if defined(__APPLE__)
233
0
  std::lock_guard<std::mutex> guard(m_core_sim_path_mutex);
234
0
  if (!m_core_simulator_framework_path.has_value()) {
235
0
    m_core_simulator_framework_path =
236
0
        FileSpec("/Library/Developer/PrivateFrameworks/CoreSimulator.framework/"
237
0
                 "CoreSimulator");
238
0
    FileSystem::Instance().Resolve(*m_core_simulator_framework_path);
239
0
  }
240
0
  return m_core_simulator_framework_path.value();
241
#else
242
  return FileSpec();
243
#endif
244
0
}
245
246
0
void PlatformAppleSimulator::LoadCoreSimulator() {
247
0
#if defined(__APPLE__)
248
0
  static llvm::once_flag g_load_core_sim_flag;
249
0
  llvm::call_once(g_load_core_sim_flag, [this] {
250
0
    const std::string core_sim_path(GetCoreSimulatorPath().GetPath());
251
0
    if (core_sim_path.size())
252
0
      dlopen(core_sim_path.c_str(), RTLD_LAZY);
253
0
  });
254
0
#endif
255
0
}
256
257
#if defined(__APPLE__)
258
0
CoreSimulatorSupport::Device PlatformAppleSimulator::GetSimulatorDevice() {
259
0
  if (!m_device.has_value()) {
260
0
    const CoreSimulatorSupport::DeviceType::ProductFamilyID dev_id = m_kind;
261
0
    std::string developer_dir =
262
0
        HostInfo::GetXcodeDeveloperDirectory().GetPath();
263
0
    m_device = CoreSimulatorSupport::DeviceSet::GetAvailableDevices(
264
0
                   developer_dir.c_str())
265
0
                   .GetFanciest(dev_id);
266
0
  }
267
268
0
  if (m_device.has_value())
269
0
    return m_device.value();
270
0
  else
271
0
    return CoreSimulatorSupport::Device();
272
0
}
273
#endif
274
275
std::vector<ArchSpec> PlatformAppleSimulator::GetSupportedArchitectures(
276
17
    const ArchSpec &process_host_arch) {
277
17
  std::vector<ArchSpec> result(m_supported_triples.size());
278
17
  llvm::transform(m_supported_triples, result.begin(),
279
46
                  [](llvm::StringRef triple) { return ArchSpec(triple); });
280
17
  return result;
281
17
}
282
283
static llvm::StringRef GetXcodeSDKDir(std::string preferred,
284
0
                                      std::string secondary) {
285
0
  llvm::StringRef sdk;
286
0
  auto get_sdk = [&](std::string sdk) -> llvm::StringRef {
287
0
    auto sdk_path_or_err =
288
0
        HostInfo::GetSDKRoot(HostInfo::SDKOptions{XcodeSDK(std::move(sdk))});
289
0
    if (!sdk_path_or_err) {
290
0
      Debugger::ReportError("Error while searching for Xcode SDK: " +
291
0
                            toString(sdk_path_or_err.takeError()));
292
0
      return {};
293
0
    }
294
0
    return *sdk_path_or_err;
295
0
  };
296
297
0
  sdk = get_sdk(preferred);
298
0
  if (sdk.empty())
299
0
    sdk = get_sdk(secondary);
300
0
  return sdk;
301
0
}
302
303
0
llvm::StringRef PlatformAppleSimulator::GetSDKFilepath() {
304
0
  if (!m_have_searched_for_sdk) {
305
0
    m_sdk = GetXcodeSDKDir(m_sdk_name_primary, m_sdk_name_secondary);
306
0
    m_have_searched_for_sdk = true;
307
0
  }
308
0
  return m_sdk;
309
0
}
310
311
PlatformSP 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
235
    const ArchSpec *arch) {
321
235
  Log *log = GetLog(LLDBLog::Platform);
322
235
  if (log) {
323
0
    const char *arch_name;
324
0
    if (arch && arch->GetArchitectureName())
325
0
      arch_name = arch->GetArchitectureName();
326
0
    else
327
0
      arch_name = "<null>";
328
329
0
    const char *triple_cstr =
330
0
        arch ? arch->GetTriple().getTriple().c_str() : "<null>";
331
332
0
    LLDB_LOGF(log, "%s::%s(force=%s, arch={%s,%s})", class_name, __FUNCTION__,
333
0
              force ? "true" : "false", arch_name, triple_cstr);
334
0
  }
335
336
235
  bool create = force;
337
235
  if (!create && 
arch220
&&
arch->IsValid()220
) {
338
220
    if (std::count(supported_arch.begin(), supported_arch.end(),
339
220
                   arch->GetMachine())) {
340
160
      const llvm::Triple &triple = arch->GetTriple();
341
160
      switch (triple.getVendor()) {
342
16
      case llvm::Triple::Apple:
343
16
        create = true;
344
16
        break;
345
346
0
#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
0
      case llvm::Triple::UnknownVendor:
351
0
        create = !arch->TripleVendorWasSpecified();
352
0
        break;
353
0
#endif
354
144
      default:
355
144
        break;
356
160
      }
357
358
160
      if (create) {
359
16
        if (llvm::is_contained(supported_os, triple.getOS()))
360
8
          create = true;
361
8
#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
8
        else if (triple.getOS() == llvm::Triple::UnknownOS)
366
0
          create = !arch->TripleOSWasSpecified();
367
8
#endif
368
8
        else
369
8
          create = false;
370
16
      }
371
160
    }
372
220
  }
373
235
  if (create) {
374
23
    LLDB_LOGF(log, "%s::%s() creating platform", class_name, __FUNCTION__);
375
376
23
    return PlatformSP(new PlatformAppleSimulator(
377
23
        class_name, description, plugin_name, preferred_os, supported_triples,
378
23
        sdk_name_primary, sdk_name_secondary, sdk_type, kind));
379
23
  }
380
381
212
  LLDB_LOGF(log, "%s::%s() aborting creation of platform", class_name,
382
212
            __FUNCTION__);
383
384
212
  return PlatformSP();
385
235
}
386
387
Status PlatformAppleSimulator::ResolveExecutable(
388
    const ModuleSpec &module_spec, lldb::ModuleSP &exe_module_sp,
389
0
    const FileSpecList *module_search_paths_ptr) {
390
0
  Status error;
391
  // Nothing special to do here, just use the actual file and architecture
392
393
0
  ModuleSpec resolved_module_spec(module_spec);
394
395
  // If we have "ls" as the exe_file, resolve the executable loation based on
396
  // the current path variables
397
  // TODO: resolve bare executables in the Platform SDK
398
  //    if (!resolved_exe_file.Exists())
399
  //        resolved_exe_file.ResolveExecutableLocation ();
400
401
  // Resolve any executable within a bundle on MacOSX
402
  // TODO: verify that this handles shallow bundles, if not then implement one
403
  // ourselves
404
0
  Host::ResolveExecutableInBundle(resolved_module_spec.GetFileSpec());
405
406
0
  if (FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec())) {
407
0
    if (resolved_module_spec.GetArchitecture().IsValid()) {
408
0
      error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
409
0
                                          NULL, NULL, NULL);
410
411
0
      if (exe_module_sp && exe_module_sp->GetObjectFile())
412
0
        return error;
413
0
      exe_module_sp.reset();
414
0
    }
415
    // No valid architecture was specified or the exact ARM slice wasn't found
416
    // so ask the platform for the architectures that we should be using (in
417
    // the correct order) and see if we can find a match that way
418
0
    StreamString arch_names;
419
0
    llvm::ListSeparator LS;
420
0
    ArchSpec platform_arch;
421
0
    for (const ArchSpec &arch : GetSupportedArchitectures({})) {
422
0
      resolved_module_spec.GetArchitecture() = arch;
423
424
      // Only match x86 with x86 and x86_64 with x86_64...
425
0
      if (!module_spec.GetArchitecture().IsValid() ||
426
0
          module_spec.GetArchitecture().GetCore() ==
427
0
              resolved_module_spec.GetArchitecture().GetCore()) {
428
0
        error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
429
0
                                            NULL, NULL, NULL);
430
        // Did we find an executable using one of the
431
0
        if (error.Success()) {
432
0
          if (exe_module_sp && exe_module_sp->GetObjectFile())
433
0
            break;
434
0
          else
435
0
            error.SetErrorToGenericError();
436
0
        }
437
438
0
        arch_names << LS << platform_arch.GetArchitectureName();
439
0
      }
440
0
    }
441
442
0
    if (error.Fail() || !exe_module_sp) {
443
0
      if (FileSystem::Instance().Readable(resolved_module_spec.GetFileSpec())) {
444
0
        error.SetErrorStringWithFormatv(
445
0
            "'{0}' doesn't contain any '{1}' platform architectures: {2}",
446
0
            resolved_module_spec.GetFileSpec(), GetPluginName(),
447
0
            arch_names.GetString());
448
0
      } else {
449
0
        error.SetErrorStringWithFormat(
450
0
            "'%s' is not readable",
451
0
            resolved_module_spec.GetFileSpec().GetPath().c_str());
452
0
      }
453
0
    }
454
0
  } else {
455
0
    error.SetErrorStringWithFormat("'%s' does not exist",
456
0
                                   module_spec.GetFileSpec().GetPath().c_str());
457
0
  }
458
459
0
  return error;
460
0
}
461
462
Status PlatformAppleSimulator::GetSymbolFile(const FileSpec &platform_file,
463
                                             const UUID *uuid_ptr,
464
0
                                             FileSpec &local_file) {
465
0
  Status error;
466
0
  char platform_file_path[PATH_MAX];
467
0
  if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) {
468
0
    char resolved_path[PATH_MAX];
469
470
0
    llvm::StringRef sdk = GetSDKFilepath();
471
0
    if (!sdk.empty()) {
472
0
      ::snprintf(resolved_path, sizeof(resolved_path), "%s/%s",
473
0
                 sdk.str().c_str(), platform_file_path);
474
475
      // First try in the SDK and see if the file is in there
476
0
      local_file.SetFile(resolved_path, FileSpec::Style::native);
477
0
      FileSystem::Instance().Resolve(local_file);
478
0
      if (FileSystem::Instance().Exists(local_file))
479
0
        return error;
480
481
      // Else fall back to the actual path itself
482
0
      local_file.SetFile(platform_file_path, FileSpec::Style::native);
483
0
      FileSystem::Instance().Resolve(local_file);
484
0
      if (FileSystem::Instance().Exists(local_file))
485
0
        return error;
486
0
    }
487
0
    error.SetErrorStringWithFormatv(
488
0
        "unable to locate a platform file for '{0}' in platform '{1}'",
489
0
        platform_file_path, GetPluginName());
490
0
  } else {
491
0
    error.SetErrorString("invalid platform file argument");
492
0
  }
493
0
  return error;
494
0
}
495
496
Status PlatformAppleSimulator::GetSharedModule(
497
    const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp,
498
    const FileSpecList *module_search_paths_ptr,
499
0
    llvm::SmallVectorImpl<lldb::ModuleSP> *old_modules, bool *did_create_ptr) {
500
  // For iOS/tvOS/watchOS, the SDK files are all cached locally on the
501
  // host system. So first we ask for the file in the cached SDK, then
502
  // we attempt to get a shared module for the right architecture with
503
  // the right UUID.
504
0
  Status error;
505
0
  ModuleSpec platform_module_spec(module_spec);
506
0
  const FileSpec &platform_file = module_spec.GetFileSpec();
507
0
  error = GetSymbolFile(platform_file, module_spec.GetUUIDPtr(),
508
0
                        platform_module_spec.GetFileSpec());
509
0
  if (error.Success()) {
510
0
    error = ResolveExecutable(platform_module_spec, module_sp,
511
0
                              module_search_paths_ptr);
512
0
  } else {
513
0
    const bool always_create = false;
514
0
    error = ModuleList::GetSharedModule(module_spec, module_sp,
515
0
                                        module_search_paths_ptr, old_modules,
516
0
                                        did_create_ptr, always_create);
517
0
  }
518
0
  if (module_sp)
519
0
    module_sp->SetPlatformFileSpec(platform_file);
520
521
0
  return error;
522
0
}
523
524
uint32_t PlatformAppleSimulator::FindProcesses(
525
    const ProcessInstanceInfoMatch &match_info,
526
0
    ProcessInstanceInfoList &process_infos) {
527
0
  ProcessInstanceInfoList all_osx_process_infos;
528
  // First we get all OSX processes
529
0
  const uint32_t n = Host::FindProcesses(match_info, all_osx_process_infos);
530
531
  // Now we filter them down to only the matching triples.
532
0
  for (uint32_t i = 0; i < n; ++i) {
533
0
    const ProcessInstanceInfo &proc_info = all_osx_process_infos[i];
534
0
    const llvm::Triple &triple = proc_info.GetArchitecture().GetTriple();
535
0
    if (triple.getOS() == m_os_type &&
536
0
        triple.getEnvironment() == llvm::Triple::Simulator) {
537
0
      process_infos.push_back(proc_info);
538
0
    }
539
0
  }
540
0
  return process_infos.size();
541
0
}
542
543
/// Whether to skip creating a simulator platform.
544
640
static bool shouldSkipSimulatorPlatform(bool force, const ArchSpec *arch) {
545
  // If the arch is known not to specify a simulator environment, skip creating
546
  // the simulator platform (we can create it later if there's a matching arch).
547
  // This avoids very slow xcrun queries for non-simulator archs (the slowness
548
  // is due to xcrun not caching negative queries.
549
640
  return !force && 
arch625
&&
arch->IsValid()625
&&
550
640
         
!arch->TripleEnvironmentWasSpecified()625
;
551
640
}
552
553
static const char *g_ios_plugin_name = "ios-simulator";
554
static const char *g_ios_description = "iPhone simulator platform plug-in.";
555
556
/// IPhone Simulator Plugin.
557
struct PlatformiOSSimulator {
558
3.94k
  static void Initialize() {
559
3.94k
    PluginManager::RegisterPlugin(g_ios_plugin_name, g_ios_description,
560
3.94k
                                  PlatformiOSSimulator::CreateInstance);
561
3.94k
  }
562
563
3.94k
  static void Terminate() {
564
3.94k
    PluginManager::UnregisterPlugin(PlatformiOSSimulator::CreateInstance);
565
3.94k
  }
566
567
216
  static PlatformSP CreateInstance(bool force, const ArchSpec *arch) {
568
216
    if (shouldSkipSimulatorPlatform(force, arch))
569
135
      return nullptr;
570
571
81
    return PlatformAppleSimulator::CreateInstance(
572
81
        "PlatformiOSSimulator", g_ios_description,
573
81
        ConstString(g_ios_plugin_name),
574
81
        {llvm::Triple::aarch64, llvm::Triple::x86_64, llvm::Triple::x86},
575
81
        llvm::Triple::IOS,
576
81
        {// Deprecated, but still support Darwin for historical reasons.
577
81
         llvm::Triple::Darwin, llvm::Triple::MacOSX,
578
         // IOS is not used for simulator triples, but accept it just in
579
         // case.
580
81
         llvm::Triple::IOS},
581
81
        {
582
81
#ifdef __APPLE__
583
#if __arm64__
584
          "arm64e-apple-ios-simulator", "arm64-apple-ios-simulator",
585
              "x86_64-apple-ios-simulator", "x86_64h-apple-ios-simulator",
586
#else
587
81
          "x86_64h-apple-ios-simulator", "x86_64-apple-ios-simulator",
588
81
              "i386-apple-ios-simulator",
589
81
#endif
590
81
#endif
591
81
        },
592
81
        "iPhoneSimulator.Internal.sdk", "iPhoneSimulator.sdk",
593
81
        XcodeSDK::Type::iPhoneSimulator,
594
81
        CoreSimulatorSupport::DeviceType::ProductFamilyID::iPhone, force, arch);
595
216
  }
596
};
597
598
static const char *g_tvos_plugin_name = "tvos-simulator";
599
static const char *g_tvos_description = "tvOS simulator platform plug-in.";
600
601
/// Apple TV Simulator Plugin.
602
struct PlatformAppleTVSimulator {
603
3.94k
  static void Initialize() {
604
3.94k
    PluginManager::RegisterPlugin(g_tvos_plugin_name, g_tvos_description,
605
3.94k
                                  PlatformAppleTVSimulator::CreateInstance);
606
3.94k
  }
607
608
3.94k
  static void Terminate() {
609
3.94k
    PluginManager::UnregisterPlugin(PlatformAppleTVSimulator::CreateInstance);
610
3.94k
  }
611
612
213
  static PlatformSP CreateInstance(bool force, const ArchSpec *arch) {
613
213
    if (shouldSkipSimulatorPlatform(force, arch))
614
135
      return nullptr;
615
78
    return PlatformAppleSimulator::CreateInstance(
616
78
        "PlatformAppleTVSimulator", g_tvos_description,
617
78
        ConstString(g_tvos_plugin_name),
618
78
        {llvm::Triple::aarch64, llvm::Triple::x86_64}, llvm::Triple::TvOS,
619
78
        {llvm::Triple::TvOS},
620
78
        {
621
78
#ifdef __APPLE__
622
#if __arm64__
623
          "arm64e-apple-tvos-simulator", "arm64-apple-tvos-simulator",
624
              "x86_64h-apple-tvos-simulator", "x86_64-apple-tvos-simulator",
625
#else
626
78
          "x86_64h-apple-tvos-simulator", "x86_64-apple-tvos-simulator",
627
78
#endif
628
78
#endif
629
78
        },
630
78
        "AppleTVSimulator.Internal.sdk", "AppleTVSimulator.sdk",
631
78
        XcodeSDK::Type::AppleTVSimulator,
632
78
        CoreSimulatorSupport::DeviceType::ProductFamilyID::appleTV, force,
633
78
        arch);
634
213
  }
635
};
636
637
638
static const char *g_watchos_plugin_name = "watchos-simulator";
639
static const char *g_watchos_description =
640
    "Apple Watch simulator platform plug-in.";
641
642
/// Apple Watch Simulator Plugin.
643
struct PlatformAppleWatchSimulator {
644
3.94k
  static void Initialize() {
645
3.94k
    PluginManager::RegisterPlugin(g_watchos_plugin_name, g_watchos_description,
646
3.94k
                                  PlatformAppleWatchSimulator::CreateInstance);
647
3.94k
  }
648
649
3.94k
  static void Terminate() {
650
3.94k
    PluginManager::UnregisterPlugin(
651
3.94k
        PlatformAppleWatchSimulator::CreateInstance);
652
3.94k
  }
653
654
211
  static PlatformSP CreateInstance(bool force, const ArchSpec *arch) {
655
211
    if (shouldSkipSimulatorPlatform(force, arch))
656
135
      return nullptr;
657
76
    return PlatformAppleSimulator::CreateInstance(
658
76
        "PlatformAppleWatchSimulator", g_watchos_description,
659
76
        ConstString(g_watchos_plugin_name),
660
76
        {llvm::Triple::aarch64, llvm::Triple::x86_64, llvm::Triple::x86},
661
76
        llvm::Triple::WatchOS, {llvm::Triple::WatchOS},
662
76
        {
663
76
#ifdef __APPLE__
664
#if __arm64__
665
          "arm64e-apple-watchos-simulator", "arm64-apple-watchos-simulator",
666
#else
667
76
          "x86_64-apple-watchos-simulator", "x86_64h-apple-watchos-simulator",
668
76
              "i386-apple-watchos-simulator",
669
76
#endif
670
76
#endif
671
76
        },
672
76
        "WatchSimulator.Internal.sdk", "WatchSimulator.sdk",
673
76
        XcodeSDK::Type::WatchSimulator,
674
76
        CoreSimulatorSupport::DeviceType::ProductFamilyID::appleWatch, force,
675
76
        arch);
676
211
  }
677
};
678
679
680
static unsigned g_initialize_count = 0;
681
682
// Static Functions
683
3.94k
void PlatformAppleSimulator::Initialize() {
684
3.94k
  if (g_initialize_count++ == 0) {
685
3.94k
    PlatformDarwin::Initialize();
686
3.94k
    PlatformiOSSimulator::Initialize();
687
3.94k
    PlatformAppleTVSimulator::Initialize();
688
3.94k
    PlatformAppleWatchSimulator::Initialize();
689
3.94k
  }
690
3.94k
}
691
692
3.94k
void PlatformAppleSimulator::Terminate() {
693
3.94k
  if (g_initialize_count > 0)
694
3.94k
    if (--g_initialize_count == 0) {
695
3.94k
      PlatformAppleWatchSimulator::Terminate();
696
3.94k
      PlatformAppleTVSimulator::Terminate();
697
3.94k
      PlatformiOSSimulator::Terminate();
698
3.94k
      PlatformDarwin::Terminate();
699
3.94k
    }
700
3.94k
}
701