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