1 //===-- PlatformRemoteiOS.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 "PlatformRemoteiOS.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/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/Target/Process.h" 28 #include "lldb/Target/Target.h" 29 30 using namespace lldb; 31 using namespace lldb_private; 32 33 PlatformRemoteiOS::SDKDirectoryInfo::SDKDirectoryInfo (const lldb_private::FileSpec &sdk_dir) : 34 directory(sdk_dir), 35 build(), 36 version_major(0), 37 version_minor(0), 38 version_update(0), 39 user_cached(false) 40 { 41 const char *dirname_cstr = sdk_dir.GetFilename().GetCString(); 42 const char *pos = Args::StringToVersion (dirname_cstr, 43 version_major, 44 version_minor, 45 version_update); 46 47 if (pos && pos[0] == ' ' && pos[1] == '(') 48 { 49 const char *build_start = pos + 2; 50 const char *end_paren = strchr (build_start, ')'); 51 if (end_paren && build_start < end_paren) 52 build.SetCStringWithLength(build_start, end_paren - build_start); 53 } 54 } 55 56 //------------------------------------------------------------------ 57 // Static Variables 58 //------------------------------------------------------------------ 59 static uint32_t g_initialize_count = 0; 60 61 //------------------------------------------------------------------ 62 // Static Functions 63 //------------------------------------------------------------------ 64 void 65 PlatformRemoteiOS::Initialize () 66 { 67 PlatformDarwin::Initialize (); 68 69 if (g_initialize_count++ == 0) 70 { 71 PluginManager::RegisterPlugin (PlatformRemoteiOS::GetPluginNameStatic(), 72 PlatformRemoteiOS::GetDescriptionStatic(), 73 PlatformRemoteiOS::CreateInstance); 74 } 75 } 76 77 void 78 PlatformRemoteiOS::Terminate () 79 { 80 if (g_initialize_count > 0) 81 { 82 if (--g_initialize_count == 0) 83 { 84 PluginManager::UnregisterPlugin (PlatformRemoteiOS::CreateInstance); 85 } 86 } 87 88 PlatformDarwin::Terminate (); 89 } 90 91 PlatformSP 92 PlatformRemoteiOS::CreateInstance (bool force, const ArchSpec *arch) 93 { 94 bool create = force; 95 if (create == false && arch && arch->IsValid()) 96 { 97 switch (arch->GetMachine()) 98 { 99 case llvm::Triple::arm: 100 case llvm::Triple::aarch64: 101 case llvm::Triple::thumb: 102 { 103 const llvm::Triple &triple = arch->GetTriple(); 104 llvm::Triple::VendorType vendor = triple.getVendor(); 105 switch (vendor) 106 { 107 case llvm::Triple::Apple: 108 create = true; 109 break; 110 111 #if defined(__APPLE__) 112 // Only accept "unknown" for the vendor if the host is Apple and 113 // it "unknown" wasn't specified (it was just returned because it 114 // was NOT specified) 115 case llvm::Triple::UnknownArch: 116 create = !arch->TripleVendorWasSpecified(); 117 break; 118 119 #endif 120 default: 121 break; 122 } 123 if (create) 124 { 125 switch (triple.getOS()) 126 { 127 case llvm::Triple::Darwin: // Deprecated, but still support Darwin for historical reasons 128 case llvm::Triple::IOS: // This is the right triple value for iOS debugging 129 break; 130 131 #if defined(__APPLE__) 132 // Only accept "unknown" for the OS if the host is Apple and 133 // it "unknown" wasn't specified (it was just returned because it 134 // was NOT specified) 135 case llvm::Triple::UnknownOS: 136 create = !arch->TripleOSWasSpecified(); 137 break; 138 #endif 139 default: 140 create = false; 141 break; 142 } 143 } 144 } 145 break; 146 default: 147 break; 148 } 149 } 150 151 if (create) 152 return lldb::PlatformSP(new PlatformRemoteiOS ()); 153 return lldb::PlatformSP(); 154 } 155 156 157 lldb_private::ConstString 158 PlatformRemoteiOS::GetPluginNameStatic () 159 { 160 static ConstString g_name("remote-ios"); 161 return g_name; 162 } 163 164 const char * 165 PlatformRemoteiOS::GetDescriptionStatic() 166 { 167 return "Remote iOS platform plug-in."; 168 } 169 170 171 //------------------------------------------------------------------ 172 /// Default Constructor 173 //------------------------------------------------------------------ 174 PlatformRemoteiOS::PlatformRemoteiOS () : 175 PlatformDarwin (false), // This is a remote platform 176 m_sdk_directory_infos(), 177 m_device_support_directory(), 178 m_device_support_directory_for_os_version (), 179 m_build_update(), 180 m_last_module_sdk_idx (UINT32_MAX), 181 m_connected_module_sdk_idx (UINT32_MAX) 182 { 183 } 184 185 //------------------------------------------------------------------ 186 /// Destructor. 187 /// 188 /// The destructor is virtual since this class is designed to be 189 /// inherited from by the plug-in instance. 190 //------------------------------------------------------------------ 191 PlatformRemoteiOS::~PlatformRemoteiOS() 192 { 193 } 194 195 196 void 197 PlatformRemoteiOS::GetStatus (Stream &strm) 198 { 199 Platform::GetStatus (strm); 200 const char *sdk_directory = GetDeviceSupportDirectoryForOSVersion(); 201 if (sdk_directory) 202 strm.Printf (" SDK Path: \"%s\"\n", sdk_directory); 203 else 204 strm.PutCString (" SDK Path: error: unable to locate SDK\n"); 205 206 const uint32_t num_sdk_infos = m_sdk_directory_infos.size(); 207 for (uint32_t i=0; i<num_sdk_infos; ++i) 208 { 209 const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i]; 210 strm.Printf (" SDK Roots: [%2u] \"%s\"\n", 211 i, 212 sdk_dir_info.directory.GetPath().c_str()); 213 } 214 } 215 216 217 Error 218 PlatformRemoteiOS::ResolveExecutable (const ModuleSpec &ms, 219 lldb::ModuleSP &exe_module_sp, 220 const FileSpecList *module_search_paths_ptr) 221 { 222 Error error; 223 // Nothing special to do here, just use the actual file and architecture 224 225 ModuleSpec resolved_module_spec(ms); 226 227 // Resolve any executable within a bundle on MacOSX 228 // TODO: verify that this handles shallow bundles, if not then implement one ourselves 229 Host::ResolveExecutableInBundle (resolved_module_spec.GetFileSpec()); 230 231 if (resolved_module_spec.GetFileSpec().Exists()) 232 { 233 if (resolved_module_spec.GetArchitecture().IsValid() || resolved_module_spec.GetUUID().IsValid()) 234 { 235 error = ModuleList::GetSharedModule (resolved_module_spec, 236 exe_module_sp, 237 NULL, 238 NULL, 239 NULL); 240 241 if (exe_module_sp && exe_module_sp->GetObjectFile()) 242 return error; 243 exe_module_sp.reset(); 244 } 245 // No valid architecture was specified or the exact ARM slice wasn't 246 // found so ask the platform for the architectures that we should be 247 // using (in the correct order) and see if we can find a match that way 248 StreamString arch_names; 249 for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, resolved_module_spec.GetArchitecture()); ++idx) 250 { 251 error = ModuleList::GetSharedModule (resolved_module_spec, 252 exe_module_sp, 253 NULL, 254 NULL, 255 NULL); 256 // Did we find an executable using one of the 257 if (error.Success()) 258 { 259 if (exe_module_sp && exe_module_sp->GetObjectFile()) 260 break; 261 else 262 error.SetErrorToGenericError(); 263 } 264 265 if (idx > 0) 266 arch_names.PutCString (", "); 267 arch_names.PutCString (resolved_module_spec.GetArchitecture().GetArchitectureName()); 268 } 269 270 if (error.Fail() || !exe_module_sp) 271 { 272 if (resolved_module_spec.GetFileSpec().Readable()) 273 { 274 error.SetErrorStringWithFormat ("'%s' doesn't contain any '%s' platform architectures: %s", 275 resolved_module_spec.GetFileSpec().GetPath().c_str(), 276 GetPluginName().GetCString(), 277 arch_names.GetString().c_str()); 278 } 279 else 280 { 281 error.SetErrorStringWithFormat("'%s' is not readable", resolved_module_spec.GetFileSpec().GetPath().c_str()); 282 } 283 } 284 } 285 else 286 { 287 error.SetErrorStringWithFormat ("'%s' does not exist", 288 resolved_module_spec.GetFileSpec().GetPath().c_str()); 289 } 290 291 return error; 292 } 293 294 FileSpec::EnumerateDirectoryResult 295 PlatformRemoteiOS::GetContainedFilesIntoVectorOfStringsCallback (void *baton, 296 FileSpec::FileType file_type, 297 const FileSpec &file_spec) 298 { 299 ((PlatformRemoteiOS::SDKDirectoryInfoCollection *)baton)->push_back(PlatformRemoteiOS::SDKDirectoryInfo(file_spec)); 300 return FileSpec::eEnumerateDirectoryResultNext; 301 } 302 303 bool 304 PlatformRemoteiOS::UpdateSDKDirectoryInfosIfNeeded() 305 { 306 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); 307 if (m_sdk_directory_infos.empty()) 308 { 309 // A --sysroot option was supplied - add it to our list of SDKs to check 310 if (m_sdk_sysroot) 311 { 312 FileSpec sdk_sysroot_fspec(m_sdk_sysroot.GetCString(), true); 313 const SDKDirectoryInfo sdk_sysroot_directory_info(sdk_sysroot_fspec); 314 m_sdk_directory_infos.push_back(sdk_sysroot_directory_info); 315 if (log) 316 { 317 log->Printf ("PlatformRemoteiOS::UpdateSDKDirectoryInfosIfNeeded added --sysroot SDK directory %s", m_sdk_sysroot.GetCString()); 318 } 319 return true; 320 } 321 const char *device_support_dir = GetDeviceSupportDirectory(); 322 if (log) 323 { 324 log->Printf ("PlatformRemoteiOS::UpdateSDKDirectoryInfosIfNeeded Got DeviceSupport directory %s", device_support_dir); 325 } 326 if (device_support_dir) 327 { 328 const bool find_directories = true; 329 const bool find_files = false; 330 const bool find_other = false; 331 332 SDKDirectoryInfoCollection builtin_sdk_directory_infos; 333 FileSpec::EnumerateDirectory (m_device_support_directory.c_str(), 334 find_directories, 335 find_files, 336 find_other, 337 GetContainedFilesIntoVectorOfStringsCallback, 338 &builtin_sdk_directory_infos); 339 340 // Only add SDK directories that have symbols in them, some SDKs only contain 341 // developer disk images and no symbols, so they aren't useful to us. 342 FileSpec sdk_symbols_symlink_fspec; 343 for (const auto &sdk_directory_info : builtin_sdk_directory_infos) 344 { 345 sdk_symbols_symlink_fspec = sdk_directory_info.directory; 346 sdk_symbols_symlink_fspec.AppendPathComponent("Symbols"); 347 if (sdk_symbols_symlink_fspec.Exists()) 348 { 349 m_sdk_directory_infos.push_back(sdk_directory_info); 350 if (log) 351 { 352 log->Printf ("PlatformRemoteiOS::UpdateSDKDirectoryInfosIfNeeded added builtin SDK directory %s", sdk_symbols_symlink_fspec.GetPath().c_str()); 353 } 354 } 355 } 356 357 const uint32_t num_installed = m_sdk_directory_infos.size(); 358 FileSpec local_sdk_cache("~/Library/Developer/Xcode/iOS DeviceSupport", true); 359 if (local_sdk_cache.Exists()) 360 { 361 if (log) 362 { 363 log->Printf ("PlatformRemoteiOS::UpdateSDKDirectoryInfosIfNeeded searching %s for additional SDKs", local_sdk_cache.GetPath().c_str()); 364 } 365 char path[PATH_MAX]; 366 if (local_sdk_cache.GetPath(path, sizeof(path))) 367 { 368 FileSpec::EnumerateDirectory (path, 369 find_directories, 370 find_files, 371 find_other, 372 GetContainedFilesIntoVectorOfStringsCallback, 373 &m_sdk_directory_infos); 374 const uint32_t num_sdk_infos = m_sdk_directory_infos.size(); 375 // First try for an exact match of major, minor and update 376 for (uint32_t i=num_installed; i<num_sdk_infos; ++i) 377 { 378 m_sdk_directory_infos[i].user_cached = true; 379 if (log) 380 { 381 log->Printf ("PlatformRemoteiOS::UpdateSDKDirectoryInfosIfNeeded user SDK directory %s", m_sdk_directory_infos[i].directory.GetPath().c_str()); 382 } 383 } 384 } 385 } 386 } 387 } 388 return !m_sdk_directory_infos.empty(); 389 } 390 391 const PlatformRemoteiOS::SDKDirectoryInfo * 392 PlatformRemoteiOS::GetSDKDirectoryForCurrentOSVersion () 393 { 394 uint32_t i; 395 if (UpdateSDKDirectoryInfosIfNeeded()) 396 { 397 const uint32_t num_sdk_infos = m_sdk_directory_infos.size(); 398 399 // Check to see if the user specified a build string. If they did, then 400 // be sure to match it. 401 std::vector<bool> check_sdk_info(num_sdk_infos, true); 402 ConstString build(m_sdk_build); 403 if (build) 404 { 405 for (i=0; i<num_sdk_infos; ++i) 406 check_sdk_info[i] = m_sdk_directory_infos[i].build == build; 407 } 408 409 // If we are connected we can find the version of the OS the platform 410 // us running on and select the right SDK 411 uint32_t major, minor, update; 412 if (GetOSVersion(major, minor, update)) 413 { 414 if (UpdateSDKDirectoryInfosIfNeeded()) 415 { 416 // First try for an exact match of major, minor and update 417 for (i=0; i<num_sdk_infos; ++i) 418 { 419 if (check_sdk_info[i]) 420 { 421 if (m_sdk_directory_infos[i].version_major == major && 422 m_sdk_directory_infos[i].version_minor == minor && 423 m_sdk_directory_infos[i].version_update == update) 424 { 425 return &m_sdk_directory_infos[i]; 426 } 427 } 428 } 429 // First try for an exact match of major and minor 430 for (i=0; i<num_sdk_infos; ++i) 431 { 432 if (check_sdk_info[i]) 433 { 434 if (m_sdk_directory_infos[i].version_major == major && 435 m_sdk_directory_infos[i].version_minor == minor) 436 { 437 return &m_sdk_directory_infos[i]; 438 } 439 } 440 } 441 // Lastly try to match of major version only.. 442 for (i=0; i<num_sdk_infos; ++i) 443 { 444 if (check_sdk_info[i]) 445 { 446 if (m_sdk_directory_infos[i].version_major == major) 447 { 448 return &m_sdk_directory_infos[i]; 449 } 450 } 451 } 452 } 453 } 454 else if (build) 455 { 456 // No version, just a build number, search for the first one that matches 457 for (i=0; i<num_sdk_infos; ++i) 458 if (check_sdk_info[i]) 459 return &m_sdk_directory_infos[i]; 460 } 461 } 462 return NULL; 463 } 464 465 const PlatformRemoteiOS::SDKDirectoryInfo * 466 PlatformRemoteiOS::GetSDKDirectoryForLatestOSVersion () 467 { 468 const PlatformRemoteiOS::SDKDirectoryInfo *result = NULL; 469 if (UpdateSDKDirectoryInfosIfNeeded()) 470 { 471 const uint32_t num_sdk_infos = m_sdk_directory_infos.size(); 472 // First try for an exact match of major, minor and update 473 for (uint32_t i=0; i<num_sdk_infos; ++i) 474 { 475 const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i]; 476 if (sdk_dir_info.version_major != UINT32_MAX) 477 { 478 if (result == NULL || sdk_dir_info.version_major > result->version_major) 479 { 480 result = &sdk_dir_info; 481 } 482 else if (sdk_dir_info.version_major == result->version_major) 483 { 484 if (sdk_dir_info.version_minor > result->version_minor) 485 { 486 result = &sdk_dir_info; 487 } 488 else if (sdk_dir_info.version_minor == result->version_minor) 489 { 490 if (sdk_dir_info.version_update > result->version_update) 491 { 492 result = &sdk_dir_info; 493 } 494 } 495 } 496 } 497 } 498 } 499 return result; 500 } 501 502 503 504 const char * 505 PlatformRemoteiOS::GetDeviceSupportDirectory() 506 { 507 if (m_device_support_directory.empty()) 508 { 509 const char *device_support_dir = GetDeveloperDirectory(); 510 if (device_support_dir) 511 { 512 m_device_support_directory.assign (device_support_dir); 513 m_device_support_directory.append ("/Platforms/iPhoneOS.platform/DeviceSupport"); 514 } 515 else 516 { 517 // Assign a single NULL character so we know we tried to find the device 518 // support directory and we don't keep trying to find it over and over. 519 m_device_support_directory.assign (1, '\0'); 520 } 521 } 522 // We should have put a single NULL character into m_device_support_directory 523 // or it should have a valid path if the code gets here 524 assert (m_device_support_directory.empty() == false); 525 if (m_device_support_directory[0]) 526 return m_device_support_directory.c_str(); 527 return NULL; 528 } 529 530 531 const char * 532 PlatformRemoteiOS::GetDeviceSupportDirectoryForOSVersion() 533 { 534 if (m_sdk_sysroot) 535 return m_sdk_sysroot.GetCString(); 536 537 if (m_device_support_directory_for_os_version.empty()) 538 { 539 const PlatformRemoteiOS::SDKDirectoryInfo *sdk_dir_info = GetSDKDirectoryForCurrentOSVersion (); 540 if (sdk_dir_info == NULL) 541 sdk_dir_info = GetSDKDirectoryForLatestOSVersion (); 542 if (sdk_dir_info) 543 { 544 char path[PATH_MAX]; 545 if (sdk_dir_info->directory.GetPath(path, sizeof(path))) 546 { 547 m_device_support_directory_for_os_version = path; 548 return m_device_support_directory_for_os_version.c_str(); 549 } 550 } 551 else 552 { 553 // Assign a single NULL character so we know we tried to find the device 554 // support directory and we don't keep trying to find it over and over. 555 m_device_support_directory_for_os_version.assign (1, '\0'); 556 } 557 } 558 // We should have put a single NULL character into m_device_support_directory_for_os_version 559 // or it should have a valid path if the code gets here 560 assert (m_device_support_directory_for_os_version.empty() == false); 561 if (m_device_support_directory_for_os_version[0]) 562 return m_device_support_directory_for_os_version.c_str(); 563 return NULL; 564 } 565 566 uint32_t 567 PlatformRemoteiOS::FindFileInAllSDKs (const char *platform_file_path, 568 FileSpecList &file_list) 569 { 570 if (platform_file_path && platform_file_path[0] && UpdateSDKDirectoryInfosIfNeeded()) 571 { 572 const uint32_t num_sdk_infos = m_sdk_directory_infos.size(); 573 lldb_private::FileSpec local_file; 574 // First try for an exact match of major, minor and update 575 for (uint32_t sdk_idx=0; sdk_idx<num_sdk_infos; ++sdk_idx) 576 { 577 if (GetFileInSDK (platform_file_path, 578 sdk_idx, 579 local_file)) 580 { 581 file_list.Append(local_file); 582 } 583 } 584 } 585 return file_list.GetSize(); 586 } 587 588 bool 589 PlatformRemoteiOS::GetFileInSDK (const char *platform_file_path, 590 uint32_t sdk_idx, 591 lldb_private::FileSpec &local_file) 592 { 593 if (sdk_idx < m_sdk_directory_infos.size()) 594 { 595 char sdkroot_path[PATH_MAX]; 596 const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[sdk_idx]; 597 if (sdk_dir_info.directory.GetPath(sdkroot_path, sizeof(sdkroot_path))) 598 { 599 const bool symbols_dirs_only = true; 600 601 return GetFileInSDKRoot (platform_file_path, 602 sdkroot_path, 603 symbols_dirs_only, 604 local_file); 605 } 606 } 607 return false; 608 } 609 610 611 bool 612 PlatformRemoteiOS::GetFileInSDKRoot (const char *platform_file_path, 613 const char *sdkroot_path, 614 bool symbols_dirs_only, 615 lldb_private::FileSpec &local_file) 616 { 617 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); 618 if (sdkroot_path && sdkroot_path[0] && platform_file_path && platform_file_path[0]) 619 { 620 char resolved_path[PATH_MAX]; 621 622 if (!symbols_dirs_only) 623 { 624 ::snprintf (resolved_path, 625 sizeof(resolved_path), 626 "%s%s", 627 sdkroot_path, 628 platform_file_path); 629 630 local_file.SetFile(resolved_path, true); 631 if (local_file.Exists()) 632 { 633 if (log) 634 { 635 log->Printf ("Found a copy of %s in the SDK dir %s", platform_file_path, sdkroot_path); 636 } 637 return true; 638 } 639 } 640 641 ::snprintf (resolved_path, 642 sizeof(resolved_path), 643 "%s/Symbols.Internal%s", 644 sdkroot_path, 645 platform_file_path); 646 647 local_file.SetFile(resolved_path, true); 648 if (local_file.Exists()) 649 { 650 if (log) 651 { 652 log->Printf ("Found a copy of %s in the SDK dir %s/Symbols.Internal", platform_file_path, sdkroot_path); 653 } 654 return true; 655 } 656 ::snprintf (resolved_path, 657 sizeof(resolved_path), 658 "%s/Symbols%s", 659 sdkroot_path, 660 platform_file_path); 661 662 local_file.SetFile(resolved_path, true); 663 if (local_file.Exists()) 664 { 665 if (log) 666 { 667 log->Printf ("Found a copy of %s in the SDK dir %s/Symbols", platform_file_path, sdkroot_path); 668 } 669 return true; 670 } 671 } 672 return false; 673 } 674 675 676 Error 677 PlatformRemoteiOS::GetSymbolFile (const FileSpec &platform_file, 678 const UUID *uuid_ptr, 679 FileSpec &local_file) 680 { 681 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); 682 Error error; 683 char platform_file_path[PATH_MAX]; 684 if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) 685 { 686 char resolved_path[PATH_MAX]; 687 688 const char * os_version_dir = GetDeviceSupportDirectoryForOSVersion(); 689 if (os_version_dir) 690 { 691 ::snprintf (resolved_path, 692 sizeof(resolved_path), 693 "%s/%s", 694 os_version_dir, 695 platform_file_path); 696 697 local_file.SetFile(resolved_path, true); 698 if (local_file.Exists()) 699 { 700 if (log) 701 { 702 log->Printf ("Found a copy of %s in the DeviceSupport dir %s", platform_file_path, os_version_dir); 703 } 704 return error; 705 } 706 707 ::snprintf (resolved_path, 708 sizeof(resolved_path), 709 "%s/Symbols.Internal/%s", 710 os_version_dir, 711 platform_file_path); 712 713 local_file.SetFile(resolved_path, true); 714 if (local_file.Exists()) 715 { 716 if (log) 717 { 718 log->Printf ("Found a copy of %s in the DeviceSupport dir %s/Symbols.Internal", platform_file_path, os_version_dir); 719 } 720 return error; 721 } 722 ::snprintf (resolved_path, 723 sizeof(resolved_path), 724 "%s/Symbols/%s", 725 os_version_dir, 726 platform_file_path); 727 728 local_file.SetFile(resolved_path, true); 729 if (local_file.Exists()) 730 { 731 if (log) 732 { 733 log->Printf ("Found a copy of %s in the DeviceSupport dir %s/Symbols", platform_file_path, os_version_dir); 734 } 735 return error; 736 } 737 738 } 739 local_file = platform_file; 740 if (local_file.Exists()) 741 return error; 742 743 error.SetErrorStringWithFormat ("unable to locate a platform file for '%s' in platform '%s'", 744 platform_file_path, 745 GetPluginName().GetCString()); 746 } 747 else 748 { 749 error.SetErrorString ("invalid platform file argument"); 750 } 751 return error; 752 } 753 754 Error 755 PlatformRemoteiOS::GetSharedModule (const ModuleSpec &module_spec, 756 Process* process, 757 ModuleSP &module_sp, 758 const FileSpecList *module_search_paths_ptr, 759 ModuleSP *old_module_sp_ptr, 760 bool *did_create_ptr) 761 { 762 // For iOS, the SDK files are all cached locally on the host 763 // system. So first we ask for the file in the cached SDK, 764 // then we attempt to get a shared module for the right architecture 765 // with the right UUID. 766 const FileSpec &platform_file = module_spec.GetFileSpec(); 767 768 Error error; 769 char platform_file_path[PATH_MAX]; 770 771 if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) 772 { 773 ModuleSpec platform_module_spec(module_spec); 774 775 UpdateSDKDirectoryInfosIfNeeded(); 776 777 const uint32_t num_sdk_infos = m_sdk_directory_infos.size(); 778 779 // If we are connected we migth be able to correctly deduce the SDK directory 780 // using the OS build. 781 const uint32_t connected_sdk_idx = GetConnectedSDKIndex (); 782 if (connected_sdk_idx < num_sdk_infos) 783 { 784 if (GetFileInSDK (platform_file_path, connected_sdk_idx, platform_module_spec.GetFileSpec())) 785 { 786 module_sp.reset(); 787 error = ResolveExecutable (platform_module_spec, 788 module_sp, 789 NULL); 790 if (module_sp) 791 { 792 m_last_module_sdk_idx = connected_sdk_idx; 793 error.Clear(); 794 return error; 795 } 796 } 797 } 798 799 // Try the last SDK index if it is set as most files from an SDK 800 // will tend to be valid in that same SDK. 801 if (m_last_module_sdk_idx < num_sdk_infos) 802 { 803 if (GetFileInSDK (platform_file_path, m_last_module_sdk_idx, platform_module_spec.GetFileSpec())) 804 { 805 module_sp.reset(); 806 error = ResolveExecutable (platform_module_spec, 807 module_sp, 808 NULL); 809 if (module_sp) 810 { 811 error.Clear(); 812 return error; 813 } 814 } 815 } 816 817 // First try for an exact match of major, minor and update: 818 // If a particalar SDK version was specified via --version or --build, look for a match on disk. 819 const SDKDirectoryInfo *current_sdk_info = GetSDKDirectoryForCurrentOSVersion(); 820 const uint32_t current_sdk_idx = GetSDKIndexBySDKDirectoryInfo(current_sdk_info); 821 if (current_sdk_idx < num_sdk_infos && current_sdk_idx != m_last_module_sdk_idx) 822 { 823 if (GetFileInSDK (platform_file_path, current_sdk_idx, platform_module_spec.GetFileSpec())) 824 { 825 module_sp.reset(); 826 error = ResolveExecutable (platform_module_spec, 827 module_sp, 828 NULL); 829 if (module_sp) 830 { 831 m_last_module_sdk_idx = current_sdk_idx; 832 error.Clear(); 833 return error; 834 } 835 } 836 } 837 838 // Second try all SDKs that were found. 839 for (uint32_t sdk_idx=0; sdk_idx<num_sdk_infos; ++sdk_idx) 840 { 841 if (m_last_module_sdk_idx == sdk_idx) 842 { 843 // Skip the last module SDK index if we already searched 844 // it above 845 continue; 846 } 847 if (GetFileInSDK (platform_file_path, sdk_idx, platform_module_spec.GetFileSpec())) 848 { 849 //printf ("sdk[%u]: '%s'\n", sdk_idx, local_file.GetPath().c_str()); 850 851 error = ResolveExecutable (platform_module_spec, module_sp, NULL); 852 if (module_sp) 853 { 854 // Remember the index of the last SDK that we found a file 855 // in in case the wrong SDK was selected. 856 m_last_module_sdk_idx = sdk_idx; 857 error.Clear(); 858 return error; 859 } 860 } 861 } 862 } 863 // Not the module we are looking for... Nothing to see here... 864 module_sp.reset(); 865 866 // This may not be an SDK-related module. Try whether we can bring in the thing to our local cache. 867 error = GetSharedModuleWithLocalCache(module_spec, module_sp, module_search_paths_ptr, old_module_sp_ptr, did_create_ptr); 868 if (error.Success()) 869 return error; 870 871 const bool always_create = false; 872 error = ModuleList::GetSharedModule (module_spec, 873 module_sp, 874 module_search_paths_ptr, 875 old_module_sp_ptr, 876 did_create_ptr, 877 always_create); 878 879 if (module_sp) 880 module_sp->SetPlatformFileSpec(platform_file); 881 882 return error; 883 } 884 885 bool 886 PlatformRemoteiOS::GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch) 887 { 888 return ARMGetSupportedArchitectureAtIndex (idx, arch); 889 } 890 891 uint32_t 892 PlatformRemoteiOS::GetConnectedSDKIndex () 893 { 894 if (IsConnected()) 895 { 896 if (m_connected_module_sdk_idx == UINT32_MAX) 897 { 898 std::string build; 899 if (GetRemoteOSBuildString(build)) 900 { 901 const uint32_t num_sdk_infos = m_sdk_directory_infos.size(); 902 for (uint32_t i=0; i<num_sdk_infos; ++i) 903 { 904 const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i]; 905 if (strstr(sdk_dir_info.directory.GetFilename().AsCString(""), build.c_str())) 906 { 907 m_connected_module_sdk_idx = i; 908 } 909 } 910 } 911 } 912 } 913 else 914 { 915 m_connected_module_sdk_idx = UINT32_MAX; 916 } 917 return m_connected_module_sdk_idx; 918 } 919 920 uint32_t 921 PlatformRemoteiOS::GetSDKIndexBySDKDirectoryInfo (const SDKDirectoryInfo *sdk_info) 922 { 923 if (sdk_info == NULL) 924 { 925 return UINT32_MAX; 926 } 927 928 return sdk_info - &m_sdk_directory_infos[0]; 929 } 930