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 = NULL; 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::x86: 594 case llvm::Triple::x86_64: 595 { 596 static const uint8_t g_i386_breakpoint_opcode[] = { 0xCC }; 597 trap_opcode = g_i386_breakpoint_opcode; 598 trap_opcode_size = sizeof(g_i386_breakpoint_opcode); 599 } 600 break; 601 602 case llvm::Triple::aarch64: 603 { 604 // TODO: fix this with actual darwin breakpoint opcode for arm64. 605 // right now debugging uses the Z packets with GDB remote so this 606 // is not needed, but the size needs to be correct... 607 static const uint8_t g_arm64_breakpoint_opcode[] = { 0xFE, 0xDE, 0xFF, 0xE7 }; 608 trap_opcode = g_arm64_breakpoint_opcode; 609 trap_opcode_size = sizeof(g_arm64_breakpoint_opcode); 610 } 611 break; 612 613 case llvm::Triple::thumb: 614 bp_is_thumb = true; // Fall through... 615 case llvm::Triple::arm: 616 { 617 static const uint8_t g_arm_breakpoint_opcode[] = { 0xFE, 0xDE, 0xFF, 0xE7 }; 618 static const uint8_t g_thumb_breakpooint_opcode[] = { 0xFE, 0xDE }; 619 620 // Auto detect arm/thumb if it wasn't explicitly specified 621 if (!bp_is_thumb) 622 { 623 lldb::BreakpointLocationSP bp_loc_sp (bp_site->GetOwnerAtIndex (0)); 624 if (bp_loc_sp) 625 bp_is_thumb = bp_loc_sp->GetAddress().GetAddressClass () == eAddressClassCodeAlternateISA; 626 } 627 if (bp_is_thumb) 628 { 629 trap_opcode = g_thumb_breakpooint_opcode; 630 trap_opcode_size = sizeof(g_thumb_breakpooint_opcode); 631 break; 632 } 633 trap_opcode = g_arm_breakpoint_opcode; 634 trap_opcode_size = sizeof(g_arm_breakpoint_opcode); 635 } 636 break; 637 638 case llvm::Triple::ppc: 639 case llvm::Triple::ppc64: 640 { 641 static const uint8_t g_ppc_breakpoint_opcode[] = { 0x7F, 0xC0, 0x00, 0x08 }; 642 trap_opcode = g_ppc_breakpoint_opcode; 643 trap_opcode_size = sizeof(g_ppc_breakpoint_opcode); 644 } 645 break; 646 647 default: 648 assert(!"Unhandled architecture in PlatformDarwin::GetSoftwareBreakpointTrapOpcode()"); 649 break; 650 } 651 652 if (trap_opcode && trap_opcode_size) 653 { 654 if (bp_site->SetTrapOpcode(trap_opcode, trap_opcode_size)) 655 return trap_opcode_size; 656 } 657 return 0; 658 659 } 660 661 bool 662 PlatformDarwin::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info) 663 { 664 bool success = false; 665 if (IsHost()) 666 { 667 success = Platform::GetProcessInfo (pid, process_info); 668 } 669 else 670 { 671 if (m_remote_platform_sp) 672 success = m_remote_platform_sp->GetProcessInfo (pid, process_info); 673 } 674 return success; 675 } 676 677 uint32_t 678 PlatformDarwin::FindProcesses (const ProcessInstanceInfoMatch &match_info, 679 ProcessInstanceInfoList &process_infos) 680 { 681 uint32_t match_count = 0; 682 if (IsHost()) 683 { 684 // Let the base class figure out the host details 685 match_count = Platform::FindProcesses (match_info, process_infos); 686 } 687 else 688 { 689 // If we are remote, we can only return results if we are connected 690 if (m_remote_platform_sp) 691 match_count = m_remote_platform_sp->FindProcesses (match_info, process_infos); 692 } 693 return match_count; 694 } 695 696 bool 697 PlatformDarwin::ModuleIsExcludedForUnconstrainedSearches (lldb_private::Target &target, const lldb::ModuleSP &module_sp) 698 { 699 if (!module_sp) 700 return false; 701 702 ObjectFile *obj_file = module_sp->GetObjectFile(); 703 if (!obj_file) 704 return false; 705 706 ObjectFile::Type obj_type = obj_file->GetType(); 707 if (obj_type == ObjectFile::eTypeDynamicLinker) 708 return true; 709 else 710 return false; 711 } 712 713 bool 714 PlatformDarwin::x86GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch) 715 { 716 ArchSpec host_arch = HostInfo::GetArchitecture(HostInfo::eArchKindDefault); 717 if (host_arch.GetCore() == ArchSpec::eCore_x86_64_x86_64h) 718 { 719 switch (idx) 720 { 721 case 0: 722 arch = host_arch; 723 return true; 724 725 case 1: 726 arch.SetTriple("x86_64-apple-macosx"); 727 return true; 728 729 case 2: 730 arch = HostInfo::GetArchitecture(HostInfo::eArchKind32); 731 return true; 732 733 default: return false; 734 } 735 } 736 else 737 { 738 if (idx == 0) 739 { 740 arch = HostInfo::GetArchitecture(HostInfo::eArchKindDefault); 741 return arch.IsValid(); 742 } 743 else if (idx == 1) 744 { 745 ArchSpec platform_arch(HostInfo::GetArchitecture(HostInfo::eArchKindDefault)); 746 ArchSpec platform_arch64(HostInfo::GetArchitecture(HostInfo::eArchKind64)); 747 if (platform_arch.IsExactMatch(platform_arch64)) 748 { 749 // This macosx platform supports both 32 and 64 bit. Since we already 750 // returned the 64 bit arch for idx == 0, return the 32 bit arch 751 // for idx == 1 752 arch = HostInfo::GetArchitecture(HostInfo::eArchKind32); 753 return arch.IsValid(); 754 } 755 } 756 } 757 return false; 758 } 759 760 // The architecture selection rules for arm processors 761 // These cpu subtypes have distinct names (e.g. armv7f) but armv7 binaries run fine on an armv7f processor. 762 763 bool 764 PlatformDarwin::ARMGetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch) 765 { 766 ArchSpec system_arch (GetSystemArchitecture()); 767 768 // When lldb is running on a watch or tv, set the arch OS name appropriately. 769 #if defined (TARGET_OS_TV) && TARGET_OS_TV == 1 770 #define OSNAME "tvos" 771 #elif defined (TARGET_OS_WATCH) && TARGET_OS_WATCH == 1 772 #define OSNAME "watchos" 773 #else 774 #define OSNAME "ios" 775 #endif 776 777 const ArchSpec::Core system_core = system_arch.GetCore(); 778 switch (system_core) 779 { 780 default: 781 switch (idx) 782 { 783 case 0: arch.SetTriple ("arm64-apple-" OSNAME); return true; 784 case 1: arch.SetTriple ("armv7-apple-" OSNAME); return true; 785 case 2: arch.SetTriple ("armv7f-apple-" OSNAME); return true; 786 case 3: arch.SetTriple ("armv7k-apple-" OSNAME); return true; 787 case 4: arch.SetTriple ("armv7s-apple-" OSNAME); return true; 788 case 5: arch.SetTriple ("armv7m-apple-" OSNAME); return true; 789 case 6: arch.SetTriple ("armv7em-apple-" OSNAME); return true; 790 case 7: arch.SetTriple ("armv6m-apple-" OSNAME); return true; 791 case 8: arch.SetTriple ("armv6-apple-" OSNAME); return true; 792 case 9: arch.SetTriple ("armv5-apple-" OSNAME); return true; 793 case 10: arch.SetTriple ("armv4-apple-" OSNAME); return true; 794 case 11: arch.SetTriple ("arm-apple-" OSNAME); return true; 795 case 12: arch.SetTriple ("thumbv7-apple-" OSNAME); return true; 796 case 13: arch.SetTriple ("thumbv7f-apple-" OSNAME); return true; 797 case 14: arch.SetTriple ("thumbv7k-apple-" OSNAME); return true; 798 case 15: arch.SetTriple ("thumbv7s-apple-" OSNAME); return true; 799 case 16: arch.SetTriple ("thumbv7m-apple-" OSNAME); return true; 800 case 17: arch.SetTriple ("thumbv7em-apple-" OSNAME); return true; 801 case 18: arch.SetTriple ("thumbv6m-apple-" OSNAME); return true; 802 case 19: arch.SetTriple ("thumbv6-apple-" OSNAME); return true; 803 case 20: arch.SetTriple ("thumbv5-apple-" OSNAME); return true; 804 case 21: arch.SetTriple ("thumbv4t-apple-" OSNAME); return true; 805 case 22: arch.SetTriple ("thumb-apple-" OSNAME); return true; 806 default: break; 807 } 808 break; 809 810 case ArchSpec::eCore_arm_arm64: 811 switch (idx) 812 { 813 case 0: arch.SetTriple ("arm64-apple-" OSNAME); return true; 814 case 1: arch.SetTriple ("armv7s-apple-" OSNAME); return true; 815 case 2: arch.SetTriple ("armv7f-apple-" OSNAME); return true; 816 case 3: arch.SetTriple ("armv7m-apple-" OSNAME); return true; 817 case 4: arch.SetTriple ("armv7em-apple-" OSNAME); return true; 818 case 5: arch.SetTriple ("armv7-apple-" OSNAME); return true; 819 case 6: arch.SetTriple ("armv6m-apple-" OSNAME); return true; 820 case 7: arch.SetTriple ("armv6-apple-" OSNAME); return true; 821 case 8: arch.SetTriple ("armv5-apple-" OSNAME); return true; 822 case 9: arch.SetTriple ("armv4-apple-" OSNAME); return true; 823 case 10: arch.SetTriple ("arm-apple-" OSNAME); return true; 824 case 11: arch.SetTriple ("thumbv7-apple-" OSNAME); return true; 825 case 12: arch.SetTriple ("thumbv7f-apple-" OSNAME); return true; 826 case 13: arch.SetTriple ("thumbv7k-apple-" OSNAME); return true; 827 case 14: arch.SetTriple ("thumbv7s-apple-" OSNAME); return true; 828 case 15: arch.SetTriple ("thumbv7m-apple-" OSNAME); return true; 829 case 16: arch.SetTriple ("thumbv7em-apple-" OSNAME); return true; 830 case 17: arch.SetTriple ("thumbv6m-apple-" OSNAME); return true; 831 case 18: arch.SetTriple ("thumbv6-apple-" OSNAME); return true; 832 case 19: arch.SetTriple ("thumbv5-apple-" OSNAME); return true; 833 case 20: arch.SetTriple ("thumbv4t-apple-" OSNAME); return true; 834 case 21: arch.SetTriple ("thumb-apple-" OSNAME); return true; 835 default: break; 836 } 837 break; 838 839 case ArchSpec::eCore_arm_armv7f: 840 switch (idx) 841 { 842 case 0: arch.SetTriple ("armv7f-apple-" OSNAME); return true; 843 case 1: arch.SetTriple ("armv7-apple-" OSNAME); return true; 844 case 2: arch.SetTriple ("armv6m-apple-" OSNAME); return true; 845 case 3: arch.SetTriple ("armv6-apple-" OSNAME); return true; 846 case 4: arch.SetTriple ("armv5-apple-" OSNAME); return true; 847 case 5: arch.SetTriple ("armv4-apple-" OSNAME); return true; 848 case 6: arch.SetTriple ("arm-apple-" OSNAME); return true; 849 case 7: arch.SetTriple ("thumbv7f-apple-" OSNAME); return true; 850 case 8: arch.SetTriple ("thumbv7-apple-" OSNAME); return true; 851 case 9: arch.SetTriple ("thumbv6m-apple-" OSNAME); return true; 852 case 10: arch.SetTriple ("thumbv6-apple-" OSNAME); return true; 853 case 11: arch.SetTriple ("thumbv5-apple-" OSNAME); return true; 854 case 12: arch.SetTriple ("thumbv4t-apple-" OSNAME); return true; 855 case 13: arch.SetTriple ("thumb-apple-" OSNAME); return true; 856 default: break; 857 } 858 break; 859 860 case ArchSpec::eCore_arm_armv7k: 861 switch (idx) 862 { 863 case 0: arch.SetTriple ("armv7k-apple-" OSNAME); return true; 864 case 1: arch.SetTriple ("armv7-apple-" OSNAME); return true; 865 case 2: arch.SetTriple ("armv6m-apple-" OSNAME); return true; 866 case 3: arch.SetTriple ("armv6-apple-" OSNAME); return true; 867 case 4: arch.SetTriple ("armv5-apple-" OSNAME); return true; 868 case 5: arch.SetTriple ("armv4-apple-" OSNAME); return true; 869 case 6: arch.SetTriple ("arm-apple-" OSNAME); return true; 870 case 7: arch.SetTriple ("thumbv7k-apple-" OSNAME); return true; 871 case 8: arch.SetTriple ("thumbv7-apple-" OSNAME); return true; 872 case 9: arch.SetTriple ("thumbv6m-apple-" OSNAME); return true; 873 case 10: arch.SetTriple ("thumbv6-apple-" OSNAME); return true; 874 case 11: arch.SetTriple ("thumbv5-apple-" OSNAME); return true; 875 case 12: arch.SetTriple ("thumbv4t-apple-" OSNAME); return true; 876 case 13: arch.SetTriple ("thumb-apple-" OSNAME); return true; 877 default: break; 878 } 879 break; 880 881 case ArchSpec::eCore_arm_armv7s: 882 switch (idx) 883 { 884 case 0: arch.SetTriple ("armv7s-apple-" OSNAME); return true; 885 case 1: arch.SetTriple ("armv7-apple-" OSNAME); return true; 886 case 2: arch.SetTriple ("armv6m-apple-" OSNAME); return true; 887 case 3: arch.SetTriple ("armv6-apple-" OSNAME); return true; 888 case 4: arch.SetTriple ("armv5-apple-" OSNAME); return true; 889 case 5: arch.SetTriple ("armv4-apple-" OSNAME); return true; 890 case 6: arch.SetTriple ("arm-apple-" OSNAME); return true; 891 case 7: arch.SetTriple ("thumbv7s-apple-" OSNAME); return true; 892 case 8: arch.SetTriple ("thumbv7-apple-" OSNAME); return true; 893 case 9: arch.SetTriple ("thumbv6m-apple-" OSNAME); return true; 894 case 10: arch.SetTriple ("thumbv6-apple-" OSNAME); return true; 895 case 11: arch.SetTriple ("thumbv5-apple-" OSNAME); return true; 896 case 12: arch.SetTriple ("thumbv4t-apple-" OSNAME); return true; 897 case 13: arch.SetTriple ("thumb-apple-" OSNAME); return true; 898 default: break; 899 } 900 break; 901 902 case ArchSpec::eCore_arm_armv7m: 903 switch (idx) 904 { 905 case 0: arch.SetTriple ("armv7m-apple-" OSNAME); return true; 906 case 1: arch.SetTriple ("armv7-apple-" OSNAME); return true; 907 case 2: arch.SetTriple ("armv6m-apple-" OSNAME); return true; 908 case 3: arch.SetTriple ("armv6-apple-" OSNAME); return true; 909 case 4: arch.SetTriple ("armv5-apple-" OSNAME); return true; 910 case 5: arch.SetTriple ("armv4-apple-" OSNAME); return true; 911 case 6: arch.SetTriple ("arm-apple-" OSNAME); return true; 912 case 7: arch.SetTriple ("thumbv7m-apple-" OSNAME); return true; 913 case 8: arch.SetTriple ("thumbv7-apple-" OSNAME); return true; 914 case 9: arch.SetTriple ("thumbv6m-apple-" OSNAME); return true; 915 case 10: arch.SetTriple ("thumbv6-apple-" OSNAME); return true; 916 case 11: arch.SetTriple ("thumbv5-apple-" OSNAME); return true; 917 case 12: arch.SetTriple ("thumbv4t-apple-" OSNAME); return true; 918 case 13: arch.SetTriple ("thumb-apple-" OSNAME); return true; 919 default: break; 920 } 921 break; 922 923 case ArchSpec::eCore_arm_armv7em: 924 switch (idx) 925 { 926 case 0: arch.SetTriple ("armv7em-apple-" OSNAME); return true; 927 case 1: arch.SetTriple ("armv7-apple-" OSNAME); return true; 928 case 2: arch.SetTriple ("armv6m-apple-" OSNAME); return true; 929 case 3: arch.SetTriple ("armv6-apple-" OSNAME); return true; 930 case 4: arch.SetTriple ("armv5-apple-" OSNAME); return true; 931 case 5: arch.SetTriple ("armv4-apple-" OSNAME); return true; 932 case 6: arch.SetTriple ("arm-apple-" OSNAME); return true; 933 case 7: arch.SetTriple ("thumbv7em-apple-" OSNAME); return true; 934 case 8: arch.SetTriple ("thumbv7-apple-" OSNAME); return true; 935 case 9: arch.SetTriple ("thumbv6m-apple-" OSNAME); return true; 936 case 10: arch.SetTriple ("thumbv6-apple-" OSNAME); return true; 937 case 11: arch.SetTriple ("thumbv5-apple-" OSNAME); return true; 938 case 12: arch.SetTriple ("thumbv4t-apple-" OSNAME); return true; 939 case 13: arch.SetTriple ("thumb-apple-" OSNAME); return true; 940 default: break; 941 } 942 break; 943 944 case ArchSpec::eCore_arm_armv7: 945 switch (idx) 946 { 947 case 0: arch.SetTriple ("armv7-apple-" OSNAME); return true; 948 case 1: arch.SetTriple ("armv6m-apple-" OSNAME); return true; 949 case 2: arch.SetTriple ("armv6-apple-" OSNAME); return true; 950 case 3: arch.SetTriple ("armv5-apple-" OSNAME); return true; 951 case 4: arch.SetTriple ("armv4-apple-" OSNAME); return true; 952 case 5: arch.SetTriple ("arm-apple-" OSNAME); return true; 953 case 6: arch.SetTriple ("thumbv7-apple-" OSNAME); return true; 954 case 7: arch.SetTriple ("thumbv6m-apple-" OSNAME); return true; 955 case 8: arch.SetTriple ("thumbv6-apple-" OSNAME); return true; 956 case 9: arch.SetTriple ("thumbv5-apple-" OSNAME); return true; 957 case 10: arch.SetTriple ("thumbv4t-apple-" OSNAME); return true; 958 case 11: arch.SetTriple ("thumb-apple-" OSNAME); return true; 959 default: break; 960 } 961 break; 962 963 case ArchSpec::eCore_arm_armv6m: 964 switch (idx) 965 { 966 case 0: arch.SetTriple ("armv6m-apple-" OSNAME); return true; 967 case 1: arch.SetTriple ("armv6-apple-" OSNAME); return true; 968 case 2: arch.SetTriple ("armv5-apple-" OSNAME); return true; 969 case 3: arch.SetTriple ("armv4-apple-" OSNAME); return true; 970 case 4: arch.SetTriple ("arm-apple-" OSNAME); return true; 971 case 5: arch.SetTriple ("thumbv6m-apple-" OSNAME); return true; 972 case 6: arch.SetTriple ("thumbv6-apple-" OSNAME); return true; 973 case 7: arch.SetTriple ("thumbv5-apple-" OSNAME); return true; 974 case 8: arch.SetTriple ("thumbv4t-apple-" OSNAME); return true; 975 case 9: arch.SetTriple ("thumb-apple-" OSNAME); return true; 976 default: break; 977 } 978 break; 979 980 case ArchSpec::eCore_arm_armv6: 981 switch (idx) 982 { 983 case 0: arch.SetTriple ("armv6-apple-" OSNAME); return true; 984 case 1: arch.SetTriple ("armv5-apple-" OSNAME); return true; 985 case 2: arch.SetTriple ("armv4-apple-" OSNAME); return true; 986 case 3: arch.SetTriple ("arm-apple-" OSNAME); return true; 987 case 4: arch.SetTriple ("thumbv6-apple-" OSNAME); return true; 988 case 5: arch.SetTriple ("thumbv5-apple-" OSNAME); return true; 989 case 6: arch.SetTriple ("thumbv4t-apple-" OSNAME); return true; 990 case 7: arch.SetTriple ("thumb-apple-" OSNAME); return true; 991 default: break; 992 } 993 break; 994 995 case ArchSpec::eCore_arm_armv5: 996 switch (idx) 997 { 998 case 0: arch.SetTriple ("armv5-apple-" OSNAME); return true; 999 case 1: arch.SetTriple ("armv4-apple-" OSNAME); return true; 1000 case 2: arch.SetTriple ("arm-apple-" OSNAME); return true; 1001 case 3: arch.SetTriple ("thumbv5-apple-" OSNAME); return true; 1002 case 4: arch.SetTriple ("thumbv4t-apple-" OSNAME); return true; 1003 case 5: arch.SetTriple ("thumb-apple-" OSNAME); return true; 1004 default: break; 1005 } 1006 break; 1007 1008 case ArchSpec::eCore_arm_armv4: 1009 switch (idx) 1010 { 1011 case 0: arch.SetTriple ("armv4-apple-" OSNAME); return true; 1012 case 1: arch.SetTriple ("arm-apple-" OSNAME); return true; 1013 case 2: arch.SetTriple ("thumbv4t-apple-" OSNAME); return true; 1014 case 3: arch.SetTriple ("thumb-apple-" OSNAME); return true; 1015 default: break; 1016 } 1017 break; 1018 } 1019 arch.Clear(); 1020 return false; 1021 } 1022 1023 1024 const char * 1025 PlatformDarwin::GetDeveloperDirectory() 1026 { 1027 Mutex::Locker locker (m_mutex); 1028 if (m_developer_directory.empty()) 1029 { 1030 bool developer_dir_path_valid = false; 1031 char developer_dir_path[PATH_MAX]; 1032 FileSpec temp_file_spec; 1033 if (HostInfo::GetLLDBPath(ePathTypeLLDBShlibDir, temp_file_spec)) 1034 { 1035 if (temp_file_spec.GetPath (developer_dir_path, sizeof(developer_dir_path))) 1036 { 1037 char *shared_frameworks = strstr (developer_dir_path, "/SharedFrameworks/LLDB.framework"); 1038 if (shared_frameworks) 1039 { 1040 ::snprintf (shared_frameworks, 1041 sizeof(developer_dir_path) - (shared_frameworks - developer_dir_path), 1042 "/Developer"); 1043 developer_dir_path_valid = true; 1044 } 1045 else 1046 { 1047 char *lib_priv_frameworks = strstr (developer_dir_path, "/Library/PrivateFrameworks/LLDB.framework"); 1048 if (lib_priv_frameworks) 1049 { 1050 *lib_priv_frameworks = '\0'; 1051 developer_dir_path_valid = true; 1052 } 1053 } 1054 } 1055 } 1056 1057 if (!developer_dir_path_valid) 1058 { 1059 std::string xcode_dir_path; 1060 const char *xcode_select_prefix_dir = getenv ("XCODE_SELECT_PREFIX_DIR"); 1061 if (xcode_select_prefix_dir) 1062 xcode_dir_path.append (xcode_select_prefix_dir); 1063 xcode_dir_path.append ("/usr/share/xcode-select/xcode_dir_path"); 1064 temp_file_spec.SetFile(xcode_dir_path.c_str(), false); 1065 size_t bytes_read = temp_file_spec.ReadFileContents(0, developer_dir_path, sizeof(developer_dir_path), NULL); 1066 if (bytes_read > 0) 1067 { 1068 developer_dir_path[bytes_read] = '\0'; 1069 while (developer_dir_path[bytes_read-1] == '\r' || 1070 developer_dir_path[bytes_read-1] == '\n') 1071 developer_dir_path[--bytes_read] = '\0'; 1072 developer_dir_path_valid = true; 1073 } 1074 } 1075 1076 if (!developer_dir_path_valid) 1077 { 1078 FileSpec xcode_select_cmd ("/usr/bin/xcode-select", false); 1079 if (xcode_select_cmd.Exists()) 1080 { 1081 int exit_status = -1; 1082 int signo = -1; 1083 std::string command_output; 1084 Error error = Host::RunShellCommand ("/usr/bin/xcode-select --print-path", 1085 NULL, // current working directory 1086 &exit_status, 1087 &signo, 1088 &command_output, 1089 2, // short timeout 1090 false); // don't run in a shell 1091 if (error.Success() && exit_status == 0 && !command_output.empty()) 1092 { 1093 const char *cmd_output_ptr = command_output.c_str(); 1094 developer_dir_path[sizeof (developer_dir_path) - 1] = '\0'; 1095 size_t i; 1096 for (i = 0; i < sizeof (developer_dir_path) - 1; i++) 1097 { 1098 if (cmd_output_ptr[i] == '\r' || cmd_output_ptr[i] == '\n' || cmd_output_ptr[i] == '\0') 1099 break; 1100 developer_dir_path[i] = cmd_output_ptr[i]; 1101 } 1102 developer_dir_path[i] = '\0'; 1103 1104 FileSpec devel_dir (developer_dir_path, false); 1105 if (devel_dir.Exists() && devel_dir.IsDirectory()) 1106 { 1107 developer_dir_path_valid = true; 1108 } 1109 } 1110 } 1111 } 1112 1113 if (developer_dir_path_valid) 1114 { 1115 temp_file_spec.SetFile (developer_dir_path, false); 1116 if (temp_file_spec.Exists()) 1117 { 1118 m_developer_directory.assign (developer_dir_path); 1119 return m_developer_directory.c_str(); 1120 } 1121 } 1122 // Assign a single NULL character so we know we tried to find the device 1123 // support directory and we don't keep trying to find it over and over. 1124 m_developer_directory.assign (1, '\0'); 1125 } 1126 1127 // We should have put a single NULL character into m_developer_directory 1128 // or it should have a valid path if the code gets here 1129 assert (m_developer_directory.empty() == false); 1130 if (m_developer_directory[0]) 1131 return m_developer_directory.c_str(); 1132 return NULL; 1133 } 1134 1135 1136 BreakpointSP 1137 PlatformDarwin::SetThreadCreationBreakpoint (Target &target) 1138 { 1139 BreakpointSP bp_sp; 1140 static const char *g_bp_names[] = 1141 { 1142 "start_wqthread", 1143 "_pthread_wqthread", 1144 "_pthread_start", 1145 }; 1146 1147 static const char *g_bp_modules[] = 1148 { 1149 "libsystem_c.dylib", 1150 "libSystem.B.dylib" 1151 }; 1152 1153 FileSpecList bp_modules; 1154 for (size_t i = 0; i < llvm::array_lengthof(g_bp_modules); i++) 1155 { 1156 const char *bp_module = g_bp_modules[i]; 1157 bp_modules.Append(FileSpec(bp_module, false)); 1158 } 1159 1160 bool internal = true; 1161 bool hardware = false; 1162 LazyBool skip_prologue = eLazyBoolNo; 1163 bp_sp = target.CreateBreakpoint (&bp_modules, 1164 NULL, 1165 g_bp_names, 1166 llvm::array_lengthof(g_bp_names), 1167 eFunctionNameTypeFull, 1168 eLanguageTypeUnknown, 1169 skip_prologue, 1170 internal, 1171 hardware); 1172 bp_sp->SetBreakpointKind("thread-creation"); 1173 1174 return bp_sp; 1175 } 1176 1177 1178 int32_t 1179 PlatformDarwin::GetResumeCountForLaunchInfo (ProcessLaunchInfo &launch_info) 1180 { 1181 const FileSpec &shell = launch_info.GetShell(); 1182 if (!shell) 1183 return 1; 1184 1185 std::string shell_string = shell.GetPath(); 1186 const char *shell_name = strrchr (shell_string.c_str(), '/'); 1187 if (shell_name == NULL) 1188 shell_name = shell_string.c_str(); 1189 else 1190 shell_name++; 1191 1192 if (strcmp (shell_name, "sh") == 0) 1193 { 1194 // /bin/sh re-exec's itself as /bin/bash requiring another resume. 1195 // But it only does this if the COMMAND_MODE environment variable 1196 // is set to "legacy". 1197 const char **envp = launch_info.GetEnvironmentEntries().GetConstArgumentVector(); 1198 if (envp != NULL) 1199 { 1200 for (int i = 0; envp[i] != NULL; i++) 1201 { 1202 if (strcmp (envp[i], "COMMAND_MODE=legacy" ) == 0) 1203 return 2; 1204 } 1205 } 1206 return 1; 1207 } 1208 else if (strcmp (shell_name, "csh") == 0 1209 || strcmp (shell_name, "tcsh") == 0 1210 || strcmp (shell_name, "zsh") == 0) 1211 { 1212 // csh and tcsh always seem to re-exec themselves. 1213 return 2; 1214 } 1215 else 1216 return 1; 1217 } 1218 1219 void 1220 PlatformDarwin::CalculateTrapHandlerSymbolNames () 1221 { 1222 m_trap_handlers.push_back (ConstString ("_sigtramp")); 1223 } 1224 1225 1226 static const char *const sdk_strings[] = { 1227 "MacOSX", 1228 "iPhoneSimulator", 1229 "iPhoneOS", 1230 }; 1231 1232 static FileSpec 1233 CheckPathForXcode(const FileSpec &fspec) 1234 { 1235 if (fspec.Exists()) 1236 { 1237 const char substr[] = ".app/Contents/"; 1238 1239 std::string path_to_shlib = fspec.GetPath(); 1240 size_t pos = path_to_shlib.rfind(substr); 1241 if (pos != std::string::npos) 1242 { 1243 path_to_shlib.erase(pos + strlen(substr)); 1244 FileSpec ret (path_to_shlib.c_str(), false); 1245 1246 FileSpec xcode_binary_path = ret; 1247 xcode_binary_path.AppendPathComponent("MacOS"); 1248 xcode_binary_path.AppendPathComponent("Xcode"); 1249 1250 if (xcode_binary_path.Exists()) 1251 { 1252 return ret; 1253 } 1254 } 1255 } 1256 return FileSpec(); 1257 } 1258 1259 static FileSpec 1260 GetXcodeContentsPath () 1261 { 1262 static FileSpec g_xcode_filespec; 1263 static std::once_flag g_once_flag; 1264 std::call_once(g_once_flag, []() { 1265 1266 1267 FileSpec fspec; 1268 1269 // First get the program file spec. If lldb.so or LLDB.framework is running 1270 // in a program and that program is Xcode, the path returned with be the path 1271 // to Xcode.app/Contents/MacOS/Xcode, so this will be the correct Xcode to use. 1272 fspec = HostInfo::GetProgramFileSpec(); 1273 1274 if (fspec) 1275 { 1276 // Ignore the current binary if it is python. 1277 std::string basename_lower = fspec.GetFilename ().GetCString (); 1278 std::transform(basename_lower.begin (), basename_lower.end (), basename_lower.begin (), tolower); 1279 if (basename_lower != "python") 1280 { 1281 g_xcode_filespec = CheckPathForXcode(fspec); 1282 } 1283 } 1284 1285 // Next check DEVELOPER_DIR environment variable 1286 if (!g_xcode_filespec) 1287 { 1288 const char *developer_dir_env_var = getenv("DEVELOPER_DIR"); 1289 if (developer_dir_env_var && developer_dir_env_var[0]) 1290 { 1291 g_xcode_filespec = CheckPathForXcode(FileSpec(developer_dir_env_var, true)); 1292 } 1293 1294 // Fall back to using "xcrun" to find the selected Xcode 1295 if (!g_xcode_filespec) 1296 { 1297 int status = 0; 1298 int signo = 0; 1299 std::string output; 1300 const char *command = "/usr/bin/xcode-select -p"; 1301 lldb_private::Error error = Host::RunShellCommand (command, // shell command to run 1302 NULL, // current working directory 1303 &status, // Put the exit status of the process in here 1304 &signo, // Put the signal that caused the process to exit in here 1305 &output, // Get the output from the command and place it in this string 1306 3); // Timeout in seconds to wait for shell program to finish 1307 if (status == 0 && !output.empty()) 1308 { 1309 size_t first_non_newline = output.find_last_not_of("\r\n"); 1310 if (first_non_newline != std::string::npos) 1311 { 1312 output.erase(first_non_newline+1); 1313 } 1314 output.append("/.."); 1315 1316 g_xcode_filespec = CheckPathForXcode(FileSpec(output.c_str(), false)); 1317 } 1318 } 1319 } 1320 }); 1321 1322 return g_xcode_filespec; 1323 } 1324 1325 bool 1326 PlatformDarwin::SDKSupportsModules (SDKType sdk_type, uint32_t major, uint32_t minor, uint32_t micro) 1327 { 1328 switch (sdk_type) 1329 { 1330 case SDKType::MacOSX: 1331 if (major > 10 || (major == 10 && minor >= 10)) 1332 return true; 1333 break; 1334 case SDKType::iPhoneOS: 1335 case SDKType::iPhoneSimulator: 1336 if (major >= 8) 1337 return true; 1338 break; 1339 } 1340 1341 return false; 1342 } 1343 1344 bool 1345 PlatformDarwin::SDKSupportsModules (SDKType desired_type, const FileSpec &sdk_path) 1346 { 1347 ConstString last_path_component = sdk_path.GetLastPathComponent(); 1348 1349 if (last_path_component) 1350 { 1351 const llvm::StringRef sdk_name = last_path_component.GetStringRef(); 1352 1353 llvm::StringRef version_part; 1354 1355 if (sdk_name.startswith(sdk_strings[(int)desired_type])) 1356 { 1357 version_part = sdk_name.drop_front(strlen(sdk_strings[(int)desired_type])); 1358 } 1359 else 1360 { 1361 return false; 1362 } 1363 1364 const size_t major_dot_offset = version_part.find('.'); 1365 if (major_dot_offset == llvm::StringRef::npos) 1366 return false; 1367 1368 const llvm::StringRef major_version = version_part.slice(0, major_dot_offset); 1369 const llvm::StringRef minor_part = version_part.drop_front(major_dot_offset + 1); 1370 1371 const size_t minor_dot_offset = minor_part.find('.'); 1372 if (minor_dot_offset == llvm::StringRef::npos) 1373 return false; 1374 1375 const llvm::StringRef minor_version = minor_part.slice(0, minor_dot_offset); 1376 1377 unsigned int major = 0; 1378 unsigned int minor = 0; 1379 unsigned int micro = 0; 1380 1381 if (major_version.getAsInteger(10, major)) 1382 return false; 1383 1384 if (minor_version.getAsInteger(10, minor)) 1385 return false; 1386 1387 return SDKSupportsModules(desired_type, major, minor, micro); 1388 } 1389 1390 return false; 1391 } 1392 1393 FileSpec::EnumerateDirectoryResult 1394 PlatformDarwin::DirectoryEnumerator(void *baton, 1395 FileSpec::FileType file_type, 1396 const FileSpec &spec) 1397 { 1398 SDKEnumeratorInfo *enumerator_info = static_cast<SDKEnumeratorInfo*>(baton); 1399 1400 if (SDKSupportsModules(enumerator_info->sdk_type, spec)) 1401 { 1402 enumerator_info->found_path = spec; 1403 return FileSpec::EnumerateDirectoryResult::eEnumerateDirectoryResultNext; 1404 } 1405 1406 return FileSpec::EnumerateDirectoryResult::eEnumerateDirectoryResultNext; 1407 } 1408 1409 FileSpec 1410 PlatformDarwin::FindSDKInXcodeForModules (SDKType sdk_type, 1411 const FileSpec &sdks_spec) 1412 { 1413 // Look inside Xcode for the required installed iOS SDK version 1414 1415 if (!sdks_spec.IsDirectory()) 1416 return FileSpec(); 1417 1418 const bool find_directories = true; 1419 const bool find_files = false; 1420 const bool find_other = true; // include symlinks 1421 1422 SDKEnumeratorInfo enumerator_info; 1423 1424 enumerator_info.sdk_type = sdk_type; 1425 1426 FileSpec::EnumerateDirectory(sdks_spec.GetPath().c_str(), 1427 find_directories, 1428 find_files, 1429 find_other, 1430 DirectoryEnumerator, 1431 &enumerator_info); 1432 1433 if (enumerator_info.found_path.IsDirectory()) 1434 return enumerator_info.found_path; 1435 else 1436 return FileSpec(); 1437 } 1438 1439 FileSpec 1440 PlatformDarwin::GetSDKDirectoryForModules (SDKType sdk_type) 1441 { 1442 switch (sdk_type) 1443 { 1444 case SDKType::MacOSX: 1445 case SDKType::iPhoneSimulator: 1446 case SDKType::iPhoneOS: 1447 break; 1448 } 1449 1450 FileSpec sdks_spec = GetXcodeContentsPath(); 1451 sdks_spec.AppendPathComponent("Developer"); 1452 sdks_spec.AppendPathComponent("Platforms"); 1453 1454 switch (sdk_type) 1455 { 1456 case SDKType::MacOSX: 1457 sdks_spec.AppendPathComponent("MacOSX.platform"); 1458 break; 1459 case SDKType::iPhoneSimulator: 1460 sdks_spec.AppendPathComponent("iPhoneSimulator.platform"); 1461 break; 1462 case SDKType::iPhoneOS: 1463 sdks_spec.AppendPathComponent("iPhoneOS.platform"); 1464 break; 1465 } 1466 1467 sdks_spec.AppendPathComponent("Developer"); 1468 sdks_spec.AppendPathComponent("SDKs"); 1469 1470 if (sdk_type == SDKType::MacOSX) 1471 { 1472 uint32_t major = 0; 1473 uint32_t minor = 0; 1474 uint32_t micro = 0; 1475 1476 if (HostInfo::GetOSVersion(major, minor, micro)) 1477 { 1478 if (SDKSupportsModules(SDKType::MacOSX, major, minor, micro)) 1479 { 1480 // We slightly prefer the exact SDK for this machine. See if it is there. 1481 1482 FileSpec native_sdk_spec = sdks_spec; 1483 StreamString native_sdk_name; 1484 native_sdk_name.Printf("MacOSX%u.%u.sdk", major, minor); 1485 native_sdk_spec.AppendPathComponent(native_sdk_name.GetString().c_str()); 1486 1487 if (native_sdk_spec.Exists()) 1488 { 1489 return native_sdk_spec; 1490 } 1491 } 1492 } 1493 } 1494 1495 return FindSDKInXcodeForModules(sdk_type, sdks_spec); 1496 } 1497 1498 void 1499 PlatformDarwin::AddClangModuleCompilationOptionsForSDKType (Target *target, std::vector<std::string> &options, SDKType sdk_type) 1500 { 1501 const std::vector<std::string> apple_arguments = 1502 { 1503 "-x", "objective-c++", 1504 "-fobjc-arc", 1505 "-fblocks", 1506 "-D_ISO646_H", 1507 "-D__ISO646_H" 1508 }; 1509 1510 options.insert(options.end(), 1511 apple_arguments.begin(), 1512 apple_arguments.end()); 1513 1514 StreamString minimum_version_option; 1515 uint32_t versions[3] = { 0, 0, 0 }; 1516 bool use_current_os_version = false; 1517 switch (sdk_type) 1518 { 1519 case SDKType::iPhoneOS: 1520 #if defined (__arm__) || defined (__arm64__) || defined (__aarch64__) 1521 use_current_os_version = true; 1522 #else 1523 use_current_os_version = false; 1524 #endif 1525 break; 1526 1527 case SDKType::iPhoneSimulator: 1528 use_current_os_version = false; 1529 break; 1530 1531 case SDKType::MacOSX: 1532 #if defined (__i386__) || defined (__x86_64__) 1533 use_current_os_version = true; 1534 #else 1535 use_current_os_version = false; 1536 #endif 1537 break; 1538 } 1539 1540 bool versions_valid = false; 1541 if (use_current_os_version) 1542 versions_valid = GetOSVersion(versions[0], versions[1], versions[2]); 1543 else if (target) 1544 { 1545 // Our OS doesn't match our executable so we need to get the min OS version from the object file 1546 ModuleSP exe_module_sp = target->GetExecutableModule(); 1547 if (exe_module_sp) 1548 { 1549 ObjectFile *object_file = exe_module_sp->GetObjectFile(); 1550 if (object_file) 1551 versions_valid = object_file->GetMinimumOSVersion(versions, 3) > 0; 1552 } 1553 } 1554 // Only add the version-min options if we got a version from somewhere 1555 if (versions_valid && versions[0] != UINT32_MAX) 1556 { 1557 // Make any invalid versions be zero if needed 1558 if (versions[1] == UINT32_MAX) 1559 versions[1] = 0; 1560 if (versions[2] == UINT32_MAX) 1561 versions[2] = 0; 1562 1563 switch (sdk_type) 1564 { 1565 case SDKType::iPhoneOS: 1566 minimum_version_option.PutCString("-mios-version-min="); 1567 minimum_version_option.PutCString(clang::VersionTuple(versions[0], versions[1], versions[2]).getAsString().c_str()); 1568 break; 1569 case SDKType::iPhoneSimulator: 1570 minimum_version_option.PutCString("-mios-simulator-version-min="); 1571 minimum_version_option.PutCString(clang::VersionTuple(versions[0], versions[1], versions[2]).getAsString().c_str()); 1572 break; 1573 case SDKType::MacOSX: 1574 minimum_version_option.PutCString("-mmacosx-version-min="); 1575 minimum_version_option.PutCString(clang::VersionTuple(versions[0], versions[1], versions[2]).getAsString().c_str()); 1576 } 1577 options.push_back(minimum_version_option.GetString()); 1578 } 1579 1580 FileSpec sysroot_spec; 1581 // Scope for mutex locker below 1582 { 1583 Mutex::Locker locker (m_mutex); 1584 sysroot_spec = GetSDKDirectoryForModules(sdk_type); 1585 } 1586 1587 if (sysroot_spec.IsDirectory()) 1588 { 1589 options.push_back("-isysroot"); 1590 options.push_back(sysroot_spec.GetPath()); 1591 } 1592 } 1593 1594 ConstString 1595 PlatformDarwin::GetFullNameForDylib (ConstString basename) 1596 { 1597 if (basename.IsEmpty()) 1598 return basename; 1599 1600 StreamString stream; 1601 stream.Printf("lib%s.dylib", basename.GetCString()); 1602 return ConstString(stream.GetData()); 1603 } 1604 1605 bool 1606 PlatformDarwin::GetOSVersion (uint32_t &major, 1607 uint32_t &minor, 1608 uint32_t &update, 1609 Process *process) 1610 { 1611 if (process && strstr(GetPluginName().GetCString(), "-simulator")) 1612 { 1613 lldb_private::ProcessInstanceInfo proc_info; 1614 if (Host::GetProcessInfo(process->GetID(), proc_info)) 1615 { 1616 Args &env = proc_info.GetEnvironmentEntries(); 1617 const size_t n = env.GetArgumentCount(); 1618 const llvm::StringRef k_runtime_version("SIMULATOR_RUNTIME_VERSION="); 1619 const llvm::StringRef k_dyld_root_path("DYLD_ROOT_PATH="); 1620 std::string dyld_root_path; 1621 1622 for (size_t i=0; i<n; ++i) 1623 { 1624 const char *env_cstr = env.GetArgumentAtIndex(i); 1625 if (env_cstr) 1626 { 1627 llvm::StringRef env_str(env_cstr); 1628 if (env_str.startswith(k_runtime_version)) 1629 { 1630 llvm::StringRef version_str(env_str.substr(k_runtime_version.size())); 1631 Args::StringToVersion (version_str.data(), major, minor, update); 1632 if (major != UINT32_MAX) 1633 return true; 1634 } 1635 else if (env_str.startswith(k_dyld_root_path)) 1636 { 1637 dyld_root_path = env_str.substr(k_dyld_root_path.size()).str(); 1638 } 1639 } 1640 } 1641 1642 if (!dyld_root_path.empty()) 1643 { 1644 dyld_root_path += "/System/Library/CoreServices/SystemVersion.plist"; 1645 ApplePropertyList system_version_plist(dyld_root_path.c_str()); 1646 std::string product_version; 1647 if (system_version_plist.GetValueAsString("ProductVersion", product_version)) 1648 { 1649 Args::StringToVersion (product_version.c_str(), major, minor, update); 1650 return major != UINT32_MAX; 1651 } 1652 } 1653 1654 } 1655 // For simulator platforms, do NOT call back through Platform::GetOSVersion() 1656 // as it might call Process::GetHostOSVersion() which we don't want as it will be 1657 // incorrect 1658 return false; 1659 } 1660 1661 return Platform::GetOSVersion(major, minor, update, process); 1662 } 1663 1664 lldb_private::FileSpec 1665 PlatformDarwin::LocateExecutable (const char *basename) 1666 { 1667 // A collection of SBFileSpec whose SBFileSpec.m_directory members are filled in with 1668 // any executable directories that should be searched. 1669 static std::vector<FileSpec> g_executable_dirs; 1670 1671 // Find the global list of directories that we will search for 1672 // executables once so we don't keep doing the work over and over. 1673 static std::once_flag g_once_flag; 1674 std::call_once(g_once_flag, []() { 1675 1676 // When locating executables, trust the DEVELOPER_DIR first if it is set 1677 FileSpec xcode_contents_dir = GetXcodeContentsPath(); 1678 if (xcode_contents_dir) 1679 { 1680 FileSpec xcode_lldb_resources = xcode_contents_dir; 1681 xcode_lldb_resources.AppendPathComponent("SharedFrameworks"); 1682 xcode_lldb_resources.AppendPathComponent("LLDB.framework"); 1683 xcode_lldb_resources.AppendPathComponent("Resources"); 1684 if (xcode_lldb_resources.Exists()) 1685 { 1686 FileSpec dir; 1687 dir.GetDirectory().SetCString(xcode_lldb_resources.GetPath().c_str()); 1688 g_executable_dirs.push_back(dir); 1689 } 1690 } 1691 }); 1692 1693 // Now search the global list of executable directories for the executable we 1694 // are looking for 1695 for (const auto &executable_dir : g_executable_dirs) 1696 { 1697 FileSpec executable_file; 1698 executable_file.GetDirectory() = executable_dir.GetDirectory(); 1699 executable_file.GetFilename().SetCString(basename); 1700 if (executable_file.Exists()) 1701 return executable_file; 1702 } 1703 1704 return FileSpec(); 1705 } 1706