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