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 "lldb/lldb-python.h" 11 12 #include "PlatformDarwin.h" 13 14 // C Includes 15 // C++ Includes 16 // Other libraries and framework includes 17 // Project includes 18 #include "lldb/Breakpoint/BreakpointLocation.h" 19 #include "lldb/Core/Debugger.h" 20 #include "lldb/Core/Error.h" 21 #include "lldb/Core/Log.h" 22 #include "lldb/Core/Module.h" 23 #include "lldb/Core/ModuleSpec.h" 24 #include "lldb/Core/Timer.h" 25 #include "lldb/Host/Host.h" 26 #include "lldb/Host/Symbols.h" 27 #include "lldb/Symbol/ObjectFile.h" 28 #include "lldb/Symbol/SymbolFile.h" 29 #include "lldb/Symbol/SymbolVendor.h" 30 #include "lldb/Target/Target.h" 31 32 using namespace lldb; 33 using namespace lldb_private; 34 35 36 //------------------------------------------------------------------ 37 /// Default Constructor 38 //------------------------------------------------------------------ 39 PlatformDarwin::PlatformDarwin (bool is_host) : 40 PlatformPOSIX(is_host), // This is the local host platform 41 m_developer_directory () 42 { 43 } 44 45 //------------------------------------------------------------------ 46 /// Destructor. 47 /// 48 /// The destructor is virtual since this class is designed to be 49 /// inherited from by the plug-in instance. 50 //------------------------------------------------------------------ 51 PlatformDarwin::~PlatformDarwin() 52 { 53 } 54 55 FileSpecList 56 PlatformDarwin::LocateExecutableScriptingResources (Target *target, 57 Module &module) 58 { 59 FileSpecList file_list; 60 if (target && target->GetDebugger().GetScriptLanguage() == eScriptLanguagePython) 61 { 62 // NB some extensions might be meaningful and should not be stripped - "this.binary.file" 63 // should not lose ".file" but GetFileNameStrippingExtension() will do precisely that. 64 // Ideally, we should have a per-platform list of extensions (".exe", ".app", ".dSYM", ".framework") 65 // which should be stripped while leaving "this.binary.file" as-is. 66 FileSpec module_spec = module.GetFileSpec(); 67 68 if (module_spec) 69 { 70 SymbolVendor *symbols = module.GetSymbolVendor (); 71 if (symbols) 72 { 73 SymbolFile *symfile = symbols->GetSymbolFile(); 74 if (symfile) 75 { 76 ObjectFile *objfile = symfile->GetObjectFile(); 77 if (objfile) 78 { 79 FileSpec symfile_spec (objfile->GetFileSpec()); 80 if (symfile_spec && symfile_spec.Exists()) 81 { 82 while (module_spec.GetFilename()) 83 { 84 std::string module_basename (module_spec.GetFilename().GetCString()); 85 86 // FIXME: for Python, we cannot allow certain characters in module 87 // filenames we import. Theoretically, different scripting languages may 88 // have different sets of forbidden tokens in filenames, and that should 89 // be dealt with by each ScriptInterpreter. For now, we just replace dots 90 // with underscores, but if we ever support anything other than Python 91 // we will need to rework this 92 std::replace(module_basename.begin(), module_basename.end(), '.', '_'); 93 std::replace(module_basename.begin(), module_basename.end(), ' ', '_'); 94 std::replace(module_basename.begin(), module_basename.end(), '-', '_'); 95 96 97 StreamString path_string; 98 // for OSX we are going to be in .dSYM/Contents/Resources/DWARF/<basename> 99 // let us go to .dSYM/Contents/Resources/Python/<basename>.py and see if the file exists 100 path_string.Printf("%s/../Python/%s.py",symfile_spec.GetDirectory().GetCString(), module_basename.c_str()); 101 FileSpec script_fspec(path_string.GetData(), true); 102 if (script_fspec.Exists()) 103 { 104 file_list.Append (script_fspec); 105 break; 106 } 107 108 // If we didn't find the python file, then keep 109 // stripping the extensions and try again 110 ConstString filename_no_extension (module_spec.GetFileNameStrippingExtension()); 111 if (module_spec.GetFilename() == filename_no_extension) 112 break; 113 114 module_spec.GetFilename() = filename_no_extension; 115 } 116 } 117 } 118 } 119 } 120 } 121 } 122 return file_list; 123 } 124 125 Error 126 PlatformDarwin::ResolveExecutable (const FileSpec &exe_file, 127 const ArchSpec &exe_arch, 128 lldb::ModuleSP &exe_module_sp, 129 const FileSpecList *module_search_paths_ptr) 130 { 131 Error error; 132 // Nothing special to do here, just use the actual file and architecture 133 134 char exe_path[PATH_MAX]; 135 FileSpec resolved_exe_file (exe_file); 136 137 if (IsHost()) 138 { 139 // If we have "ls" as the exe_file, resolve the executable loation based on 140 // the current path variables 141 if (!resolved_exe_file.Exists()) 142 { 143 exe_file.GetPath (exe_path, sizeof(exe_path)); 144 resolved_exe_file.SetFile(exe_path, true); 145 } 146 147 if (!resolved_exe_file.Exists()) 148 resolved_exe_file.ResolveExecutableLocation (); 149 150 // Resolve any executable within a bundle on MacOSX 151 Host::ResolveExecutableInBundle (resolved_exe_file); 152 153 if (resolved_exe_file.Exists()) 154 error.Clear(); 155 else 156 { 157 exe_file.GetPath (exe_path, sizeof(exe_path)); 158 error.SetErrorStringWithFormat ("unable to find executable for '%s'", exe_path); 159 } 160 } 161 else 162 { 163 if (m_remote_platform_sp) 164 { 165 error = m_remote_platform_sp->ResolveExecutable (exe_file, 166 exe_arch, 167 exe_module_sp, 168 module_search_paths_ptr); 169 } 170 else 171 { 172 // We may connect to a process and use the provided executable (Don't use local $PATH). 173 174 // Resolve any executable within a bundle on MacOSX 175 Host::ResolveExecutableInBundle (resolved_exe_file); 176 177 if (resolved_exe_file.Exists()) 178 error.Clear(); 179 else 180 error.SetErrorStringWithFormat("the platform is not currently connected, and '%s' doesn't exist in the system root.", resolved_exe_file.GetFilename().AsCString("")); 181 } 182 } 183 184 185 if (error.Success()) 186 { 187 ModuleSpec module_spec (resolved_exe_file, exe_arch); 188 if (module_spec.GetArchitecture().IsValid()) 189 { 190 error = ModuleList::GetSharedModule (module_spec, 191 exe_module_sp, 192 module_search_paths_ptr, 193 NULL, 194 NULL); 195 196 if (error.Fail() || exe_module_sp.get() == NULL || exe_module_sp->GetObjectFile() == NULL) 197 { 198 exe_module_sp.reset(); 199 error.SetErrorStringWithFormat ("'%s' doesn't contain the architecture %s", 200 exe_file.GetPath().c_str(), 201 exe_arch.GetArchitectureName()); 202 } 203 } 204 else 205 { 206 // No valid architecture was specified, ask the platform for 207 // the architectures that we should be using (in the correct order) 208 // and see if we can find a match that way 209 StreamString arch_names; 210 for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, module_spec.GetArchitecture()); ++idx) 211 { 212 error = GetSharedModule (module_spec, 213 exe_module_sp, 214 module_search_paths_ptr, 215 NULL, 216 NULL); 217 // Did we find an executable using one of the 218 if (error.Success()) 219 { 220 if (exe_module_sp && exe_module_sp->GetObjectFile()) 221 break; 222 else 223 error.SetErrorToGenericError(); 224 } 225 226 if (idx > 0) 227 arch_names.PutCString (", "); 228 arch_names.PutCString (module_spec.GetArchitecture().GetArchitectureName()); 229 } 230 231 if (error.Fail() || !exe_module_sp) 232 { 233 error.SetErrorStringWithFormat ("'%s' doesn't contain any '%s' platform architectures: %s", 234 exe_file.GetPath().c_str(), 235 GetPluginName().GetCString(), 236 arch_names.GetString().c_str()); 237 } 238 } 239 } 240 241 return error; 242 } 243 244 Error 245 PlatformDarwin::ResolveSymbolFile (Target &target, 246 const ModuleSpec &sym_spec, 247 FileSpec &sym_file) 248 { 249 Error error; 250 sym_file = sym_spec.GetSymbolFileSpec(); 251 if (sym_file.Exists()) 252 { 253 if (sym_file.GetFileType() == FileSpec::eFileTypeDirectory) 254 { 255 sym_file = Symbols::FindSymbolFileInBundle (sym_file, 256 sym_spec.GetUUIDPtr(), 257 sym_spec.GetArchitecturePtr()); 258 } 259 } 260 else 261 { 262 if (sym_spec.GetUUID().IsValid()) 263 { 264 265 } 266 } 267 return error; 268 269 } 270 271 static lldb_private::Error 272 MakeCacheFolderForFile (const FileSpec& module_cache_spec) 273 { 274 FileSpec module_cache_folder = module_cache_spec.CopyByRemovingLastPathComponent(); 275 return Host::MakeDirectory(module_cache_folder.GetPath().c_str(), eFilePermissionsDirectoryDefault); 276 } 277 278 static lldb_private::Error 279 BringInRemoteFile (Platform* platform, 280 const lldb_private::ModuleSpec &module_spec, 281 const FileSpec& module_cache_spec) 282 { 283 MakeCacheFolderForFile(module_cache_spec); 284 Error err = platform->GetFile(module_spec.GetFileSpec(), module_cache_spec); 285 return err; 286 } 287 288 lldb_private::Error 289 PlatformDarwin::GetSharedModuleWithLocalCache (const lldb_private::ModuleSpec &module_spec, 290 lldb::ModuleSP &module_sp, 291 const lldb_private::FileSpecList *module_search_paths_ptr, 292 lldb::ModuleSP *old_module_sp_ptr, 293 bool *did_create_ptr) 294 { 295 296 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM)); 297 if (log) 298 log->Printf("[%s] Trying to find module %s/%s - platform path %s/%s symbol path %s/%s", 299 (IsHost() ? "host" : "remote"), 300 module_spec.GetFileSpec().GetDirectory().AsCString(), 301 module_spec.GetFileSpec().GetFilename().AsCString(), 302 module_spec.GetPlatformFileSpec().GetDirectory().AsCString(), 303 module_spec.GetPlatformFileSpec().GetFilename().AsCString(), 304 module_spec.GetSymbolFileSpec().GetDirectory().AsCString(), 305 module_spec.GetSymbolFileSpec().GetFilename().AsCString()); 306 307 Error err; 308 309 err = ModuleList::GetSharedModule(module_spec, module_sp, module_search_paths_ptr, old_module_sp_ptr, did_create_ptr); 310 if (module_sp) 311 return err; 312 313 if (!IsHost()) 314 { 315 std::string cache_path(GetLocalCacheDirectory()); 316 // Only search for a locally cached file if we have a valid cache path 317 if (!cache_path.empty()) 318 { 319 std::string module_path (module_spec.GetFileSpec().GetPath()); 320 cache_path.append(module_path); 321 FileSpec module_cache_spec(cache_path.c_str(),false); 322 323 // if rsync is supported, always bring in the file - rsync will be very efficient 324 // when files are the same on the local and remote end of the connection 325 if (this->GetSupportsRSync()) 326 { 327 err = BringInRemoteFile (this, module_spec, module_cache_spec); 328 if (err.Fail()) 329 return err; 330 if (module_cache_spec.Exists()) 331 { 332 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM)); 333 if (log) 334 log->Printf("[%s] module %s/%s was rsynced and is now there", 335 (IsHost() ? "host" : "remote"), 336 module_spec.GetFileSpec().GetDirectory().AsCString(), 337 module_spec.GetFileSpec().GetFilename().AsCString()); 338 ModuleSpec local_spec(module_cache_spec, module_spec.GetArchitecture()); 339 module_sp.reset(new Module(local_spec)); 340 module_sp->SetPlatformFileSpec(module_spec.GetFileSpec()); 341 return Error(); 342 } 343 } 344 345 // try to find the module in the cache 346 if (module_cache_spec.Exists()) 347 { 348 // get the local and remote MD5 and compare 349 if (m_remote_platform_sp) 350 { 351 // when going over the *slow* GDB remote transfer mechanism we first check 352 // the hashes of the files - and only do the actual transfer if they differ 353 uint64_t high_local,high_remote,low_local,low_remote; 354 Host::CalculateMD5 (module_cache_spec, low_local, high_local); 355 m_remote_platform_sp->CalculateMD5(module_spec.GetFileSpec(), low_remote, high_remote); 356 if (low_local != low_remote || high_local != high_remote) 357 { 358 // bring in the remote file 359 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM)); 360 if (log) 361 log->Printf("[%s] module %s/%s needs to be replaced from remote copy", 362 (IsHost() ? "host" : "remote"), 363 module_spec.GetFileSpec().GetDirectory().AsCString(), 364 module_spec.GetFileSpec().GetFilename().AsCString()); 365 Error err = BringInRemoteFile (this, module_spec, module_cache_spec); 366 if (err.Fail()) 367 return err; 368 } 369 } 370 371 ModuleSpec local_spec(module_cache_spec, module_spec.GetArchitecture()); 372 module_sp.reset(new Module(local_spec)); 373 module_sp->SetPlatformFileSpec(module_spec.GetFileSpec()); 374 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM)); 375 if (log) 376 log->Printf("[%s] module %s/%s was found in the cache", 377 (IsHost() ? "host" : "remote"), 378 module_spec.GetFileSpec().GetDirectory().AsCString(), 379 module_spec.GetFileSpec().GetFilename().AsCString()); 380 return Error(); 381 } 382 383 // bring in the remote module file 384 if (log) 385 log->Printf("[%s] module %s/%s needs to come in remotely", 386 (IsHost() ? "host" : "remote"), 387 module_spec.GetFileSpec().GetDirectory().AsCString(), 388 module_spec.GetFileSpec().GetFilename().AsCString()); 389 Error err = BringInRemoteFile (this, module_spec, module_cache_spec); 390 if (err.Fail()) 391 return err; 392 if (module_cache_spec.Exists()) 393 { 394 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM)); 395 if (log) 396 log->Printf("[%s] module %s/%s is now cached and fine", 397 (IsHost() ? "host" : "remote"), 398 module_spec.GetFileSpec().GetDirectory().AsCString(), 399 module_spec.GetFileSpec().GetFilename().AsCString()); 400 ModuleSpec local_spec(module_cache_spec, module_spec.GetArchitecture()); 401 module_sp.reset(new Module(local_spec)); 402 module_sp->SetPlatformFileSpec(module_spec.GetFileSpec()); 403 return Error(); 404 } 405 else 406 return Error("unable to obtain valid module file"); 407 } 408 else 409 return Error("no cache path"); 410 } 411 else 412 return Error ("unable to resolve module"); 413 } 414 415 Error 416 PlatformDarwin::GetSharedModule (const ModuleSpec &module_spec, 417 ModuleSP &module_sp, 418 const FileSpecList *module_search_paths_ptr, 419 ModuleSP *old_module_sp_ptr, 420 bool *did_create_ptr) 421 { 422 Error error; 423 module_sp.reset(); 424 425 if (IsRemote()) 426 { 427 // If we have a remote platform always, let it try and locate 428 // the shared module first. 429 if (m_remote_platform_sp) 430 { 431 error = m_remote_platform_sp->GetSharedModule (module_spec, 432 module_sp, 433 module_search_paths_ptr, 434 old_module_sp_ptr, 435 did_create_ptr); 436 } 437 } 438 439 if (!module_sp) 440 { 441 // Fall back to the local platform and find the file locally 442 error = Platform::GetSharedModule (module_spec, 443 module_sp, 444 module_search_paths_ptr, 445 old_module_sp_ptr, 446 did_create_ptr); 447 448 const FileSpec &platform_file = module_spec.GetFileSpec(); 449 if (!module_sp && module_search_paths_ptr && platform_file) 450 { 451 // We can try to pull off part of the file path up to the bundle 452 // directory level and try any module search paths... 453 FileSpec bundle_directory; 454 if (Host::GetBundleDirectory (platform_file, bundle_directory)) 455 { 456 if (platform_file == bundle_directory) 457 { 458 ModuleSpec new_module_spec (module_spec); 459 new_module_spec.GetFileSpec() = bundle_directory; 460 if (Host::ResolveExecutableInBundle (new_module_spec.GetFileSpec())) 461 { 462 Error new_error (Platform::GetSharedModule (new_module_spec, 463 module_sp, 464 NULL, 465 old_module_sp_ptr, 466 did_create_ptr)); 467 468 if (module_sp) 469 return new_error; 470 } 471 } 472 else 473 { 474 char platform_path[PATH_MAX]; 475 char bundle_dir[PATH_MAX]; 476 platform_file.GetPath (platform_path, sizeof(platform_path)); 477 const size_t bundle_directory_len = bundle_directory.GetPath (bundle_dir, sizeof(bundle_dir)); 478 char new_path[PATH_MAX]; 479 size_t num_module_search_paths = module_search_paths_ptr->GetSize(); 480 for (size_t i=0; i<num_module_search_paths; ++i) 481 { 482 const size_t search_path_len = module_search_paths_ptr->GetFileSpecAtIndex(i).GetPath(new_path, sizeof(new_path)); 483 if (search_path_len < sizeof(new_path)) 484 { 485 snprintf (new_path + search_path_len, sizeof(new_path) - search_path_len, "/%s", platform_path + bundle_directory_len); 486 FileSpec new_file_spec (new_path, false); 487 if (new_file_spec.Exists()) 488 { 489 ModuleSpec new_module_spec (module_spec); 490 new_module_spec.GetFileSpec() = new_file_spec; 491 Error new_error (Platform::GetSharedModule (new_module_spec, 492 module_sp, 493 NULL, 494 old_module_sp_ptr, 495 did_create_ptr)); 496 497 if (module_sp) 498 { 499 module_sp->SetPlatformFileSpec(new_file_spec); 500 return new_error; 501 } 502 } 503 } 504 } 505 } 506 } 507 } 508 } 509 if (module_sp) 510 module_sp->SetPlatformFileSpec(module_spec.GetFileSpec()); 511 return error; 512 } 513 514 size_t 515 PlatformDarwin::GetSoftwareBreakpointTrapOpcode (Target &target, BreakpointSite *bp_site) 516 { 517 const uint8_t *trap_opcode = NULL; 518 uint32_t trap_opcode_size = 0; 519 bool bp_is_thumb = false; 520 521 llvm::Triple::ArchType machine = target.GetArchitecture().GetMachine(); 522 switch (machine) 523 { 524 case llvm::Triple::x86: 525 case llvm::Triple::x86_64: 526 { 527 static const uint8_t g_i386_breakpoint_opcode[] = { 0xCC }; 528 trap_opcode = g_i386_breakpoint_opcode; 529 trap_opcode_size = sizeof(g_i386_breakpoint_opcode); 530 } 531 break; 532 533 case llvm::Triple::arm64: 534 { 535 // TODO: fix this with actual darwin breakpoint opcode for arm64. 536 // right now debugging uses the Z packets with GDB remote so this 537 // is not needed, but the size needs to be correct... 538 static const uint8_t g_arm64_breakpoint_opcode[] = { 0xFE, 0xDE, 0xFF, 0xE7 }; 539 trap_opcode = g_arm64_breakpoint_opcode; 540 trap_opcode_size = sizeof(g_arm64_breakpoint_opcode); 541 } 542 break; 543 544 case llvm::Triple::thumb: 545 bp_is_thumb = true; // Fall through... 546 case llvm::Triple::arm: 547 { 548 static const uint8_t g_arm_breakpoint_opcode[] = { 0xFE, 0xDE, 0xFF, 0xE7 }; 549 static const uint8_t g_thumb_breakpooint_opcode[] = { 0xFE, 0xDE }; 550 551 // Auto detect arm/thumb if it wasn't explicitly specified 552 if (!bp_is_thumb) 553 { 554 lldb::BreakpointLocationSP bp_loc_sp (bp_site->GetOwnerAtIndex (0)); 555 if (bp_loc_sp) 556 bp_is_thumb = bp_loc_sp->GetAddress().GetAddressClass () == eAddressClassCodeAlternateISA; 557 } 558 if (bp_is_thumb) 559 { 560 trap_opcode = g_thumb_breakpooint_opcode; 561 trap_opcode_size = sizeof(g_thumb_breakpooint_opcode); 562 break; 563 } 564 trap_opcode = g_arm_breakpoint_opcode; 565 trap_opcode_size = sizeof(g_arm_breakpoint_opcode); 566 } 567 break; 568 569 case llvm::Triple::ppc: 570 case llvm::Triple::ppc64: 571 { 572 static const uint8_t g_ppc_breakpoint_opcode[] = { 0x7F, 0xC0, 0x00, 0x08 }; 573 trap_opcode = g_ppc_breakpoint_opcode; 574 trap_opcode_size = sizeof(g_ppc_breakpoint_opcode); 575 } 576 break; 577 578 default: 579 assert(!"Unhandled architecture in PlatformDarwin::GetSoftwareBreakpointTrapOpcode()"); 580 break; 581 } 582 583 if (trap_opcode && trap_opcode_size) 584 { 585 if (bp_site->SetTrapOpcode(trap_opcode, trap_opcode_size)) 586 return trap_opcode_size; 587 } 588 return 0; 589 590 } 591 592 bool 593 PlatformDarwin::GetRemoteOSVersion () 594 { 595 if (m_remote_platform_sp) 596 return m_remote_platform_sp->GetOSVersion (m_major_os_version, 597 m_minor_os_version, 598 m_update_os_version); 599 return false; 600 } 601 602 bool 603 PlatformDarwin::GetRemoteOSBuildString (std::string &s) 604 { 605 if (m_remote_platform_sp) 606 return m_remote_platform_sp->GetRemoteOSBuildString (s); 607 s.clear(); 608 return false; 609 } 610 611 bool 612 PlatformDarwin::GetRemoteOSKernelDescription (std::string &s) 613 { 614 if (m_remote_platform_sp) 615 return m_remote_platform_sp->GetRemoteOSKernelDescription (s); 616 s.clear(); 617 return false; 618 } 619 620 // Remote Platform subclasses need to override this function 621 ArchSpec 622 PlatformDarwin::GetRemoteSystemArchitecture () 623 { 624 if (m_remote_platform_sp) 625 return m_remote_platform_sp->GetRemoteSystemArchitecture (); 626 return ArchSpec(); 627 } 628 629 630 const char * 631 PlatformDarwin::GetHostname () 632 { 633 if (IsHost()) 634 return Platform::GetHostname(); 635 636 if (m_remote_platform_sp) 637 return m_remote_platform_sp->GetHostname (); 638 return NULL; 639 } 640 641 bool 642 PlatformDarwin::IsConnected () const 643 { 644 if (IsHost()) 645 return true; 646 else if (m_remote_platform_sp) 647 return m_remote_platform_sp->IsConnected(); 648 return false; 649 } 650 651 Error 652 PlatformDarwin::ConnectRemote (Args& args) 653 { 654 Error error; 655 if (IsHost()) 656 { 657 error.SetErrorStringWithFormat ("can't connect to the host platform '%s', always connected", GetPluginName().GetCString()); 658 } 659 else 660 { 661 if (!m_remote_platform_sp) 662 m_remote_platform_sp = Platform::Create ("remote-gdb-server", error); 663 664 if (m_remote_platform_sp && error.Success()) 665 error = m_remote_platform_sp->ConnectRemote (args); 666 else 667 error.SetErrorString ("failed to create a 'remote-gdb-server' platform"); 668 669 if (error.Fail()) 670 m_remote_platform_sp.reset(); 671 } 672 673 if (error.Success() && m_remote_platform_sp) 674 { 675 if (m_options.get()) 676 { 677 OptionGroupOptions* options = m_options.get(); 678 OptionGroupPlatformRSync* m_rsync_options = (OptionGroupPlatformRSync*)options->GetGroupWithOption('r'); 679 OptionGroupPlatformSSH* m_ssh_options = (OptionGroupPlatformSSH*)options->GetGroupWithOption('s'); 680 OptionGroupPlatformCaching* m_cache_options = (OptionGroupPlatformCaching*)options->GetGroupWithOption('c'); 681 682 if (m_rsync_options->m_rsync) 683 { 684 SetSupportsRSync(true); 685 SetRSyncOpts(m_rsync_options->m_rsync_opts.c_str()); 686 SetRSyncPrefix(m_rsync_options->m_rsync_prefix.c_str()); 687 SetIgnoresRemoteHostname(m_rsync_options->m_ignores_remote_hostname); 688 } 689 if (m_ssh_options->m_ssh) 690 { 691 SetSupportsSSH(true); 692 SetSSHOpts(m_ssh_options->m_ssh_opts.c_str()); 693 } 694 SetLocalCacheDirectory(m_cache_options->m_cache_dir.c_str()); 695 } 696 } 697 698 return error; 699 } 700 701 Error 702 PlatformDarwin::DisconnectRemote () 703 { 704 Error error; 705 706 if (IsHost()) 707 { 708 error.SetErrorStringWithFormat ("can't disconnect from the host platform '%s', always connected", GetPluginName().GetCString()); 709 } 710 else 711 { 712 if (m_remote_platform_sp) 713 error = m_remote_platform_sp->DisconnectRemote (); 714 else 715 error.SetErrorString ("the platform is not currently connected"); 716 } 717 return error; 718 } 719 720 721 bool 722 PlatformDarwin::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info) 723 { 724 bool sucess = false; 725 if (IsHost()) 726 { 727 sucess = Platform::GetProcessInfo (pid, process_info); 728 } 729 else 730 { 731 if (m_remote_platform_sp) 732 sucess = m_remote_platform_sp->GetProcessInfo (pid, process_info); 733 } 734 return sucess; 735 } 736 737 738 739 uint32_t 740 PlatformDarwin::FindProcesses (const ProcessInstanceInfoMatch &match_info, 741 ProcessInstanceInfoList &process_infos) 742 { 743 uint32_t match_count = 0; 744 if (IsHost()) 745 { 746 // Let the base class figure out the host details 747 match_count = Platform::FindProcesses (match_info, process_infos); 748 } 749 else 750 { 751 // If we are remote, we can only return results if we are connected 752 if (m_remote_platform_sp) 753 match_count = m_remote_platform_sp->FindProcesses (match_info, process_infos); 754 } 755 return match_count; 756 } 757 758 Error 759 PlatformDarwin::LaunchProcess (ProcessLaunchInfo &launch_info) 760 { 761 Error error; 762 763 if (IsHost()) 764 { 765 error = Platform::LaunchProcess (launch_info); 766 } 767 else 768 { 769 if (m_remote_platform_sp) 770 error = m_remote_platform_sp->LaunchProcess (launch_info); 771 else 772 error.SetErrorString ("the platform is not currently connected"); 773 } 774 return error; 775 } 776 777 lldb::ProcessSP 778 PlatformDarwin::DebugProcess (ProcessLaunchInfo &launch_info, 779 Debugger &debugger, 780 Target *target, // Can be NULL, if NULL create a new target, else use existing one 781 Listener &listener, 782 Error &error) 783 { 784 ProcessSP process_sp; 785 786 if (IsHost()) 787 { 788 // We are going to hand this process off to debugserver which will monitor the process itself. 789 // So don't also monitor it from lldb or we set up a race between debugserver & us for who will find out 790 // about the debugged process's death. 791 launch_info.GetFlags().Set(eLaunchFlagsDontMonitorProcess); 792 process_sp = Platform::DebugProcess (launch_info, debugger, target, listener, error); 793 } 794 else 795 { 796 if (m_remote_platform_sp) 797 process_sp = m_remote_platform_sp->DebugProcess (launch_info, debugger, target, listener, error); 798 else 799 error.SetErrorString ("the platform is not currently connected"); 800 } 801 return process_sp; 802 803 } 804 805 806 lldb::ProcessSP 807 PlatformDarwin::Attach (ProcessAttachInfo &attach_info, 808 Debugger &debugger, 809 Target *target, 810 Listener &listener, 811 Error &error) 812 { 813 lldb::ProcessSP process_sp; 814 815 if (IsHost()) 816 { 817 if (target == NULL) 818 { 819 TargetSP new_target_sp; 820 821 error = debugger.GetTargetList().CreateTarget (debugger, 822 NULL, 823 NULL, 824 false, 825 NULL, 826 new_target_sp); 827 target = new_target_sp.get(); 828 } 829 else 830 error.Clear(); 831 832 if (target && error.Success()) 833 { 834 debugger.GetTargetList().SetSelectedTarget(target); 835 836 process_sp = target->CreateProcess (listener, attach_info.GetProcessPluginName(), NULL); 837 838 if (process_sp) 839 { 840 ListenerSP listener_sp (new Listener("lldb.PlatformDarwin.attach.hijack")); 841 attach_info.SetHijackListener(listener_sp); 842 process_sp->HijackProcessEvents(listener_sp.get()); 843 error = process_sp->Attach (attach_info); 844 } 845 } 846 } 847 else 848 { 849 if (m_remote_platform_sp) 850 process_sp = m_remote_platform_sp->Attach (attach_info, debugger, target, listener, error); 851 else 852 error.SetErrorString ("the platform is not currently connected"); 853 } 854 return process_sp; 855 } 856 857 const char * 858 PlatformDarwin::GetUserName (uint32_t uid) 859 { 860 // Check the cache in Platform in case we have already looked this uid up 861 const char *user_name = Platform::GetUserName(uid); 862 if (user_name) 863 return user_name; 864 865 if (IsRemote() && m_remote_platform_sp) 866 return m_remote_platform_sp->GetUserName(uid); 867 return NULL; 868 } 869 870 const char * 871 PlatformDarwin::GetGroupName (uint32_t gid) 872 { 873 const char *group_name = Platform::GetGroupName(gid); 874 if (group_name) 875 return group_name; 876 877 if (IsRemote() && m_remote_platform_sp) 878 return m_remote_platform_sp->GetGroupName(gid); 879 return NULL; 880 } 881 882 bool 883 PlatformDarwin::ModuleIsExcludedForNonModuleSpecificSearches (lldb_private::Target &target, const lldb::ModuleSP &module_sp) 884 { 885 if (!module_sp) 886 return false; 887 888 ObjectFile *obj_file = module_sp->GetObjectFile(); 889 if (!obj_file) 890 return false; 891 892 ObjectFile::Type obj_type = obj_file->GetType(); 893 if (obj_type == ObjectFile::eTypeDynamicLinker) 894 return true; 895 else 896 return false; 897 } 898 899 bool 900 PlatformDarwin::x86GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch) 901 { 902 ArchSpec host_arch = Host::GetArchitecture (Host::eSystemDefaultArchitecture); 903 if (host_arch.GetCore() == ArchSpec::eCore_x86_64_x86_64h) 904 { 905 switch (idx) 906 { 907 case 0: 908 arch = host_arch; 909 return true; 910 911 case 1: 912 arch.SetTriple("x86_64-apple-macosx"); 913 return true; 914 915 case 2: 916 arch = Host::GetArchitecture (Host::eSystemDefaultArchitecture32); 917 return true; 918 919 default: return false; 920 } 921 } 922 else 923 { 924 if (idx == 0) 925 { 926 arch = Host::GetArchitecture (Host::eSystemDefaultArchitecture); 927 return arch.IsValid(); 928 } 929 else if (idx == 1) 930 { 931 ArchSpec platform_arch (Host::GetArchitecture (Host::eSystemDefaultArchitecture)); 932 ArchSpec platform_arch64 (Host::GetArchitecture (Host::eSystemDefaultArchitecture64)); 933 if (platform_arch.IsExactMatch(platform_arch64)) 934 { 935 // This macosx platform supports both 32 and 64 bit. Since we already 936 // returned the 64 bit arch for idx == 0, return the 32 bit arch 937 // for idx == 1 938 arch = Host::GetArchitecture (Host::eSystemDefaultArchitecture32); 939 return arch.IsValid(); 940 } 941 } 942 } 943 return false; 944 } 945 946 // The architecture selection rules for arm processors 947 // These cpu subtypes have distinct names (e.g. armv7f) but armv7 binaries run fine on an armv7f processor. 948 949 bool 950 PlatformDarwin::ARMGetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch) 951 { 952 ArchSpec system_arch (GetSystemArchitecture()); 953 954 const ArchSpec::Core system_core = system_arch.GetCore(); 955 switch (system_core) 956 { 957 default: 958 switch (idx) 959 { 960 case 0: arch.SetTriple ("arm64-apple-ios"); return true; 961 case 1: arch.SetTriple ("armv7-apple-ios"); return true; 962 case 2: arch.SetTriple ("armv7f-apple-ios"); return true; 963 case 3: arch.SetTriple ("armv7k-apple-ios"); return true; 964 case 4: arch.SetTriple ("armv7s-apple-ios"); return true; 965 case 5: arch.SetTriple ("armv7m-apple-ios"); return true; 966 case 6: arch.SetTriple ("armv7em-apple-ios"); return true; 967 case 7: arch.SetTriple ("armv6m-apple-ios"); return true; 968 case 8: arch.SetTriple ("armv6-apple-ios"); return true; 969 case 9: arch.SetTriple ("armv5-apple-ios"); return true; 970 case 10: arch.SetTriple ("armv4-apple-ios"); return true; 971 case 11: arch.SetTriple ("arm-apple-ios"); return true; 972 case 12: arch.SetTriple ("thumbv7-apple-ios"); return true; 973 case 13: arch.SetTriple ("thumbv7f-apple-ios"); return true; 974 case 14: arch.SetTriple ("thumbv7k-apple-ios"); return true; 975 case 15: arch.SetTriple ("thumbv7s-apple-ios"); return true; 976 case 16: arch.SetTriple ("thumbv7m-apple-ios"); return true; 977 case 17: arch.SetTriple ("thumbv7em-apple-ios"); return true; 978 case 18: arch.SetTriple ("thumbv6m-apple-ios"); return true; 979 case 19: arch.SetTriple ("thumbv6-apple-ios"); return true; 980 case 20: arch.SetTriple ("thumbv5-apple-ios"); return true; 981 case 21: arch.SetTriple ("thumbv4t-apple-ios"); return true; 982 case 22: arch.SetTriple ("thumb-apple-ios"); return true; 983 default: break; 984 } 985 break; 986 987 case ArchSpec::eCore_arm_arm64: 988 switch (idx) 989 { 990 case 0: arch.SetTriple ("arm64-apple-ios"); return true; 991 case 1: arch.SetTriple ("armv7s-apple-ios"); return true; 992 case 2: arch.SetTriple ("armv7f-apple-ios"); return true; 993 case 3: arch.SetTriple ("armv7m-apple-ios"); return true; 994 case 4: arch.SetTriple ("armv7em-apple-ios"); return true; 995 case 5: arch.SetTriple ("armv7-apple-ios"); return true; 996 case 6: arch.SetTriple ("armv6m-apple-ios"); return true; 997 case 7: arch.SetTriple ("armv6-apple-ios"); return true; 998 case 8: arch.SetTriple ("armv5-apple-ios"); return true; 999 case 9: arch.SetTriple ("armv4-apple-ios"); return true; 1000 case 10: arch.SetTriple ("arm-apple-ios"); return true; 1001 case 11: arch.SetTriple ("thumbv7-apple-ios"); return true; 1002 case 12: arch.SetTriple ("thumbv7f-apple-ios"); return true; 1003 case 13: arch.SetTriple ("thumbv7k-apple-ios"); return true; 1004 case 14: arch.SetTriple ("thumbv7s-apple-ios"); return true; 1005 case 15: arch.SetTriple ("thumbv7m-apple-ios"); return true; 1006 case 16: arch.SetTriple ("thumbv7em-apple-ios"); return true; 1007 case 17: arch.SetTriple ("thumbv6m-apple-ios"); return true; 1008 case 18: arch.SetTriple ("thumbv6-apple-ios"); return true; 1009 case 19: arch.SetTriple ("thumbv5-apple-ios"); return true; 1010 case 20: arch.SetTriple ("thumbv4t-apple-ios"); return true; 1011 case 21: arch.SetTriple ("thumb-apple-ios"); return true; 1012 default: break; 1013 } 1014 break; 1015 1016 case ArchSpec::eCore_arm_armv7f: 1017 switch (idx) 1018 { 1019 case 0: arch.SetTriple ("armv7f-apple-ios"); return true; 1020 case 1: arch.SetTriple ("armv7-apple-ios"); return true; 1021 case 2: arch.SetTriple ("armv6m-apple-ios"); return true; 1022 case 3: arch.SetTriple ("armv6-apple-ios"); return true; 1023 case 4: arch.SetTriple ("armv5-apple-ios"); return true; 1024 case 5: arch.SetTriple ("armv4-apple-ios"); return true; 1025 case 6: arch.SetTriple ("arm-apple-ios"); return true; 1026 case 7: arch.SetTriple ("thumbv7f-apple-ios"); return true; 1027 case 8: arch.SetTriple ("thumbv7-apple-ios"); return true; 1028 case 9: arch.SetTriple ("thumbv6m-apple-ios"); return true; 1029 case 10: arch.SetTriple ("thumbv6-apple-ios"); return true; 1030 case 11: arch.SetTriple ("thumbv5-apple-ios"); return true; 1031 case 12: arch.SetTriple ("thumbv4t-apple-ios"); return true; 1032 case 13: arch.SetTriple ("thumb-apple-ios"); return true; 1033 default: break; 1034 } 1035 break; 1036 1037 case ArchSpec::eCore_arm_armv7k: 1038 switch (idx) 1039 { 1040 case 0: arch.SetTriple ("armv7k-apple-ios"); return true; 1041 case 1: arch.SetTriple ("armv7-apple-ios"); return true; 1042 case 2: arch.SetTriple ("armv6m-apple-ios"); return true; 1043 case 3: arch.SetTriple ("armv6-apple-ios"); return true; 1044 case 4: arch.SetTriple ("armv5-apple-ios"); return true; 1045 case 5: arch.SetTriple ("armv4-apple-ios"); return true; 1046 case 6: arch.SetTriple ("arm-apple-ios"); return true; 1047 case 7: arch.SetTriple ("thumbv7k-apple-ios"); return true; 1048 case 8: arch.SetTriple ("thumbv7-apple-ios"); return true; 1049 case 9: arch.SetTriple ("thumbv6m-apple-ios"); return true; 1050 case 10: arch.SetTriple ("thumbv6-apple-ios"); return true; 1051 case 11: arch.SetTriple ("thumbv5-apple-ios"); return true; 1052 case 12: arch.SetTriple ("thumbv4t-apple-ios"); return true; 1053 case 13: arch.SetTriple ("thumb-apple-ios"); return true; 1054 default: break; 1055 } 1056 break; 1057 1058 case ArchSpec::eCore_arm_armv7s: 1059 switch (idx) 1060 { 1061 case 0: arch.SetTriple ("armv7s-apple-ios"); return true; 1062 case 1: arch.SetTriple ("armv7-apple-ios"); return true; 1063 case 2: arch.SetTriple ("armv6m-apple-ios"); return true; 1064 case 3: arch.SetTriple ("armv6-apple-ios"); return true; 1065 case 4: arch.SetTriple ("armv5-apple-ios"); return true; 1066 case 5: arch.SetTriple ("armv4-apple-ios"); return true; 1067 case 6: arch.SetTriple ("arm-apple-ios"); return true; 1068 case 7: arch.SetTriple ("thumbv7s-apple-ios"); return true; 1069 case 8: arch.SetTriple ("thumbv7-apple-ios"); return true; 1070 case 9: arch.SetTriple ("thumbv6m-apple-ios"); return true; 1071 case 10: arch.SetTriple ("thumbv6-apple-ios"); return true; 1072 case 11: arch.SetTriple ("thumbv5-apple-ios"); return true; 1073 case 12: arch.SetTriple ("thumbv4t-apple-ios"); return true; 1074 case 13: arch.SetTriple ("thumb-apple-ios"); return true; 1075 default: break; 1076 } 1077 break; 1078 1079 case ArchSpec::eCore_arm_armv7m: 1080 switch (idx) 1081 { 1082 case 0: arch.SetTriple ("armv7m-apple-ios"); return true; 1083 case 1: arch.SetTriple ("armv7-apple-ios"); return true; 1084 case 2: arch.SetTriple ("armv6m-apple-ios"); return true; 1085 case 3: arch.SetTriple ("armv6-apple-ios"); return true; 1086 case 4: arch.SetTriple ("armv5-apple-ios"); return true; 1087 case 5: arch.SetTriple ("armv4-apple-ios"); return true; 1088 case 6: arch.SetTriple ("arm-apple-ios"); return true; 1089 case 7: arch.SetTriple ("thumbv7m-apple-ios"); return true; 1090 case 8: arch.SetTriple ("thumbv7-apple-ios"); return true; 1091 case 9: arch.SetTriple ("thumbv6m-apple-ios"); return true; 1092 case 10: arch.SetTriple ("thumbv6-apple-ios"); return true; 1093 case 11: arch.SetTriple ("thumbv5-apple-ios"); return true; 1094 case 12: arch.SetTriple ("thumbv4t-apple-ios"); return true; 1095 case 13: arch.SetTriple ("thumb-apple-ios"); return true; 1096 default: break; 1097 } 1098 break; 1099 1100 case ArchSpec::eCore_arm_armv7em: 1101 switch (idx) 1102 { 1103 case 0: arch.SetTriple ("armv7em-apple-ios"); return true; 1104 case 1: arch.SetTriple ("armv7-apple-ios"); return true; 1105 case 2: arch.SetTriple ("armv6m-apple-ios"); return true; 1106 case 3: arch.SetTriple ("armv6-apple-ios"); return true; 1107 case 4: arch.SetTriple ("armv5-apple-ios"); return true; 1108 case 5: arch.SetTriple ("armv4-apple-ios"); return true; 1109 case 6: arch.SetTriple ("arm-apple-ios"); return true; 1110 case 7: arch.SetTriple ("thumbv7em-apple-ios"); return true; 1111 case 8: arch.SetTriple ("thumbv7-apple-ios"); return true; 1112 case 9: arch.SetTriple ("thumbv6m-apple-ios"); return true; 1113 case 10: arch.SetTriple ("thumbv6-apple-ios"); return true; 1114 case 11: arch.SetTriple ("thumbv5-apple-ios"); return true; 1115 case 12: arch.SetTriple ("thumbv4t-apple-ios"); return true; 1116 case 13: arch.SetTriple ("thumb-apple-ios"); return true; 1117 default: break; 1118 } 1119 break; 1120 1121 case ArchSpec::eCore_arm_armv7: 1122 switch (idx) 1123 { 1124 case 0: arch.SetTriple ("armv7-apple-ios"); return true; 1125 case 1: arch.SetTriple ("armv6m-apple-ios"); return true; 1126 case 2: arch.SetTriple ("armv6-apple-ios"); return true; 1127 case 3: arch.SetTriple ("armv5-apple-ios"); return true; 1128 case 4: arch.SetTriple ("armv4-apple-ios"); return true; 1129 case 5: arch.SetTriple ("arm-apple-ios"); return true; 1130 case 6: arch.SetTriple ("thumbv7-apple-ios"); return true; 1131 case 7: arch.SetTriple ("thumbv6m-apple-ios"); return true; 1132 case 8: arch.SetTriple ("thumbv6-apple-ios"); return true; 1133 case 9: arch.SetTriple ("thumbv5-apple-ios"); return true; 1134 case 10: arch.SetTriple ("thumbv4t-apple-ios"); return true; 1135 case 11: arch.SetTriple ("thumb-apple-ios"); return true; 1136 default: break; 1137 } 1138 break; 1139 1140 case ArchSpec::eCore_arm_armv6m: 1141 switch (idx) 1142 { 1143 case 0: arch.SetTriple ("armv6m-apple-ios"); return true; 1144 case 1: arch.SetTriple ("armv6-apple-ios"); return true; 1145 case 2: arch.SetTriple ("armv5-apple-ios"); return true; 1146 case 3: arch.SetTriple ("armv4-apple-ios"); return true; 1147 case 4: arch.SetTriple ("arm-apple-ios"); return true; 1148 case 5: arch.SetTriple ("thumbv6m-apple-ios"); return true; 1149 case 6: arch.SetTriple ("thumbv6-apple-ios"); return true; 1150 case 7: arch.SetTriple ("thumbv5-apple-ios"); return true; 1151 case 8: arch.SetTriple ("thumbv4t-apple-ios"); return true; 1152 case 9: arch.SetTriple ("thumb-apple-ios"); return true; 1153 default: break; 1154 } 1155 break; 1156 1157 case ArchSpec::eCore_arm_armv6: 1158 switch (idx) 1159 { 1160 case 0: arch.SetTriple ("armv6-apple-ios"); return true; 1161 case 1: arch.SetTriple ("armv5-apple-ios"); return true; 1162 case 2: arch.SetTriple ("armv4-apple-ios"); return true; 1163 case 3: arch.SetTriple ("arm-apple-ios"); return true; 1164 case 4: arch.SetTriple ("thumbv6-apple-ios"); return true; 1165 case 5: arch.SetTriple ("thumbv5-apple-ios"); return true; 1166 case 6: arch.SetTriple ("thumbv4t-apple-ios"); return true; 1167 case 7: arch.SetTriple ("thumb-apple-ios"); return true; 1168 default: break; 1169 } 1170 break; 1171 1172 case ArchSpec::eCore_arm_armv5: 1173 switch (idx) 1174 { 1175 case 0: arch.SetTriple ("armv5-apple-ios"); return true; 1176 case 1: arch.SetTriple ("armv4-apple-ios"); return true; 1177 case 2: arch.SetTriple ("arm-apple-ios"); return true; 1178 case 3: arch.SetTriple ("thumbv5-apple-ios"); return true; 1179 case 4: arch.SetTriple ("thumbv4t-apple-ios"); return true; 1180 case 5: arch.SetTriple ("thumb-apple-ios"); return true; 1181 default: break; 1182 } 1183 break; 1184 1185 case ArchSpec::eCore_arm_armv4: 1186 switch (idx) 1187 { 1188 case 0: arch.SetTriple ("armv4-apple-ios"); return true; 1189 case 1: arch.SetTriple ("arm-apple-ios"); return true; 1190 case 2: arch.SetTriple ("thumbv4t-apple-ios"); return true; 1191 case 3: arch.SetTriple ("thumb-apple-ios"); return true; 1192 default: break; 1193 } 1194 break; 1195 } 1196 arch.Clear(); 1197 return false; 1198 } 1199 1200 1201 const char * 1202 PlatformDarwin::GetDeveloperDirectory() 1203 { 1204 if (m_developer_directory.empty()) 1205 { 1206 bool developer_dir_path_valid = false; 1207 char developer_dir_path[PATH_MAX]; 1208 FileSpec temp_file_spec; 1209 if (Host::GetLLDBPath (ePathTypeLLDBShlibDir, temp_file_spec)) 1210 { 1211 if (temp_file_spec.GetPath (developer_dir_path, sizeof(developer_dir_path))) 1212 { 1213 char *shared_frameworks = strstr (developer_dir_path, "/SharedFrameworks/LLDB.framework"); 1214 if (shared_frameworks) 1215 { 1216 ::snprintf (shared_frameworks, 1217 sizeof(developer_dir_path) - (shared_frameworks - developer_dir_path), 1218 "/Developer"); 1219 developer_dir_path_valid = true; 1220 } 1221 else 1222 { 1223 char *lib_priv_frameworks = strstr (developer_dir_path, "/Library/PrivateFrameworks/LLDB.framework"); 1224 if (lib_priv_frameworks) 1225 { 1226 *lib_priv_frameworks = '\0'; 1227 developer_dir_path_valid = true; 1228 } 1229 } 1230 } 1231 } 1232 1233 if (!developer_dir_path_valid) 1234 { 1235 std::string xcode_dir_path; 1236 const char *xcode_select_prefix_dir = getenv ("XCODE_SELECT_PREFIX_DIR"); 1237 if (xcode_select_prefix_dir) 1238 xcode_dir_path.append (xcode_select_prefix_dir); 1239 xcode_dir_path.append ("/usr/share/xcode-select/xcode_dir_path"); 1240 temp_file_spec.SetFile(xcode_dir_path.c_str(), false); 1241 size_t bytes_read = temp_file_spec.ReadFileContents(0, developer_dir_path, sizeof(developer_dir_path), NULL); 1242 if (bytes_read > 0) 1243 { 1244 developer_dir_path[bytes_read] = '\0'; 1245 while (developer_dir_path[bytes_read-1] == '\r' || 1246 developer_dir_path[bytes_read-1] == '\n') 1247 developer_dir_path[--bytes_read] = '\0'; 1248 developer_dir_path_valid = true; 1249 } 1250 } 1251 1252 if (!developer_dir_path_valid) 1253 { 1254 FileSpec xcode_select_cmd ("/usr/bin/xcode-select", false); 1255 if (xcode_select_cmd.Exists()) 1256 { 1257 int exit_status = -1; 1258 int signo = -1; 1259 std::string command_output; 1260 Error error = Host::RunShellCommand ("/usr/bin/xcode-select --print-path", 1261 NULL, // current working directory 1262 &exit_status, 1263 &signo, 1264 &command_output, 1265 2, // short timeout 1266 NULL); // don't run in a shell 1267 if (error.Success() && exit_status == 0 && !command_output.empty()) 1268 { 1269 const char *cmd_output_ptr = command_output.c_str(); 1270 developer_dir_path[sizeof (developer_dir_path) - 1] = '\0'; 1271 size_t i; 1272 for (i = 0; i < sizeof (developer_dir_path) - 1; i++) 1273 { 1274 if (cmd_output_ptr[i] == '\r' || cmd_output_ptr[i] == '\n' || cmd_output_ptr[i] == '\0') 1275 break; 1276 developer_dir_path[i] = cmd_output_ptr[i]; 1277 } 1278 developer_dir_path[i] = '\0'; 1279 1280 FileSpec devel_dir (developer_dir_path, false); 1281 if (devel_dir.Exists() && devel_dir.IsDirectory()) 1282 { 1283 developer_dir_path_valid = true; 1284 } 1285 } 1286 } 1287 } 1288 1289 if (developer_dir_path_valid) 1290 { 1291 temp_file_spec.SetFile (developer_dir_path, false); 1292 if (temp_file_spec.Exists()) 1293 { 1294 m_developer_directory.assign (developer_dir_path); 1295 return m_developer_directory.c_str(); 1296 } 1297 } 1298 // Assign a single NULL character so we know we tried to find the device 1299 // support directory and we don't keep trying to find it over and over. 1300 m_developer_directory.assign (1, '\0'); 1301 } 1302 1303 // We should have put a single NULL character into m_developer_directory 1304 // or it should have a valid path if the code gets here 1305 assert (m_developer_directory.empty() == false); 1306 if (m_developer_directory[0]) 1307 return m_developer_directory.c_str(); 1308 return NULL; 1309 } 1310 1311 1312 BreakpointSP 1313 PlatformDarwin::SetThreadCreationBreakpoint (Target &target) 1314 { 1315 BreakpointSP bp_sp; 1316 static const char *g_bp_names[] = 1317 { 1318 "start_wqthread", 1319 "_pthread_wqthread", 1320 "_pthread_start", 1321 }; 1322 1323 static const char *g_bp_modules[] = 1324 { 1325 "libsystem_c.dylib", 1326 "libSystem.B.dylib" 1327 }; 1328 1329 FileSpecList bp_modules; 1330 for (size_t i = 0; i < sizeof(g_bp_modules)/sizeof(const char *); i++) 1331 { 1332 const char *bp_module = g_bp_modules[i]; 1333 bp_modules.Append(FileSpec(bp_module, false)); 1334 } 1335 1336 bool internal = true; 1337 bool hardware = false; 1338 LazyBool skip_prologue = eLazyBoolNo; 1339 bp_sp = target.CreateBreakpoint (&bp_modules, 1340 NULL, 1341 g_bp_names, 1342 sizeof(g_bp_names)/sizeof(const char *), 1343 eFunctionNameTypeFull, 1344 skip_prologue, 1345 internal, 1346 hardware); 1347 bp_sp->SetBreakpointKind("thread-creation"); 1348 1349 return bp_sp; 1350 } 1351 1352 size_t 1353 PlatformDarwin::GetEnvironment (StringList &env) 1354 { 1355 if (IsRemote()) 1356 { 1357 if (m_remote_platform_sp) 1358 return m_remote_platform_sp->GetEnvironment(env); 1359 return 0; 1360 } 1361 return Host::GetEnvironment(env); 1362 } 1363 1364 int32_t 1365 PlatformDarwin::GetResumeCountForLaunchInfo (ProcessLaunchInfo &launch_info) 1366 { 1367 const char *shell = launch_info.GetShell(); 1368 if (shell == NULL) 1369 return 1; 1370 1371 const char *shell_name = strrchr (shell, '/'); 1372 if (shell_name == NULL) 1373 shell_name = shell; 1374 else 1375 shell_name++; 1376 1377 if (strcmp (shell_name, "sh") == 0) 1378 { 1379 // /bin/sh re-exec's itself as /bin/bash requiring another resume. 1380 // But it only does this if the COMMAND_MODE environment variable 1381 // is set to "legacy". 1382 char * const *envp = (char * const*)launch_info.GetEnvironmentEntries().GetConstArgumentVector(); 1383 if (envp != NULL) 1384 { 1385 for (int i = 0; envp[i] != NULL; i++) 1386 { 1387 if (strcmp (envp[i], "COMMAND_MODE=legacy" ) == 0) 1388 return 2; 1389 } 1390 } 1391 return 1; 1392 } 1393 else if (strcmp (shell_name, "csh") == 0 1394 || strcmp (shell_name, "tcsh") == 0 1395 || strcmp (shell_name, "zsh") == 0) 1396 { 1397 // csh and tcsh always seem to re-exec themselves. 1398 return 2; 1399 } 1400 else 1401 return 1; 1402 } 1403 1404 void 1405 PlatformDarwin::CalculateTrapHandlerSymbolNames () 1406 { 1407 m_trap_handlers.push_back (ConstString ("_sigtramp")); 1408 } 1409