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.GetString().c_str()); 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 if (m_sdk_directory_infos.empty()) { 267 // A --sysroot option was supplied - add it to our list of SDKs to check 268 if (m_sdk_sysroot) { 269 FileSpec sdk_sysroot_fspec(m_sdk_sysroot.GetCString(), true); 270 const SDKDirectoryInfo sdk_sysroot_directory_info(sdk_sysroot_fspec); 271 m_sdk_directory_infos.push_back(sdk_sysroot_directory_info); 272 if (log) { 273 log->Printf("PlatformRemoteiOS::UpdateSDKDirectoryInfosIfNeeded added " 274 "--sysroot SDK directory %s", 275 m_sdk_sysroot.GetCString()); 276 } 277 return true; 278 } 279 const char *device_support_dir = GetDeviceSupportDirectory(); 280 if (log) { 281 log->Printf("PlatformRemoteiOS::UpdateSDKDirectoryInfosIfNeeded Got " 282 "DeviceSupport directory %s", 283 device_support_dir); 284 } 285 if (device_support_dir) { 286 const bool find_directories = true; 287 const bool find_files = false; 288 const bool find_other = false; 289 290 SDKDirectoryInfoCollection builtin_sdk_directory_infos; 291 FileSpec::EnumerateDirectory(m_device_support_directory.c_str(), 292 find_directories, find_files, find_other, 293 GetContainedFilesIntoVectorOfStringsCallback, 294 &builtin_sdk_directory_infos); 295 296 // Only add SDK directories that have symbols in them, some SDKs only 297 // contain 298 // developer disk images and no symbols, so they aren't useful to us. 299 FileSpec sdk_symbols_symlink_fspec; 300 for (const auto &sdk_directory_info : builtin_sdk_directory_infos) { 301 sdk_symbols_symlink_fspec = sdk_directory_info.directory; 302 sdk_symbols_symlink_fspec.AppendPathComponent("Symbols"); 303 if (sdk_symbols_symlink_fspec.Exists()) { 304 m_sdk_directory_infos.push_back(sdk_directory_info); 305 if (log) { 306 log->Printf("PlatformRemoteiOS::UpdateSDKDirectoryInfosIfNeeded " 307 "added builtin SDK directory %s", 308 sdk_symbols_symlink_fspec.GetPath().c_str()); 309 } 310 } 311 } 312 313 const uint32_t num_installed = m_sdk_directory_infos.size(); 314 FileSpec local_sdk_cache("~/Library/Developer/Xcode/iOS DeviceSupport", 315 true); 316 if (local_sdk_cache.Exists()) { 317 if (log) { 318 log->Printf("PlatformRemoteiOS::UpdateSDKDirectoryInfosIfNeeded " 319 "searching %s for additional SDKs", 320 local_sdk_cache.GetPath().c_str()); 321 } 322 char path[PATH_MAX]; 323 if (local_sdk_cache.GetPath(path, sizeof(path))) { 324 FileSpec::EnumerateDirectory( 325 path, find_directories, find_files, find_other, 326 GetContainedFilesIntoVectorOfStringsCallback, 327 &m_sdk_directory_infos); 328 const uint32_t num_sdk_infos = m_sdk_directory_infos.size(); 329 // First try for an exact match of major, minor and update 330 for (uint32_t i = num_installed; i < num_sdk_infos; ++i) { 331 m_sdk_directory_infos[i].user_cached = true; 332 if (log) { 333 log->Printf("PlatformRemoteiOS::UpdateSDKDirectoryInfosIfNeeded " 334 "user SDK directory %s", 335 m_sdk_directory_infos[i].directory.GetPath().c_str()); 336 } 337 } 338 } 339 } 340 } 341 } 342 return !m_sdk_directory_infos.empty(); 343 } 344 345 const PlatformRemoteiOS::SDKDirectoryInfo * 346 PlatformRemoteiOS::GetSDKDirectoryForCurrentOSVersion() { 347 uint32_t i; 348 if (UpdateSDKDirectoryInfosIfNeeded()) { 349 const uint32_t num_sdk_infos = m_sdk_directory_infos.size(); 350 351 // Check to see if the user specified a build string. If they did, then 352 // be sure to match it. 353 std::vector<bool> check_sdk_info(num_sdk_infos, true); 354 ConstString build(m_sdk_build); 355 if (build) { 356 for (i = 0; i < num_sdk_infos; ++i) 357 check_sdk_info[i] = m_sdk_directory_infos[i].build == build; 358 } 359 360 // If we are connected we can find the version of the OS the platform 361 // us running on and select the right SDK 362 uint32_t major, minor, update; 363 if (GetOSVersion(major, minor, update)) { 364 if (UpdateSDKDirectoryInfosIfNeeded()) { 365 // First try for an exact match of major, minor and update 366 for (i = 0; i < num_sdk_infos; ++i) { 367 if (check_sdk_info[i]) { 368 if (m_sdk_directory_infos[i].version_major == major && 369 m_sdk_directory_infos[i].version_minor == minor && 370 m_sdk_directory_infos[i].version_update == update) { 371 return &m_sdk_directory_infos[i]; 372 } 373 } 374 } 375 // First try for an exact match of major and minor 376 for (i = 0; i < num_sdk_infos; ++i) { 377 if (check_sdk_info[i]) { 378 if (m_sdk_directory_infos[i].version_major == major && 379 m_sdk_directory_infos[i].version_minor == minor) { 380 return &m_sdk_directory_infos[i]; 381 } 382 } 383 } 384 // Lastly try to match of major version only.. 385 for (i = 0; i < num_sdk_infos; ++i) { 386 if (check_sdk_info[i]) { 387 if (m_sdk_directory_infos[i].version_major == major) { 388 return &m_sdk_directory_infos[i]; 389 } 390 } 391 } 392 } 393 } else if (build) { 394 // No version, just a build number, search for the first one that matches 395 for (i = 0; i < num_sdk_infos; ++i) 396 if (check_sdk_info[i]) 397 return &m_sdk_directory_infos[i]; 398 } 399 } 400 return NULL; 401 } 402 403 const PlatformRemoteiOS::SDKDirectoryInfo * 404 PlatformRemoteiOS::GetSDKDirectoryForLatestOSVersion() { 405 const PlatformRemoteiOS::SDKDirectoryInfo *result = NULL; 406 if (UpdateSDKDirectoryInfosIfNeeded()) { 407 const uint32_t num_sdk_infos = m_sdk_directory_infos.size(); 408 // First try for an exact match of major, minor and update 409 for (uint32_t i = 0; i < num_sdk_infos; ++i) { 410 const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i]; 411 if (sdk_dir_info.version_major != UINT32_MAX) { 412 if (result == NULL || 413 sdk_dir_info.version_major > result->version_major) { 414 result = &sdk_dir_info; 415 } else if (sdk_dir_info.version_major == result->version_major) { 416 if (sdk_dir_info.version_minor > result->version_minor) { 417 result = &sdk_dir_info; 418 } else if (sdk_dir_info.version_minor == result->version_minor) { 419 if (sdk_dir_info.version_update > result->version_update) { 420 result = &sdk_dir_info; 421 } 422 } 423 } 424 } 425 } 426 } 427 return result; 428 } 429 430 const char *PlatformRemoteiOS::GetDeviceSupportDirectory() { 431 if (m_device_support_directory.empty()) { 432 const char *device_support_dir = GetDeveloperDirectory(); 433 if (device_support_dir) { 434 m_device_support_directory.assign(device_support_dir); 435 m_device_support_directory.append( 436 "/Platforms/iPhoneOS.platform/DeviceSupport"); 437 } else { 438 // Assign a single NULL character so we know we tried to find the device 439 // support directory and we don't keep trying to find it over and over. 440 m_device_support_directory.assign(1, '\0'); 441 } 442 } 443 // We should have put a single NULL character into m_device_support_directory 444 // or it should have a valid path if the code gets here 445 assert(m_device_support_directory.empty() == false); 446 if (m_device_support_directory[0]) 447 return m_device_support_directory.c_str(); 448 return NULL; 449 } 450 451 const char *PlatformRemoteiOS::GetDeviceSupportDirectoryForOSVersion() { 452 if (m_sdk_sysroot) 453 return m_sdk_sysroot.GetCString(); 454 455 if (m_device_support_directory_for_os_version.empty()) { 456 const PlatformRemoteiOS::SDKDirectoryInfo *sdk_dir_info = 457 GetSDKDirectoryForCurrentOSVersion(); 458 if (sdk_dir_info == NULL) 459 sdk_dir_info = GetSDKDirectoryForLatestOSVersion(); 460 if (sdk_dir_info) { 461 char path[PATH_MAX]; 462 if (sdk_dir_info->directory.GetPath(path, sizeof(path))) { 463 m_device_support_directory_for_os_version = path; 464 return m_device_support_directory_for_os_version.c_str(); 465 } 466 } else { 467 // Assign a single NULL character so we know we tried to find the device 468 // support directory and we don't keep trying to find it over and over. 469 m_device_support_directory_for_os_version.assign(1, '\0'); 470 } 471 } 472 // We should have put a single NULL character into 473 // m_device_support_directory_for_os_version 474 // or it should have a valid path if the code gets here 475 assert(m_device_support_directory_for_os_version.empty() == false); 476 if (m_device_support_directory_for_os_version[0]) 477 return m_device_support_directory_for_os_version.c_str(); 478 return NULL; 479 } 480 481 uint32_t PlatformRemoteiOS::FindFileInAllSDKs(const char *platform_file_path, 482 FileSpecList &file_list) { 483 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST | 484 LIBLLDB_LOG_VERBOSE); 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 if (log) { 492 log->Printf("Searching for %s in sdk path %s", platform_file_path, 493 m_sdk_directory_infos[sdk_idx].directory.GetPath().c_str()); 494 } 495 if (GetFileInSDK(platform_file_path, sdk_idx, local_file)) { 496 file_list.Append(local_file); 497 } 498 } 499 } 500 return file_list.GetSize(); 501 } 502 503 bool PlatformRemoteiOS::GetFileInSDK(const char *platform_file_path, 504 uint32_t sdk_idx, 505 lldb_private::FileSpec &local_file) { 506 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); 507 if (sdk_idx < m_sdk_directory_infos.size()) { 508 std::string sdkroot_path = 509 m_sdk_directory_infos[sdk_idx].directory.GetPath(); 510 local_file.Clear(); 511 512 if (!sdkroot_path.empty() && platform_file_path && platform_file_path[0]) { 513 // We may need to interpose "/Symbols/" or "/Symbols.Internal/" between 514 // the 515 // SDK root directory and the file path. 516 517 const char *paths_to_try[] = {"Symbols", "", "Symbols.Internal", nullptr}; 518 for (size_t i = 0; paths_to_try[i] != nullptr; i++) { 519 local_file.SetFile(sdkroot_path.c_str(), false); 520 if (paths_to_try[i][0] != '\0') 521 local_file.AppendPathComponent(paths_to_try[i]); 522 local_file.AppendPathComponent(platform_file_path); 523 local_file.ResolvePath(); 524 if (local_file.Exists()) { 525 if (log) 526 log->Printf("Found a copy of %s in the SDK dir %s/%s", 527 platform_file_path, sdkroot_path.c_str(), 528 paths_to_try[i]); 529 return true; 530 } 531 local_file.Clear(); 532 } 533 } 534 } 535 return false; 536 } 537 538 Error PlatformRemoteiOS::GetSymbolFile(const FileSpec &platform_file, 539 const UUID *uuid_ptr, 540 FileSpec &local_file) { 541 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); 542 Error error; 543 char platform_file_path[PATH_MAX]; 544 if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) { 545 char resolved_path[PATH_MAX]; 546 547 const char *os_version_dir = GetDeviceSupportDirectoryForOSVersion(); 548 if (os_version_dir) { 549 ::snprintf(resolved_path, sizeof(resolved_path), "%s/%s", os_version_dir, 550 platform_file_path); 551 552 local_file.SetFile(resolved_path, true); 553 if (local_file.Exists()) { 554 if (log) { 555 log->Printf("Found a copy of %s in the DeviceSupport dir %s", 556 platform_file_path, os_version_dir); 557 } 558 return error; 559 } 560 561 ::snprintf(resolved_path, sizeof(resolved_path), "%s/Symbols.Internal/%s", 562 os_version_dir, platform_file_path); 563 564 local_file.SetFile(resolved_path, true); 565 if (local_file.Exists()) { 566 if (log) { 567 log->Printf( 568 "Found a copy of %s in the DeviceSupport dir %s/Symbols.Internal", 569 platform_file_path, os_version_dir); 570 } 571 return error; 572 } 573 ::snprintf(resolved_path, sizeof(resolved_path), "%s/Symbols/%s", 574 os_version_dir, platform_file_path); 575 576 local_file.SetFile(resolved_path, true); 577 if (local_file.Exists()) { 578 if (log) { 579 log->Printf("Found a copy of %s in the DeviceSupport dir %s/Symbols", 580 platform_file_path, os_version_dir); 581 } 582 return error; 583 } 584 } 585 local_file = platform_file; 586 if (local_file.Exists()) 587 return error; 588 589 error.SetErrorStringWithFormat( 590 "unable to locate a platform file for '%s' in platform '%s'", 591 platform_file_path, GetPluginName().GetCString()); 592 } else { 593 error.SetErrorString("invalid platform file argument"); 594 } 595 return error; 596 } 597 598 Error PlatformRemoteiOS::GetSharedModule( 599 const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp, 600 const FileSpecList *module_search_paths_ptr, ModuleSP *old_module_sp_ptr, 601 bool *did_create_ptr) { 602 // For iOS, the SDK files are all cached locally on the host 603 // system. So first we ask for the file in the cached SDK, 604 // then we attempt to get a shared module for the right architecture 605 // with the right UUID. 606 const FileSpec &platform_file = module_spec.GetFileSpec(); 607 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST | 608 LIBLLDB_LOG_VERBOSE); 609 610 Error error; 611 char platform_file_path[PATH_MAX]; 612 613 if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) { 614 ModuleSpec platform_module_spec(module_spec); 615 616 UpdateSDKDirectoryInfosIfNeeded(); 617 618 const uint32_t num_sdk_infos = m_sdk_directory_infos.size(); 619 620 // If we are connected we migth be able to correctly deduce the SDK 621 // directory 622 // using the OS build. 623 const uint32_t connected_sdk_idx = GetConnectedSDKIndex(); 624 if (connected_sdk_idx < num_sdk_infos) { 625 if (log) { 626 log->Printf("Searching for %s in sdk path %s", platform_file_path, 627 m_sdk_directory_infos[connected_sdk_idx] 628 .directory.GetPath() 629 .c_str()); 630 } 631 if (GetFileInSDK(platform_file_path, connected_sdk_idx, 632 platform_module_spec.GetFileSpec())) { 633 module_sp.reset(); 634 error = ResolveExecutable(platform_module_spec, module_sp, NULL); 635 if (module_sp) { 636 m_last_module_sdk_idx = connected_sdk_idx; 637 error.Clear(); 638 return error; 639 } 640 } 641 } 642 643 // Try the last SDK index if it is set as most files from an SDK 644 // will tend to be valid in that same SDK. 645 if (m_last_module_sdk_idx < num_sdk_infos) { 646 if (log) { 647 log->Printf("Searching for %s in sdk path %s", platform_file_path, 648 m_sdk_directory_infos[m_last_module_sdk_idx] 649 .directory.GetPath() 650 .c_str()); 651 } 652 if (GetFileInSDK(platform_file_path, m_last_module_sdk_idx, 653 platform_module_spec.GetFileSpec())) { 654 module_sp.reset(); 655 error = ResolveExecutable(platform_module_spec, module_sp, NULL); 656 if (module_sp) { 657 error.Clear(); 658 return error; 659 } 660 } 661 } 662 663 // First try for an exact match of major, minor and update: 664 // If a particalar SDK version was specified via --version or --build, look 665 // for a match on disk. 666 const SDKDirectoryInfo *current_sdk_info = 667 GetSDKDirectoryForCurrentOSVersion(); 668 const uint32_t current_sdk_idx = 669 GetSDKIndexBySDKDirectoryInfo(current_sdk_info); 670 if (current_sdk_idx < num_sdk_infos && 671 current_sdk_idx != m_last_module_sdk_idx) { 672 if (log) { 673 log->Printf( 674 "Searching for %s in sdk path %s", platform_file_path, 675 m_sdk_directory_infos[current_sdk_idx].directory.GetPath().c_str()); 676 } 677 if (GetFileInSDK(platform_file_path, current_sdk_idx, 678 platform_module_spec.GetFileSpec())) { 679 module_sp.reset(); 680 error = ResolveExecutable(platform_module_spec, module_sp, NULL); 681 if (module_sp) { 682 m_last_module_sdk_idx = current_sdk_idx; 683 error.Clear(); 684 return error; 685 } 686 } 687 } 688 689 // Second try all SDKs that were found. 690 for (uint32_t sdk_idx = 0; sdk_idx < num_sdk_infos; ++sdk_idx) { 691 if (m_last_module_sdk_idx == sdk_idx) { 692 // Skip the last module SDK index if we already searched 693 // it above 694 continue; 695 } 696 if (log) { 697 log->Printf("Searching for %s in sdk path %s", platform_file_path, 698 m_sdk_directory_infos[sdk_idx].directory.GetPath().c_str()); 699 } 700 if (GetFileInSDK(platform_file_path, sdk_idx, 701 platform_module_spec.GetFileSpec())) { 702 // printf ("sdk[%u]: '%s'\n", sdk_idx, local_file.GetPath().c_str()); 703 704 error = ResolveExecutable(platform_module_spec, module_sp, NULL); 705 if (module_sp) { 706 // Remember the index of the last SDK that we found a file 707 // in in case the wrong SDK was selected. 708 m_last_module_sdk_idx = sdk_idx; 709 error.Clear(); 710 return error; 711 } 712 } 713 } 714 } 715 // Not the module we are looking for... Nothing to see here... 716 module_sp.reset(); 717 718 // This may not be an SDK-related module. Try whether we can bring in the 719 // thing to our local cache. 720 error = GetSharedModuleWithLocalCache(module_spec, module_sp, 721 module_search_paths_ptr, 722 old_module_sp_ptr, did_create_ptr); 723 if (error.Success()) 724 return error; 725 726 // See if the file is present in any of the module_search_paths_ptr 727 // directories. 728 if (!module_sp && module_search_paths_ptr && platform_file) { 729 // create a vector of all the file / directory names in platform_file 730 // e.g. this might be 731 // /System/Library/PrivateFrameworks/UIFoundation.framework/UIFoundation 732 // 733 // We'll need to look in the module_search_paths_ptr directories for 734 // both "UIFoundation" and "UIFoundation.framework" -- most likely the 735 // latter will be the one we find there. 736 737 FileSpec platform_pull_apart(platform_file); 738 std::vector<std::string> path_parts; 739 ConstString unix_root_dir("/"); 740 while (true) { 741 ConstString part = platform_pull_apart.GetLastPathComponent(); 742 platform_pull_apart.RemoveLastPathComponent(); 743 if (part.IsEmpty() || part == unix_root_dir) 744 break; 745 path_parts.push_back(part.AsCString()); 746 } 747 const size_t path_parts_size = path_parts.size(); 748 749 size_t num_module_search_paths = module_search_paths_ptr->GetSize(); 750 for (size_t i = 0; i < num_module_search_paths; ++i) { 751 Log *log_verbose = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST | 752 LIBLLDB_LOG_VERBOSE); 753 if (log_verbose) 754 log_verbose->Printf ("PlatformRemoteiOS::GetSharedModule searching for binary in search-path %s", module_search_paths_ptr->GetFileSpecAtIndex(i).GetPath().c_str()); 755 // Create a new FileSpec with this module_search_paths_ptr 756 // plus just the filename ("UIFoundation"), then the parent 757 // dir plus filename ("UIFoundation.framework/UIFoundation") 758 // etc - up to four names (to handle "Foo.framework/Contents/MacOS/Foo") 759 760 for (size_t j = 0; j < 4 && j < path_parts_size - 1; ++j) { 761 FileSpec path_to_try(module_search_paths_ptr->GetFileSpecAtIndex(i)); 762 763 // Add the components backwards. For 764 // .../PrivateFrameworks/UIFoundation.framework/UIFoundation 765 // path_parts is 766 // [0] UIFoundation 767 // [1] UIFoundation.framework 768 // [2] PrivateFrameworks 769 // 770 // and if 'j' is 2, we want to append path_parts[1] and then 771 // path_parts[0], aka 772 // 'UIFoundation.framework/UIFoundation', to the module_search_paths_ptr 773 // path. 774 775 for (int k = j; k >= 0; --k) { 776 path_to_try.AppendPathComponent(path_parts[k]); 777 } 778 779 if (path_to_try.Exists()) { 780 ModuleSpec new_module_spec(module_spec); 781 new_module_spec.GetFileSpec() = path_to_try; 782 Error new_error(Platform::GetSharedModule( 783 new_module_spec, process, module_sp, NULL, old_module_sp_ptr, 784 did_create_ptr)); 785 786 if (module_sp) { 787 module_sp->SetPlatformFileSpec(path_to_try); 788 return new_error; 789 } 790 } 791 } 792 } 793 } 794 795 const bool always_create = false; 796 error = ModuleList::GetSharedModule( 797 module_spec, module_sp, module_search_paths_ptr, old_module_sp_ptr, 798 did_create_ptr, always_create); 799 800 if (module_sp) 801 module_sp->SetPlatformFileSpec(platform_file); 802 803 return error; 804 } 805 806 bool PlatformRemoteiOS::GetSupportedArchitectureAtIndex(uint32_t idx, 807 ArchSpec &arch) { 808 return ARMGetSupportedArchitectureAtIndex(idx, arch); 809 } 810 811 uint32_t PlatformRemoteiOS::GetConnectedSDKIndex() { 812 if (IsConnected()) { 813 if (m_connected_module_sdk_idx == UINT32_MAX) { 814 std::string build; 815 if (GetRemoteOSBuildString(build)) { 816 const uint32_t num_sdk_infos = m_sdk_directory_infos.size(); 817 for (uint32_t i = 0; i < num_sdk_infos; ++i) { 818 const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i]; 819 if (strstr(sdk_dir_info.directory.GetFilename().AsCString(""), 820 build.c_str())) { 821 m_connected_module_sdk_idx = i; 822 } 823 } 824 } 825 } 826 } else { 827 m_connected_module_sdk_idx = UINT32_MAX; 828 } 829 return m_connected_module_sdk_idx; 830 } 831 832 uint32_t PlatformRemoteiOS::GetSDKIndexBySDKDirectoryInfo( 833 const SDKDirectoryInfo *sdk_info) { 834 if (sdk_info == NULL) { 835 return UINT32_MAX; 836 } 837 838 return sdk_info - &m_sdk_directory_infos[0]; 839 } 840