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