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