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