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 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); 326 if (m_sdk_directory_infos.empty()) 327 { 328 const char *device_support_dir = GetDeviceSupportDirectory(); 329 if (log) 330 { 331 log->Printf ("PlatformRemoteAppleWatch::UpdateSDKDirectoryInfosIfNeeded Got DeviceSupport directory %s", device_support_dir); 332 } 333 if (device_support_dir) 334 { 335 const bool find_directories = true; 336 const bool find_files = false; 337 const bool find_other = false; 338 339 SDKDirectoryInfoCollection builtin_sdk_directory_infos; 340 FileSpec::EnumerateDirectory (m_device_support_directory.c_str(), 341 find_directories, 342 find_files, 343 find_other, 344 GetContainedFilesIntoVectorOfStringsCallback, 345 &builtin_sdk_directory_infos); 346 347 // Only add SDK directories that have symbols in them, some SDKs only contain 348 // developer disk images and no symbols, so they aren't useful to us. 349 FileSpec sdk_symbols_symlink_fspec; 350 for (const auto &sdk_directory_info : builtin_sdk_directory_infos) 351 { 352 sdk_symbols_symlink_fspec = sdk_directory_info.directory; 353 sdk_symbols_symlink_fspec.AppendPathComponent("Symbols.Internal"); 354 if (sdk_symbols_symlink_fspec.Exists()) 355 { 356 m_sdk_directory_infos.push_back(sdk_directory_info); 357 if (log) 358 { 359 log->Printf ("PlatformRemoteAppleWatch::UpdateSDKDirectoryInfosIfNeeded added builtin SDK directory %s", sdk_symbols_symlink_fspec.GetPath().c_str()); 360 } 361 } 362 else 363 { 364 sdk_symbols_symlink_fspec.GetFilename().SetCString("Symbols"); 365 if (sdk_symbols_symlink_fspec.Exists()) 366 m_sdk_directory_infos.push_back(sdk_directory_info); 367 if (log) 368 { 369 log->Printf ("PlatformRemoteAppleWatch::UpdateSDKDirectoryInfosIfNeeded added builtin SDK directory %s", sdk_symbols_symlink_fspec.GetPath().c_str()); 370 } 371 } 372 } 373 374 const uint32_t num_installed = m_sdk_directory_infos.size(); 375 FileSpec local_sdk_cache("~/Library/Developer/Xcode/watchOS DeviceSupport", true); 376 if (!local_sdk_cache.Exists()) 377 { 378 local_sdk_cache = FileSpec("~/Library/Developer/Xcode/watch OS DeviceSupport", true); 379 } 380 if (!local_sdk_cache.Exists()) 381 { 382 local_sdk_cache = FileSpec("~/Library/Developer/Xcode/WatchOS DeviceSupport", true); 383 } 384 if (!local_sdk_cache.Exists()) 385 { 386 local_sdk_cache = FileSpec("~/Library/Developer/Xcode/Watch OS DeviceSupport", true); 387 } 388 if (local_sdk_cache.Exists()) 389 { 390 if (log) 391 { 392 log->Printf ("PlatformRemoteAppleWatch::UpdateSDKDirectoryInfosIfNeeded searching %s for additional SDKs", local_sdk_cache.GetPath().c_str()); 393 } 394 char path[PATH_MAX]; 395 if (local_sdk_cache.GetPath(path, sizeof(path))) 396 { 397 FileSpec::EnumerateDirectory (path, 398 find_directories, 399 find_files, 400 find_other, 401 GetContainedFilesIntoVectorOfStringsCallback, 402 &m_sdk_directory_infos); 403 const uint32_t num_sdk_infos = m_sdk_directory_infos.size(); 404 // First try for an exact match of major, minor and update 405 for (uint32_t i=num_installed; i<num_sdk_infos; ++i) 406 { 407 m_sdk_directory_infos[i].user_cached = true; 408 if (log) 409 { 410 log->Printf ("PlatformRemoteAppleWatch::UpdateSDKDirectoryInfosIfNeeded user SDK directory %s", m_sdk_directory_infos[i].directory.GetPath().c_str()); 411 } 412 } 413 } 414 } 415 } 416 } 417 return !m_sdk_directory_infos.empty(); 418 } 419 420 const PlatformRemoteAppleWatch::SDKDirectoryInfo * 421 PlatformRemoteAppleWatch::GetSDKDirectoryForCurrentOSVersion () 422 { 423 uint32_t i; 424 if (UpdateSDKDirectoryInfosIfNeeded()) 425 { 426 const uint32_t num_sdk_infos = m_sdk_directory_infos.size(); 427 428 // Check to see if the user specified a build string. If they did, then 429 // be sure to match it. 430 std::vector<bool> check_sdk_info(num_sdk_infos, true); 431 ConstString build(m_sdk_build); 432 if (build) 433 { 434 for (i=0; i<num_sdk_infos; ++i) 435 check_sdk_info[i] = m_sdk_directory_infos[i].build == build; 436 } 437 438 // If we are connected we can find the version of the OS the platform 439 // us running on and select the right SDK 440 uint32_t major, minor, update; 441 if (GetOSVersion(major, minor, update)) 442 { 443 if (UpdateSDKDirectoryInfosIfNeeded()) 444 { 445 // First try for an exact match of major, minor and update 446 for (i=0; i<num_sdk_infos; ++i) 447 { 448 if (check_sdk_info[i]) 449 { 450 if (m_sdk_directory_infos[i].version_major == major && 451 m_sdk_directory_infos[i].version_minor == minor && 452 m_sdk_directory_infos[i].version_update == update) 453 { 454 return &m_sdk_directory_infos[i]; 455 } 456 } 457 } 458 // First try for an exact match of major and minor 459 for (i=0; i<num_sdk_infos; ++i) 460 { 461 if (check_sdk_info[i]) 462 { 463 if (m_sdk_directory_infos[i].version_major == major && 464 m_sdk_directory_infos[i].version_minor == minor) 465 { 466 return &m_sdk_directory_infos[i]; 467 } 468 } 469 } 470 // Lastly try to match of major version only.. 471 for (i=0; i<num_sdk_infos; ++i) 472 { 473 if (check_sdk_info[i]) 474 { 475 if (m_sdk_directory_infos[i].version_major == major) 476 { 477 return &m_sdk_directory_infos[i]; 478 } 479 } 480 } 481 } 482 } 483 else if (build) 484 { 485 // No version, just a build number, search for the first one that matches 486 for (i=0; i<num_sdk_infos; ++i) 487 if (check_sdk_info[i]) 488 return &m_sdk_directory_infos[i]; 489 } 490 } 491 return nullptr; 492 } 493 494 const PlatformRemoteAppleWatch::SDKDirectoryInfo * 495 PlatformRemoteAppleWatch::GetSDKDirectoryForLatestOSVersion () 496 { 497 const PlatformRemoteAppleWatch::SDKDirectoryInfo *result = nullptr; 498 if (UpdateSDKDirectoryInfosIfNeeded()) 499 { 500 const uint32_t num_sdk_infos = m_sdk_directory_infos.size(); 501 // First try for an exact match of major, minor and update 502 for (uint32_t i=0; i<num_sdk_infos; ++i) 503 { 504 const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i]; 505 if (sdk_dir_info.version_major != UINT32_MAX) 506 { 507 if (result == nullptr || sdk_dir_info.version_major > result->version_major) 508 { 509 result = &sdk_dir_info; 510 } 511 else if (sdk_dir_info.version_major == result->version_major) 512 { 513 if (sdk_dir_info.version_minor > result->version_minor) 514 { 515 result = &sdk_dir_info; 516 } 517 else if (sdk_dir_info.version_minor == result->version_minor) 518 { 519 if (sdk_dir_info.version_update > result->version_update) 520 { 521 result = &sdk_dir_info; 522 } 523 } 524 } 525 } 526 } 527 } 528 return result; 529 } 530 531 const char * 532 PlatformRemoteAppleWatch::GetDeviceSupportDirectory() 533 { 534 if (m_device_support_directory.empty()) 535 { 536 const char *device_support_dir = GetDeveloperDirectory(); 537 if (device_support_dir) 538 { 539 m_device_support_directory.assign (device_support_dir); 540 m_device_support_directory.append ("/Platforms/watchOS.platform/DeviceSupport"); 541 FileSpec platform_device_support_dir (m_device_support_directory.c_str(), true); 542 if (!platform_device_support_dir.Exists()) 543 { 544 std::string alt_platform_dirname = device_support_dir; 545 alt_platform_dirname.append ("/Platforms/WatchOS.platform/DeviceSupport"); 546 FileSpec alt_platform_device_support_dir (m_device_support_directory.c_str(), true); 547 if (alt_platform_device_support_dir.Exists()) 548 { 549 m_device_support_directory = alt_platform_dirname; 550 } 551 } 552 } 553 else 554 { 555 // Assign a single NULL character so we know we tried to find the device 556 // support directory and we don't keep trying to find it over and over. 557 m_device_support_directory.assign (1, '\0'); 558 } 559 } 560 // We should have put a single NULL character into m_device_support_directory 561 // or it should have a valid path if the code gets here 562 assert (m_device_support_directory.empty() == false); 563 if (m_device_support_directory[0]) 564 return m_device_support_directory.c_str(); 565 return nullptr; 566 } 567 568 const char * 569 PlatformRemoteAppleWatch::GetDeviceSupportDirectoryForOSVersion() 570 { 571 if (m_sdk_sysroot) 572 return m_sdk_sysroot.GetCString(); 573 574 if (m_device_support_directory_for_os_version.empty()) 575 { 576 const PlatformRemoteAppleWatch::SDKDirectoryInfo *sdk_dir_info = GetSDKDirectoryForCurrentOSVersion (); 577 if (sdk_dir_info == nullptr) 578 sdk_dir_info = GetSDKDirectoryForLatestOSVersion (); 579 if (sdk_dir_info) 580 { 581 char path[PATH_MAX]; 582 if (sdk_dir_info->directory.GetPath(path, sizeof(path))) 583 { 584 m_device_support_directory_for_os_version = path; 585 return m_device_support_directory_for_os_version.c_str(); 586 } 587 } 588 else 589 { 590 // Assign a single NULL character so we know we tried to find the device 591 // support directory and we don't keep trying to find it over and over. 592 m_device_support_directory_for_os_version.assign (1, '\0'); 593 } 594 } 595 // We should have put a single NULL character into m_device_support_directory_for_os_version 596 // or it should have a valid path if the code gets here 597 assert (m_device_support_directory_for_os_version.empty() == false); 598 if (m_device_support_directory_for_os_version[0]) 599 return m_device_support_directory_for_os_version.c_str(); 600 return nullptr; 601 } 602 603 uint32_t 604 PlatformRemoteAppleWatch::FindFileInAllSDKs (const char *platform_file_path, 605 FileSpecList &file_list) 606 { 607 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST | LIBLLDB_LOG_VERBOSE); 608 if (platform_file_path && platform_file_path[0] && UpdateSDKDirectoryInfosIfNeeded()) 609 { 610 const uint32_t num_sdk_infos = m_sdk_directory_infos.size(); 611 lldb_private::FileSpec local_file; 612 // First try for an exact match of major, minor and update 613 for (uint32_t sdk_idx=0; sdk_idx<num_sdk_infos; ++sdk_idx) 614 { 615 if (log) 616 { 617 log->Printf ("Searching for %s in sdk path %s", platform_file_path, m_sdk_directory_infos[sdk_idx].directory.GetPath().c_str()); 618 } 619 if (GetFileInSDK (platform_file_path, 620 sdk_idx, 621 local_file)) 622 { 623 file_list.Append(local_file); 624 } 625 } 626 } 627 return file_list.GetSize(); 628 } 629 630 bool 631 PlatformRemoteAppleWatch::GetFileInSDK (const char *platform_file_path, 632 uint32_t sdk_idx, 633 lldb_private::FileSpec &local_file) 634 { 635 if (sdk_idx < m_sdk_directory_infos.size()) 636 { 637 char sdkroot_path[PATH_MAX]; 638 const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[sdk_idx]; 639 if (sdk_dir_info.directory.GetPath(sdkroot_path, sizeof(sdkroot_path))) 640 { 641 const bool symbols_dirs_only = true; 642 643 return GetFileInSDKRoot (platform_file_path, 644 sdkroot_path, 645 symbols_dirs_only, 646 local_file); 647 } 648 } 649 return false; 650 } 651 652 bool 653 PlatformRemoteAppleWatch::GetFileInSDKRoot (const char *platform_file_path, 654 const char *sdkroot_path, 655 bool symbols_dirs_only, 656 lldb_private::FileSpec &local_file) 657 { 658 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); 659 if (sdkroot_path && sdkroot_path[0] && platform_file_path && platform_file_path[0]) 660 { 661 char resolved_path[PATH_MAX]; 662 663 if (!symbols_dirs_only) 664 { 665 ::snprintf (resolved_path, 666 sizeof(resolved_path), 667 "%s%s", 668 sdkroot_path, 669 platform_file_path); 670 671 local_file.SetFile(resolved_path, true); 672 if (local_file.Exists()) 673 { 674 if (log) 675 { 676 log->Printf ("Found a copy of %s in the SDK dir %s", platform_file_path, sdkroot_path); 677 } 678 return true; 679 } 680 } 681 682 ::snprintf (resolved_path, 683 sizeof(resolved_path), 684 "%s/Symbols.Internal%s", 685 sdkroot_path, 686 platform_file_path); 687 688 local_file.SetFile(resolved_path, true); 689 if (local_file.Exists()) 690 { 691 if (log) 692 { 693 log->Printf ("Found a copy of %s in the SDK dir %s/Symbols.Internal", platform_file_path, sdkroot_path); 694 } 695 return true; 696 } 697 ::snprintf (resolved_path, 698 sizeof(resolved_path), 699 "%s/Symbols%s", 700 sdkroot_path, 701 platform_file_path); 702 703 local_file.SetFile(resolved_path, true); 704 if (local_file.Exists()) 705 { 706 if (log) 707 { 708 log->Printf ("Found a copy of %s in the SDK dir %s/Symbols", platform_file_path, sdkroot_path); 709 } 710 return true; 711 } 712 } 713 return false; 714 } 715 716 Error 717 PlatformRemoteAppleWatch::GetSymbolFile (const FileSpec &platform_file, 718 const UUID *uuid_ptr, 719 FileSpec &local_file) 720 { 721 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); 722 Error error; 723 char platform_file_path[PATH_MAX]; 724 if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) 725 { 726 char resolved_path[PATH_MAX]; 727 728 const char * os_version_dir = GetDeviceSupportDirectoryForOSVersion(); 729 if (os_version_dir) 730 { 731 ::snprintf (resolved_path, 732 sizeof(resolved_path), 733 "%s/%s", 734 os_version_dir, 735 platform_file_path); 736 737 local_file.SetFile(resolved_path, true); 738 if (local_file.Exists()) 739 { 740 if (log) 741 { 742 log->Printf ("Found a copy of %s in the DeviceSupport dir %s", platform_file_path, os_version_dir); 743 } 744 return error; 745 } 746 747 ::snprintf (resolved_path, 748 sizeof(resolved_path), 749 "%s/Symbols.Internal/%s", 750 os_version_dir, 751 platform_file_path); 752 753 local_file.SetFile(resolved_path, true); 754 if (local_file.Exists()) 755 { 756 if (log) 757 { 758 log->Printf ("Found a copy of %s in the DeviceSupport dir %s/Symbols.Internal", platform_file_path, os_version_dir); 759 } 760 return error; 761 } 762 ::snprintf (resolved_path, 763 sizeof(resolved_path), 764 "%s/Symbols/%s", 765 os_version_dir, 766 platform_file_path); 767 768 local_file.SetFile(resolved_path, true); 769 if (local_file.Exists()) 770 { 771 if (log) 772 { 773 log->Printf ("Found a copy of %s in the DeviceSupport dir %s/Symbols", platform_file_path, os_version_dir); 774 } 775 return error; 776 } 777 778 } 779 local_file = platform_file; 780 if (local_file.Exists()) 781 return error; 782 783 error.SetErrorStringWithFormat ("unable to locate a platform file for '%s' in platform '%s'", 784 platform_file_path, 785 GetPluginName().GetCString()); 786 } 787 else 788 { 789 error.SetErrorString ("invalid platform file argument"); 790 } 791 return error; 792 } 793 794 Error 795 PlatformRemoteAppleWatch::GetSharedModule (const ModuleSpec &module_spec, 796 lldb_private::Process* process, 797 ModuleSP &module_sp, 798 const FileSpecList *module_search_paths_ptr, 799 ModuleSP *old_module_sp_ptr, 800 bool *did_create_ptr) 801 { 802 // For Apple Watch, the SDK files are all cached locally on the host 803 // system. So first we ask for the file in the cached SDK, 804 // then we attempt to get a shared module for the right architecture 805 // with the right UUID. 806 const FileSpec &platform_file = module_spec.GetFileSpec(); 807 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST | LIBLLDB_LOG_VERBOSE); 808 809 Error error; 810 char platform_file_path[PATH_MAX]; 811 812 if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) 813 { 814 ModuleSpec platform_module_spec(module_spec); 815 816 UpdateSDKDirectoryInfosIfNeeded(); 817 818 const uint32_t num_sdk_infos = m_sdk_directory_infos.size(); 819 820 // If we are connected we migth be able to correctly deduce the SDK directory 821 // using the OS build. 822 const uint32_t connected_sdk_idx = GetConnectedSDKIndex (); 823 if (connected_sdk_idx < num_sdk_infos) 824 { 825 if (log) 826 { 827 log->Printf ("Searching for %s in sdk path %s", platform_file_path, m_sdk_directory_infos[connected_sdk_idx].directory.GetPath().c_str()); 828 } 829 if (GetFileInSDK (platform_file_path, connected_sdk_idx, platform_module_spec.GetFileSpec())) 830 { 831 module_sp.reset(); 832 error = ResolveExecutable(platform_module_spec, 833 module_sp, 834 nullptr); 835 if (module_sp) 836 { 837 m_last_module_sdk_idx = connected_sdk_idx; 838 error.Clear(); 839 return error; 840 } 841 } 842 } 843 844 // Try the last SDK index if it is set as most files from an SDK 845 // will tend to be valid in that same SDK. 846 if (m_last_module_sdk_idx < num_sdk_infos) 847 { 848 if (log) 849 { 850 log->Printf ("Searching for %s in sdk path %s", platform_file_path, m_sdk_directory_infos[m_last_module_sdk_idx].directory.GetPath().c_str()); 851 } 852 if (GetFileInSDK (platform_file_path, m_last_module_sdk_idx, platform_module_spec.GetFileSpec())) 853 { 854 module_sp.reset(); 855 error = ResolveExecutable(platform_module_spec, 856 module_sp, 857 nullptr); 858 if (module_sp) 859 { 860 error.Clear(); 861 return error; 862 } 863 } 864 } 865 866 // First try for an exact match of major, minor and update 867 for (uint32_t sdk_idx=0; sdk_idx<num_sdk_infos; ++sdk_idx) 868 { 869 if (m_last_module_sdk_idx == sdk_idx) 870 { 871 // Skip the last module SDK index if we already searched 872 // it above 873 continue; 874 } 875 if (log) 876 { 877 log->Printf ("Searching for %s in sdk path %s", platform_file_path, m_sdk_directory_infos[sdk_idx].directory.GetPath().c_str()); 878 } 879 if (GetFileInSDK (platform_file_path, sdk_idx, platform_module_spec.GetFileSpec())) 880 { 881 //printf ("sdk[%u]: '%s'\n", sdk_idx, local_file.GetPath().c_str()); 882 883 error = ResolveExecutable(platform_module_spec, module_sp, nullptr); 884 if (module_sp) 885 { 886 // Remember the index of the last SDK that we found a file 887 // in in case the wrong SDK was selected. 888 m_last_module_sdk_idx = sdk_idx; 889 error.Clear(); 890 return error; 891 } 892 } 893 } 894 } 895 // Not the module we are looking for... Nothing to see here... 896 module_sp.reset(); 897 898 // This may not be an SDK-related module. Try whether we can bring in the thing to our local cache. 899 error = GetSharedModuleWithLocalCache(module_spec, module_sp, module_search_paths_ptr, old_module_sp_ptr, did_create_ptr); 900 if (error.Success()) 901 return error; 902 903 const bool always_create = false; 904 error = ModuleList::GetSharedModule (module_spec, 905 module_sp, 906 module_search_paths_ptr, 907 old_module_sp_ptr, 908 did_create_ptr, 909 always_create); 910 911 if (module_sp) 912 module_sp->SetPlatformFileSpec(platform_file); 913 914 return error; 915 } 916 917 bool 918 PlatformRemoteAppleWatch::GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch) 919 { 920 ArchSpec system_arch (GetSystemArchitecture()); 921 922 const ArchSpec::Core system_core = system_arch.GetCore(); 923 switch (system_core) 924 { 925 default: 926 switch (idx) 927 { 928 case 0: arch.SetTriple ("arm64-apple-watchos"); return true; 929 case 1: arch.SetTriple ("armv7k-apple-watchos"); return true; 930 case 2: arch.SetTriple ("armv7s-apple-watchos"); return true; 931 case 3: arch.SetTriple ("armv7-apple-watchos"); return true; 932 case 4: arch.SetTriple ("thumbv7k-apple-watchos"); return true; 933 case 5: arch.SetTriple ("thumbv7-apple-watchos"); return true; 934 case 6: arch.SetTriple ("thumbv7s-apple-watchos"); return true; 935 default: break; 936 } 937 break; 938 939 case ArchSpec::eCore_arm_arm64: 940 switch (idx) 941 { 942 case 0: arch.SetTriple ("arm64-apple-watchos"); return true; 943 case 1: arch.SetTriple ("armv7k-apple-watchos"); return true; 944 case 2: arch.SetTriple ("armv7s-apple-watchos"); return true; 945 case 3: arch.SetTriple ("armv7-apple-watchos"); return true; 946 case 4: arch.SetTriple ("thumbv7k-apple-watchos"); return true; 947 case 5: arch.SetTriple ("thumbv7-apple-watchos"); return true; 948 case 6: arch.SetTriple ("thumbv7s-apple-watchos"); return true; 949 default: break; 950 } 951 break; 952 953 case ArchSpec::eCore_arm_armv7k: 954 switch (idx) 955 { 956 case 0: arch.SetTriple ("armv7k-apple-watchos"); return true; 957 case 1: arch.SetTriple ("armv7s-apple-watchos"); return true; 958 case 2: arch.SetTriple ("armv7-apple-watchos"); return true; 959 case 3: arch.SetTriple ("thumbv7k-apple-watchos"); return true; 960 case 4: arch.SetTriple ("thumbv7-apple-watchos"); return true; 961 case 5: arch.SetTriple ("thumbv7s-apple-watchos"); return true; 962 default: break; 963 } 964 break; 965 966 case ArchSpec::eCore_arm_armv7s: 967 switch (idx) 968 { 969 case 0: arch.SetTriple ("armv7s-apple-watchos"); return true; 970 case 1: arch.SetTriple ("armv7k-apple-watchos"); return true; 971 case 2: arch.SetTriple ("armv7-apple-watchos"); return true; 972 case 3: arch.SetTriple ("thumbv7k-apple-watchos"); return true; 973 case 4: arch.SetTriple ("thumbv7-apple-watchos"); return true; 974 case 5: arch.SetTriple ("thumbv7s-apple-watchos"); return true; 975 default: break; 976 } 977 break; 978 979 case ArchSpec::eCore_arm_armv7: 980 switch (idx) 981 { 982 case 0: arch.SetTriple ("armv7-apple-watchos"); return true; 983 case 1: arch.SetTriple ("armv7k-apple-watchos"); return true; 984 case 2: arch.SetTriple ("thumbv7k-apple-watchos"); return true; 985 case 3: arch.SetTriple ("thumbv7-apple-watchos"); return true; 986 default: break; 987 } 988 break; 989 } 990 arch.Clear(); 991 return false; 992 } 993 994 uint32_t 995 PlatformRemoteAppleWatch::GetConnectedSDKIndex () 996 { 997 if (IsConnected()) 998 { 999 if (m_connected_module_sdk_idx == UINT32_MAX) 1000 { 1001 std::string build; 1002 if (GetRemoteOSBuildString(build)) 1003 { 1004 const uint32_t num_sdk_infos = m_sdk_directory_infos.size(); 1005 for (uint32_t i=0; i<num_sdk_infos; ++i) 1006 { 1007 const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i]; 1008 if (strstr(sdk_dir_info.directory.GetFilename().AsCString(""), build.c_str())) 1009 { 1010 m_connected_module_sdk_idx = i; 1011 } 1012 } 1013 } 1014 } 1015 } 1016 else 1017 { 1018 m_connected_module_sdk_idx = UINT32_MAX; 1019 } 1020 return m_connected_module_sdk_idx; 1021 } 1022