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