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