1 //===-- PlatformDarwin.cpp ------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "PlatformDarwin.h" 10 11 #include <cstring> 12 13 #include <algorithm> 14 #include <memory> 15 #include <mutex> 16 17 #include "lldb/Breakpoint/BreakpointLocation.h" 18 #include "lldb/Breakpoint/BreakpointSite.h" 19 #include "lldb/Core/Debugger.h" 20 #include "lldb/Core/Module.h" 21 #include "lldb/Core/ModuleSpec.h" 22 #include "lldb/Core/Section.h" 23 #include "lldb/Host/Host.h" 24 #include "lldb/Host/HostInfo.h" 25 #include "lldb/Host/XML.h" 26 #include "lldb/Interpreter/CommandInterpreter.h" 27 #include "lldb/Symbol/LocateSymbolFile.h" 28 #include "lldb/Symbol/ObjectFile.h" 29 #include "lldb/Symbol/SymbolFile.h" 30 #include "lldb/Symbol/SymbolVendor.h" 31 #include "lldb/Target/Platform.h" 32 #include "lldb/Target/Process.h" 33 #include "lldb/Target/Target.h" 34 #include "lldb/Utility/Log.h" 35 #include "lldb/Utility/ProcessInfo.h" 36 #include "lldb/Utility/Status.h" 37 #include "lldb/Utility/Timer.h" 38 #include "llvm/ADT/STLExtras.h" 39 #include "llvm/Support/FileSystem.h" 40 #include "llvm/Support/Threading.h" 41 #include "llvm/Support/VersionTuple.h" 42 43 #if defined(__APPLE__) 44 #include <TargetConditionals.h> 45 #endif 46 47 using namespace lldb; 48 using namespace lldb_private; 49 50 /// Default Constructor 51 PlatformDarwin::PlatformDarwin(bool is_host) : PlatformPOSIX(is_host) {} 52 53 /// Destructor. 54 /// 55 /// The destructor is virtual since this class is designed to be 56 /// inherited from by the plug-in instance. 57 PlatformDarwin::~PlatformDarwin() = default; 58 59 lldb_private::Status 60 PlatformDarwin::PutFile(const lldb_private::FileSpec &source, 61 const lldb_private::FileSpec &destination, uint32_t uid, 62 uint32_t gid) { 63 // Unconditionally unlink the destination. If it is an executable, 64 // simply opening it and truncating its contents would invalidate 65 // its cached code signature. 66 Unlink(destination); 67 return PlatformPOSIX::PutFile(source, destination, uid, gid); 68 } 69 70 FileSpecList PlatformDarwin::LocateExecutableScriptingResources( 71 Target *target, Module &module, Stream *feedback_stream) { 72 FileSpecList file_list; 73 if (target && 74 target->GetDebugger().GetScriptLanguage() == eScriptLanguagePython) { 75 // NB some extensions might be meaningful and should not be stripped - 76 // "this.binary.file" 77 // should not lose ".file" but GetFileNameStrippingExtension() will do 78 // precisely that. Ideally, we should have a per-platform list of 79 // extensions (".exe", ".app", ".dSYM", ".framework") which should be 80 // stripped while leaving "this.binary.file" as-is. 81 82 FileSpec module_spec = module.GetFileSpec(); 83 84 if (module_spec) { 85 if (SymbolFile *symfile = module.GetSymbolFile()) { 86 ObjectFile *objfile = symfile->GetObjectFile(); 87 if (objfile) { 88 FileSpec symfile_spec(objfile->GetFileSpec()); 89 if (symfile_spec && 90 strcasestr(symfile_spec.GetPath().c_str(), 91 ".dSYM/Contents/Resources/DWARF") != nullptr && 92 FileSystem::Instance().Exists(symfile_spec)) { 93 while (module_spec.GetFilename()) { 94 std::string module_basename( 95 module_spec.GetFilename().GetCString()); 96 std::string original_module_basename(module_basename); 97 98 bool was_keyword = false; 99 100 // FIXME: for Python, we cannot allow certain characters in 101 // module 102 // filenames we import. Theoretically, different scripting 103 // languages may have different sets of forbidden tokens in 104 // filenames, and that should be dealt with by each 105 // ScriptInterpreter. For now, we just replace dots with 106 // underscores, but if we ever support anything other than 107 // Python we will need to rework this 108 std::replace(module_basename.begin(), module_basename.end(), '.', 109 '_'); 110 std::replace(module_basename.begin(), module_basename.end(), ' ', 111 '_'); 112 std::replace(module_basename.begin(), module_basename.end(), '-', 113 '_'); 114 ScriptInterpreter *script_interpreter = 115 target->GetDebugger().GetScriptInterpreter(); 116 if (script_interpreter && 117 script_interpreter->IsReservedWord(module_basename.c_str())) { 118 module_basename.insert(module_basename.begin(), '_'); 119 was_keyword = true; 120 } 121 122 StreamString path_string; 123 StreamString original_path_string; 124 // for OSX we are going to be in 125 // .dSYM/Contents/Resources/DWARF/<basename> let us go to 126 // .dSYM/Contents/Resources/Python/<basename>.py and see if the 127 // file exists 128 path_string.Printf("%s/../Python/%s.py", 129 symfile_spec.GetDirectory().GetCString(), 130 module_basename.c_str()); 131 original_path_string.Printf( 132 "%s/../Python/%s.py", 133 symfile_spec.GetDirectory().GetCString(), 134 original_module_basename.c_str()); 135 FileSpec script_fspec(path_string.GetString()); 136 FileSystem::Instance().Resolve(script_fspec); 137 FileSpec orig_script_fspec(original_path_string.GetString()); 138 FileSystem::Instance().Resolve(orig_script_fspec); 139 140 // if we did some replacements of reserved characters, and a 141 // file with the untampered name exists, then warn the user 142 // that the file as-is shall not be loaded 143 if (feedback_stream) { 144 if (module_basename != original_module_basename && 145 FileSystem::Instance().Exists(orig_script_fspec)) { 146 const char *reason_for_complaint = 147 was_keyword ? "conflicts with a keyword" 148 : "contains reserved characters"; 149 if (FileSystem::Instance().Exists(script_fspec)) 150 feedback_stream->Printf( 151 "warning: the symbol file '%s' contains a debug " 152 "script. However, its name" 153 " '%s' %s and as such cannot be loaded. LLDB will" 154 " load '%s' instead. Consider removing the file with " 155 "the malformed name to" 156 " eliminate this warning.\n", 157 symfile_spec.GetPath().c_str(), 158 original_path_string.GetData(), reason_for_complaint, 159 path_string.GetData()); 160 else 161 feedback_stream->Printf( 162 "warning: the symbol file '%s' contains a debug " 163 "script. However, its name" 164 " %s and as such cannot be loaded. If you intend" 165 " to have this script loaded, please rename '%s' to " 166 "'%s' and retry.\n", 167 symfile_spec.GetPath().c_str(), reason_for_complaint, 168 original_path_string.GetData(), path_string.GetData()); 169 } 170 } 171 172 if (FileSystem::Instance().Exists(script_fspec)) { 173 file_list.Append(script_fspec); 174 break; 175 } 176 177 // If we didn't find the python file, then keep stripping the 178 // extensions and try again 179 ConstString filename_no_extension( 180 module_spec.GetFileNameStrippingExtension()); 181 if (module_spec.GetFilename() == filename_no_extension) 182 break; 183 184 module_spec.GetFilename() = filename_no_extension; 185 } 186 } 187 } 188 } 189 } 190 } 191 return file_list; 192 } 193 194 Status PlatformDarwin::ResolveSymbolFile(Target &target, 195 const ModuleSpec &sym_spec, 196 FileSpec &sym_file) { 197 sym_file = sym_spec.GetSymbolFileSpec(); 198 if (FileSystem::Instance().IsDirectory(sym_file)) { 199 sym_file = Symbols::FindSymbolFileInBundle(sym_file, sym_spec.GetUUIDPtr(), 200 sym_spec.GetArchitecturePtr()); 201 } 202 return {}; 203 } 204 205 static lldb_private::Status 206 MakeCacheFolderForFile(const FileSpec &module_cache_spec) { 207 FileSpec module_cache_folder = 208 module_cache_spec.CopyByRemovingLastPathComponent(); 209 return llvm::sys::fs::create_directory(module_cache_folder.GetPath()); 210 } 211 212 static lldb_private::Status 213 BringInRemoteFile(Platform *platform, 214 const lldb_private::ModuleSpec &module_spec, 215 const FileSpec &module_cache_spec) { 216 MakeCacheFolderForFile(module_cache_spec); 217 Status err = platform->GetFile(module_spec.GetFileSpec(), module_cache_spec); 218 return err; 219 } 220 221 lldb_private::Status PlatformDarwin::GetSharedModuleWithLocalCache( 222 const lldb_private::ModuleSpec &module_spec, lldb::ModuleSP &module_sp, 223 const lldb_private::FileSpecList *module_search_paths_ptr, 224 llvm::SmallVectorImpl<lldb::ModuleSP> *old_modules, bool *did_create_ptr) { 225 226 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM)); 227 LLDB_LOGF(log, 228 "[%s] Trying to find module %s/%s - platform path %s/%s symbol " 229 "path %s/%s", 230 (IsHost() ? "host" : "remote"), 231 module_spec.GetFileSpec().GetDirectory().AsCString(), 232 module_spec.GetFileSpec().GetFilename().AsCString(), 233 module_spec.GetPlatformFileSpec().GetDirectory().AsCString(), 234 module_spec.GetPlatformFileSpec().GetFilename().AsCString(), 235 module_spec.GetSymbolFileSpec().GetDirectory().AsCString(), 236 module_spec.GetSymbolFileSpec().GetFilename().AsCString()); 237 238 Status err; 239 240 if (IsHost()) { 241 // When debugging on the host, we are most likely using the same shared 242 // cache as our inferior. The dylibs from the shared cache might not 243 // exist on the filesystem, so let's use the images in our own memory 244 // to create the modules. 245 246 // Check if the requested image is in our shared cache. 247 SharedCacheImageInfo image_info = 248 HostInfo::GetSharedCacheImageInfo(module_spec.GetFileSpec().GetPath()); 249 250 // If we found it and it has the correct UUID, let's proceed with 251 // creating a module from the memory contents. 252 if (image_info.uuid && 253 (!module_spec.GetUUID() || module_spec.GetUUID() == image_info.uuid)) { 254 ModuleSpec shared_cache_spec(module_spec.GetFileSpec(), image_info.uuid, 255 image_info.data_sp); 256 err = ModuleList::GetSharedModule(shared_cache_spec, module_sp, 257 module_search_paths_ptr, old_modules, 258 did_create_ptr); 259 if (module_sp) 260 return err; 261 } 262 } 263 264 err = ModuleList::GetSharedModule(module_spec, module_sp, 265 module_search_paths_ptr, old_modules, 266 did_create_ptr); 267 if (module_sp) 268 return err; 269 270 if (!IsHost()) { 271 std::string cache_path(GetLocalCacheDirectory()); 272 // Only search for a locally cached file if we have a valid cache path 273 if (!cache_path.empty()) { 274 std::string module_path(module_spec.GetFileSpec().GetPath()); 275 cache_path.append(module_path); 276 FileSpec module_cache_spec(cache_path); 277 278 // if rsync is supported, always bring in the file - rsync will be very 279 // efficient when files are the same on the local and remote end of the 280 // connection 281 if (this->GetSupportsRSync()) { 282 err = BringInRemoteFile(this, module_spec, module_cache_spec); 283 if (err.Fail()) 284 return err; 285 if (FileSystem::Instance().Exists(module_cache_spec)) { 286 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM)); 287 LLDB_LOGF(log, "[%s] module %s/%s was rsynced and is now there", 288 (IsHost() ? "host" : "remote"), 289 module_spec.GetFileSpec().GetDirectory().AsCString(), 290 module_spec.GetFileSpec().GetFilename().AsCString()); 291 ModuleSpec local_spec(module_cache_spec, 292 module_spec.GetArchitecture()); 293 module_sp = std::make_shared<Module>(local_spec); 294 module_sp->SetPlatformFileSpec(module_spec.GetFileSpec()); 295 return Status(); 296 } 297 } 298 299 // try to find the module in the cache 300 if (FileSystem::Instance().Exists(module_cache_spec)) { 301 // get the local and remote MD5 and compare 302 if (m_remote_platform_sp) { 303 // when going over the *slow* GDB remote transfer mechanism we first 304 // check the hashes of the files - and only do the actual transfer if 305 // they differ 306 uint64_t high_local, high_remote, low_local, low_remote; 307 auto MD5 = llvm::sys::fs::md5_contents(module_cache_spec.GetPath()); 308 if (!MD5) 309 return Status(MD5.getError()); 310 std::tie(high_local, low_local) = MD5->words(); 311 312 m_remote_platform_sp->CalculateMD5(module_spec.GetFileSpec(), 313 low_remote, high_remote); 314 if (low_local != low_remote || high_local != high_remote) { 315 // bring in the remote file 316 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM)); 317 LLDB_LOGF(log, 318 "[%s] module %s/%s needs to be replaced from remote copy", 319 (IsHost() ? "host" : "remote"), 320 module_spec.GetFileSpec().GetDirectory().AsCString(), 321 module_spec.GetFileSpec().GetFilename().AsCString()); 322 Status err = 323 BringInRemoteFile(this, module_spec, module_cache_spec); 324 if (err.Fail()) 325 return err; 326 } 327 } 328 329 ModuleSpec local_spec(module_cache_spec, module_spec.GetArchitecture()); 330 module_sp = std::make_shared<Module>(local_spec); 331 module_sp->SetPlatformFileSpec(module_spec.GetFileSpec()); 332 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM)); 333 LLDB_LOGF(log, "[%s] module %s/%s was found in the cache", 334 (IsHost() ? "host" : "remote"), 335 module_spec.GetFileSpec().GetDirectory().AsCString(), 336 module_spec.GetFileSpec().GetFilename().AsCString()); 337 return Status(); 338 } 339 340 // bring in the remote module file 341 LLDB_LOGF(log, "[%s] module %s/%s needs to come in remotely", 342 (IsHost() ? "host" : "remote"), 343 module_spec.GetFileSpec().GetDirectory().AsCString(), 344 module_spec.GetFileSpec().GetFilename().AsCString()); 345 Status err = BringInRemoteFile(this, module_spec, module_cache_spec); 346 if (err.Fail()) 347 return err; 348 if (FileSystem::Instance().Exists(module_cache_spec)) { 349 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM)); 350 LLDB_LOGF(log, "[%s] module %s/%s is now cached and fine", 351 (IsHost() ? "host" : "remote"), 352 module_spec.GetFileSpec().GetDirectory().AsCString(), 353 module_spec.GetFileSpec().GetFilename().AsCString()); 354 ModuleSpec local_spec(module_cache_spec, module_spec.GetArchitecture()); 355 module_sp = std::make_shared<Module>(local_spec); 356 module_sp->SetPlatformFileSpec(module_spec.GetFileSpec()); 357 return Status(); 358 } else 359 return Status("unable to obtain valid module file"); 360 } else 361 return Status("no cache path"); 362 } else 363 return Status("unable to resolve module"); 364 } 365 366 Status PlatformDarwin::GetSharedModule( 367 const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp, 368 const FileSpecList *module_search_paths_ptr, 369 llvm::SmallVectorImpl<ModuleSP> *old_modules, bool *did_create_ptr) { 370 Status error; 371 module_sp.reset(); 372 373 if (IsRemote()) { 374 // If we have a remote platform always, let it try and locate the shared 375 // module first. 376 if (m_remote_platform_sp) { 377 error = m_remote_platform_sp->GetSharedModule( 378 module_spec, process, module_sp, module_search_paths_ptr, old_modules, 379 did_create_ptr); 380 } 381 } 382 383 if (!module_sp) { 384 // Fall back to the local platform and find the file locally 385 error = Platform::GetSharedModule(module_spec, process, module_sp, 386 module_search_paths_ptr, old_modules, 387 did_create_ptr); 388 389 const FileSpec &platform_file = module_spec.GetFileSpec(); 390 if (!module_sp && module_search_paths_ptr && platform_file) { 391 // We can try to pull off part of the file path up to the bundle 392 // directory level and try any module search paths... 393 FileSpec bundle_directory; 394 if (Host::GetBundleDirectory(platform_file, bundle_directory)) { 395 if (platform_file == bundle_directory) { 396 ModuleSpec new_module_spec(module_spec); 397 new_module_spec.GetFileSpec() = bundle_directory; 398 if (Host::ResolveExecutableInBundle(new_module_spec.GetFileSpec())) { 399 Status new_error(Platform::GetSharedModule( 400 new_module_spec, process, module_sp, nullptr, old_modules, 401 did_create_ptr)); 402 403 if (module_sp) 404 return new_error; 405 } 406 } else { 407 char platform_path[PATH_MAX]; 408 char bundle_dir[PATH_MAX]; 409 platform_file.GetPath(platform_path, sizeof(platform_path)); 410 const size_t bundle_directory_len = 411 bundle_directory.GetPath(bundle_dir, sizeof(bundle_dir)); 412 char new_path[PATH_MAX]; 413 size_t num_module_search_paths = module_search_paths_ptr->GetSize(); 414 for (size_t i = 0; i < num_module_search_paths; ++i) { 415 const size_t search_path_len = 416 module_search_paths_ptr->GetFileSpecAtIndex(i).GetPath( 417 new_path, sizeof(new_path)); 418 if (search_path_len < sizeof(new_path)) { 419 snprintf(new_path + search_path_len, 420 sizeof(new_path) - search_path_len, "/%s", 421 platform_path + bundle_directory_len); 422 FileSpec new_file_spec(new_path); 423 if (FileSystem::Instance().Exists(new_file_spec)) { 424 ModuleSpec new_module_spec(module_spec); 425 new_module_spec.GetFileSpec() = new_file_spec; 426 Status new_error(Platform::GetSharedModule( 427 new_module_spec, process, module_sp, nullptr, old_modules, 428 did_create_ptr)); 429 430 if (module_sp) { 431 module_sp->SetPlatformFileSpec(new_file_spec); 432 return new_error; 433 } 434 } 435 } 436 } 437 } 438 } 439 } 440 } 441 if (module_sp) 442 module_sp->SetPlatformFileSpec(module_spec.GetFileSpec()); 443 return error; 444 } 445 446 size_t 447 PlatformDarwin::GetSoftwareBreakpointTrapOpcode(Target &target, 448 BreakpointSite *bp_site) { 449 const uint8_t *trap_opcode = nullptr; 450 uint32_t trap_opcode_size = 0; 451 bool bp_is_thumb = false; 452 453 llvm::Triple::ArchType machine = target.GetArchitecture().GetMachine(); 454 switch (machine) { 455 case llvm::Triple::aarch64_32: 456 case llvm::Triple::aarch64: { 457 // 'brk #0' or 0xd4200000 in BE byte order 458 static const uint8_t g_arm64_breakpoint_opcode[] = {0x00, 0x00, 0x20, 0xD4}; 459 trap_opcode = g_arm64_breakpoint_opcode; 460 trap_opcode_size = sizeof(g_arm64_breakpoint_opcode); 461 } break; 462 463 case llvm::Triple::thumb: 464 bp_is_thumb = true; 465 LLVM_FALLTHROUGH; 466 case llvm::Triple::arm: { 467 static const uint8_t g_arm_breakpoint_opcode[] = {0xFE, 0xDE, 0xFF, 0xE7}; 468 static const uint8_t g_thumb_breakpooint_opcode[] = {0xFE, 0xDE}; 469 470 // Auto detect arm/thumb if it wasn't explicitly specified 471 if (!bp_is_thumb) { 472 lldb::BreakpointLocationSP bp_loc_sp(bp_site->GetOwnerAtIndex(0)); 473 if (bp_loc_sp) 474 bp_is_thumb = bp_loc_sp->GetAddress().GetAddressClass() == 475 AddressClass::eCodeAlternateISA; 476 } 477 if (bp_is_thumb) { 478 trap_opcode = g_thumb_breakpooint_opcode; 479 trap_opcode_size = sizeof(g_thumb_breakpooint_opcode); 480 break; 481 } 482 trap_opcode = g_arm_breakpoint_opcode; 483 trap_opcode_size = sizeof(g_arm_breakpoint_opcode); 484 } break; 485 486 case llvm::Triple::ppc: 487 case llvm::Triple::ppc64: { 488 static const uint8_t g_ppc_breakpoint_opcode[] = {0x7F, 0xC0, 0x00, 0x08}; 489 trap_opcode = g_ppc_breakpoint_opcode; 490 trap_opcode_size = sizeof(g_ppc_breakpoint_opcode); 491 } break; 492 493 default: 494 return Platform::GetSoftwareBreakpointTrapOpcode(target, bp_site); 495 } 496 497 if (trap_opcode && trap_opcode_size) { 498 if (bp_site->SetTrapOpcode(trap_opcode, trap_opcode_size)) 499 return trap_opcode_size; 500 } 501 return 0; 502 } 503 504 bool PlatformDarwin::ModuleIsExcludedForUnconstrainedSearches( 505 lldb_private::Target &target, const lldb::ModuleSP &module_sp) { 506 if (!module_sp) 507 return false; 508 509 ObjectFile *obj_file = module_sp->GetObjectFile(); 510 if (!obj_file) 511 return false; 512 513 ObjectFile::Type obj_type = obj_file->GetType(); 514 return obj_type == ObjectFile::eTypeDynamicLinker; 515 } 516 517 bool PlatformDarwin::x86GetSupportedArchitectureAtIndex(uint32_t idx, 518 ArchSpec &arch) { 519 ArchSpec host_arch = HostInfo::GetArchitecture(HostInfo::eArchKindDefault); 520 if (host_arch.GetCore() == ArchSpec::eCore_x86_64_x86_64h) { 521 switch (idx) { 522 case 0: 523 arch = host_arch; 524 return true; 525 526 case 1: 527 arch.SetTriple("x86_64-apple-macosx"); 528 return true; 529 530 case 2: 531 arch = HostInfo::GetArchitecture(HostInfo::eArchKind32); 532 return true; 533 534 default: 535 return false; 536 } 537 } else { 538 if (idx == 0) { 539 arch = HostInfo::GetArchitecture(HostInfo::eArchKindDefault); 540 return arch.IsValid(); 541 } else if (idx == 1) { 542 ArchSpec platform_arch( 543 HostInfo::GetArchitecture(HostInfo::eArchKindDefault)); 544 ArchSpec platform_arch64( 545 HostInfo::GetArchitecture(HostInfo::eArchKind64)); 546 if (platform_arch.IsExactMatch(platform_arch64)) { 547 // This macosx platform supports both 32 and 64 bit. Since we already 548 // returned the 64 bit arch for idx == 0, return the 32 bit arch for 549 // idx == 1 550 arch = HostInfo::GetArchitecture(HostInfo::eArchKind32); 551 return arch.IsValid(); 552 } 553 } 554 } 555 return false; 556 } 557 558 // The architecture selection rules for arm processors These cpu subtypes have 559 // distinct names (e.g. armv7f) but armv7 binaries run fine on an armv7f 560 // processor. 561 562 bool PlatformDarwin::ARMGetSupportedArchitectureAtIndex(uint32_t idx, 563 ArchSpec &arch) { 564 ArchSpec system_arch(GetSystemArchitecture()); 565 566 // When lldb is running on a watch or tv, set the arch OS name appropriately. 567 #if defined(TARGET_OS_TV) && TARGET_OS_TV == 1 568 #define OSNAME "tvos" 569 #elif defined(TARGET_OS_WATCH) && TARGET_OS_WATCH == 1 570 #define OSNAME "watchos" 571 #elif defined(TARGET_OS_BRIDGE) && TARGET_OS_BRIDGE == 1 572 #define OSNAME "bridgeos" 573 #else 574 #define OSNAME "ios" 575 #endif 576 577 #if TARGET_OS_OSX 578 if (IsHost()) { 579 if (idx == 0) { 580 arch.SetTriple("arm64e-apple-macosx"); 581 return true; 582 } else if (idx == 1) { 583 arch.SetTriple("arm64-apple-macosx"); 584 return true; 585 } 586 return false; 587 } 588 #endif 589 590 const ArchSpec::Core system_core = system_arch.GetCore(); 591 switch (system_core) { 592 default: 593 switch (idx) { 594 case 0: 595 arch.SetTriple("arm64-apple-" OSNAME); 596 return true; 597 case 1: 598 arch.SetTriple("armv7-apple-" OSNAME); 599 return true; 600 case 2: 601 arch.SetTriple("armv7f-apple-" OSNAME); 602 return true; 603 case 3: 604 arch.SetTriple("armv7k-apple-" OSNAME); 605 return true; 606 case 4: 607 arch.SetTriple("armv7s-apple-" OSNAME); 608 return true; 609 case 5: 610 arch.SetTriple("armv7m-apple-" OSNAME); 611 return true; 612 case 6: 613 arch.SetTriple("armv7em-apple-" OSNAME); 614 return true; 615 case 7: 616 arch.SetTriple("armv6m-apple-" OSNAME); 617 return true; 618 case 8: 619 arch.SetTriple("armv6-apple-" OSNAME); 620 return true; 621 case 9: 622 arch.SetTriple("armv5-apple-" OSNAME); 623 return true; 624 case 10: 625 arch.SetTriple("armv4-apple-" OSNAME); 626 return true; 627 case 11: 628 arch.SetTriple("arm-apple-" OSNAME); 629 return true; 630 case 12: 631 arch.SetTriple("thumbv7-apple-" OSNAME); 632 return true; 633 case 13: 634 arch.SetTriple("thumbv7f-apple-" OSNAME); 635 return true; 636 case 14: 637 arch.SetTriple("thumbv7k-apple-" OSNAME); 638 return true; 639 case 15: 640 arch.SetTriple("thumbv7s-apple-" OSNAME); 641 return true; 642 case 16: 643 arch.SetTriple("thumbv7m-apple-" OSNAME); 644 return true; 645 case 17: 646 arch.SetTriple("thumbv7em-apple-" OSNAME); 647 return true; 648 case 18: 649 arch.SetTriple("thumbv6m-apple-" OSNAME); 650 return true; 651 case 19: 652 arch.SetTriple("thumbv6-apple-" OSNAME); 653 return true; 654 case 20: 655 arch.SetTriple("thumbv5-apple-" OSNAME); 656 return true; 657 case 21: 658 arch.SetTriple("thumbv4t-apple-" OSNAME); 659 return true; 660 case 22: 661 arch.SetTriple("thumb-apple-" OSNAME); 662 return true; 663 default: 664 break; 665 } 666 break; 667 668 case ArchSpec::eCore_arm_arm64: 669 switch (idx) { 670 case 0: 671 arch.SetTriple("arm64-apple-" OSNAME); 672 return true; 673 case 1: 674 arch.SetTriple("armv7s-apple-" OSNAME); 675 return true; 676 case 2: 677 arch.SetTriple("armv7f-apple-" OSNAME); 678 return true; 679 case 3: 680 arch.SetTriple("armv7m-apple-" OSNAME); 681 return true; 682 case 4: 683 arch.SetTriple("armv7em-apple-" OSNAME); 684 return true; 685 case 5: 686 arch.SetTriple("armv7-apple-" OSNAME); 687 return true; 688 case 6: 689 arch.SetTriple("armv6m-apple-" OSNAME); 690 return true; 691 case 7: 692 arch.SetTriple("armv6-apple-" OSNAME); 693 return true; 694 case 8: 695 arch.SetTriple("armv5-apple-" OSNAME); 696 return true; 697 case 9: 698 arch.SetTriple("armv4-apple-" OSNAME); 699 return true; 700 case 10: 701 arch.SetTriple("arm-apple-" OSNAME); 702 return true; 703 case 11: 704 arch.SetTriple("thumbv7-apple-" OSNAME); 705 return true; 706 case 12: 707 arch.SetTriple("thumbv7f-apple-" OSNAME); 708 return true; 709 case 13: 710 arch.SetTriple("thumbv7k-apple-" OSNAME); 711 return true; 712 case 14: 713 arch.SetTriple("thumbv7s-apple-" OSNAME); 714 return true; 715 case 15: 716 arch.SetTriple("thumbv7m-apple-" OSNAME); 717 return true; 718 case 16: 719 arch.SetTriple("thumbv7em-apple-" OSNAME); 720 return true; 721 case 17: 722 arch.SetTriple("thumbv6m-apple-" OSNAME); 723 return true; 724 case 18: 725 arch.SetTriple("thumbv6-apple-" OSNAME); 726 return true; 727 case 19: 728 arch.SetTriple("thumbv5-apple-" OSNAME); 729 return true; 730 case 20: 731 arch.SetTriple("thumbv4t-apple-" OSNAME); 732 return true; 733 case 21: 734 arch.SetTriple("thumb-apple-" OSNAME); 735 return true; 736 default: 737 break; 738 } 739 break; 740 741 case ArchSpec::eCore_arm_armv7f: 742 switch (idx) { 743 case 0: 744 arch.SetTriple("armv7f-apple-" OSNAME); 745 return true; 746 case 1: 747 arch.SetTriple("armv7-apple-" OSNAME); 748 return true; 749 case 2: 750 arch.SetTriple("armv6m-apple-" OSNAME); 751 return true; 752 case 3: 753 arch.SetTriple("armv6-apple-" OSNAME); 754 return true; 755 case 4: 756 arch.SetTriple("armv5-apple-" OSNAME); 757 return true; 758 case 5: 759 arch.SetTriple("armv4-apple-" OSNAME); 760 return true; 761 case 6: 762 arch.SetTriple("arm-apple-" OSNAME); 763 return true; 764 case 7: 765 arch.SetTriple("thumbv7f-apple-" OSNAME); 766 return true; 767 case 8: 768 arch.SetTriple("thumbv7-apple-" OSNAME); 769 return true; 770 case 9: 771 arch.SetTriple("thumbv6m-apple-" OSNAME); 772 return true; 773 case 10: 774 arch.SetTriple("thumbv6-apple-" OSNAME); 775 return true; 776 case 11: 777 arch.SetTriple("thumbv5-apple-" OSNAME); 778 return true; 779 case 12: 780 arch.SetTriple("thumbv4t-apple-" OSNAME); 781 return true; 782 case 13: 783 arch.SetTriple("thumb-apple-" OSNAME); 784 return true; 785 default: 786 break; 787 } 788 break; 789 790 case ArchSpec::eCore_arm_armv7k: 791 switch (idx) { 792 case 0: 793 arch.SetTriple("armv7k-apple-" OSNAME); 794 return true; 795 case 1: 796 arch.SetTriple("armv7-apple-" OSNAME); 797 return true; 798 case 2: 799 arch.SetTriple("armv6m-apple-" OSNAME); 800 return true; 801 case 3: 802 arch.SetTriple("armv6-apple-" OSNAME); 803 return true; 804 case 4: 805 arch.SetTriple("armv5-apple-" OSNAME); 806 return true; 807 case 5: 808 arch.SetTriple("armv4-apple-" OSNAME); 809 return true; 810 case 6: 811 arch.SetTriple("arm-apple-" OSNAME); 812 return true; 813 case 7: 814 arch.SetTriple("thumbv7k-apple-" OSNAME); 815 return true; 816 case 8: 817 arch.SetTriple("thumbv7-apple-" OSNAME); 818 return true; 819 case 9: 820 arch.SetTriple("thumbv6m-apple-" OSNAME); 821 return true; 822 case 10: 823 arch.SetTriple("thumbv6-apple-" OSNAME); 824 return true; 825 case 11: 826 arch.SetTriple("thumbv5-apple-" OSNAME); 827 return true; 828 case 12: 829 arch.SetTriple("thumbv4t-apple-" OSNAME); 830 return true; 831 case 13: 832 arch.SetTriple("thumb-apple-" OSNAME); 833 return true; 834 default: 835 break; 836 } 837 break; 838 839 case ArchSpec::eCore_arm_armv7s: 840 switch (idx) { 841 case 0: 842 arch.SetTriple("armv7s-apple-" OSNAME); 843 return true; 844 case 1: 845 arch.SetTriple("armv7-apple-" OSNAME); 846 return true; 847 case 2: 848 arch.SetTriple("armv6m-apple-" OSNAME); 849 return true; 850 case 3: 851 arch.SetTriple("armv6-apple-" OSNAME); 852 return true; 853 case 4: 854 arch.SetTriple("armv5-apple-" OSNAME); 855 return true; 856 case 5: 857 arch.SetTriple("armv4-apple-" OSNAME); 858 return true; 859 case 6: 860 arch.SetTriple("arm-apple-" OSNAME); 861 return true; 862 case 7: 863 arch.SetTriple("thumbv7s-apple-" OSNAME); 864 return true; 865 case 8: 866 arch.SetTriple("thumbv7-apple-" OSNAME); 867 return true; 868 case 9: 869 arch.SetTriple("thumbv6m-apple-" OSNAME); 870 return true; 871 case 10: 872 arch.SetTriple("thumbv6-apple-" OSNAME); 873 return true; 874 case 11: 875 arch.SetTriple("thumbv5-apple-" OSNAME); 876 return true; 877 case 12: 878 arch.SetTriple("thumbv4t-apple-" OSNAME); 879 return true; 880 case 13: 881 arch.SetTriple("thumb-apple-" OSNAME); 882 return true; 883 default: 884 break; 885 } 886 break; 887 888 case ArchSpec::eCore_arm_armv7m: 889 switch (idx) { 890 case 0: 891 arch.SetTriple("armv7m-apple-" OSNAME); 892 return true; 893 case 1: 894 arch.SetTriple("armv7-apple-" OSNAME); 895 return true; 896 case 2: 897 arch.SetTriple("armv6m-apple-" OSNAME); 898 return true; 899 case 3: 900 arch.SetTriple("armv6-apple-" OSNAME); 901 return true; 902 case 4: 903 arch.SetTriple("armv5-apple-" OSNAME); 904 return true; 905 case 5: 906 arch.SetTriple("armv4-apple-" OSNAME); 907 return true; 908 case 6: 909 arch.SetTriple("arm-apple-" OSNAME); 910 return true; 911 case 7: 912 arch.SetTriple("thumbv7m-apple-" OSNAME); 913 return true; 914 case 8: 915 arch.SetTriple("thumbv7-apple-" OSNAME); 916 return true; 917 case 9: 918 arch.SetTriple("thumbv6m-apple-" OSNAME); 919 return true; 920 case 10: 921 arch.SetTriple("thumbv6-apple-" OSNAME); 922 return true; 923 case 11: 924 arch.SetTriple("thumbv5-apple-" OSNAME); 925 return true; 926 case 12: 927 arch.SetTriple("thumbv4t-apple-" OSNAME); 928 return true; 929 case 13: 930 arch.SetTriple("thumb-apple-" OSNAME); 931 return true; 932 default: 933 break; 934 } 935 break; 936 937 case ArchSpec::eCore_arm_armv7em: 938 switch (idx) { 939 case 0: 940 arch.SetTriple("armv7em-apple-" OSNAME); 941 return true; 942 case 1: 943 arch.SetTriple("armv7-apple-" OSNAME); 944 return true; 945 case 2: 946 arch.SetTriple("armv6m-apple-" OSNAME); 947 return true; 948 case 3: 949 arch.SetTriple("armv6-apple-" OSNAME); 950 return true; 951 case 4: 952 arch.SetTriple("armv5-apple-" OSNAME); 953 return true; 954 case 5: 955 arch.SetTriple("armv4-apple-" OSNAME); 956 return true; 957 case 6: 958 arch.SetTriple("arm-apple-" OSNAME); 959 return true; 960 case 7: 961 arch.SetTriple("thumbv7em-apple-" OSNAME); 962 return true; 963 case 8: 964 arch.SetTriple("thumbv7-apple-" OSNAME); 965 return true; 966 case 9: 967 arch.SetTriple("thumbv6m-apple-" OSNAME); 968 return true; 969 case 10: 970 arch.SetTriple("thumbv6-apple-" OSNAME); 971 return true; 972 case 11: 973 arch.SetTriple("thumbv5-apple-" OSNAME); 974 return true; 975 case 12: 976 arch.SetTriple("thumbv4t-apple-" OSNAME); 977 return true; 978 case 13: 979 arch.SetTriple("thumb-apple-" OSNAME); 980 return true; 981 default: 982 break; 983 } 984 break; 985 986 case ArchSpec::eCore_arm_armv7: 987 switch (idx) { 988 case 0: 989 arch.SetTriple("armv7-apple-" OSNAME); 990 return true; 991 case 1: 992 arch.SetTriple("armv6m-apple-" OSNAME); 993 return true; 994 case 2: 995 arch.SetTriple("armv6-apple-" OSNAME); 996 return true; 997 case 3: 998 arch.SetTriple("armv5-apple-" OSNAME); 999 return true; 1000 case 4: 1001 arch.SetTriple("armv4-apple-" OSNAME); 1002 return true; 1003 case 5: 1004 arch.SetTriple("arm-apple-" OSNAME); 1005 return true; 1006 case 6: 1007 arch.SetTriple("thumbv7-apple-" OSNAME); 1008 return true; 1009 case 7: 1010 arch.SetTriple("thumbv6m-apple-" OSNAME); 1011 return true; 1012 case 8: 1013 arch.SetTriple("thumbv6-apple-" OSNAME); 1014 return true; 1015 case 9: 1016 arch.SetTriple("thumbv5-apple-" OSNAME); 1017 return true; 1018 case 10: 1019 arch.SetTriple("thumbv4t-apple-" OSNAME); 1020 return true; 1021 case 11: 1022 arch.SetTriple("thumb-apple-" OSNAME); 1023 return true; 1024 default: 1025 break; 1026 } 1027 break; 1028 1029 case ArchSpec::eCore_arm_armv6m: 1030 switch (idx) { 1031 case 0: 1032 arch.SetTriple("armv6m-apple-" OSNAME); 1033 return true; 1034 case 1: 1035 arch.SetTriple("armv6-apple-" OSNAME); 1036 return true; 1037 case 2: 1038 arch.SetTriple("armv5-apple-" OSNAME); 1039 return true; 1040 case 3: 1041 arch.SetTriple("armv4-apple-" OSNAME); 1042 return true; 1043 case 4: 1044 arch.SetTriple("arm-apple-" OSNAME); 1045 return true; 1046 case 5: 1047 arch.SetTriple("thumbv6m-apple-" OSNAME); 1048 return true; 1049 case 6: 1050 arch.SetTriple("thumbv6-apple-" OSNAME); 1051 return true; 1052 case 7: 1053 arch.SetTriple("thumbv5-apple-" OSNAME); 1054 return true; 1055 case 8: 1056 arch.SetTriple("thumbv4t-apple-" OSNAME); 1057 return true; 1058 case 9: 1059 arch.SetTriple("thumb-apple-" OSNAME); 1060 return true; 1061 default: 1062 break; 1063 } 1064 break; 1065 1066 case ArchSpec::eCore_arm_armv6: 1067 switch (idx) { 1068 case 0: 1069 arch.SetTriple("armv6-apple-" OSNAME); 1070 return true; 1071 case 1: 1072 arch.SetTriple("armv5-apple-" OSNAME); 1073 return true; 1074 case 2: 1075 arch.SetTriple("armv4-apple-" OSNAME); 1076 return true; 1077 case 3: 1078 arch.SetTriple("arm-apple-" OSNAME); 1079 return true; 1080 case 4: 1081 arch.SetTriple("thumbv6-apple-" OSNAME); 1082 return true; 1083 case 5: 1084 arch.SetTriple("thumbv5-apple-" OSNAME); 1085 return true; 1086 case 6: 1087 arch.SetTriple("thumbv4t-apple-" OSNAME); 1088 return true; 1089 case 7: 1090 arch.SetTriple("thumb-apple-" OSNAME); 1091 return true; 1092 default: 1093 break; 1094 } 1095 break; 1096 1097 case ArchSpec::eCore_arm_armv5: 1098 switch (idx) { 1099 case 0: 1100 arch.SetTriple("armv5-apple-" OSNAME); 1101 return true; 1102 case 1: 1103 arch.SetTriple("armv4-apple-" OSNAME); 1104 return true; 1105 case 2: 1106 arch.SetTriple("arm-apple-" OSNAME); 1107 return true; 1108 case 3: 1109 arch.SetTriple("thumbv5-apple-" OSNAME); 1110 return true; 1111 case 4: 1112 arch.SetTriple("thumbv4t-apple-" OSNAME); 1113 return true; 1114 case 5: 1115 arch.SetTriple("thumb-apple-" OSNAME); 1116 return true; 1117 default: 1118 break; 1119 } 1120 break; 1121 1122 case ArchSpec::eCore_arm_armv4: 1123 switch (idx) { 1124 case 0: 1125 arch.SetTriple("armv4-apple-" OSNAME); 1126 return true; 1127 case 1: 1128 arch.SetTriple("arm-apple-" OSNAME); 1129 return true; 1130 case 2: 1131 arch.SetTriple("thumbv4t-apple-" OSNAME); 1132 return true; 1133 case 3: 1134 arch.SetTriple("thumb-apple-" OSNAME); 1135 return true; 1136 default: 1137 break; 1138 } 1139 break; 1140 } 1141 arch.Clear(); 1142 return false; 1143 } 1144 1145 static FileSpec GetXcodeSelectPath() { 1146 static FileSpec g_xcode_select_filespec; 1147 1148 if (!g_xcode_select_filespec) { 1149 FileSpec xcode_select_cmd("/usr/bin/xcode-select"); 1150 if (FileSystem::Instance().Exists(xcode_select_cmd)) { 1151 int exit_status = -1; 1152 int signo = -1; 1153 std::string command_output; 1154 Status status = 1155 Host::RunShellCommand("/usr/bin/xcode-select --print-path", 1156 FileSpec(), // current working directory 1157 &exit_status, &signo, &command_output, 1158 std::chrono::seconds(2), // short timeout 1159 false); // don't run in a shell 1160 if (status.Success() && exit_status == 0 && !command_output.empty()) { 1161 size_t first_non_newline = command_output.find_last_not_of("\r\n"); 1162 if (first_non_newline != std::string::npos) { 1163 command_output.erase(first_non_newline + 1); 1164 } 1165 g_xcode_select_filespec = FileSpec(command_output); 1166 } 1167 } 1168 } 1169 1170 return g_xcode_select_filespec; 1171 } 1172 1173 BreakpointSP PlatformDarwin::SetThreadCreationBreakpoint(Target &target) { 1174 BreakpointSP bp_sp; 1175 static const char *g_bp_names[] = { 1176 "start_wqthread", "_pthread_wqthread", "_pthread_start", 1177 }; 1178 1179 static const char *g_bp_modules[] = {"libsystem_c.dylib", 1180 "libSystem.B.dylib"}; 1181 1182 FileSpecList bp_modules; 1183 for (size_t i = 0; i < llvm::array_lengthof(g_bp_modules); i++) { 1184 const char *bp_module = g_bp_modules[i]; 1185 bp_modules.EmplaceBack(bp_module); 1186 } 1187 1188 bool internal = true; 1189 bool hardware = false; 1190 LazyBool skip_prologue = eLazyBoolNo; 1191 bp_sp = target.CreateBreakpoint(&bp_modules, nullptr, g_bp_names, 1192 llvm::array_lengthof(g_bp_names), 1193 eFunctionNameTypeFull, eLanguageTypeUnknown, 1194 0, skip_prologue, internal, hardware); 1195 bp_sp->SetBreakpointKind("thread-creation"); 1196 1197 return bp_sp; 1198 } 1199 1200 uint32_t 1201 PlatformDarwin::GetResumeCountForLaunchInfo(ProcessLaunchInfo &launch_info) { 1202 const FileSpec &shell = launch_info.GetShell(); 1203 if (!shell) 1204 return 1; 1205 1206 std::string shell_string = shell.GetPath(); 1207 const char *shell_name = strrchr(shell_string.c_str(), '/'); 1208 if (shell_name == nullptr) 1209 shell_name = shell_string.c_str(); 1210 else 1211 shell_name++; 1212 1213 if (strcmp(shell_name, "sh") == 0) { 1214 // /bin/sh re-exec's itself as /bin/bash requiring another resume. But it 1215 // only does this if the COMMAND_MODE environment variable is set to 1216 // "legacy". 1217 if (launch_info.GetEnvironment().lookup("COMMAND_MODE") == "legacy") 1218 return 2; 1219 return 1; 1220 } else if (strcmp(shell_name, "csh") == 0 || 1221 strcmp(shell_name, "tcsh") == 0 || 1222 strcmp(shell_name, "zsh") == 0) { 1223 // csh and tcsh always seem to re-exec themselves. 1224 return 2; 1225 } else 1226 return 1; 1227 } 1228 1229 lldb::ProcessSP 1230 PlatformDarwin::DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger, 1231 Target *target, // Can be NULL, if NULL create 1232 // a new target, else use existing 1233 // one 1234 Status &error) { 1235 ProcessSP process_sp; 1236 1237 if (IsHost()) { 1238 // We are going to hand this process off to debugserver which will be in 1239 // charge of setting the exit status. However, we still need to reap it 1240 // from lldb. So, make sure we use a exit callback which does not set exit 1241 // status. 1242 const bool monitor_signals = false; 1243 launch_info.SetMonitorProcessCallback( 1244 &ProcessLaunchInfo::NoOpMonitorCallback, monitor_signals); 1245 process_sp = Platform::DebugProcess(launch_info, debugger, target, error); 1246 } else { 1247 if (m_remote_platform_sp) 1248 process_sp = m_remote_platform_sp->DebugProcess(launch_info, debugger, 1249 target, error); 1250 else 1251 error.SetErrorString("the platform is not currently connected"); 1252 } 1253 return process_sp; 1254 } 1255 1256 void PlatformDarwin::CalculateTrapHandlerSymbolNames() { 1257 m_trap_handlers.push_back(ConstString("_sigtramp")); 1258 } 1259 1260 static FileSpec GetCommandLineToolsLibraryPath() { 1261 static FileSpec g_command_line_tools_filespec; 1262 1263 if (!g_command_line_tools_filespec) { 1264 FileSpec command_line_tools_path(GetXcodeSelectPath()); 1265 command_line_tools_path.AppendPathComponent("Library"); 1266 if (FileSystem::Instance().Exists(command_line_tools_path)) { 1267 g_command_line_tools_filespec = command_line_tools_path; 1268 } 1269 } 1270 1271 return g_command_line_tools_filespec; 1272 } 1273 1274 FileSystem::EnumerateDirectoryResult PlatformDarwin::DirectoryEnumerator( 1275 void *baton, llvm::sys::fs::file_type file_type, llvm::StringRef path) { 1276 SDKEnumeratorInfo *enumerator_info = static_cast<SDKEnumeratorInfo *>(baton); 1277 1278 FileSpec spec(path); 1279 if (XcodeSDK::SDKSupportsModules(enumerator_info->sdk_type, spec)) { 1280 enumerator_info->found_path = spec; 1281 return FileSystem::EnumerateDirectoryResult::eEnumerateDirectoryResultNext; 1282 } 1283 1284 return FileSystem::EnumerateDirectoryResult::eEnumerateDirectoryResultNext; 1285 } 1286 1287 FileSpec PlatformDarwin::FindSDKInXcodeForModules(XcodeSDK::Type sdk_type, 1288 const FileSpec &sdks_spec) { 1289 // Look inside Xcode for the required installed iOS SDK version 1290 1291 if (!FileSystem::Instance().IsDirectory(sdks_spec)) { 1292 return FileSpec(); 1293 } 1294 1295 const bool find_directories = true; 1296 const bool find_files = false; 1297 const bool find_other = true; // include symlinks 1298 1299 SDKEnumeratorInfo enumerator_info; 1300 1301 enumerator_info.sdk_type = sdk_type; 1302 1303 FileSystem::Instance().EnumerateDirectory( 1304 sdks_spec.GetPath(), find_directories, find_files, find_other, 1305 DirectoryEnumerator, &enumerator_info); 1306 1307 if (FileSystem::Instance().IsDirectory(enumerator_info.found_path)) 1308 return enumerator_info.found_path; 1309 else 1310 return FileSpec(); 1311 } 1312 1313 FileSpec PlatformDarwin::GetSDKDirectoryForModules(XcodeSDK::Type sdk_type) { 1314 FileSpec sdks_spec = HostInfo::GetXcodeContentsDirectory(); 1315 sdks_spec.AppendPathComponent("Developer"); 1316 sdks_spec.AppendPathComponent("Platforms"); 1317 1318 switch (sdk_type) { 1319 case XcodeSDK::Type::MacOSX: 1320 sdks_spec.AppendPathComponent("MacOSX.platform"); 1321 break; 1322 case XcodeSDK::Type::iPhoneSimulator: 1323 sdks_spec.AppendPathComponent("iPhoneSimulator.platform"); 1324 break; 1325 case XcodeSDK::Type::iPhoneOS: 1326 sdks_spec.AppendPathComponent("iPhoneOS.platform"); 1327 break; 1328 case XcodeSDK::Type::WatchSimulator: 1329 sdks_spec.AppendPathComponent("WatchSimulator.platform"); 1330 break; 1331 case XcodeSDK::Type::AppleTVSimulator: 1332 sdks_spec.AppendPathComponent("AppleTVSimulator.platform"); 1333 break; 1334 default: 1335 llvm_unreachable("unsupported sdk"); 1336 } 1337 1338 sdks_spec.AppendPathComponent("Developer"); 1339 sdks_spec.AppendPathComponent("SDKs"); 1340 1341 if (sdk_type == XcodeSDK::Type::MacOSX) { 1342 llvm::VersionTuple version = HostInfo::GetOSVersion(); 1343 1344 if (!version.empty()) { 1345 if (XcodeSDK::SDKSupportsModules(XcodeSDK::Type::MacOSX, version)) { 1346 // If the Xcode SDKs are not available then try to use the 1347 // Command Line Tools one which is only for MacOSX. 1348 if (!FileSystem::Instance().Exists(sdks_spec)) { 1349 sdks_spec = GetCommandLineToolsLibraryPath(); 1350 sdks_spec.AppendPathComponent("SDKs"); 1351 } 1352 1353 // We slightly prefer the exact SDK for this machine. See if it is 1354 // there. 1355 1356 FileSpec native_sdk_spec = sdks_spec; 1357 StreamString native_sdk_name; 1358 native_sdk_name.Printf("MacOSX%u.%u.sdk", version.getMajor(), 1359 version.getMinor().getValueOr(0)); 1360 native_sdk_spec.AppendPathComponent(native_sdk_name.GetString()); 1361 1362 if (FileSystem::Instance().Exists(native_sdk_spec)) { 1363 return native_sdk_spec; 1364 } 1365 } 1366 } 1367 } 1368 1369 return FindSDKInXcodeForModules(sdk_type, sdks_spec); 1370 } 1371 1372 std::tuple<llvm::VersionTuple, llvm::StringRef> 1373 PlatformDarwin::ParseVersionBuildDir(llvm::StringRef dir) { 1374 llvm::StringRef build; 1375 llvm::StringRef version_str; 1376 llvm::StringRef build_str; 1377 std::tie(version_str, build_str) = dir.split(' '); 1378 llvm::VersionTuple version; 1379 if (!version.tryParse(version_str) || 1380 build_str.empty()) { 1381 if (build_str.consume_front("(")) { 1382 size_t pos = build_str.find(')'); 1383 build = build_str.slice(0, pos); 1384 } 1385 } 1386 1387 return std::make_tuple(version, build); 1388 } 1389 1390 llvm::Expected<StructuredData::DictionarySP> 1391 PlatformDarwin::FetchExtendedCrashInformation(Process &process) { 1392 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); 1393 1394 StructuredData::ArraySP annotations = ExtractCrashInfoAnnotations(process); 1395 1396 if (!annotations || !annotations->GetSize()) { 1397 LLDB_LOG(log, "Couldn't extract crash information annotations"); 1398 return nullptr; 1399 } 1400 1401 StructuredData::DictionarySP extended_crash_info = 1402 std::make_shared<StructuredData::Dictionary>(); 1403 1404 extended_crash_info->AddItem("crash-info annotations", annotations); 1405 1406 return extended_crash_info; 1407 } 1408 1409 StructuredData::ArraySP 1410 PlatformDarwin::ExtractCrashInfoAnnotations(Process &process) { 1411 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); 1412 1413 ConstString section_name("__crash_info"); 1414 Target &target = process.GetTarget(); 1415 StructuredData::ArraySP array_sp = std::make_shared<StructuredData::Array>(); 1416 1417 for (ModuleSP module : target.GetImages().Modules()) { 1418 SectionList *sections = module->GetSectionList(); 1419 1420 std::string module_name = module->GetSpecificationDescription(); 1421 1422 // The DYDL module is skipped since it's always loaded when running the 1423 // binary. 1424 if (module_name == "/usr/lib/dyld") 1425 continue; 1426 1427 if (!sections) { 1428 LLDB_LOG(log, "Module {0} doesn't have any section!", module_name); 1429 continue; 1430 } 1431 1432 SectionSP crash_info = sections->FindSectionByName(section_name); 1433 if (!crash_info) { 1434 LLDB_LOG(log, "Module {0} doesn't have section {1}!", module_name, 1435 section_name); 1436 continue; 1437 } 1438 1439 addr_t load_addr = crash_info->GetLoadBaseAddress(&target); 1440 1441 if (load_addr == LLDB_INVALID_ADDRESS) { 1442 LLDB_LOG(log, "Module {0} has an invalid '{1}' section load address: {2}", 1443 module_name, section_name, load_addr); 1444 continue; 1445 } 1446 1447 Status error; 1448 CrashInfoAnnotations annotations; 1449 size_t expected_size = sizeof(CrashInfoAnnotations); 1450 size_t bytes_read = process.ReadMemoryFromInferior(load_addr, &annotations, 1451 expected_size, error); 1452 1453 if (expected_size != bytes_read || error.Fail()) { 1454 LLDB_LOG(log, "Failed to read {0} section from memory in module {1}: {2}", 1455 section_name, module_name, error); 1456 continue; 1457 } 1458 1459 // initial support added for version 5 1460 if (annotations.version < 5) { 1461 LLDB_LOG(log, 1462 "Annotation version lower than 5 unsupported! Module {0} has " 1463 "version {1} instead.", 1464 module_name, annotations.version); 1465 continue; 1466 } 1467 1468 if (!annotations.message) { 1469 LLDB_LOG(log, "No message available for module {0}.", module_name); 1470 continue; 1471 } 1472 1473 std::string message; 1474 bytes_read = 1475 process.ReadCStringFromMemory(annotations.message, message, error); 1476 1477 if (message.empty() || bytes_read != message.size() || error.Fail()) { 1478 LLDB_LOG(log, "Failed to read the message from memory in module {0}: {1}", 1479 module_name, error); 1480 continue; 1481 } 1482 1483 // Remove trailing newline from message 1484 if (message.back() == '\n') 1485 message.pop_back(); 1486 1487 if (!annotations.message2) 1488 LLDB_LOG(log, "No message2 available for module {0}.", module_name); 1489 1490 std::string message2; 1491 bytes_read = 1492 process.ReadCStringFromMemory(annotations.message2, message2, error); 1493 1494 if (!message2.empty() && bytes_read == message2.size() && error.Success()) 1495 if (message2.back() == '\n') 1496 message2.pop_back(); 1497 1498 StructuredData::DictionarySP entry_sp = 1499 std::make_shared<StructuredData::Dictionary>(); 1500 1501 entry_sp->AddStringItem("image", module->GetFileSpec().GetPath(false)); 1502 entry_sp->AddStringItem("uuid", module->GetUUID().GetAsString()); 1503 entry_sp->AddStringItem("message", message); 1504 entry_sp->AddStringItem("message2", message2); 1505 entry_sp->AddIntegerItem("abort-cause", annotations.abort_cause); 1506 1507 array_sp->AddItem(entry_sp); 1508 } 1509 1510 return array_sp; 1511 } 1512 1513 void PlatformDarwin::AddClangModuleCompilationOptionsForSDKType( 1514 Target *target, std::vector<std::string> &options, XcodeSDK::Type sdk_type) { 1515 const std::vector<std::string> apple_arguments = { 1516 "-x", "objective-c++", "-fobjc-arc", 1517 "-fblocks", "-D_ISO646_H", "-D__ISO646_H", 1518 "-fgnuc-version=4.2.1"}; 1519 1520 options.insert(options.end(), apple_arguments.begin(), apple_arguments.end()); 1521 1522 StreamString minimum_version_option; 1523 bool use_current_os_version = false; 1524 // If the SDK type is for the host OS, use its version number. 1525 auto get_host_os = []() { return HostInfo::GetTargetTriple().getOS(); }; 1526 switch (sdk_type) { 1527 case XcodeSDK::Type::MacOSX: 1528 use_current_os_version = get_host_os() == llvm::Triple::MacOSX; 1529 break; 1530 case XcodeSDK::Type::iPhoneOS: 1531 use_current_os_version = get_host_os() == llvm::Triple::IOS; 1532 break; 1533 case XcodeSDK::Type::AppleTVOS: 1534 use_current_os_version = get_host_os() == llvm::Triple::TvOS; 1535 break; 1536 case XcodeSDK::Type::watchOS: 1537 use_current_os_version = get_host_os() == llvm::Triple::WatchOS; 1538 break; 1539 default: 1540 break; 1541 } 1542 1543 llvm::VersionTuple version; 1544 if (use_current_os_version) 1545 version = GetOSVersion(); 1546 else if (target) { 1547 // Our OS doesn't match our executable so we need to get the min OS version 1548 // from the object file 1549 ModuleSP exe_module_sp = target->GetExecutableModule(); 1550 if (exe_module_sp) { 1551 ObjectFile *object_file = exe_module_sp->GetObjectFile(); 1552 if (object_file) 1553 version = object_file->GetMinimumOSVersion(); 1554 } 1555 } 1556 // Only add the version-min options if we got a version from somewhere 1557 if (!version.empty() && sdk_type != XcodeSDK::Type::Linux) { 1558 #define OPTION(PREFIX, NAME, VAR, ...) \ 1559 const char *opt_##VAR = NAME; \ 1560 (void)opt_##VAR; 1561 #include "clang/Driver/Options.inc" 1562 #undef OPTION 1563 minimum_version_option << '-'; 1564 switch (sdk_type) { 1565 case XcodeSDK::Type::MacOSX: 1566 minimum_version_option << opt_mmacosx_version_min_EQ; 1567 break; 1568 case XcodeSDK::Type::iPhoneSimulator: 1569 minimum_version_option << opt_mios_simulator_version_min_EQ; 1570 break; 1571 case XcodeSDK::Type::iPhoneOS: 1572 minimum_version_option << opt_mios_version_min_EQ; 1573 break; 1574 case XcodeSDK::Type::AppleTVSimulator: 1575 minimum_version_option << opt_mtvos_simulator_version_min_EQ; 1576 break; 1577 case XcodeSDK::Type::AppleTVOS: 1578 minimum_version_option << opt_mtvos_version_min_EQ; 1579 break; 1580 case XcodeSDK::Type::WatchSimulator: 1581 minimum_version_option << opt_mwatchos_simulator_version_min_EQ; 1582 break; 1583 case XcodeSDK::Type::watchOS: 1584 minimum_version_option << opt_mwatchos_version_min_EQ; 1585 break; 1586 case XcodeSDK::Type::bridgeOS: 1587 case XcodeSDK::Type::Linux: 1588 case XcodeSDK::Type::unknown: 1589 if (lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST)) { 1590 XcodeSDK::Info info; 1591 info.type = sdk_type; 1592 LLDB_LOGF(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST), 1593 "Clang modules on %s are not supported", 1594 XcodeSDK::GetCanonicalName(info).c_str()); 1595 } 1596 return; 1597 } 1598 minimum_version_option << version.getAsString(); 1599 options.emplace_back(std::string(minimum_version_option.GetString())); 1600 } 1601 1602 FileSpec sysroot_spec; 1603 // Scope for mutex locker below 1604 { 1605 std::lock_guard<std::mutex> guard(m_mutex); 1606 sysroot_spec = GetSDKDirectoryForModules(sdk_type); 1607 } 1608 1609 if (FileSystem::Instance().IsDirectory(sysroot_spec.GetPath())) { 1610 options.push_back("-isysroot"); 1611 options.push_back(sysroot_spec.GetPath()); 1612 } 1613 } 1614 1615 ConstString PlatformDarwin::GetFullNameForDylib(ConstString basename) { 1616 if (basename.IsEmpty()) 1617 return basename; 1618 1619 StreamString stream; 1620 stream.Printf("lib%s.dylib", basename.GetCString()); 1621 return ConstString(stream.GetString()); 1622 } 1623 1624 llvm::VersionTuple PlatformDarwin::GetOSVersion(Process *process) { 1625 if (process && strstr(GetPluginName().GetCString(), "-simulator")) { 1626 lldb_private::ProcessInstanceInfo proc_info; 1627 if (Host::GetProcessInfo(process->GetID(), proc_info)) { 1628 const Environment &env = proc_info.GetEnvironment(); 1629 1630 llvm::VersionTuple result; 1631 if (!result.tryParse(env.lookup("SIMULATOR_RUNTIME_VERSION"))) 1632 return result; 1633 1634 std::string dyld_root_path = env.lookup("DYLD_ROOT_PATH"); 1635 if (!dyld_root_path.empty()) { 1636 dyld_root_path += "/System/Library/CoreServices/SystemVersion.plist"; 1637 ApplePropertyList system_version_plist(dyld_root_path.c_str()); 1638 std::string product_version; 1639 if (system_version_plist.GetValueAsString("ProductVersion", 1640 product_version)) { 1641 if (!result.tryParse(product_version)) 1642 return result; 1643 } 1644 } 1645 } 1646 // For simulator platforms, do NOT call back through 1647 // Platform::GetOSVersion() as it might call Process::GetHostOSVersion() 1648 // which we don't want as it will be incorrect 1649 return llvm::VersionTuple(); 1650 } 1651 1652 return Platform::GetOSVersion(process); 1653 } 1654 1655 lldb_private::FileSpec PlatformDarwin::LocateExecutable(const char *basename) { 1656 // A collection of SBFileSpec whose SBFileSpec.m_directory members are filled 1657 // in with any executable directories that should be searched. 1658 static std::vector<FileSpec> g_executable_dirs; 1659 1660 // Find the global list of directories that we will search for executables 1661 // once so we don't keep doing the work over and over. 1662 static llvm::once_flag g_once_flag; 1663 llvm::call_once(g_once_flag, []() { 1664 1665 // When locating executables, trust the DEVELOPER_DIR first if it is set 1666 FileSpec xcode_contents_dir = HostInfo::GetXcodeContentsDirectory(); 1667 if (xcode_contents_dir) { 1668 FileSpec xcode_lldb_resources = xcode_contents_dir; 1669 xcode_lldb_resources.AppendPathComponent("SharedFrameworks"); 1670 xcode_lldb_resources.AppendPathComponent("LLDB.framework"); 1671 xcode_lldb_resources.AppendPathComponent("Resources"); 1672 if (FileSystem::Instance().Exists(xcode_lldb_resources)) { 1673 FileSpec dir; 1674 dir.GetDirectory().SetCString(xcode_lldb_resources.GetPath().c_str()); 1675 g_executable_dirs.push_back(dir); 1676 } 1677 } 1678 // Xcode might not be installed so we also check for the Command Line Tools. 1679 FileSpec command_line_tools_dir = GetCommandLineToolsLibraryPath(); 1680 if (command_line_tools_dir) { 1681 FileSpec cmd_line_lldb_resources = command_line_tools_dir; 1682 cmd_line_lldb_resources.AppendPathComponent("PrivateFrameworks"); 1683 cmd_line_lldb_resources.AppendPathComponent("LLDB.framework"); 1684 cmd_line_lldb_resources.AppendPathComponent("Resources"); 1685 if (FileSystem::Instance().Exists(cmd_line_lldb_resources)) { 1686 FileSpec dir; 1687 dir.GetDirectory().SetCString( 1688 cmd_line_lldb_resources.GetPath().c_str()); 1689 g_executable_dirs.push_back(dir); 1690 } 1691 } 1692 }); 1693 1694 // Now search the global list of executable directories for the executable we 1695 // are looking for 1696 for (const auto &executable_dir : g_executable_dirs) { 1697 FileSpec executable_file; 1698 executable_file.GetDirectory() = executable_dir.GetDirectory(); 1699 executable_file.GetFilename().SetCString(basename); 1700 if (FileSystem::Instance().Exists(executable_file)) 1701 return executable_file; 1702 } 1703 1704 return FileSpec(); 1705 } 1706 1707 lldb_private::Status 1708 PlatformDarwin::LaunchProcess(lldb_private::ProcessLaunchInfo &launch_info) { 1709 // Starting in Fall 2016 OSes, NSLog messages only get mirrored to stderr if 1710 // the OS_ACTIVITY_DT_MODE environment variable is set. (It doesn't require 1711 // any specific value; rather, it just needs to exist). We will set it here 1712 // as long as the IDE_DISABLED_OS_ACTIVITY_DT_MODE flag is not set. Xcode 1713 // makes use of IDE_DISABLED_OS_ACTIVITY_DT_MODE to tell 1714 // LLDB *not* to muck with the OS_ACTIVITY_DT_MODE flag when they 1715 // specifically want it unset. 1716 const char *disable_env_var = "IDE_DISABLED_OS_ACTIVITY_DT_MODE"; 1717 auto &env_vars = launch_info.GetEnvironment(); 1718 if (!env_vars.count(disable_env_var)) { 1719 // We want to make sure that OS_ACTIVITY_DT_MODE is set so that we get 1720 // os_log and NSLog messages mirrored to the target process stderr. 1721 env_vars.try_emplace("OS_ACTIVITY_DT_MODE", "enable"); 1722 } 1723 1724 // Let our parent class do the real launching. 1725 return PlatformPOSIX::LaunchProcess(launch_info); 1726 } 1727 1728 lldb_private::Status PlatformDarwin::FindBundleBinaryInExecSearchPaths( 1729 const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp, 1730 const FileSpecList *module_search_paths_ptr, 1731 llvm::SmallVectorImpl<ModuleSP> *old_modules, bool *did_create_ptr) { 1732 const FileSpec &platform_file = module_spec.GetFileSpec(); 1733 // See if the file is present in any of the module_search_paths_ptr 1734 // directories. 1735 if (!module_sp && module_search_paths_ptr && platform_file) { 1736 // create a vector of all the file / directory names in platform_file e.g. 1737 // this might be 1738 // /System/Library/PrivateFrameworks/UIFoundation.framework/UIFoundation 1739 // 1740 // We'll need to look in the module_search_paths_ptr directories for both 1741 // "UIFoundation" and "UIFoundation.framework" -- most likely the latter 1742 // will be the one we find there. 1743 1744 FileSpec platform_pull_upart(platform_file); 1745 std::vector<std::string> path_parts; 1746 path_parts.push_back( 1747 platform_pull_upart.GetLastPathComponent().AsCString()); 1748 while (platform_pull_upart.RemoveLastPathComponent()) { 1749 ConstString part = platform_pull_upart.GetLastPathComponent(); 1750 path_parts.push_back(part.AsCString()); 1751 } 1752 const size_t path_parts_size = path_parts.size(); 1753 1754 size_t num_module_search_paths = module_search_paths_ptr->GetSize(); 1755 for (size_t i = 0; i < num_module_search_paths; ++i) { 1756 Log *log_verbose = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); 1757 LLDB_LOGF( 1758 log_verbose, 1759 "PlatformRemoteDarwinDevice::GetSharedModule searching for binary in " 1760 "search-path %s", 1761 module_search_paths_ptr->GetFileSpecAtIndex(i).GetPath().c_str()); 1762 // Create a new FileSpec with this module_search_paths_ptr plus just the 1763 // filename ("UIFoundation"), then the parent dir plus filename 1764 // ("UIFoundation.framework/UIFoundation") etc - up to four names (to 1765 // handle "Foo.framework/Contents/MacOS/Foo") 1766 1767 for (size_t j = 0; j < 4 && j < path_parts_size - 1; ++j) { 1768 FileSpec path_to_try(module_search_paths_ptr->GetFileSpecAtIndex(i)); 1769 1770 // Add the components backwards. For 1771 // .../PrivateFrameworks/UIFoundation.framework/UIFoundation path_parts 1772 // is 1773 // [0] UIFoundation 1774 // [1] UIFoundation.framework 1775 // [2] PrivateFrameworks 1776 // 1777 // and if 'j' is 2, we want to append path_parts[1] and then 1778 // path_parts[0], aka 'UIFoundation.framework/UIFoundation', to the 1779 // module_search_paths_ptr path. 1780 1781 for (int k = j; k >= 0; --k) { 1782 path_to_try.AppendPathComponent(path_parts[k]); 1783 } 1784 1785 if (FileSystem::Instance().Exists(path_to_try)) { 1786 ModuleSpec new_module_spec(module_spec); 1787 new_module_spec.GetFileSpec() = path_to_try; 1788 Status new_error( 1789 Platform::GetSharedModule(new_module_spec, process, module_sp, 1790 nullptr, old_modules, did_create_ptr)); 1791 1792 if (module_sp) { 1793 module_sp->SetPlatformFileSpec(path_to_try); 1794 return new_error; 1795 } 1796 } 1797 } 1798 } 1799 } 1800 return Status(); 1801 } 1802 1803 std::string PlatformDarwin::FindComponentInPath(llvm::StringRef path, 1804 llvm::StringRef component) { 1805 auto begin = llvm::sys::path::begin(path); 1806 auto end = llvm::sys::path::end(path); 1807 for (auto it = begin; it != end; ++it) { 1808 if (it->contains(component)) { 1809 llvm::SmallString<128> buffer; 1810 llvm::sys::path::append(buffer, begin, ++it, 1811 llvm::sys::path::Style::posix); 1812 return buffer.str().str(); 1813 } 1814 } 1815 return {}; 1816 } 1817 1818 FileSpec PlatformDarwin::GetCurrentToolchainDirectory() { 1819 if (FileSpec fspec = HostInfo::GetShlibDir()) 1820 return FileSpec(FindComponentInPath(fspec.GetPath(), ".xctoolchain")); 1821 return {}; 1822 } 1823 1824 FileSpec PlatformDarwin::GetCurrentCommandLineToolsDirectory() { 1825 if (FileSpec fspec = HostInfo::GetShlibDir()) 1826 return FileSpec(FindComponentInPath(fspec.GetPath(), "CommandLineTools")); 1827 return {}; 1828 } 1829