LLDB  mainline
PlatformAppleTVSimulator.cpp
Go to the documentation of this file.
1 //===-- PlatformAppleTVSimulator.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 
10 
12 #include "lldb/Core/Module.h"
13 #include "lldb/Core/ModuleList.h"
14 #include "lldb/Core/ModuleSpec.h"
16 #include "lldb/Host/Host.h"
17 #include "lldb/Host/HostInfo.h"
18 #include "lldb/Target/Target.h"
19 #include "lldb/Utility/ArchSpec.h"
20 #include "lldb/Utility/FileSpec.h"
21 #include "lldb/Utility/Log.h"
23 #include "lldb/Utility/Status.h"
25 
26 #include "llvm/Support/FileSystem.h"
27 
28 using namespace lldb;
29 using namespace lldb_private;
30 
31 namespace lldb_private {
32 class Process;
33 }
34 
35 // Static Variables
37 
38 // Static Functions
41 
42  if (g_initialize_count++ == 0) {
43  PluginManager::RegisterPlugin(
47  }
48 }
49 
51  if (g_initialize_count > 0) {
52  if (--g_initialize_count == 0) {
53  PluginManager::UnregisterPlugin(PlatformAppleTVSimulator::CreateInstance);
54  }
55  }
56 
58 }
59 
61  const ArchSpec *arch) {
63  if (log) {
64  const char *arch_name;
65  if (arch && arch->GetArchitectureName())
66  arch_name = arch->GetArchitectureName();
67  else
68  arch_name = "<null>";
69 
70  const char *triple_cstr =
71  arch ? arch->GetTriple().getTriple().c_str() : "<null>";
72 
73  LLDB_LOGF(log, "PlatformAppleTVSimulator::%s(force=%s, arch={%s,%s})",
74  __FUNCTION__, force ? "true" : "false", arch_name, triple_cstr);
75  }
76 
77  bool create = force;
78  if (!create && arch && arch->IsValid()) {
79  switch (arch->GetMachine()) {
80  case llvm::Triple::x86_64: {
81  const llvm::Triple &triple = arch->GetTriple();
82  switch (triple.getVendor()) {
83  case llvm::Triple::Apple:
84  create = true;
85  break;
86 
87 #if defined(__APPLE__)
88  // Only accept "unknown" for the vendor if the host is Apple and it
89  // "unknown" wasn't specified (it was just returned because it was NOT
90  // specified)
91  case llvm::Triple::UnknownVendor:
92  create = !arch->TripleVendorWasSpecified();
93  break;
94 #endif
95  default:
96  break;
97  }
98 
99  if (create) {
100  switch (triple.getOS()) {
101  case llvm::Triple::TvOS:
102  break;
103 
104 #if defined(__APPLE__)
105  // Only accept "unknown" for the OS if the host is Apple and it
106  // "unknown" wasn't specified (it was just returned because it was NOT
107  // specified)
108  case llvm::Triple::UnknownOS:
109  create = !arch->TripleOSWasSpecified();
110  break;
111 #endif
112  default:
113  create = false;
114  break;
115  }
116  }
117  } break;
118  default:
119  break;
120  }
121  }
122  if (create) {
123  LLDB_LOGF(log, "PlatformAppleTVSimulator::%s() creating platform",
124  __FUNCTION__);
125 
126  return PlatformSP(new PlatformAppleTVSimulator());
127  }
128 
129  LLDB_LOGF(log, "PlatformAppleTVSimulator::%s() aborting creation of platform",
130  __FUNCTION__);
131 
132  return PlatformSP();
133 }
134 
136  static ConstString g_name("tvos-simulator");
137  return g_name;
138 }
139 
141  return "Apple TV simulator platform plug-in.";
142 }
143 
144 /// Default Constructor
147  CoreSimulatorSupport::DeviceType::ProductFamilyID::appleTV) {}
148 
149 /// Destructor.
150 ///
151 /// The destructor is virtual since this class is designed to be
152 /// inherited from by the plug-in instance.
154 
156  Platform::GetStatus(strm);
157  llvm::StringRef sdk_directory = GetSDKDirectoryAsCString();
158  if (!sdk_directory.empty())
159  strm.Printf(" SDK Path: \"%s\"\n", sdk_directory.str().c_str());
160  else
161  strm.PutCString(" SDK Path: error: unable to locate SDK\n");
162 }
163 
165  const ModuleSpec &module_spec, lldb::ModuleSP &exe_module_sp,
166  const FileSpecList *module_search_paths_ptr) {
167  Status error;
168  // Nothing special to do here, just use the actual file and architecture
169 
170  ModuleSpec resolved_module_spec(module_spec);
171 
172  // If we have "ls" as the exe_file, resolve the executable loation based on
173  // the current path variables
174  // TODO: resolve bare executables in the Platform SDK
175  // if (!resolved_exe_file.Exists())
176  // resolved_exe_file.ResolveExecutableLocation ();
177 
178  // Resolve any executable within a bundle on MacOSX
179  // TODO: verify that this handles shallow bundles, if not then implement one
180  // ourselves
181  Host::ResolveExecutableInBundle(resolved_module_spec.GetFileSpec());
182 
183  if (FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec())) {
184  if (resolved_module_spec.GetArchitecture().IsValid()) {
185  error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
186  NULL, NULL, NULL);
187 
188  if (exe_module_sp && exe_module_sp->GetObjectFile())
189  return error;
190  exe_module_sp.reset();
191  }
192  // No valid architecture was specified or the exact ARM slice wasn't found
193  // so ask the platform for the architectures that we should be using (in
194  // the correct order) and see if we can find a match that way
195  StreamString arch_names;
196  ArchSpec platform_arch;
198  idx, resolved_module_spec.GetArchitecture());
199  ++idx) {
200  // Only match x86 with x86 and x86_64 with x86_64...
201  if (!module_spec.GetArchitecture().IsValid() ||
202  module_spec.GetArchitecture().GetCore() ==
203  resolved_module_spec.GetArchitecture().GetCore()) {
204  error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
205  NULL, NULL, NULL);
206  // Did we find an executable using one of the
207  if (error.Success()) {
208  if (exe_module_sp && exe_module_sp->GetObjectFile())
209  break;
210  else
211  error.SetErrorToGenericError();
212  }
213 
214  if (idx > 0)
215  arch_names.PutCString(", ");
216  arch_names.PutCString(platform_arch.GetArchitectureName());
217  }
218  }
219 
220  if (error.Fail() || !exe_module_sp) {
221  if (FileSystem::Instance().Readable(resolved_module_spec.GetFileSpec())) {
223  "'%s' doesn't contain any '%s' platform architectures: %s",
224  resolved_module_spec.GetFileSpec().GetPath().c_str(),
225  GetPluginName().GetCString(), arch_names.GetString().str().c_str());
226  } else {
228  "'%s' is not readable",
229  resolved_module_spec.GetFileSpec().GetPath().c_str());
230  }
231  }
232  } else {
233  error.SetErrorStringWithFormat("'%s' does not exist",
234  module_spec.GetFileSpec().GetPath().c_str());
235  }
236 
237  return error;
238 }
239 
241  llvm::StringRef sdk;
242  sdk = HostInfo::GetXcodeSDKPath(XcodeSDK("AppleTVSimulator.Internal.sdk"));
243  if (sdk.empty())
244  sdk = HostInfo::GetXcodeSDKPath(XcodeSDK("AppleTVSimulator.sdk"));
245  return sdk;
246 }
247 
249  const UUID *uuid_ptr,
250  FileSpec &local_file) {
251  Status error;
252  char platform_file_path[PATH_MAX];
253  if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) {
254  char resolved_path[PATH_MAX];
255 
256  llvm::StringRef sdk_dir = GetSDKDirectoryAsCString();
257  if (!sdk_dir.empty()) {
258  ::snprintf(resolved_path, sizeof(resolved_path), "%s/%s",
259  sdk_dir.str().c_str(), platform_file_path);
260 
261  // First try in the SDK and see if the file is in there
262  local_file.SetFile(resolved_path, FileSpec::Style::native);
263  FileSystem::Instance().Resolve(local_file);
264  if (FileSystem::Instance().Exists(local_file))
265  return error;
266 
267  // Else fall back to the actual path itself
268  local_file.SetFile(platform_file_path, FileSpec::Style::native);
269  FileSystem::Instance().Resolve(local_file);
270  if (FileSystem::Instance().Exists(local_file))
271  return error;
272  }
274  "unable to locate a platform file for '%s' in platform '%s'",
275  platform_file_path, GetPluginName().GetCString());
276  } else {
277  error.SetErrorString("invalid platform file argument");
278  }
279  return error;
280 }
281 
283  const ModuleSpec &module_spec, lldb_private::Process *process,
284  ModuleSP &module_sp, const FileSpecList *module_search_paths_ptr,
285  ModuleSP *old_module_sp_ptr, bool *did_create_ptr) {
286  // For AppleTV, the SDK files are all cached locally on the host system. So
287  // first we ask for the file in the cached SDK, then we attempt to get a
288  // shared module for the right architecture with the right UUID.
289  Status error;
290  ModuleSpec platform_module_spec(module_spec);
291  const FileSpec &platform_file = module_spec.GetFileSpec();
292  error = GetSymbolFile(platform_file, module_spec.GetUUIDPtr(),
293  platform_module_spec.GetFileSpec());
294  if (error.Success()) {
295  error = ResolveExecutable(platform_module_spec, module_sp,
296  module_search_paths_ptr);
297  } else {
298  const bool always_create = false;
299  error = ModuleList::GetSharedModule(
300  module_spec, module_sp, module_search_paths_ptr, old_module_sp_ptr,
301  did_create_ptr, always_create);
302  }
303  if (module_sp)
304  module_sp->SetPlatformFileSpec(platform_file);
305 
306  return error;
307 }
308 
310  const ProcessInstanceInfoMatch &match_info,
311  ProcessInstanceInfoList &process_infos) {
312  ProcessInstanceInfoList all_osx_process_infos;
313  // First we get all OSX processes
314  const uint32_t n = Host::FindProcesses(match_info, all_osx_process_infos);
315 
316  // Now we filter them down to only the TvOS triples
317  for (uint32_t i = 0; i < n; ++i) {
318  const ProcessInstanceInfo &proc_info = all_osx_process_infos[i];
319  if (proc_info.GetArchitecture().GetTriple().getOS() == llvm::Triple::TvOS) {
320  process_infos.push_back(proc_info);
321  }
322  }
323  return process_infos.size();
324 }
325 
327  ArchSpec &arch) {
328  static const ArchSpec platform_arch(
329  HostInfo::GetArchitecture(HostInfo::eArchKind64));
330 
331  if (idx == 0) {
332  arch = platform_arch;
333  if (arch.IsValid()) {
334  arch.GetTriple().setOS(llvm::Triple::TvOS);
335  arch.GetTriple().setEnvironment(llvm::Triple::Simulator);
336  return true;
337  }
338  }
339  return false;
340 }
virtual lldb_private::Status GetSymbolFile(const lldb_private::FileSpec &platform_file, const lldb_private::UUID *uuid_ptr, lldb_private::FileSpec &local_file)
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
Definition: Stream.cpp:63
Core GetCore() const
Definition: ArchSpec.h:413
A class that represents a running process on the host machine.
A stream class that can stream formatted output to a file.
Definition: Stream.h:28
virtual ~PlatformAppleTVSimulator()
Destructor.
std::vector< ProcessInstanceInfo > ProcessInstanceInfoList
Definition: Host.h:30
static const char * GetDescriptionStatic()
lldb_private::Status GetSharedModule(const lldb_private::ModuleSpec &module_spec, lldb_private::Process *process, lldb::ModuleSP &module_sp, const lldb_private::FileSpecList *module_search_paths_ptr, lldb::ModuleSP *old_module_sp_ptr, bool *did_create_ptr) override
A file utility class.
Definition: FileSpec.h:56
An architecture specification class.
Definition: ArchSpec.h:33
lldb_private::ConstString GetPluginName() override
#define LIBLLDB_LOG_PLATFORM
Definition: Logging.h:39
static lldb_private::ConstString GetPluginNameStatic()
static void Terminate()
Definition: Platform.cpp:152
bool IsValid() const
Tests if this ArchSpec is valid.
Definition: ArchSpec.h:332
llvm::Triple & GetTriple()
Architecture triple accessor.
Definition: ArchSpec.h:434
bool TripleVendorWasSpecified() const
Definition: ArchSpec.h:337
const char * GetArchitectureName() const
Returns a static string representing the current architecture.
Definition: ArchSpec.cpp:585
void SetErrorToGenericError()
Set the current error to a generic error.
Definition: Status.cpp:232
static llvm::raw_ostream & error(Stream &strm)
Log * GetLogIfAllCategoriesSet(uint32_t mask)
Definition: Logging.cpp:58
static void Initialize()
Definition: Platform.cpp:150
uint32_t FindProcesses(const lldb_private::ProcessInstanceInfoMatch &match_info, lldb_private::ProcessInstanceInfoList &process_infos) override
Attach to an existing process by process name.
llvm::StringRef GetString() const
void SetErrorString(llvm::StringRef err_str)
Set the current error string to err_str.
Definition: Status.cpp:242
A plug-in interface definition class for debugging a process.
Definition: Process.h:362
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition: Stream.cpp:107
ArchSpec & GetArchitecture()
Definition: ProcessInfo.h:62
bool Success() const
Test for success condition.
Definition: Status.cpp:288
FileSpec & GetFileSpec()
Definition: ModuleSpec.h:75
PlatformAppleTVSimulator()
Default Constructor.
ArchSpec & GetArchitecture()
Definition: ModuleSpec.h:111
#define LLDB_LOGF(log,...)
Definition: Log.h:249
void GetStatus(lldb_private::Stream &strm) override
Report the current status for this platform.
A uniqued constant string class.
Definition: ConstString.h:40
bool Fail() const
Test for error condition.
Definition: Status.cpp:182
const char * GetCString() const
Get the string value as a C string.
Definition: ConstString.h:246
An abstraction for Xcode-style SDKs that works like ArchSpec.
Definition: XcodeSDK.h:24
static lldb::PlatformSP CreateInstance(bool force, const lldb_private::ArchSpec *arch)
Definition: SBAddress.h:15
bool GetSupportedArchitectureAtIndex(uint32_t idx, lldb_private::ArchSpec &arch) override
Get the platform&#39;s supported architectures in the order in which they should be searched.
bool TripleOSWasSpecified() const
Definition: ArchSpec.h:341
lldb_private::Status ResolveExecutable(const lldb_private::ModuleSpec &module_spec, lldb::ModuleSP &module_sp, const lldb_private::FileSpecList *module_search_paths_ptr) override
#define PATH_MAX
int SetErrorStringWithFormat(const char *format,...) __attribute__((format(printf
Set the current error string to a formatted error string.
Definition: Status.cpp:256
void SetFile(llvm::StringRef path, Style style)
Change the file specified with a new path.
Definition: FileSpec.cpp:174
#define NULL
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
Definition: FileSpec.cpp:348
llvm::Triple::ArchType GetMachine() const
Returns a machine family for the current architecture.
Definition: ArchSpec.cpp:714
An error handling class.
Definition: Status.h:44
static uint32_t g_initialize_count