PlatformiOSSimulator.cpp revision b1db658333cdebca31a128be95e926d80c3c7796
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 const llvm::Triple::OSType os = triple.getOS(); 75 const llvm::Triple::VendorType vendor = triple.getVendor(); 76 if (os == llvm::Triple::Darwin && vendor == llvm::Triple::Apple) 77 create = true; 78 } 79 break; 80 default: 81 break; 82 } 83 } 84 if (create) 85 return new PlatformiOSSimulator (); 86 return NULL; 87} 88 89 90const char * 91PlatformiOSSimulator::GetPluginNameStatic () 92{ 93 return "PlatformiOSSimulator"; 94} 95 96const char * 97PlatformiOSSimulator::GetShortPluginNameStatic() 98{ 99 return "ios-simulator"; 100} 101 102const char * 103PlatformiOSSimulator::GetDescriptionStatic() 104{ 105 return "iOS simulator platform plug-in."; 106} 107 108 109//------------------------------------------------------------------ 110/// Default Constructor 111//------------------------------------------------------------------ 112PlatformiOSSimulator::PlatformiOSSimulator () : 113 PlatformDarwin (false), 114 m_sdk_directory () 115{ 116} 117 118//------------------------------------------------------------------ 119/// Destructor. 120/// 121/// The destructor is virtual since this class is designed to be 122/// inherited from by the plug-in instance. 123//------------------------------------------------------------------ 124PlatformiOSSimulator::~PlatformiOSSimulator() 125{ 126} 127 128 129void 130PlatformiOSSimulator::GetStatus (Stream &strm) 131{ 132 Platform::GetStatus (strm); 133 const char *sdk_directory = GetSDKDirectory(); 134 if (sdk_directory) 135 strm.Printf (" SDK Path: \"%s\"\n", sdk_directory); 136 else 137 strm.PutCString (" SDK Path: error: unable to locate SDK\n"); 138} 139 140 141Error 142PlatformiOSSimulator::ResolveExecutable (const FileSpec &exe_file, 143 const ArchSpec &exe_arch, 144 lldb::ModuleSP &exe_module_sp, 145 const FileSpecList *module_search_paths_ptr) 146{ 147 Error error; 148 // Nothing special to do here, just use the actual file and architecture 149 150 FileSpec resolved_exe_file (exe_file); 151 152 // If we have "ls" as the exe_file, resolve the executable loation based on 153 // the current path variables 154 // TODO: resolve bare executables in the Platform SDK 155// if (!resolved_exe_file.Exists()) 156// resolved_exe_file.ResolveExecutableLocation (); 157 158 // Resolve any executable within a bundle on MacOSX 159 // TODO: verify that this handles shallow bundles, if not then implement one ourselves 160 Host::ResolveExecutableInBundle (resolved_exe_file); 161 162 if (resolved_exe_file.Exists()) 163 { 164 ModuleSpec module_spec(resolved_exe_file, exe_arch); 165 if (exe_arch.IsValid()) 166 { 167 error = ModuleList::GetSharedModule (module_spec, 168 exe_module_sp, 169 NULL, 170 NULL, 171 NULL); 172 173 if (exe_module_sp->GetObjectFile()) 174 return error; 175 exe_module_sp.reset(); 176 } 177 // No valid architecture was specified or the exact ARM slice wasn't 178 // found so ask the platform for the architectures that we should be 179 // using (in the correct order) and see if we can find a match that way 180 StreamString arch_names; 181 ArchSpec platform_arch; 182 for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, module_spec.GetArchitecture()); ++idx) 183 { 184 185 error = ModuleList::GetSharedModule (module_spec, 186 exe_module_sp, 187 NULL, 188 NULL, 189 NULL); 190 // Did we find an executable using one of the 191 if (error.Success()) 192 { 193 if (exe_module_sp && exe_module_sp->GetObjectFile()) 194 break; 195 else 196 error.SetErrorToGenericError(); 197 } 198 199 if (idx > 0) 200 arch_names.PutCString (", "); 201 arch_names.PutCString (platform_arch.GetArchitectureName()); 202 } 203 204 if (error.Fail() || !exe_module_sp) 205 { 206 error.SetErrorStringWithFormat ("'%s%s%s' doesn't contain any '%s' platform architectures: %s", 207 exe_file.GetDirectory().AsCString(""), 208 exe_file.GetDirectory() ? "/" : "", 209 exe_file.GetFilename().AsCString(""), 210 GetShortPluginName(), 211 arch_names.GetString().c_str()); 212 } 213 } 214 else 215 { 216 error.SetErrorStringWithFormat ("'%s%s%s' does not exist", 217 exe_file.GetDirectory().AsCString(""), 218 exe_file.GetDirectory() ? "/" : "", 219 exe_file.GetFilename().AsCString("")); 220 } 221 222 return error; 223} 224 225static FileSpec::EnumerateDirectoryResult 226EnumerateDirectoryCallback (void *baton, FileSpec::FileType file_type, const FileSpec &file_spec) 227{ 228 if (file_type == FileSpec::eFileTypeDirectory) 229 { 230 const char *filename = file_spec.GetFilename().GetCString(); 231 if (filename && strncmp(filename, "iPhoneSimulator", strlen ("iPhoneSimulator")) == 0) 232 { 233 ::snprintf ((char *)baton, PATH_MAX, "%s", filename); 234 return FileSpec::eEnumerateDirectoryResultQuit; 235 } 236 } 237 return FileSpec::eEnumerateDirectoryResultNext; 238} 239 240 241 242const char * 243PlatformiOSSimulator::GetSDKDirectory() 244{ 245 if (m_sdk_directory.empty()) 246 { 247 const char *developer_dir = GetDeveloperDirectory(); 248 if (developer_dir) 249 { 250 char sdks_directory[PATH_MAX]; 251 char sdk_dirname[PATH_MAX]; 252 sdk_dirname[0] = '\0'; 253 snprintf (sdks_directory, 254 sizeof(sdks_directory), 255 "%s/Platforms/iPhoneSimulator.platform/Developer/SDKs", 256 developer_dir); 257 FileSpec simulator_sdk_spec; 258 bool find_directories = true; 259 bool find_files = false; 260 bool find_other = false; 261 FileSpec::EnumerateDirectory (sdks_directory, 262 find_directories, 263 find_files, 264 find_other, 265 EnumerateDirectoryCallback, 266 sdk_dirname); 267 268 if (sdk_dirname[0]) 269 { 270 m_sdk_directory = sdks_directory; 271 m_sdk_directory.append (1, '/'); 272 m_sdk_directory.append (sdk_dirname); 273 return m_sdk_directory.c_str(); 274 } 275 } 276 // Assign a single NULL character so we know we tried to find the device 277 // support directory and we don't keep trying to find it over and over. 278 m_sdk_directory.assign (1, '\0'); 279 } 280 281 // We should have put a single NULL character into m_sdk_directory 282 // or it should have a valid path if the code gets here 283 assert (m_sdk_directory.empty() == false); 284 if (m_sdk_directory[0]) 285 return m_sdk_directory.c_str(); 286 return NULL; 287} 288 289Error 290PlatformiOSSimulator::GetFile (const FileSpec &platform_file, 291 const UUID *uuid_ptr, 292 FileSpec &local_file) 293{ 294 Error error; 295 char platform_file_path[PATH_MAX]; 296 if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) 297 { 298 char resolved_path[PATH_MAX]; 299 300 const char * sdk_dir = GetSDKDirectory(); 301 if (sdk_dir) 302 { 303 ::snprintf (resolved_path, 304 sizeof(resolved_path), 305 "%s/%s", 306 sdk_dir, 307 platform_file_path); 308 309 // First try in the SDK and see if the file is in there 310 local_file.SetFile(resolved_path, true); 311 if (local_file.Exists()) 312 return error; 313 314 // Else fall back to the actual path itself 315 local_file.SetFile(platform_file_path, true); 316 if (local_file.Exists()) 317 return error; 318 319 } 320 error.SetErrorStringWithFormat ("unable to locate a platform file for '%s' in platform '%s'", 321 platform_file_path, 322 GetPluginName()); 323 } 324 else 325 { 326 error.SetErrorString ("invalid platform file argument"); 327 } 328 return error; 329} 330 331Error 332PlatformiOSSimulator::GetSharedModule (const ModuleSpec &module_spec, 333 ModuleSP &module_sp, 334 const FileSpecList *module_search_paths_ptr, 335 ModuleSP *old_module_sp_ptr, 336 bool *did_create_ptr) 337{ 338 // For iOS, the SDK files are all cached locally on the host 339 // system. So first we ask for the file in the cached SDK, 340 // then we attempt to get a shared module for the right architecture 341 // with the right UUID. 342 Error error; 343 FileSpec local_file; 344 const FileSpec &platform_file = module_spec.GetFileSpec(); 345 error = GetFile (platform_file, module_spec.GetUUIDPtr(), local_file); 346 if (error.Success()) 347 { 348 error = ResolveExecutable (local_file, module_spec.GetArchitecture(), module_sp, module_search_paths_ptr); 349 } 350 else 351 { 352 const bool always_create = false; 353 error = ModuleList::GetSharedModule (module_spec, 354 module_sp, 355 module_search_paths_ptr, 356 old_module_sp_ptr, 357 did_create_ptr, 358 always_create); 359 360 } 361 if (module_sp) 362 module_sp->SetPlatformFileSpec(platform_file); 363 364 return error; 365} 366 367 368uint32_t 369PlatformiOSSimulator::FindProcesses (const ProcessInstanceInfoMatch &match_info, 370 ProcessInstanceInfoList &process_infos) 371{ 372 // TODO: if connected, send a packet to get the remote process infos by name 373 process_infos.Clear(); 374 return 0; 375} 376 377bool 378PlatformiOSSimulator::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info) 379{ 380 // TODO: if connected, send a packet to get the remote process info 381 process_info.Clear(); 382 return false; 383} 384 385bool 386PlatformiOSSimulator::GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch) 387{ 388 if (idx == 0) 389 { 390 // All iOS simulator binaries are currently i386 391 arch = Host::GetArchitecture (Host::eSystemDefaultArchitecture32); 392 return arch.IsValid(); 393 } 394 return false; 395} 396