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