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