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 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 LIBLLDB_LOG_VERBOSE); 486 if (platform_file_path && platform_file_path[0] && 487 UpdateSDKDirectoryInfosIfNeeded()) { 488 const uint32_t num_sdk_infos = m_sdk_directory_infos.size(); 489 lldb_private::FileSpec local_file; 490 // First try for an exact match of major, minor and update 491 for (uint32_t sdk_idx = 0; sdk_idx < num_sdk_infos; ++sdk_idx) { 492 if (log) { 493 log->Printf("Searching for %s in sdk path %s", platform_file_path, 494 m_sdk_directory_infos[sdk_idx].directory.GetPath().c_str()); 495 } 496 if (GetFileInSDK(platform_file_path, sdk_idx, local_file)) { 497 file_list.Append(local_file); 498 } 499 } 500 } 501 return file_list.GetSize(); 502 } 503 504 bool PlatformRemoteiOS::GetFileInSDK(const char *platform_file_path, 505 uint32_t sdk_idx, 506 lldb_private::FileSpec &local_file) { 507 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); 508 if (sdk_idx < m_sdk_directory_infos.size()) { 509 std::string sdkroot_path = 510 m_sdk_directory_infos[sdk_idx].directory.GetPath(); 511 local_file.Clear(); 512 513 if (!sdkroot_path.empty() && platform_file_path && platform_file_path[0]) { 514 // We may need to interpose "/Symbols/" or "/Symbols.Internal/" between 515 // the 516 // SDK root directory and the file path. 517 518 const char *paths_to_try[] = {"Symbols", "", "Symbols.Internal", nullptr}; 519 for (size_t i = 0; paths_to_try[i] != nullptr; i++) { 520 local_file.SetFile(sdkroot_path, false); 521 if (paths_to_try[i][0] != '\0') 522 local_file.AppendPathComponent(paths_to_try[i]); 523 local_file.AppendPathComponent(platform_file_path); 524 local_file.ResolvePath(); 525 if (local_file.Exists()) { 526 if (log) 527 log->Printf("Found a copy of %s in the SDK dir %s/%s", 528 platform_file_path, sdkroot_path.c_str(), 529 paths_to_try[i]); 530 return true; 531 } 532 local_file.Clear(); 533 } 534 } 535 } 536 return false; 537 } 538 539 Error PlatformRemoteiOS::GetSymbolFile(const FileSpec &platform_file, 540 const UUID *uuid_ptr, 541 FileSpec &local_file) { 542 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); 543 Error error; 544 char platform_file_path[PATH_MAX]; 545 if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) { 546 char resolved_path[PATH_MAX]; 547 548 const char *os_version_dir = GetDeviceSupportDirectoryForOSVersion(); 549 if (os_version_dir) { 550 ::snprintf(resolved_path, sizeof(resolved_path), "%s/%s", os_version_dir, 551 platform_file_path); 552 553 local_file.SetFile(resolved_path, true); 554 if (local_file.Exists()) { 555 if (log) { 556 log->Printf("Found a copy of %s in the DeviceSupport dir %s", 557 platform_file_path, os_version_dir); 558 } 559 return error; 560 } 561 562 ::snprintf(resolved_path, sizeof(resolved_path), "%s/Symbols.Internal/%s", 563 os_version_dir, platform_file_path); 564 565 local_file.SetFile(resolved_path, true); 566 if (local_file.Exists()) { 567 if (log) { 568 log->Printf( 569 "Found a copy of %s in the DeviceSupport dir %s/Symbols.Internal", 570 platform_file_path, os_version_dir); 571 } 572 return error; 573 } 574 ::snprintf(resolved_path, sizeof(resolved_path), "%s/Symbols/%s", 575 os_version_dir, platform_file_path); 576 577 local_file.SetFile(resolved_path, true); 578 if (local_file.Exists()) { 579 if (log) { 580 log->Printf("Found a copy of %s in the DeviceSupport dir %s/Symbols", 581 platform_file_path, os_version_dir); 582 } 583 return error; 584 } 585 } 586 local_file = platform_file; 587 if (local_file.Exists()) 588 return error; 589 590 error.SetErrorStringWithFormat( 591 "unable to locate a platform file for '%s' in platform '%s'", 592 platform_file_path, GetPluginName().GetCString()); 593 } else { 594 error.SetErrorString("invalid platform file argument"); 595 } 596 return error; 597 } 598 599 Error PlatformRemoteiOS::GetSharedModule( 600 const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp, 601 const FileSpecList *module_search_paths_ptr, ModuleSP *old_module_sp_ptr, 602 bool *did_create_ptr) { 603 // For iOS, the SDK files are all cached locally on the host 604 // system. So first we ask for the file in the cached SDK, 605 // then we attempt to get a shared module for the right architecture 606 // with the right UUID. 607 const FileSpec &platform_file = module_spec.GetFileSpec(); 608 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST | 609 LIBLLDB_LOG_VERBOSE); 610 611 Error error; 612 char platform_file_path[PATH_MAX]; 613 614 if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) { 615 ModuleSpec platform_module_spec(module_spec); 616 617 UpdateSDKDirectoryInfosIfNeeded(); 618 619 const uint32_t num_sdk_infos = m_sdk_directory_infos.size(); 620 621 // If we are connected we migth be able to correctly deduce the SDK 622 // directory 623 // using the OS build. 624 const uint32_t connected_sdk_idx = GetConnectedSDKIndex(); 625 if (connected_sdk_idx < num_sdk_infos) { 626 if (log) { 627 log->Printf("Searching for %s in sdk path %s", platform_file_path, 628 m_sdk_directory_infos[connected_sdk_idx] 629 .directory.GetPath() 630 .c_str()); 631 } 632 if (GetFileInSDK(platform_file_path, connected_sdk_idx, 633 platform_module_spec.GetFileSpec())) { 634 module_sp.reset(); 635 error = ResolveExecutable(platform_module_spec, module_sp, NULL); 636 if (module_sp) { 637 m_last_module_sdk_idx = connected_sdk_idx; 638 error.Clear(); 639 return error; 640 } 641 } 642 } 643 644 // Try the last SDK index if it is set as most files from an SDK 645 // will tend to be valid in that same SDK. 646 if (m_last_module_sdk_idx < num_sdk_infos) { 647 if (log) { 648 log->Printf("Searching for %s in sdk path %s", platform_file_path, 649 m_sdk_directory_infos[m_last_module_sdk_idx] 650 .directory.GetPath() 651 .c_str()); 652 } 653 if (GetFileInSDK(platform_file_path, m_last_module_sdk_idx, 654 platform_module_spec.GetFileSpec())) { 655 module_sp.reset(); 656 error = ResolveExecutable(platform_module_spec, module_sp, NULL); 657 if (module_sp) { 658 error.Clear(); 659 return error; 660 } 661 } 662 } 663 664 // First try for an exact match of major, minor and update: 665 // If a particalar SDK version was specified via --version or --build, look 666 // for a match on disk. 667 const SDKDirectoryInfo *current_sdk_info = 668 GetSDKDirectoryForCurrentOSVersion(); 669 const uint32_t current_sdk_idx = 670 GetSDKIndexBySDKDirectoryInfo(current_sdk_info); 671 if (current_sdk_idx < num_sdk_infos && 672 current_sdk_idx != m_last_module_sdk_idx) { 673 if (log) { 674 log->Printf( 675 "Searching for %s in sdk path %s", platform_file_path, 676 m_sdk_directory_infos[current_sdk_idx].directory.GetPath().c_str()); 677 } 678 if (GetFileInSDK(platform_file_path, current_sdk_idx, 679 platform_module_spec.GetFileSpec())) { 680 module_sp.reset(); 681 error = ResolveExecutable(platform_module_spec, module_sp, NULL); 682 if (module_sp) { 683 m_last_module_sdk_idx = current_sdk_idx; 684 error.Clear(); 685 return error; 686 } 687 } 688 } 689 690 // Second try all SDKs that were found. 691 for (uint32_t sdk_idx = 0; sdk_idx < num_sdk_infos; ++sdk_idx) { 692 if (m_last_module_sdk_idx == sdk_idx) { 693 // Skip the last module SDK index if we already searched 694 // it above 695 continue; 696 } 697 if (log) { 698 log->Printf("Searching for %s in sdk path %s", platform_file_path, 699 m_sdk_directory_infos[sdk_idx].directory.GetPath().c_str()); 700 } 701 if (GetFileInSDK(platform_file_path, sdk_idx, 702 platform_module_spec.GetFileSpec())) { 703 // printf ("sdk[%u]: '%s'\n", sdk_idx, local_file.GetPath().c_str()); 704 705 error = ResolveExecutable(platform_module_spec, module_sp, NULL); 706 if (module_sp) { 707 // Remember the index of the last SDK that we found a file 708 // in in case the wrong SDK was selected. 709 m_last_module_sdk_idx = sdk_idx; 710 error.Clear(); 711 return error; 712 } 713 } 714 } 715 } 716 // Not the module we are looking for... Nothing to see here... 717 module_sp.reset(); 718 719 // This may not be an SDK-related module. Try whether we can bring in the 720 // thing to our local cache. 721 error = GetSharedModuleWithLocalCache(module_spec, module_sp, 722 module_search_paths_ptr, 723 old_module_sp_ptr, did_create_ptr); 724 if (error.Success()) 725 return error; 726 727 // See if the file is present in any of the module_search_paths_ptr 728 // directories. 729 if (!module_sp && module_search_paths_ptr && platform_file) { 730 // create a vector of all the file / directory names in platform_file 731 // e.g. this might be 732 // /System/Library/PrivateFrameworks/UIFoundation.framework/UIFoundation 733 // 734 // We'll need to look in the module_search_paths_ptr directories for 735 // both "UIFoundation" and "UIFoundation.framework" -- most likely the 736 // latter will be the one we find there. 737 738 FileSpec platform_pull_apart(platform_file); 739 std::vector<std::string> path_parts; 740 ConstString unix_root_dir("/"); 741 while (true) { 742 ConstString part = platform_pull_apart.GetLastPathComponent(); 743 platform_pull_apart.RemoveLastPathComponent(); 744 if (part.IsEmpty() || part == unix_root_dir) 745 break; 746 path_parts.push_back(part.AsCString()); 747 } 748 const size_t path_parts_size = path_parts.size(); 749 750 size_t num_module_search_paths = module_search_paths_ptr->GetSize(); 751 for (size_t i = 0; i < num_module_search_paths; ++i) { 752 Log *log_verbose = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST | 753 LIBLLDB_LOG_VERBOSE); 754 if (log_verbose) 755 log_verbose->Printf ("PlatformRemoteiOS::GetSharedModule searching for binary in search-path %s", module_search_paths_ptr->GetFileSpecAtIndex(i).GetPath().c_str()); 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