PlatformiOSSimulator.cpp revision b170aee2daacc83e3d71c3e3acc9d56c89893a7b
1//===-- PlatformiOSSimulator.cpp -----------------------------------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10#include "PlatformiOSSimulator.h" 11 12// C Includes 13// C++ Includes 14// Other libraries and framework includes 15// Project includes 16#include "lldb/Breakpoint/BreakpointLocation.h" 17#include "lldb/Core/ArchSpec.h" 18#include "lldb/Core/Error.h" 19#include "lldb/Core/Module.h" 20#include "lldb/Core/ModuleList.h" 21#include "lldb/Core/PluginManager.h" 22#include "lldb/Core/StreamString.h" 23#include "lldb/Host/FileSpec.h" 24#include "lldb/Host/Host.h" 25#include "lldb/Target/Process.h" 26#include "lldb/Target/Target.h" 27 28using namespace lldb; 29using namespace lldb_private; 30 31//------------------------------------------------------------------ 32// Static Variables 33//------------------------------------------------------------------ 34static uint32_t g_initialize_count = 0; 35 36//------------------------------------------------------------------ 37// Static Functions 38//------------------------------------------------------------------ 39void 40PlatformiOSSimulator::Initialize () 41{ 42 if (g_initialize_count++ == 0) 43 { 44 PluginManager::RegisterPlugin (PlatformiOSSimulator::GetShortPluginNameStatic(), 45 PlatformiOSSimulator::GetDescriptionStatic(), 46 PlatformiOSSimulator::CreateInstance); 47 } 48} 49 50void 51PlatformiOSSimulator::Terminate () 52{ 53 if (g_initialize_count > 0) 54 { 55 if (--g_initialize_count == 0) 56 { 57 PluginManager::UnregisterPlugin (PlatformiOSSimulator::CreateInstance); 58 } 59 } 60} 61 62Platform* 63PlatformiOSSimulator::CreateInstance (bool force, const ArchSpec *arch) 64{ 65 bool create = force; 66 if (create == false && arch && arch->IsValid()) 67 { 68 switch (arch->GetMachine()) 69 { 70 // Currently simulator is i386 only... 71 case llvm::Triple::x86: 72 { 73 const llvm::Triple &triple = arch->GetTriple(); 74 switch (triple.getVendor()) 75 { 76 case llvm::Triple::Apple: 77 create = true; 78 break; 79 80 case llvm::Triple::UnknownArch: 81 create = !arch->TripleVendorWasSpecified(); 82 break; 83 84 default: 85 break; 86 } 87 88 if (create) 89 { 90 switch (triple.getOS()) 91 { 92 case llvm::Triple::Darwin: // Deprecated, but still support Darwin for historical reasons 93 case llvm::Triple::MacOSX: 94 case llvm::Triple::IOS: // IOS is not used for simulator triples, but accept it just in case 95 break; 96 97 case llvm::Triple::UnknownOS: 98 create = !arch->TripleOSWasSpecified(); 99 break; 100 101 default: 102 create = false; 103 break; 104 } 105 } 106 } 107 break; 108 default: 109 break; 110 } 111 } 112 if (create) 113 return new PlatformiOSSimulator (); 114 return NULL; 115} 116 117 118const char * 119PlatformiOSSimulator::GetPluginNameStatic () 120{ 121 return "PlatformiOSSimulator"; 122} 123 124const char * 125PlatformiOSSimulator::GetShortPluginNameStatic() 126{ 127 return "ios-simulator"; 128} 129 130const char * 131PlatformiOSSimulator::GetDescriptionStatic() 132{ 133 return "iOS simulator platform plug-in."; 134} 135 136 137//------------------------------------------------------------------ 138/// Default Constructor 139//------------------------------------------------------------------ 140PlatformiOSSimulator::PlatformiOSSimulator () : 141 PlatformDarwin (false), 142 m_sdk_directory () 143{ 144} 145 146//------------------------------------------------------------------ 147/// Destructor. 148/// 149/// The destructor is virtual since this class is designed to be 150/// inherited from by the plug-in instance. 151//------------------------------------------------------------------ 152PlatformiOSSimulator::~PlatformiOSSimulator() 153{ 154} 155 156 157void 158PlatformiOSSimulator::GetStatus (Stream &strm) 159{ 160 Platform::GetStatus (strm); 161 const char *sdk_directory = GetSDKDirectory(); 162 if (sdk_directory) 163 strm.Printf (" SDK Path: \"%s\"\n", sdk_directory); 164 else 165 strm.PutCString (" SDK Path: error: unable to locate SDK\n"); 166} 167 168 169Error 170PlatformiOSSimulator::ResolveExecutable (const FileSpec &exe_file, 171 const ArchSpec &exe_arch, 172 lldb::ModuleSP &exe_module_sp, 173 const FileSpecList *module_search_paths_ptr) 174{ 175 Error error; 176 // Nothing special to do here, just use the actual file and architecture 177 178 FileSpec resolved_exe_file (exe_file); 179 180 // If we have "ls" as the exe_file, resolve the executable loation based on 181 // the current path variables 182 // TODO: resolve bare executables in the Platform SDK 183// if (!resolved_exe_file.Exists()) 184// resolved_exe_file.ResolveExecutableLocation (); 185 186 // Resolve any executable within a bundle on MacOSX 187 // TODO: verify that this handles shallow bundles, if not then implement one ourselves 188 Host::ResolveExecutableInBundle (resolved_exe_file); 189 190 if (resolved_exe_file.Exists()) 191 { 192 ModuleSpec module_spec(resolved_exe_file, exe_arch); 193 if (exe_arch.IsValid()) 194 { 195 error = ModuleList::GetSharedModule (module_spec, 196 exe_module_sp, 197 NULL, 198 NULL, 199 NULL); 200 201 if (exe_module_sp->GetObjectFile()) 202 return error; 203 exe_module_sp.reset(); 204 } 205 // No valid architecture was specified or the exact ARM slice wasn't 206 // found so ask the platform for the architectures that we should be 207 // using (in the correct order) and see if we can find a match that way 208 StreamString arch_names; 209 ArchSpec platform_arch; 210 for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, module_spec.GetArchitecture()); ++idx) 211 { 212 213 error = ModuleList::GetSharedModule (module_spec, 214 exe_module_sp, 215 NULL, 216 NULL, 217 NULL); 218 // Did we find an executable using one of the 219 if (error.Success()) 220 { 221 if (exe_module_sp && exe_module_sp->GetObjectFile()) 222 break; 223 else 224 error.SetErrorToGenericError(); 225 } 226 227 if (idx > 0) 228 arch_names.PutCString (", "); 229 arch_names.PutCString (platform_arch.GetArchitectureName()); 230 } 231 232 if (error.Fail() || !exe_module_sp) 233 { 234 error.SetErrorStringWithFormat ("'%s%s%s' doesn't contain any '%s' platform architectures: %s", 235 exe_file.GetDirectory().AsCString(""), 236 exe_file.GetDirectory() ? "/" : "", 237 exe_file.GetFilename().AsCString(""), 238 GetShortPluginName(), 239 arch_names.GetString().c_str()); 240 } 241 } 242 else 243 { 244 error.SetErrorStringWithFormat ("'%s%s%s' does not exist", 245 exe_file.GetDirectory().AsCString(""), 246 exe_file.GetDirectory() ? "/" : "", 247 exe_file.GetFilename().AsCString("")); 248 } 249 250 return error; 251} 252 253static FileSpec::EnumerateDirectoryResult 254EnumerateDirectoryCallback (void *baton, FileSpec::FileType file_type, const FileSpec &file_spec) 255{ 256 if (file_type == FileSpec::eFileTypeDirectory) 257 { 258 const char *filename = file_spec.GetFilename().GetCString(); 259 if (filename && strncmp(filename, "iPhoneSimulator", strlen ("iPhoneSimulator")) == 0) 260 { 261 ::snprintf ((char *)baton, PATH_MAX, "%s", filename); 262 return FileSpec::eEnumerateDirectoryResultQuit; 263 } 264 } 265 return FileSpec::eEnumerateDirectoryResultNext; 266} 267 268 269 270const char * 271PlatformiOSSimulator::GetSDKDirectory() 272{ 273 if (m_sdk_directory.empty()) 274 { 275 const char *developer_dir = GetDeveloperDirectory(); 276 if (developer_dir) 277 { 278 char sdks_directory[PATH_MAX]; 279 char sdk_dirname[PATH_MAX]; 280 sdk_dirname[0] = '\0'; 281 snprintf (sdks_directory, 282 sizeof(sdks_directory), 283 "%s/Platforms/iPhoneSimulator.platform/Developer/SDKs", 284 developer_dir); 285 FileSpec simulator_sdk_spec; 286 bool find_directories = true; 287 bool find_files = false; 288 bool find_other = false; 289 FileSpec::EnumerateDirectory (sdks_directory, 290 find_directories, 291 find_files, 292 find_other, 293 EnumerateDirectoryCallback, 294 sdk_dirname); 295 296 if (sdk_dirname[0]) 297 { 298 m_sdk_directory = sdks_directory; 299 m_sdk_directory.append (1, '/'); 300 m_sdk_directory.append (sdk_dirname); 301 return m_sdk_directory.c_str(); 302 } 303 } 304 // Assign a single NULL character so we know we tried to find the device 305 // support directory and we don't keep trying to find it over and over. 306 m_sdk_directory.assign (1, '\0'); 307 } 308 309 // We should have put a single NULL character into m_sdk_directory 310 // or it should have a valid path if the code gets here 311 assert (m_sdk_directory.empty() == false); 312 if (m_sdk_directory[0]) 313 return m_sdk_directory.c_str(); 314 return NULL; 315} 316 317Error 318PlatformiOSSimulator::GetFile (const FileSpec &platform_file, 319 const UUID *uuid_ptr, 320 FileSpec &local_file) 321{ 322 Error error; 323 char platform_file_path[PATH_MAX]; 324 if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) 325 { 326 char resolved_path[PATH_MAX]; 327 328 const char * sdk_dir = GetSDKDirectory(); 329 if (sdk_dir) 330 { 331 ::snprintf (resolved_path, 332 sizeof(resolved_path), 333 "%s/%s", 334 sdk_dir, 335 platform_file_path); 336 337 // First try in the SDK and see if the file is in there 338 local_file.SetFile(resolved_path, true); 339 if (local_file.Exists()) 340 return error; 341 342 // Else fall back to the actual path itself 343 local_file.SetFile(platform_file_path, true); 344 if (local_file.Exists()) 345 return error; 346 347 } 348 error.SetErrorStringWithFormat ("unable to locate a platform file for '%s' in platform '%s'", 349 platform_file_path, 350 GetPluginName()); 351 } 352 else 353 { 354 error.SetErrorString ("invalid platform file argument"); 355 } 356 return error; 357} 358 359Error 360PlatformiOSSimulator::GetSharedModule (const ModuleSpec &module_spec, 361 ModuleSP &module_sp, 362 const FileSpecList *module_search_paths_ptr, 363 ModuleSP *old_module_sp_ptr, 364 bool *did_create_ptr) 365{ 366 // For iOS, the SDK files are all cached locally on the host 367 // system. So first we ask for the file in the cached SDK, 368 // then we attempt to get a shared module for the right architecture 369 // with the right UUID. 370 Error error; 371 FileSpec local_file; 372 const FileSpec &platform_file = module_spec.GetFileSpec(); 373 error = GetFile (platform_file, module_spec.GetUUIDPtr(), local_file); 374 if (error.Success()) 375 { 376 error = ResolveExecutable (local_file, module_spec.GetArchitecture(), module_sp, module_search_paths_ptr); 377 } 378 else 379 { 380 const bool always_create = false; 381 error = ModuleList::GetSharedModule (module_spec, 382 module_sp, 383 module_search_paths_ptr, 384 old_module_sp_ptr, 385 did_create_ptr, 386 always_create); 387 388 } 389 if (module_sp) 390 module_sp->SetPlatformFileSpec(platform_file); 391 392 return error; 393} 394 395 396uint32_t 397PlatformiOSSimulator::FindProcesses (const ProcessInstanceInfoMatch &match_info, 398 ProcessInstanceInfoList &process_infos) 399{ 400 // TODO: if connected, send a packet to get the remote process infos by name 401 process_infos.Clear(); 402 return 0; 403} 404 405bool 406PlatformiOSSimulator::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info) 407{ 408 // TODO: if connected, send a packet to get the remote process info 409 process_info.Clear(); 410 return false; 411} 412 413bool 414PlatformiOSSimulator::GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch) 415{ 416 if (idx == 0) 417 { 418 // All iOS simulator binaries are currently i386 419 arch = Host::GetArchitecture (Host::eSystemDefaultArchitecture32); 420 return arch.IsValid(); 421 } 422 return false; 423} 424