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