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_32: 422 case llvm::Triple::aarch64: { 423 // 'brk #0' or 0xd4200000 in BE byte order 424 static const uint8_t g_arm64_breakpoint_opcode[] = {0x00, 0x00, 0x20, 0xD4}; 425 trap_opcode = g_arm64_breakpoint_opcode; 426 trap_opcode_size = sizeof(g_arm64_breakpoint_opcode); 427 } break; 428 429 case llvm::Triple::thumb: 430 bp_is_thumb = true; 431 LLVM_FALLTHROUGH; 432 case llvm::Triple::arm: { 433 static const uint8_t g_arm_breakpoint_opcode[] = {0xFE, 0xDE, 0xFF, 0xE7}; 434 static const uint8_t g_thumb_breakpooint_opcode[] = {0xFE, 0xDE}; 435 436 // Auto detect arm/thumb if it wasn't explicitly specified 437 if (!bp_is_thumb) { 438 lldb::BreakpointLocationSP bp_loc_sp(bp_site->GetOwnerAtIndex(0)); 439 if (bp_loc_sp) 440 bp_is_thumb = bp_loc_sp->GetAddress().GetAddressClass() == 441 AddressClass::eCodeAlternateISA; 442 } 443 if (bp_is_thumb) { 444 trap_opcode = g_thumb_breakpooint_opcode; 445 trap_opcode_size = sizeof(g_thumb_breakpooint_opcode); 446 break; 447 } 448 trap_opcode = g_arm_breakpoint_opcode; 449 trap_opcode_size = sizeof(g_arm_breakpoint_opcode); 450 } break; 451 452 case llvm::Triple::ppc: 453 case llvm::Triple::ppc64: { 454 static const uint8_t g_ppc_breakpoint_opcode[] = {0x7F, 0xC0, 0x00, 0x08}; 455 trap_opcode = g_ppc_breakpoint_opcode; 456 trap_opcode_size = sizeof(g_ppc_breakpoint_opcode); 457 } break; 458 459 default: 460 return Platform::GetSoftwareBreakpointTrapOpcode(target, bp_site); 461 } 462 463 if (trap_opcode && trap_opcode_size) { 464 if (bp_site->SetTrapOpcode(trap_opcode, trap_opcode_size)) 465 return trap_opcode_size; 466 } 467 return 0; 468 } 469 470 bool PlatformDarwin::ModuleIsExcludedForUnconstrainedSearches( 471 lldb_private::Target &target, const lldb::ModuleSP &module_sp) { 472 if (!module_sp) 473 return false; 474 475 ObjectFile *obj_file = module_sp->GetObjectFile(); 476 if (!obj_file) 477 return false; 478 479 ObjectFile::Type obj_type = obj_file->GetType(); 480 return obj_type == ObjectFile::eTypeDynamicLinker; 481 } 482 483 bool PlatformDarwin::x86GetSupportedArchitectureAtIndex(uint32_t idx, 484 ArchSpec &arch) { 485 ArchSpec host_arch = HostInfo::GetArchitecture(HostInfo::eArchKindDefault); 486 if (host_arch.GetCore() == ArchSpec::eCore_x86_64_x86_64h) { 487 switch (idx) { 488 case 0: 489 arch = host_arch; 490 return true; 491 492 case 1: 493 arch.SetTriple("x86_64-apple-macosx"); 494 return true; 495 496 case 2: 497 arch = HostInfo::GetArchitecture(HostInfo::eArchKind32); 498 return true; 499 500 default: 501 return false; 502 } 503 } else { 504 if (idx == 0) { 505 arch = HostInfo::GetArchitecture(HostInfo::eArchKindDefault); 506 return arch.IsValid(); 507 } else if (idx == 1) { 508 ArchSpec platform_arch( 509 HostInfo::GetArchitecture(HostInfo::eArchKindDefault)); 510 ArchSpec platform_arch64( 511 HostInfo::GetArchitecture(HostInfo::eArchKind64)); 512 if (platform_arch.IsExactMatch(platform_arch64)) { 513 // This macosx platform supports both 32 and 64 bit. Since we already 514 // returned the 64 bit arch for idx == 0, return the 32 bit arch for 515 // idx == 1 516 arch = HostInfo::GetArchitecture(HostInfo::eArchKind32); 517 return arch.IsValid(); 518 } 519 } 520 } 521 return false; 522 } 523 524 // The architecture selection rules for arm processors These cpu subtypes have 525 // distinct names (e.g. armv7f) but armv7 binaries run fine on an armv7f 526 // processor. 527 528 bool PlatformDarwin::ARMGetSupportedArchitectureAtIndex(uint32_t idx, 529 ArchSpec &arch) { 530 ArchSpec system_arch(GetSystemArchitecture()); 531 532 // When lldb is running on a watch or tv, set the arch OS name appropriately. 533 #if defined(TARGET_OS_TV) && TARGET_OS_TV == 1 534 #define OSNAME "tvos" 535 #elif defined(TARGET_OS_WATCH) && TARGET_OS_WATCH == 1 536 #define OSNAME "watchos" 537 #elif defined(TARGET_OS_BRIDGE) && TARGET_OS_BRIDGE == 1 538 #define OSNAME "bridgeos" 539 #else 540 #define OSNAME "ios" 541 #endif 542 543 const ArchSpec::Core system_core = system_arch.GetCore(); 544 switch (system_core) { 545 default: 546 switch (idx) { 547 case 0: 548 arch.SetTriple("arm64-apple-" OSNAME); 549 return true; 550 case 1: 551 arch.SetTriple("armv7-apple-" OSNAME); 552 return true; 553 case 2: 554 arch.SetTriple("armv7f-apple-" OSNAME); 555 return true; 556 case 3: 557 arch.SetTriple("armv7k-apple-" OSNAME); 558 return true; 559 case 4: 560 arch.SetTriple("armv7s-apple-" OSNAME); 561 return true; 562 case 5: 563 arch.SetTriple("armv7m-apple-" OSNAME); 564 return true; 565 case 6: 566 arch.SetTriple("armv7em-apple-" OSNAME); 567 return true; 568 case 7: 569 arch.SetTriple("armv6m-apple-" OSNAME); 570 return true; 571 case 8: 572 arch.SetTriple("armv6-apple-" OSNAME); 573 return true; 574 case 9: 575 arch.SetTriple("armv5-apple-" OSNAME); 576 return true; 577 case 10: 578 arch.SetTriple("armv4-apple-" OSNAME); 579 return true; 580 case 11: 581 arch.SetTriple("arm-apple-" OSNAME); 582 return true; 583 case 12: 584 arch.SetTriple("thumbv7-apple-" OSNAME); 585 return true; 586 case 13: 587 arch.SetTriple("thumbv7f-apple-" OSNAME); 588 return true; 589 case 14: 590 arch.SetTriple("thumbv7k-apple-" OSNAME); 591 return true; 592 case 15: 593 arch.SetTriple("thumbv7s-apple-" OSNAME); 594 return true; 595 case 16: 596 arch.SetTriple("thumbv7m-apple-" OSNAME); 597 return true; 598 case 17: 599 arch.SetTriple("thumbv7em-apple-" OSNAME); 600 return true; 601 case 18: 602 arch.SetTriple("thumbv6m-apple-" OSNAME); 603 return true; 604 case 19: 605 arch.SetTriple("thumbv6-apple-" OSNAME); 606 return true; 607 case 20: 608 arch.SetTriple("thumbv5-apple-" OSNAME); 609 return true; 610 case 21: 611 arch.SetTriple("thumbv4t-apple-" OSNAME); 612 return true; 613 case 22: 614 arch.SetTriple("thumb-apple-" OSNAME); 615 return true; 616 default: 617 break; 618 } 619 break; 620 621 case ArchSpec::eCore_arm_arm64: 622 switch (idx) { 623 case 0: 624 arch.SetTriple("arm64-apple-" OSNAME); 625 return true; 626 case 1: 627 arch.SetTriple("armv7s-apple-" OSNAME); 628 return true; 629 case 2: 630 arch.SetTriple("armv7f-apple-" OSNAME); 631 return true; 632 case 3: 633 arch.SetTriple("armv7m-apple-" OSNAME); 634 return true; 635 case 4: 636 arch.SetTriple("armv7em-apple-" OSNAME); 637 return true; 638 case 5: 639 arch.SetTriple("armv7-apple-" OSNAME); 640 return true; 641 case 6: 642 arch.SetTriple("armv6m-apple-" OSNAME); 643 return true; 644 case 7: 645 arch.SetTriple("armv6-apple-" OSNAME); 646 return true; 647 case 8: 648 arch.SetTriple("armv5-apple-" OSNAME); 649 return true; 650 case 9: 651 arch.SetTriple("armv4-apple-" OSNAME); 652 return true; 653 case 10: 654 arch.SetTriple("arm-apple-" OSNAME); 655 return true; 656 case 11: 657 arch.SetTriple("thumbv7-apple-" OSNAME); 658 return true; 659 case 12: 660 arch.SetTriple("thumbv7f-apple-" OSNAME); 661 return true; 662 case 13: 663 arch.SetTriple("thumbv7k-apple-" OSNAME); 664 return true; 665 case 14: 666 arch.SetTriple("thumbv7s-apple-" OSNAME); 667 return true; 668 case 15: 669 arch.SetTriple("thumbv7m-apple-" OSNAME); 670 return true; 671 case 16: 672 arch.SetTriple("thumbv7em-apple-" OSNAME); 673 return true; 674 case 17: 675 arch.SetTriple("thumbv6m-apple-" OSNAME); 676 return true; 677 case 18: 678 arch.SetTriple("thumbv6-apple-" OSNAME); 679 return true; 680 case 19: 681 arch.SetTriple("thumbv5-apple-" OSNAME); 682 return true; 683 case 20: 684 arch.SetTriple("thumbv4t-apple-" OSNAME); 685 return true; 686 case 21: 687 arch.SetTriple("thumb-apple-" OSNAME); 688 return true; 689 default: 690 break; 691 } 692 break; 693 694 case ArchSpec::eCore_arm_armv7f: 695 switch (idx) { 696 case 0: 697 arch.SetTriple("armv7f-apple-" OSNAME); 698 return true; 699 case 1: 700 arch.SetTriple("armv7-apple-" OSNAME); 701 return true; 702 case 2: 703 arch.SetTriple("armv6m-apple-" OSNAME); 704 return true; 705 case 3: 706 arch.SetTriple("armv6-apple-" OSNAME); 707 return true; 708 case 4: 709 arch.SetTriple("armv5-apple-" OSNAME); 710 return true; 711 case 5: 712 arch.SetTriple("armv4-apple-" OSNAME); 713 return true; 714 case 6: 715 arch.SetTriple("arm-apple-" OSNAME); 716 return true; 717 case 7: 718 arch.SetTriple("thumbv7f-apple-" OSNAME); 719 return true; 720 case 8: 721 arch.SetTriple("thumbv7-apple-" OSNAME); 722 return true; 723 case 9: 724 arch.SetTriple("thumbv6m-apple-" OSNAME); 725 return true; 726 case 10: 727 arch.SetTriple("thumbv6-apple-" OSNAME); 728 return true; 729 case 11: 730 arch.SetTriple("thumbv5-apple-" OSNAME); 731 return true; 732 case 12: 733 arch.SetTriple("thumbv4t-apple-" OSNAME); 734 return true; 735 case 13: 736 arch.SetTriple("thumb-apple-" OSNAME); 737 return true; 738 default: 739 break; 740 } 741 break; 742 743 case ArchSpec::eCore_arm_armv7k: 744 switch (idx) { 745 case 0: 746 arch.SetTriple("armv7k-apple-" OSNAME); 747 return true; 748 case 1: 749 arch.SetTriple("armv7-apple-" OSNAME); 750 return true; 751 case 2: 752 arch.SetTriple("armv6m-apple-" OSNAME); 753 return true; 754 case 3: 755 arch.SetTriple("armv6-apple-" OSNAME); 756 return true; 757 case 4: 758 arch.SetTriple("armv5-apple-" OSNAME); 759 return true; 760 case 5: 761 arch.SetTriple("armv4-apple-" OSNAME); 762 return true; 763 case 6: 764 arch.SetTriple("arm-apple-" OSNAME); 765 return true; 766 case 7: 767 arch.SetTriple("thumbv7k-apple-" OSNAME); 768 return true; 769 case 8: 770 arch.SetTriple("thumbv7-apple-" OSNAME); 771 return true; 772 case 9: 773 arch.SetTriple("thumbv6m-apple-" OSNAME); 774 return true; 775 case 10: 776 arch.SetTriple("thumbv6-apple-" OSNAME); 777 return true; 778 case 11: 779 arch.SetTriple("thumbv5-apple-" OSNAME); 780 return true; 781 case 12: 782 arch.SetTriple("thumbv4t-apple-" OSNAME); 783 return true; 784 case 13: 785 arch.SetTriple("thumb-apple-" OSNAME); 786 return true; 787 default: 788 break; 789 } 790 break; 791 792 case ArchSpec::eCore_arm_armv7s: 793 switch (idx) { 794 case 0: 795 arch.SetTriple("armv7s-apple-" OSNAME); 796 return true; 797 case 1: 798 arch.SetTriple("armv7-apple-" OSNAME); 799 return true; 800 case 2: 801 arch.SetTriple("armv6m-apple-" OSNAME); 802 return true; 803 case 3: 804 arch.SetTriple("armv6-apple-" OSNAME); 805 return true; 806 case 4: 807 arch.SetTriple("armv5-apple-" OSNAME); 808 return true; 809 case 5: 810 arch.SetTriple("armv4-apple-" OSNAME); 811 return true; 812 case 6: 813 arch.SetTriple("arm-apple-" OSNAME); 814 return true; 815 case 7: 816 arch.SetTriple("thumbv7s-apple-" OSNAME); 817 return true; 818 case 8: 819 arch.SetTriple("thumbv7-apple-" OSNAME); 820 return true; 821 case 9: 822 arch.SetTriple("thumbv6m-apple-" OSNAME); 823 return true; 824 case 10: 825 arch.SetTriple("thumbv6-apple-" OSNAME); 826 return true; 827 case 11: 828 arch.SetTriple("thumbv5-apple-" OSNAME); 829 return true; 830 case 12: 831 arch.SetTriple("thumbv4t-apple-" OSNAME); 832 return true; 833 case 13: 834 arch.SetTriple("thumb-apple-" OSNAME); 835 return true; 836 default: 837 break; 838 } 839 break; 840 841 case ArchSpec::eCore_arm_armv7m: 842 switch (idx) { 843 case 0: 844 arch.SetTriple("armv7m-apple-" OSNAME); 845 return true; 846 case 1: 847 arch.SetTriple("armv7-apple-" OSNAME); 848 return true; 849 case 2: 850 arch.SetTriple("armv6m-apple-" OSNAME); 851 return true; 852 case 3: 853 arch.SetTriple("armv6-apple-" OSNAME); 854 return true; 855 case 4: 856 arch.SetTriple("armv5-apple-" OSNAME); 857 return true; 858 case 5: 859 arch.SetTriple("armv4-apple-" OSNAME); 860 return true; 861 case 6: 862 arch.SetTriple("arm-apple-" OSNAME); 863 return true; 864 case 7: 865 arch.SetTriple("thumbv7m-apple-" OSNAME); 866 return true; 867 case 8: 868 arch.SetTriple("thumbv7-apple-" OSNAME); 869 return true; 870 case 9: 871 arch.SetTriple("thumbv6m-apple-" OSNAME); 872 return true; 873 case 10: 874 arch.SetTriple("thumbv6-apple-" OSNAME); 875 return true; 876 case 11: 877 arch.SetTriple("thumbv5-apple-" OSNAME); 878 return true; 879 case 12: 880 arch.SetTriple("thumbv4t-apple-" OSNAME); 881 return true; 882 case 13: 883 arch.SetTriple("thumb-apple-" OSNAME); 884 return true; 885 default: 886 break; 887 } 888 break; 889 890 case ArchSpec::eCore_arm_armv7em: 891 switch (idx) { 892 case 0: 893 arch.SetTriple("armv7em-apple-" OSNAME); 894 return true; 895 case 1: 896 arch.SetTriple("armv7-apple-" OSNAME); 897 return true; 898 case 2: 899 arch.SetTriple("armv6m-apple-" OSNAME); 900 return true; 901 case 3: 902 arch.SetTriple("armv6-apple-" OSNAME); 903 return true; 904 case 4: 905 arch.SetTriple("armv5-apple-" OSNAME); 906 return true; 907 case 5: 908 arch.SetTriple("armv4-apple-" OSNAME); 909 return true; 910 case 6: 911 arch.SetTriple("arm-apple-" OSNAME); 912 return true; 913 case 7: 914 arch.SetTriple("thumbv7em-apple-" OSNAME); 915 return true; 916 case 8: 917 arch.SetTriple("thumbv7-apple-" OSNAME); 918 return true; 919 case 9: 920 arch.SetTriple("thumbv6m-apple-" OSNAME); 921 return true; 922 case 10: 923 arch.SetTriple("thumbv6-apple-" OSNAME); 924 return true; 925 case 11: 926 arch.SetTriple("thumbv5-apple-" OSNAME); 927 return true; 928 case 12: 929 arch.SetTriple("thumbv4t-apple-" OSNAME); 930 return true; 931 case 13: 932 arch.SetTriple("thumb-apple-" OSNAME); 933 return true; 934 default: 935 break; 936 } 937 break; 938 939 case ArchSpec::eCore_arm_armv7: 940 switch (idx) { 941 case 0: 942 arch.SetTriple("armv7-apple-" OSNAME); 943 return true; 944 case 1: 945 arch.SetTriple("armv6m-apple-" OSNAME); 946 return true; 947 case 2: 948 arch.SetTriple("armv6-apple-" OSNAME); 949 return true; 950 case 3: 951 arch.SetTriple("armv5-apple-" OSNAME); 952 return true; 953 case 4: 954 arch.SetTriple("armv4-apple-" OSNAME); 955 return true; 956 case 5: 957 arch.SetTriple("arm-apple-" OSNAME); 958 return true; 959 case 6: 960 arch.SetTriple("thumbv7-apple-" OSNAME); 961 return true; 962 case 7: 963 arch.SetTriple("thumbv6m-apple-" OSNAME); 964 return true; 965 case 8: 966 arch.SetTriple("thumbv6-apple-" OSNAME); 967 return true; 968 case 9: 969 arch.SetTriple("thumbv5-apple-" OSNAME); 970 return true; 971 case 10: 972 arch.SetTriple("thumbv4t-apple-" OSNAME); 973 return true; 974 case 11: 975 arch.SetTriple("thumb-apple-" OSNAME); 976 return true; 977 default: 978 break; 979 } 980 break; 981 982 case ArchSpec::eCore_arm_armv6m: 983 switch (idx) { 984 case 0: 985 arch.SetTriple("armv6m-apple-" OSNAME); 986 return true; 987 case 1: 988 arch.SetTriple("armv6-apple-" OSNAME); 989 return true; 990 case 2: 991 arch.SetTriple("armv5-apple-" OSNAME); 992 return true; 993 case 3: 994 arch.SetTriple("armv4-apple-" OSNAME); 995 return true; 996 case 4: 997 arch.SetTriple("arm-apple-" OSNAME); 998 return true; 999 case 5: 1000 arch.SetTriple("thumbv6m-apple-" OSNAME); 1001 return true; 1002 case 6: 1003 arch.SetTriple("thumbv6-apple-" OSNAME); 1004 return true; 1005 case 7: 1006 arch.SetTriple("thumbv5-apple-" OSNAME); 1007 return true; 1008 case 8: 1009 arch.SetTriple("thumbv4t-apple-" OSNAME); 1010 return true; 1011 case 9: 1012 arch.SetTriple("thumb-apple-" OSNAME); 1013 return true; 1014 default: 1015 break; 1016 } 1017 break; 1018 1019 case ArchSpec::eCore_arm_armv6: 1020 switch (idx) { 1021 case 0: 1022 arch.SetTriple("armv6-apple-" OSNAME); 1023 return true; 1024 case 1: 1025 arch.SetTriple("armv5-apple-" OSNAME); 1026 return true; 1027 case 2: 1028 arch.SetTriple("armv4-apple-" OSNAME); 1029 return true; 1030 case 3: 1031 arch.SetTriple("arm-apple-" OSNAME); 1032 return true; 1033 case 4: 1034 arch.SetTriple("thumbv6-apple-" OSNAME); 1035 return true; 1036 case 5: 1037 arch.SetTriple("thumbv5-apple-" OSNAME); 1038 return true; 1039 case 6: 1040 arch.SetTriple("thumbv4t-apple-" OSNAME); 1041 return true; 1042 case 7: 1043 arch.SetTriple("thumb-apple-" OSNAME); 1044 return true; 1045 default: 1046 break; 1047 } 1048 break; 1049 1050 case ArchSpec::eCore_arm_armv5: 1051 switch (idx) { 1052 case 0: 1053 arch.SetTriple("armv5-apple-" OSNAME); 1054 return true; 1055 case 1: 1056 arch.SetTriple("armv4-apple-" OSNAME); 1057 return true; 1058 case 2: 1059 arch.SetTriple("arm-apple-" OSNAME); 1060 return true; 1061 case 3: 1062 arch.SetTriple("thumbv5-apple-" OSNAME); 1063 return true; 1064 case 4: 1065 arch.SetTriple("thumbv4t-apple-" OSNAME); 1066 return true; 1067 case 5: 1068 arch.SetTriple("thumb-apple-" OSNAME); 1069 return true; 1070 default: 1071 break; 1072 } 1073 break; 1074 1075 case ArchSpec::eCore_arm_armv4: 1076 switch (idx) { 1077 case 0: 1078 arch.SetTriple("armv4-apple-" OSNAME); 1079 return true; 1080 case 1: 1081 arch.SetTriple("arm-apple-" OSNAME); 1082 return true; 1083 case 2: 1084 arch.SetTriple("thumbv4t-apple-" OSNAME); 1085 return true; 1086 case 3: 1087 arch.SetTriple("thumb-apple-" OSNAME); 1088 return true; 1089 default: 1090 break; 1091 } 1092 break; 1093 } 1094 arch.Clear(); 1095 return false; 1096 } 1097 1098 static FileSpec GetXcodeSelectPath() { 1099 static FileSpec g_xcode_select_filespec; 1100 1101 if (!g_xcode_select_filespec) { 1102 FileSpec xcode_select_cmd("/usr/bin/xcode-select"); 1103 if (FileSystem::Instance().Exists(xcode_select_cmd)) { 1104 int exit_status = -1; 1105 int signo = -1; 1106 std::string command_output; 1107 Status status = 1108 Host::RunShellCommand("/usr/bin/xcode-select --print-path", 1109 FileSpec(), // current working directory 1110 &exit_status, &signo, &command_output, 1111 std::chrono::seconds(2), // short timeout 1112 false); // don't run in a shell 1113 if (status.Success() && exit_status == 0 && !command_output.empty()) { 1114 size_t first_non_newline = command_output.find_last_not_of("\r\n"); 1115 if (first_non_newline != std::string::npos) { 1116 command_output.erase(first_non_newline + 1); 1117 } 1118 g_xcode_select_filespec = FileSpec(command_output); 1119 } 1120 } 1121 } 1122 1123 return g_xcode_select_filespec; 1124 } 1125 1126 // Return a directory path like /Applications/Xcode.app/Contents/Developer 1127 const char *PlatformDarwin::GetDeveloperDirectory() { 1128 std::lock_guard<std::mutex> guard(m_mutex); 1129 if (m_developer_directory.empty()) { 1130 bool developer_dir_path_valid = false; 1131 char developer_dir_path[PATH_MAX]; 1132 1133 // Get the lldb framework's file path, and if it exists, truncate some 1134 // components to only the developer directory path. 1135 FileSpec temp_file_spec = HostInfo::GetShlibDir(); 1136 if (temp_file_spec) { 1137 if (temp_file_spec.GetPath(developer_dir_path, 1138 sizeof(developer_dir_path))) { 1139 // e.g. 1140 // /Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework 1141 char *shared_frameworks = 1142 strstr(developer_dir_path, "/SharedFrameworks/LLDB.framework"); 1143 if (shared_frameworks) { 1144 shared_frameworks[0] = '\0'; // truncate developer_dir_path at this point 1145 strncat (developer_dir_path, "/Developer", sizeof (developer_dir_path) - 1); // add /Developer on 1146 developer_dir_path_valid = true; 1147 } else { 1148 // e.g. 1149 // /Applications/Xcode.app/Contents/Developer/Toolchains/iOS11.2.xctoolchain/System/Library/PrivateFrameworks/LLDB.framework 1150 char *developer_toolchains = 1151 strstr(developer_dir_path, "/Contents/Developer/Toolchains/"); 1152 if (developer_toolchains) { 1153 developer_toolchains += sizeof ("/Contents/Developer") - 1; 1154 developer_toolchains[0] = '\0'; // truncate developer_dir_path at this point 1155 developer_dir_path_valid = true; 1156 } 1157 } 1158 } 1159 } 1160 1161 if (!developer_dir_path_valid) { 1162 std::string xcode_dir_path; 1163 const char *xcode_select_prefix_dir = getenv("XCODE_SELECT_PREFIX_DIR"); 1164 if (xcode_select_prefix_dir) 1165 xcode_dir_path.append(xcode_select_prefix_dir); 1166 xcode_dir_path.append("/usr/share/xcode-select/xcode_dir_path"); 1167 temp_file_spec.SetFile(xcode_dir_path, FileSpec::Style::native); 1168 auto dir_buffer = 1169 FileSystem::Instance().CreateDataBuffer(temp_file_spec.GetPath()); 1170 if (dir_buffer && dir_buffer->GetByteSize() > 0) { 1171 llvm::StringRef path_ref(dir_buffer->GetChars()); 1172 // Trim tailing newlines and make sure there is enough room for a null 1173 // terminator. 1174 path_ref = 1175 path_ref.rtrim("\r\n").take_front(sizeof(developer_dir_path) - 1); 1176 ::memcpy(developer_dir_path, path_ref.data(), path_ref.size()); 1177 developer_dir_path[path_ref.size()] = '\0'; 1178 developer_dir_path_valid = true; 1179 } 1180 } 1181 1182 if (!developer_dir_path_valid) { 1183 FileSpec devel_dir = GetXcodeSelectPath(); 1184 if (FileSystem::Instance().IsDirectory(devel_dir)) { 1185 devel_dir.GetPath(&developer_dir_path[0], sizeof(developer_dir_path)); 1186 developer_dir_path_valid = true; 1187 } 1188 } 1189 1190 if (developer_dir_path_valid) { 1191 temp_file_spec.SetFile(developer_dir_path, FileSpec::Style::native); 1192 if (FileSystem::Instance().Exists(temp_file_spec)) { 1193 m_developer_directory.assign(developer_dir_path); 1194 return m_developer_directory.c_str(); 1195 } 1196 } 1197 // Assign a single NULL character so we know we tried to find the device 1198 // support directory and we don't keep trying to find it over and over. 1199 m_developer_directory.assign(1, '\0'); 1200 } 1201 1202 // We should have put a single NULL character into m_developer_directory or 1203 // it should have a valid path if the code gets here 1204 assert(m_developer_directory.empty() == false); 1205 if (m_developer_directory[0]) 1206 return m_developer_directory.c_str(); 1207 return nullptr; 1208 } 1209 1210 BreakpointSP PlatformDarwin::SetThreadCreationBreakpoint(Target &target) { 1211 BreakpointSP bp_sp; 1212 static const char *g_bp_names[] = { 1213 "start_wqthread", "_pthread_wqthread", "_pthread_start", 1214 }; 1215 1216 static const char *g_bp_modules[] = {"libsystem_c.dylib", 1217 "libSystem.B.dylib"}; 1218 1219 FileSpecList bp_modules; 1220 for (size_t i = 0; i < llvm::array_lengthof(g_bp_modules); i++) { 1221 const char *bp_module = g_bp_modules[i]; 1222 bp_modules.EmplaceBack(bp_module); 1223 } 1224 1225 bool internal = true; 1226 bool hardware = false; 1227 LazyBool skip_prologue = eLazyBoolNo; 1228 bp_sp = target.CreateBreakpoint(&bp_modules, nullptr, g_bp_names, 1229 llvm::array_lengthof(g_bp_names), 1230 eFunctionNameTypeFull, eLanguageTypeUnknown, 1231 0, skip_prologue, internal, hardware); 1232 bp_sp->SetBreakpointKind("thread-creation"); 1233 1234 return bp_sp; 1235 } 1236 1237 int32_t 1238 PlatformDarwin::GetResumeCountForLaunchInfo(ProcessLaunchInfo &launch_info) { 1239 const FileSpec &shell = launch_info.GetShell(); 1240 if (!shell) 1241 return 1; 1242 1243 std::string shell_string = shell.GetPath(); 1244 const char *shell_name = strrchr(shell_string.c_str(), '/'); 1245 if (shell_name == nullptr) 1246 shell_name = shell_string.c_str(); 1247 else 1248 shell_name++; 1249 1250 if (strcmp(shell_name, "sh") == 0) { 1251 // /bin/sh re-exec's itself as /bin/bash requiring another resume. But it 1252 // only does this if the COMMAND_MODE environment variable is set to 1253 // "legacy". 1254 if (launch_info.GetEnvironment().lookup("COMMAND_MODE") == "legacy") 1255 return 2; 1256 return 1; 1257 } else if (strcmp(shell_name, "csh") == 0 || 1258 strcmp(shell_name, "tcsh") == 0 || 1259 strcmp(shell_name, "zsh") == 0) { 1260 // csh and tcsh always seem to re-exec themselves. 1261 return 2; 1262 } else 1263 return 1; 1264 } 1265 1266 void PlatformDarwin::CalculateTrapHandlerSymbolNames() { 1267 m_trap_handlers.push_back(ConstString("_sigtramp")); 1268 } 1269 1270 static const char *const sdk_strings[] = { 1271 "MacOSX", "iPhoneSimulator", "iPhoneOS", 1272 }; 1273 1274 static FileSpec CheckPathForXcode(const FileSpec &fspec) { 1275 if (FileSystem::Instance().Exists(fspec)) { 1276 const char substr[] = ".app/Contents"; 1277 1278 std::string path_to_shlib = fspec.GetPath(); 1279 size_t pos = path_to_shlib.rfind(substr); 1280 if (pos != std::string::npos) { 1281 path_to_shlib.erase(pos + strlen(substr)); 1282 FileSpec ret(path_to_shlib); 1283 1284 FileSpec xcode_binary_path = ret; 1285 xcode_binary_path.AppendPathComponent("MacOS"); 1286 xcode_binary_path.AppendPathComponent("Xcode"); 1287 1288 if (FileSystem::Instance().Exists(xcode_binary_path)) { 1289 return ret; 1290 } 1291 } 1292 } 1293 return FileSpec(); 1294 } 1295 1296 static FileSpec GetXcodeContentsPath() { 1297 static FileSpec g_xcode_filespec; 1298 static llvm::once_flag g_once_flag; 1299 llvm::call_once(g_once_flag, []() { 1300 1301 FileSpec fspec; 1302 1303 // First get the program file spec. If lldb.so or LLDB.framework is running 1304 // in a program and that program is Xcode, the path returned with be the 1305 // path to Xcode.app/Contents/MacOS/Xcode, so this will be the correct 1306 // Xcode to use. 1307 fspec = HostInfo::GetProgramFileSpec(); 1308 1309 if (fspec) { 1310 // Ignore the current binary if it is python. 1311 std::string basename_lower = fspec.GetFilename().GetCString(); 1312 std::transform(basename_lower.begin(), basename_lower.end(), 1313 basename_lower.begin(), tolower); 1314 if (basename_lower != "python") { 1315 g_xcode_filespec = CheckPathForXcode(fspec); 1316 } 1317 } 1318 1319 // Next check DEVELOPER_DIR environment variable 1320 if (!g_xcode_filespec) { 1321 const char *developer_dir_env_var = getenv("DEVELOPER_DIR"); 1322 if (developer_dir_env_var && developer_dir_env_var[0]) { 1323 FileSpec developer_dir_spec = FileSpec(developer_dir_env_var); 1324 FileSystem::Instance().Resolve(developer_dir_spec); 1325 g_xcode_filespec = CheckPathForXcode(developer_dir_spec); 1326 } 1327 1328 // Fall back to using "xcode-select" to find the selected Xcode 1329 if (!g_xcode_filespec) { 1330 FileSpec xcode_select_path(GetXcodeSelectPath()); 1331 xcode_select_path.RemoveLastPathComponent(); 1332 g_xcode_filespec = CheckPathForXcode(xcode_select_path); 1333 } 1334 } 1335 }); 1336 1337 return g_xcode_filespec; 1338 } 1339 1340 static FileSpec GetCommandLineToolsLibraryPath() { 1341 static FileSpec g_command_line_tools_filespec; 1342 1343 if (!g_command_line_tools_filespec) { 1344 FileSpec command_line_tools_path(GetXcodeSelectPath()); 1345 command_line_tools_path.AppendPathComponent("Library"); 1346 if (FileSystem::Instance().Exists(command_line_tools_path)) { 1347 g_command_line_tools_filespec = command_line_tools_path; 1348 } 1349 } 1350 1351 return g_command_line_tools_filespec; 1352 } 1353 1354 bool PlatformDarwin::SDKSupportsModules(SDKType sdk_type, 1355 llvm::VersionTuple version) { 1356 switch (sdk_type) { 1357 case SDKType::MacOSX: 1358 return version >= llvm::VersionTuple(10, 10); 1359 case SDKType::iPhoneOS: 1360 case SDKType::iPhoneSimulator: 1361 return version >= llvm::VersionTuple(8); 1362 } 1363 1364 return false; 1365 } 1366 1367 bool PlatformDarwin::SDKSupportsModules(SDKType desired_type, 1368 const FileSpec &sdk_path) { 1369 ConstString last_path_component = sdk_path.GetLastPathComponent(); 1370 1371 if (last_path_component) { 1372 const llvm::StringRef sdk_name = last_path_component.GetStringRef(); 1373 1374 if (!sdk_name.startswith(sdk_strings[desired_type])) 1375 return false; 1376 auto version_part = 1377 sdk_name.drop_front(strlen(sdk_strings[desired_type])); 1378 version_part.consume_back(".sdk"); 1379 1380 llvm::VersionTuple version; 1381 if (version.tryParse(version_part)) 1382 return false; 1383 return SDKSupportsModules(desired_type, version); 1384 } 1385 1386 return false; 1387 } 1388 1389 FileSystem::EnumerateDirectoryResult PlatformDarwin::DirectoryEnumerator( 1390 void *baton, llvm::sys::fs::file_type file_type, llvm::StringRef path) { 1391 SDKEnumeratorInfo *enumerator_info = static_cast<SDKEnumeratorInfo *>(baton); 1392 1393 FileSpec spec(path); 1394 if (SDKSupportsModules(enumerator_info->sdk_type, spec)) { 1395 enumerator_info->found_path = spec; 1396 return FileSystem::EnumerateDirectoryResult::eEnumerateDirectoryResultNext; 1397 } 1398 1399 return FileSystem::EnumerateDirectoryResult::eEnumerateDirectoryResultNext; 1400 } 1401 1402 FileSpec PlatformDarwin::FindSDKInXcodeForModules(SDKType sdk_type, 1403 const FileSpec &sdks_spec) { 1404 // Look inside Xcode for the required installed iOS SDK version 1405 1406 if (!FileSystem::Instance().IsDirectory(sdks_spec)) { 1407 return FileSpec(); 1408 } 1409 1410 const bool find_directories = true; 1411 const bool find_files = false; 1412 const bool find_other = true; // include symlinks 1413 1414 SDKEnumeratorInfo enumerator_info; 1415 1416 enumerator_info.sdk_type = sdk_type; 1417 1418 FileSystem::Instance().EnumerateDirectory( 1419 sdks_spec.GetPath(), find_directories, find_files, find_other, 1420 DirectoryEnumerator, &enumerator_info); 1421 1422 if (FileSystem::Instance().IsDirectory(enumerator_info.found_path)) 1423 return enumerator_info.found_path; 1424 else 1425 return FileSpec(); 1426 } 1427 1428 FileSpec PlatformDarwin::GetSDKDirectoryForModules(SDKType sdk_type) { 1429 switch (sdk_type) { 1430 case SDKType::MacOSX: 1431 case SDKType::iPhoneSimulator: 1432 case SDKType::iPhoneOS: 1433 break; 1434 } 1435 1436 FileSpec sdks_spec = GetXcodeContentsPath(); 1437 sdks_spec.AppendPathComponent("Developer"); 1438 sdks_spec.AppendPathComponent("Platforms"); 1439 1440 switch (sdk_type) { 1441 case SDKType::MacOSX: 1442 sdks_spec.AppendPathComponent("MacOSX.platform"); 1443 break; 1444 case SDKType::iPhoneSimulator: 1445 sdks_spec.AppendPathComponent("iPhoneSimulator.platform"); 1446 break; 1447 case SDKType::iPhoneOS: 1448 sdks_spec.AppendPathComponent("iPhoneOS.platform"); 1449 break; 1450 } 1451 1452 sdks_spec.AppendPathComponent("Developer"); 1453 sdks_spec.AppendPathComponent("SDKs"); 1454 1455 if (sdk_type == SDKType::MacOSX) { 1456 llvm::VersionTuple version = HostInfo::GetOSVersion(); 1457 1458 if (!version.empty()) { 1459 if (SDKSupportsModules(SDKType::MacOSX, version)) { 1460 // If the Xcode SDKs are not available then try to use the 1461 // Command Line Tools one which is only for MacOSX. 1462 if (!FileSystem::Instance().Exists(sdks_spec)) { 1463 sdks_spec = GetCommandLineToolsLibraryPath(); 1464 sdks_spec.AppendPathComponent("SDKs"); 1465 } 1466 1467 // We slightly prefer the exact SDK for this machine. See if it is 1468 // there. 1469 1470 FileSpec native_sdk_spec = sdks_spec; 1471 StreamString native_sdk_name; 1472 native_sdk_name.Printf("MacOSX%u.%u.sdk", version.getMajor(), 1473 version.getMinor().getValueOr(0)); 1474 native_sdk_spec.AppendPathComponent(native_sdk_name.GetString()); 1475 1476 if (FileSystem::Instance().Exists(native_sdk_spec)) { 1477 return native_sdk_spec; 1478 } 1479 } 1480 } 1481 } 1482 1483 return FindSDKInXcodeForModules(sdk_type, sdks_spec); 1484 } 1485 1486 std::tuple<llvm::VersionTuple, llvm::StringRef> 1487 PlatformDarwin::ParseVersionBuildDir(llvm::StringRef dir) { 1488 llvm::StringRef build; 1489 llvm::StringRef version_str; 1490 llvm::StringRef build_str; 1491 std::tie(version_str, build_str) = dir.split(' '); 1492 llvm::VersionTuple version; 1493 if (!version.tryParse(version_str) || 1494 build_str.empty()) { 1495 if (build_str.consume_front("(")) { 1496 size_t pos = build_str.find(')'); 1497 build = build_str.slice(0, pos); 1498 } 1499 } 1500 1501 return std::make_tuple(version, build); 1502 } 1503 1504 void PlatformDarwin::AddClangModuleCompilationOptionsForSDKType( 1505 Target *target, std::vector<std::string> &options, SDKType sdk_type) { 1506 const std::vector<std::string> apple_arguments = { 1507 "-x", "objective-c++", "-fobjc-arc", 1508 "-fblocks", "-D_ISO646_H", "-D__ISO646_H", 1509 "-fgnuc-version=4.2.1"}; 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