1 //===-- PlatformiOSSimulator.cpp -----------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "PlatformiOSSimulator.h"
14 // Other libraries and framework includes
16 #include "lldb/Breakpoint/BreakpointLocation.h"
17 #include "lldb/Core/ArchSpec.h"
18 #include "lldb/Core/Error.h"
19 #include "lldb/Core/Log.h"
20 #include "lldb/Core/Module.h"
21 #include "lldb/Core/ModuleList.h"
22 #include "lldb/Core/ModuleSpec.h"
23 #include "lldb/Core/PluginManager.h"
24 #include "lldb/Core/StreamString.h"
25 #include "lldb/Host/FileSpec.h"
26 #include "lldb/Host/Host.h"
27 #include "lldb/Host/HostInfo.h"
28 #include "lldb/Target/Process.h"
29 #include "lldb/Target/Target.h"
32 using namespace lldb_private;
34 //------------------------------------------------------------------
36 //------------------------------------------------------------------
37 static uint32_t g_initialize_count = 0;
39 //------------------------------------------------------------------
41 //------------------------------------------------------------------
43 PlatformiOSSimulator::Initialize ()
45 PlatformAppleSimulator::Initialize ();
47 if (g_initialize_count++ == 0)
49 PluginManager::RegisterPlugin (PlatformiOSSimulator::GetPluginNameStatic(),
50 PlatformiOSSimulator::GetDescriptionStatic(),
51 PlatformiOSSimulator::CreateInstance);
56 PlatformiOSSimulator::Terminate ()
58 if (g_initialize_count > 0)
60 if (--g_initialize_count == 0)
62 PluginManager::UnregisterPlugin (PlatformiOSSimulator::CreateInstance);
66 PlatformAppleSimulator::Terminate ();
70 PlatformiOSSimulator::CreateInstance (bool force, const ArchSpec *arch)
72 Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_PLATFORM));
75 const char *arch_name;
76 if (arch && arch->GetArchitectureName ())
77 arch_name = arch->GetArchitectureName ();
81 const char *triple_cstr = arch ? arch->GetTriple ().getTriple ().c_str() : "<null>";
83 log->Printf ("PlatformiOSSimulator::%s(force=%s, arch={%s,%s})", __FUNCTION__, force ? "true" : "false", arch_name, triple_cstr);
87 if (create == false && arch && arch->IsValid())
89 switch (arch->GetMachine())
91 case llvm::Triple::x86_64:
92 case llvm::Triple::x86:
94 const llvm::Triple &triple = arch->GetTriple();
95 switch (triple.getVendor())
97 case llvm::Triple::Apple:
101 #if defined(__APPLE__)
102 // Only accept "unknown" for the vendor if the host is Apple and
103 // it "unknown" wasn't specified (it was just returned because it
104 // was NOT specified)
105 case llvm::Triple::UnknownArch:
106 create = !arch->TripleVendorWasSpecified();
115 switch (triple.getOS())
117 case llvm::Triple::Darwin: // Deprecated, but still support Darwin for historical reasons
118 case llvm::Triple::MacOSX:
119 case llvm::Triple::IOS: // IOS is not used for simulator triples, but accept it just in case
122 #if defined(__APPLE__)
123 // Only accept "unknown" for the OS if the host is Apple and
124 // it "unknown" wasn't specified (it was just returned because it
125 // was NOT specified)
126 case llvm::Triple::UnknownOS:
127 create = !arch->TripleOSWasSpecified();
144 log->Printf ("PlatformiOSSimulator::%s() creating platform", __FUNCTION__);
146 return PlatformSP(new PlatformiOSSimulator ());
150 log->Printf ("PlatformiOSSimulator::%s() aborting creation of platform", __FUNCTION__);
156 lldb_private::ConstString
157 PlatformiOSSimulator::GetPluginNameStatic ()
159 static ConstString g_name("ios-simulator");
164 PlatformiOSSimulator::GetDescriptionStatic()
166 return "iOS simulator platform plug-in.";
170 //------------------------------------------------------------------
171 /// Default Constructor
172 //------------------------------------------------------------------
173 PlatformiOSSimulator::PlatformiOSSimulator () :
174 PlatformAppleSimulator (),
179 //------------------------------------------------------------------
182 /// The destructor is virtual since this class is designed to be
183 /// inherited from by the plug-in instance.
184 //------------------------------------------------------------------
185 PlatformiOSSimulator::~PlatformiOSSimulator()
191 PlatformiOSSimulator::GetStatus (Stream &strm)
193 Platform::GetStatus (strm);
194 const char *sdk_directory = GetSDKDirectoryAsCString();
196 strm.Printf (" SDK Path: \"%s\"\n", sdk_directory);
198 strm.PutCString (" SDK Path: error: unable to locate SDK\n");
199 PlatformAppleSimulator::GetStatus(strm);
204 PlatformiOSSimulator::ResolveExecutable (const ModuleSpec &module_spec,
205 lldb::ModuleSP &exe_module_sp,
206 const FileSpecList *module_search_paths_ptr)
209 // Nothing special to do here, just use the actual file and architecture
211 ModuleSpec resolved_module_spec(module_spec);
213 // If we have "ls" as the exe_file, resolve the executable loation based on
214 // the current path variables
215 // TODO: resolve bare executables in the Platform SDK
216 // if (!resolved_exe_file.Exists())
217 // resolved_exe_file.ResolveExecutableLocation ();
219 // Resolve any executable within a bundle on MacOSX
220 // TODO: verify that this handles shallow bundles, if not then implement one ourselves
221 Host::ResolveExecutableInBundle (resolved_module_spec.GetFileSpec());
223 if (resolved_module_spec.GetFileSpec().Exists())
225 if (resolved_module_spec.GetArchitecture().IsValid())
227 error = ModuleList::GetSharedModule (resolved_module_spec,
233 if (exe_module_sp && exe_module_sp->GetObjectFile())
235 exe_module_sp.reset();
237 // No valid architecture was specified or the exact ARM slice wasn't
238 // found so ask the platform for the architectures that we should be
239 // using (in the correct order) and see if we can find a match that way
240 StreamString arch_names;
241 ArchSpec platform_arch;
242 for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, resolved_module_spec.GetArchitecture()); ++idx)
244 // Only match x86 with x86 and x86_64 with x86_64...
245 if (!module_spec.GetArchitecture().IsValid() || module_spec.GetArchitecture().GetCore() == resolved_module_spec.GetArchitecture().GetCore())
247 error = ModuleList::GetSharedModule (resolved_module_spec,
252 // Did we find an executable using one of the
255 if (exe_module_sp && exe_module_sp->GetObjectFile())
258 error.SetErrorToGenericError();
262 arch_names.PutCString (", ");
263 arch_names.PutCString (platform_arch.GetArchitectureName());
267 if (error.Fail() || !exe_module_sp)
269 if (resolved_module_spec.GetFileSpec().Readable())
271 error.SetErrorStringWithFormat ("'%s' doesn't contain any '%s' platform architectures: %s",
272 resolved_module_spec.GetFileSpec().GetPath().c_str(),
273 GetPluginName().GetCString(),
274 arch_names.GetString().c_str());
278 error.SetErrorStringWithFormat("'%s' is not readable", resolved_module_spec.GetFileSpec().GetPath().c_str());
284 error.SetErrorStringWithFormat ("'%s' does not exist",
285 module_spec.GetFileSpec().GetPath().c_str());
291 static FileSpec::EnumerateDirectoryResult
292 EnumerateDirectoryCallback (void *baton, FileSpec::FileType file_type, const FileSpec &file_spec)
294 if (file_type == FileSpec::eFileTypeDirectory)
296 const char *filename = file_spec.GetFilename().GetCString();
297 if (filename && strncmp(filename, "iPhoneSimulator", strlen ("iPhoneSimulator")) == 0)
299 ::snprintf ((char *)baton, PATH_MAX, "%s", filename);
300 return FileSpec::eEnumerateDirectoryResultQuit;
303 return FileSpec::eEnumerateDirectoryResultNext;
309 PlatformiOSSimulator::GetSDKDirectoryAsCString()
311 Mutex::Locker locker (m_mutex);
312 if (m_sdk_directory.empty())
314 const char *developer_dir = GetDeveloperDirectory();
317 char sdks_directory[PATH_MAX];
318 char sdk_dirname[PATH_MAX];
319 sdk_dirname[0] = '\0';
320 snprintf (sdks_directory,
321 sizeof(sdks_directory),
322 "%s/Platforms/iPhoneSimulator.platform/Developer/SDKs",
324 FileSpec simulator_sdk_spec;
325 bool find_directories = true;
326 bool find_files = false;
327 bool find_other = false;
328 FileSpec::EnumerateDirectory (sdks_directory,
332 EnumerateDirectoryCallback,
337 m_sdk_directory = sdks_directory;
338 m_sdk_directory.append (1, '/');
339 m_sdk_directory.append (sdk_dirname);
340 return m_sdk_directory.c_str();
343 // Assign a single NULL character so we know we tried to find the device
344 // support directory and we don't keep trying to find it over and over.
345 m_sdk_directory.assign (1, '\0');
348 // We should have put a single NULL character into m_sdk_directory
349 // or it should have a valid path if the code gets here
350 assert (m_sdk_directory.empty() == false);
351 if (m_sdk_directory[0])
352 return m_sdk_directory.c_str();
357 PlatformiOSSimulator::GetSymbolFile (const FileSpec &platform_file,
358 const UUID *uuid_ptr,
359 FileSpec &local_file)
362 char platform_file_path[PATH_MAX];
363 if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path)))
365 char resolved_path[PATH_MAX];
367 const char * sdk_dir = GetSDKDirectoryAsCString();
370 ::snprintf (resolved_path,
371 sizeof(resolved_path),
376 // First try in the SDK and see if the file is in there
377 local_file.SetFile(resolved_path, true);
378 if (local_file.Exists())
381 // Else fall back to the actual path itself
382 local_file.SetFile(platform_file_path, true);
383 if (local_file.Exists())
387 error.SetErrorStringWithFormat ("unable to locate a platform file for '%s' in platform '%s'",
389 GetPluginName().GetCString());
393 error.SetErrorString ("invalid platform file argument");
399 PlatformiOSSimulator::GetSharedModule (const ModuleSpec &module_spec,
402 const FileSpecList *module_search_paths_ptr,
403 ModuleSP *old_module_sp_ptr,
404 bool *did_create_ptr)
406 // For iOS, the SDK files are all cached locally on the host
407 // system. So first we ask for the file in the cached SDK,
408 // then we attempt to get a shared module for the right architecture
409 // with the right UUID.
411 ModuleSpec platform_module_spec (module_spec);
412 const FileSpec &platform_file = module_spec.GetFileSpec();
413 error = GetSymbolFile (platform_file, module_spec.GetUUIDPtr(), platform_module_spec.GetFileSpec());
416 error = ResolveExecutable (platform_module_spec, module_sp, module_search_paths_ptr);
420 const bool always_create = false;
421 error = ModuleList::GetSharedModule (module_spec,
423 module_search_paths_ptr,
430 module_sp->SetPlatformFileSpec(platform_file);
437 PlatformiOSSimulator::FindProcesses (const ProcessInstanceInfoMatch &match_info,
438 ProcessInstanceInfoList &process_infos)
440 ProcessInstanceInfoList all_osx_process_infos;
441 // First we get all OSX processes
442 const uint32_t n = Host::FindProcesses (match_info, all_osx_process_infos);
444 // Now we filter them down to only the iOS triples
445 for (uint32_t i=0; i<n; ++i)
447 const ProcessInstanceInfo &proc_info = all_osx_process_infos.GetProcessInfoAtIndex(i);
448 if (proc_info.GetArchitecture().GetTriple().getOS() == llvm::Triple::IOS) {
449 process_infos.Append(proc_info);
452 return process_infos.GetSize();
456 PlatformiOSSimulator::GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch)
458 static const ArchSpec platform_arch(HostInfo::GetArchitecture(HostInfo::eArchKindDefault));
459 static const ArchSpec platform_arch64(HostInfo::GetArchitecture(HostInfo::eArchKind64));
463 arch = platform_arch;
466 arch.GetTriple().setOS (llvm::Triple::IOS);
472 if (platform_arch.IsExactMatch(platform_arch64))
474 // This macosx platform supports both 32 and 64 bit.
477 // 32/64: return "x86_64-apple-macosx" for architecture 1
478 arch = platform_arch64;
481 else if (idx == 2 || idx == 3)
483 arch = HostInfo::GetArchitecture(HostInfo::eArchKind32);
487 arch.GetTriple().setOS (llvm::Triple::IOS);
488 // 32/64: return "i386-apple-ios" for architecture 2
489 // 32/64: return "i386-apple-macosx" for architecture 3
496 // This macosx platform supports only 32 bit, so return the *-apple-macosx version
497 arch = platform_arch;