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