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