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 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST | LIBLLDB_LOG_VERBOSE); 571 if (platform_file_path && platform_file_path[0] && UpdateSDKDirectoryInfosIfNeeded()) 572 { 573 const uint32_t num_sdk_infos = m_sdk_directory_infos.size(); 574 lldb_private::FileSpec local_file; 575 // First try for an exact match of major, minor and update 576 for (uint32_t sdk_idx=0; sdk_idx<num_sdk_infos; ++sdk_idx) 577 { 578 if (log) 579 { 580 log->Printf ("Searching for %s in sdk path %s", platform_file_path, m_sdk_directory_infos[sdk_idx].directory.GetPath().c_str()); 581 } 582 if (GetFileInSDK (platform_file_path, 583 sdk_idx, 584 local_file)) 585 { 586 file_list.Append(local_file); 587 } 588 } 589 } 590 return file_list.GetSize(); 591 } 592 593 bool 594 PlatformRemoteiOS::GetFileInSDK (const char *platform_file_path, 595 uint32_t sdk_idx, 596 lldb_private::FileSpec &local_file) 597 { 598 if (sdk_idx < m_sdk_directory_infos.size()) 599 { 600 char sdkroot_path[PATH_MAX]; 601 const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[sdk_idx]; 602 if (sdk_dir_info.directory.GetPath(sdkroot_path, sizeof(sdkroot_path))) 603 { 604 const bool symbols_dirs_only = true; 605 606 return GetFileInSDKRoot (platform_file_path, 607 sdkroot_path, 608 symbols_dirs_only, 609 local_file); 610 } 611 } 612 return false; 613 } 614 615 616 bool 617 PlatformRemoteiOS::GetFileInSDKRoot (const char *platform_file_path, 618 const char *sdkroot_path, 619 bool symbols_dirs_only, 620 lldb_private::FileSpec &local_file) 621 { 622 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); 623 if (sdkroot_path && sdkroot_path[0] && platform_file_path && platform_file_path[0]) 624 { 625 char resolved_path[PATH_MAX]; 626 627 if (!symbols_dirs_only) 628 { 629 ::snprintf (resolved_path, 630 sizeof(resolved_path), 631 "%s%s", 632 sdkroot_path, 633 platform_file_path); 634 635 local_file.SetFile(resolved_path, true); 636 if (local_file.Exists()) 637 { 638 if (log) 639 { 640 log->Printf ("Found a copy of %s in the SDK dir %s", platform_file_path, sdkroot_path); 641 } 642 return true; 643 } 644 } 645 646 ::snprintf (resolved_path, 647 sizeof(resolved_path), 648 "%s/Symbols.Internal%s", 649 sdkroot_path, 650 platform_file_path); 651 652 local_file.SetFile(resolved_path, true); 653 if (local_file.Exists()) 654 { 655 if (log) 656 { 657 log->Printf ("Found a copy of %s in the SDK dir %s/Symbols.Internal", platform_file_path, sdkroot_path); 658 } 659 return true; 660 } 661 ::snprintf (resolved_path, 662 sizeof(resolved_path), 663 "%s/Symbols%s", 664 sdkroot_path, 665 platform_file_path); 666 667 local_file.SetFile(resolved_path, true); 668 if (local_file.Exists()) 669 { 670 if (log) 671 { 672 log->Printf ("Found a copy of %s in the SDK dir %s/Symbols", platform_file_path, sdkroot_path); 673 } 674 return true; 675 } 676 } 677 return false; 678 } 679 680 681 Error 682 PlatformRemoteiOS::GetSymbolFile (const FileSpec &platform_file, 683 const UUID *uuid_ptr, 684 FileSpec &local_file) 685 { 686 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); 687 Error error; 688 char platform_file_path[PATH_MAX]; 689 if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) 690 { 691 char resolved_path[PATH_MAX]; 692 693 const char * os_version_dir = GetDeviceSupportDirectoryForOSVersion(); 694 if (os_version_dir) 695 { 696 ::snprintf (resolved_path, 697 sizeof(resolved_path), 698 "%s/%s", 699 os_version_dir, 700 platform_file_path); 701 702 local_file.SetFile(resolved_path, true); 703 if (local_file.Exists()) 704 { 705 if (log) 706 { 707 log->Printf ("Found a copy of %s in the DeviceSupport dir %s", platform_file_path, os_version_dir); 708 } 709 return error; 710 } 711 712 ::snprintf (resolved_path, 713 sizeof(resolved_path), 714 "%s/Symbols.Internal/%s", 715 os_version_dir, 716 platform_file_path); 717 718 local_file.SetFile(resolved_path, true); 719 if (local_file.Exists()) 720 { 721 if (log) 722 { 723 log->Printf ("Found a copy of %s in the DeviceSupport dir %s/Symbols.Internal", platform_file_path, os_version_dir); 724 } 725 return error; 726 } 727 ::snprintf (resolved_path, 728 sizeof(resolved_path), 729 "%s/Symbols/%s", 730 os_version_dir, 731 platform_file_path); 732 733 local_file.SetFile(resolved_path, true); 734 if (local_file.Exists()) 735 { 736 if (log) 737 { 738 log->Printf ("Found a copy of %s in the DeviceSupport dir %s/Symbols", platform_file_path, os_version_dir); 739 } 740 return error; 741 } 742 743 } 744 local_file = platform_file; 745 if (local_file.Exists()) 746 return error; 747 748 error.SetErrorStringWithFormat ("unable to locate a platform file for '%s' in platform '%s'", 749 platform_file_path, 750 GetPluginName().GetCString()); 751 } 752 else 753 { 754 error.SetErrorString ("invalid platform file argument"); 755 } 756 return error; 757 } 758 759 Error 760 PlatformRemoteiOS::GetSharedModule (const ModuleSpec &module_spec, 761 Process* process, 762 ModuleSP &module_sp, 763 const FileSpecList *module_search_paths_ptr, 764 ModuleSP *old_module_sp_ptr, 765 bool *did_create_ptr) 766 { 767 // For iOS, the SDK files are all cached locally on the host 768 // system. So first we ask for the file in the cached SDK, 769 // then we attempt to get a shared module for the right architecture 770 // with the right UUID. 771 const FileSpec &platform_file = module_spec.GetFileSpec(); 772 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST | LIBLLDB_LOG_VERBOSE); 773 774 Error error; 775 char platform_file_path[PATH_MAX]; 776 777 if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) 778 { 779 ModuleSpec platform_module_spec(module_spec); 780 781 UpdateSDKDirectoryInfosIfNeeded(); 782 783 const uint32_t num_sdk_infos = m_sdk_directory_infos.size(); 784 785 // If we are connected we migth be able to correctly deduce the SDK directory 786 // using the OS build. 787 const uint32_t connected_sdk_idx = GetConnectedSDKIndex (); 788 if (connected_sdk_idx < num_sdk_infos) 789 { 790 if (log) 791 { 792 log->Printf ("Searching for %s in sdk path %s", platform_file_path, m_sdk_directory_infos[connected_sdk_idx].directory.GetPath().c_str()); 793 } 794 if (GetFileInSDK (platform_file_path, connected_sdk_idx, platform_module_spec.GetFileSpec())) 795 { 796 module_sp.reset(); 797 error = ResolveExecutable (platform_module_spec, 798 module_sp, 799 NULL); 800 if (module_sp) 801 { 802 m_last_module_sdk_idx = connected_sdk_idx; 803 error.Clear(); 804 return error; 805 } 806 } 807 } 808 809 // Try the last SDK index if it is set as most files from an SDK 810 // will tend to be valid in that same SDK. 811 if (m_last_module_sdk_idx < num_sdk_infos) 812 { 813 if (log) 814 { 815 log->Printf ("Searching for %s in sdk path %s", platform_file_path, m_sdk_directory_infos[m_last_module_sdk_idx].directory.GetPath().c_str()); 816 } 817 if (GetFileInSDK (platform_file_path, m_last_module_sdk_idx, platform_module_spec.GetFileSpec())) 818 { 819 module_sp.reset(); 820 error = ResolveExecutable (platform_module_spec, 821 module_sp, 822 NULL); 823 if (module_sp) 824 { 825 error.Clear(); 826 return error; 827 } 828 } 829 } 830 831 // First try for an exact match of major, minor and update: 832 // If a particalar SDK version was specified via --version or --build, look for a match on disk. 833 const SDKDirectoryInfo *current_sdk_info = GetSDKDirectoryForCurrentOSVersion(); 834 const uint32_t current_sdk_idx = GetSDKIndexBySDKDirectoryInfo(current_sdk_info); 835 if (current_sdk_idx < num_sdk_infos && current_sdk_idx != m_last_module_sdk_idx) 836 { 837 if (log) 838 { 839 log->Printf ("Searching for %s in sdk path %s", platform_file_path, m_sdk_directory_infos[current_sdk_idx].directory.GetPath().c_str()); 840 } 841 if (GetFileInSDK (platform_file_path, current_sdk_idx, platform_module_spec.GetFileSpec())) 842 { 843 module_sp.reset(); 844 error = ResolveExecutable (platform_module_spec, 845 module_sp, 846 NULL); 847 if (module_sp) 848 { 849 m_last_module_sdk_idx = current_sdk_idx; 850 error.Clear(); 851 return error; 852 } 853 } 854 } 855 856 // Second try all SDKs that were found. 857 for (uint32_t sdk_idx=0; sdk_idx<num_sdk_infos; ++sdk_idx) 858 { 859 if (m_last_module_sdk_idx == sdk_idx) 860 { 861 // Skip the last module SDK index if we already searched 862 // it above 863 continue; 864 } 865 if (log) 866 { 867 log->Printf ("Searching for %s in sdk path %s", platform_file_path, m_sdk_directory_infos[sdk_idx].directory.GetPath().c_str()); 868 } 869 if (GetFileInSDK (platform_file_path, sdk_idx, platform_module_spec.GetFileSpec())) 870 { 871 //printf ("sdk[%u]: '%s'\n", sdk_idx, local_file.GetPath().c_str()); 872 873 error = ResolveExecutable (platform_module_spec, module_sp, NULL); 874 if (module_sp) 875 { 876 // Remember the index of the last SDK that we found a file 877 // in in case the wrong SDK was selected. 878 m_last_module_sdk_idx = sdk_idx; 879 error.Clear(); 880 return error; 881 } 882 } 883 } 884 } 885 // Not the module we are looking for... Nothing to see here... 886 module_sp.reset(); 887 888 // This may not be an SDK-related module. Try whether we can bring in the thing to our local cache. 889 error = GetSharedModuleWithLocalCache(module_spec, module_sp, module_search_paths_ptr, old_module_sp_ptr, did_create_ptr); 890 if (error.Success()) 891 return error; 892 893 const bool always_create = false; 894 error = ModuleList::GetSharedModule (module_spec, 895 module_sp, 896 module_search_paths_ptr, 897 old_module_sp_ptr, 898 did_create_ptr, 899 always_create); 900 901 if (module_sp) 902 module_sp->SetPlatformFileSpec(platform_file); 903 904 return error; 905 } 906 907 bool 908 PlatformRemoteiOS::GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch) 909 { 910 return ARMGetSupportedArchitectureAtIndex (idx, arch); 911 } 912 913 uint32_t 914 PlatformRemoteiOS::GetConnectedSDKIndex () 915 { 916 if (IsConnected()) 917 { 918 if (m_connected_module_sdk_idx == UINT32_MAX) 919 { 920 std::string build; 921 if (GetRemoteOSBuildString(build)) 922 { 923 const uint32_t num_sdk_infos = m_sdk_directory_infos.size(); 924 for (uint32_t i=0; i<num_sdk_infos; ++i) 925 { 926 const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i]; 927 if (strstr(sdk_dir_info.directory.GetFilename().AsCString(""), build.c_str())) 928 { 929 m_connected_module_sdk_idx = i; 930 } 931 } 932 } 933 } 934 } 935 else 936 { 937 m_connected_module_sdk_idx = UINT32_MAX; 938 } 939 return m_connected_module_sdk_idx; 940 } 941 942 uint32_t 943 PlatformRemoteiOS::GetSDKIndexBySDKDirectoryInfo (const SDKDirectoryInfo *sdk_info) 944 { 945 if (sdk_info == NULL) 946 { 947 return UINT32_MAX; 948 } 949 950 return sdk_info - &m_sdk_directory_infos[0]; 951 } 952