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