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