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