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