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 std::string cache_path(GetLocalCacheDirectory()); 308 std::string module_path (module_spec.GetFileSpec().GetPath()); 309 cache_path.append(module_path); 310 FileSpec module_cache_spec(cache_path.c_str(),false); 311 312 // if rsync is supported, always bring in the file - rsync will be very efficient 313 // when files are the same on the local and remote end of the connection 314 if (this->GetSupportsRSync()) 315 { 316 Error err = BringInRemoteFile (this, module_spec, module_cache_spec); 317 if (err.Fail()) 318 return err; 319 if (module_cache_spec.Exists()) 320 { 321 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM)); 322 if (log) 323 log->Printf("[%s] module %s/%s was rsynced and is now there", 324 (IsHost() ? "host" : "remote"), 325 module_spec.GetFileSpec().GetDirectory().AsCString(), 326 module_spec.GetFileSpec().GetFilename().AsCString()); 327 ModuleSpec local_spec(module_cache_spec, module_spec.GetArchitecture()); 328 module_sp.reset(new Module(local_spec)); 329 module_sp->SetPlatformFileSpec(module_spec.GetFileSpec()); 330 return Error(); 331 } 332 } 333 334 if (module_spec.GetFileSpec().Exists() && !module_sp) 335 { 336 module_sp.reset(new Module(module_spec)); 337 return Error(); 338 } 339 340 // try to find the module in the cache 341 if (module_cache_spec.Exists()) 342 { 343 // get the local and remote MD5 and compare 344 if (m_remote_platform_sp) 345 { 346 // when going over the *slow* GDB remote transfer mechanism we first check 347 // the hashes of the files - and only do the actual transfer if they differ 348 uint64_t high_local,high_remote,low_local,low_remote; 349 Host::CalculateMD5 (module_cache_spec, low_local, high_local); 350 m_remote_platform_sp->CalculateMD5(module_spec.GetFileSpec(), low_remote, high_remote); 351 if (low_local != low_remote || high_local != high_remote) 352 { 353 // bring in the remote file 354 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM)); 355 if (log) 356 log->Printf("[%s] module %s/%s needs to be replaced from remote copy", 357 (IsHost() ? "host" : "remote"), 358 module_spec.GetFileSpec().GetDirectory().AsCString(), 359 module_spec.GetFileSpec().GetFilename().AsCString()); 360 Error err = BringInRemoteFile (this, module_spec, module_cache_spec); 361 if (err.Fail()) 362 return err; 363 } 364 } 365 366 ModuleSpec local_spec(module_cache_spec, module_spec.GetArchitecture()); 367 module_sp.reset(new Module(local_spec)); 368 module_sp->SetPlatformFileSpec(module_spec.GetFileSpec()); 369 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM)); 370 if (log) 371 log->Printf("[%s] module %s/%s was found in the cache", 372 (IsHost() ? "host" : "remote"), 373 module_spec.GetFileSpec().GetDirectory().AsCString(), 374 module_spec.GetFileSpec().GetFilename().AsCString()); 375 return Error(); 376 } 377 378 // bring in the remote module file 379 if (log) 380 log->Printf("[%s] module %s/%s needs to come in remotely", 381 (IsHost() ? "host" : "remote"), 382 module_spec.GetFileSpec().GetDirectory().AsCString(), 383 module_spec.GetFileSpec().GetFilename().AsCString()); 384 Error err = BringInRemoteFile (this, module_spec, module_cache_spec); 385 if (err.Fail()) 386 return err; 387 if (module_cache_spec.Exists()) 388 { 389 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM)); 390 if (log) 391 log->Printf("[%s] module %s/%s is now cached and fine", 392 (IsHost() ? "host" : "remote"), 393 module_spec.GetFileSpec().GetDirectory().AsCString(), 394 module_spec.GetFileSpec().GetFilename().AsCString()); 395 ModuleSpec local_spec(module_cache_spec, module_spec.GetArchitecture()); 396 module_sp.reset(new Module(local_spec)); 397 module_sp->SetPlatformFileSpec(module_spec.GetFileSpec()); 398 return Error(); 399 } 400 else 401 return Error("unable to obtain valid module file"); 402 } 403 404 Error 405 PlatformDarwin::GetSharedModule (const ModuleSpec &module_spec, 406 ModuleSP &module_sp, 407 const FileSpecList *module_search_paths_ptr, 408 ModuleSP *old_module_sp_ptr, 409 bool *did_create_ptr) 410 { 411 Error error; 412 module_sp.reset(); 413 414 if (IsRemote()) 415 { 416 // If we have a remote platform always, let it try and locate 417 // the shared module first. 418 if (m_remote_platform_sp) 419 { 420 error = m_remote_platform_sp->GetSharedModule (module_spec, 421 module_sp, 422 module_search_paths_ptr, 423 old_module_sp_ptr, 424 did_create_ptr); 425 } 426 } 427 428 if (!module_sp) 429 { 430 // Fall back to the local platform and find the file locally 431 error = Platform::GetSharedModule (module_spec, 432 module_sp, 433 module_search_paths_ptr, 434 old_module_sp_ptr, 435 did_create_ptr); 436 437 const FileSpec &platform_file = module_spec.GetFileSpec(); 438 if (!module_sp && module_search_paths_ptr && platform_file) 439 { 440 // We can try to pull off part of the file path up to the bundle 441 // directory level and try any module search paths... 442 FileSpec bundle_directory; 443 if (Host::GetBundleDirectory (platform_file, bundle_directory)) 444 { 445 if (platform_file == bundle_directory) 446 { 447 ModuleSpec new_module_spec (module_spec); 448 new_module_spec.GetFileSpec() = bundle_directory; 449 if (Host::ResolveExecutableInBundle (new_module_spec.GetFileSpec())) 450 { 451 Error new_error (Platform::GetSharedModule (new_module_spec, 452 module_sp, 453 NULL, 454 old_module_sp_ptr, 455 did_create_ptr)); 456 457 if (module_sp) 458 return new_error; 459 } 460 } 461 else 462 { 463 char platform_path[PATH_MAX]; 464 char bundle_dir[PATH_MAX]; 465 platform_file.GetPath (platform_path, sizeof(platform_path)); 466 const size_t bundle_directory_len = bundle_directory.GetPath (bundle_dir, sizeof(bundle_dir)); 467 char new_path[PATH_MAX]; 468 size_t num_module_search_paths = module_search_paths_ptr->GetSize(); 469 for (size_t i=0; i<num_module_search_paths; ++i) 470 { 471 const size_t search_path_len = module_search_paths_ptr->GetFileSpecAtIndex(i).GetPath(new_path, sizeof(new_path)); 472 if (search_path_len < sizeof(new_path)) 473 { 474 snprintf (new_path + search_path_len, sizeof(new_path) - search_path_len, "/%s", platform_path + bundle_directory_len); 475 FileSpec new_file_spec (new_path, false); 476 if (new_file_spec.Exists()) 477 { 478 ModuleSpec new_module_spec (module_spec); 479 new_module_spec.GetFileSpec() = new_file_spec; 480 Error new_error (Platform::GetSharedModule (new_module_spec, 481 module_sp, 482 NULL, 483 old_module_sp_ptr, 484 did_create_ptr)); 485 486 if (module_sp) 487 { 488 module_sp->SetPlatformFileSpec(new_file_spec); 489 return new_error; 490 } 491 } 492 } 493 } 494 } 495 } 496 } 497 } 498 if (module_sp) 499 module_sp->SetPlatformFileSpec(module_spec.GetFileSpec()); 500 return error; 501 } 502 503 size_t 504 PlatformDarwin::GetSoftwareBreakpointTrapOpcode (Target &target, BreakpointSite *bp_site) 505 { 506 const uint8_t *trap_opcode = NULL; 507 uint32_t trap_opcode_size = 0; 508 bool bp_is_thumb = false; 509 510 llvm::Triple::ArchType machine = target.GetArchitecture().GetMachine(); 511 switch (machine) 512 { 513 case llvm::Triple::x86: 514 case llvm::Triple::x86_64: 515 { 516 static const uint8_t g_i386_breakpoint_opcode[] = { 0xCC }; 517 trap_opcode = g_i386_breakpoint_opcode; 518 trap_opcode_size = sizeof(g_i386_breakpoint_opcode); 519 } 520 break; 521 522 case llvm::Triple::thumb: 523 bp_is_thumb = true; // Fall through... 524 case llvm::Triple::arm: 525 { 526 static const uint8_t g_arm_breakpoint_opcode[] = { 0xFE, 0xDE, 0xFF, 0xE7 }; 527 static const uint8_t g_thumb_breakpooint_opcode[] = { 0xFE, 0xDE }; 528 529 // Auto detect arm/thumb if it wasn't explicitly specified 530 if (!bp_is_thumb) 531 { 532 lldb::BreakpointLocationSP bp_loc_sp (bp_site->GetOwnerAtIndex (0)); 533 if (bp_loc_sp) 534 bp_is_thumb = bp_loc_sp->GetAddress().GetAddressClass () == eAddressClassCodeAlternateISA; 535 } 536 if (bp_is_thumb) 537 { 538 trap_opcode = g_thumb_breakpooint_opcode; 539 trap_opcode_size = sizeof(g_thumb_breakpooint_opcode); 540 break; 541 } 542 trap_opcode = g_arm_breakpoint_opcode; 543 trap_opcode_size = sizeof(g_arm_breakpoint_opcode); 544 } 545 break; 546 547 case llvm::Triple::ppc: 548 case llvm::Triple::ppc64: 549 { 550 static const uint8_t g_ppc_breakpoint_opcode[] = { 0x7F, 0xC0, 0x00, 0x08 }; 551 trap_opcode = g_ppc_breakpoint_opcode; 552 trap_opcode_size = sizeof(g_ppc_breakpoint_opcode); 553 } 554 break; 555 556 default: 557 assert(!"Unhandled architecture in PlatformDarwin::GetSoftwareBreakpointTrapOpcode()"); 558 break; 559 } 560 561 if (trap_opcode && trap_opcode_size) 562 { 563 if (bp_site->SetTrapOpcode(trap_opcode, trap_opcode_size)) 564 return trap_opcode_size; 565 } 566 return 0; 567 568 } 569 570 bool 571 PlatformDarwin::GetRemoteOSVersion () 572 { 573 if (m_remote_platform_sp) 574 return m_remote_platform_sp->GetOSVersion (m_major_os_version, 575 m_minor_os_version, 576 m_update_os_version); 577 return false; 578 } 579 580 bool 581 PlatformDarwin::GetRemoteOSBuildString (std::string &s) 582 { 583 if (m_remote_platform_sp) 584 return m_remote_platform_sp->GetRemoteOSBuildString (s); 585 s.clear(); 586 return false; 587 } 588 589 bool 590 PlatformDarwin::GetRemoteOSKernelDescription (std::string &s) 591 { 592 if (m_remote_platform_sp) 593 return m_remote_platform_sp->GetRemoteOSKernelDescription (s); 594 s.clear(); 595 return false; 596 } 597 598 // Remote Platform subclasses need to override this function 599 ArchSpec 600 PlatformDarwin::GetRemoteSystemArchitecture () 601 { 602 if (m_remote_platform_sp) 603 return m_remote_platform_sp->GetRemoteSystemArchitecture (); 604 return ArchSpec(); 605 } 606 607 608 const char * 609 PlatformDarwin::GetHostname () 610 { 611 if (IsHost()) 612 return Platform::GetHostname(); 613 614 if (m_remote_platform_sp) 615 return m_remote_platform_sp->GetHostname (); 616 return NULL; 617 } 618 619 bool 620 PlatformDarwin::IsConnected () const 621 { 622 if (IsHost()) 623 return true; 624 else if (m_remote_platform_sp) 625 return m_remote_platform_sp->IsConnected(); 626 return false; 627 } 628 629 Error 630 PlatformDarwin::ConnectRemote (Args& args) 631 { 632 Error error; 633 if (IsHost()) 634 { 635 error.SetErrorStringWithFormat ("can't connect to the host platform '%s', always connected", GetPluginName().GetCString()); 636 } 637 else 638 { 639 if (!m_remote_platform_sp) 640 m_remote_platform_sp = Platform::Create ("remote-gdb-server", error); 641 642 if (m_remote_platform_sp && error.Success()) 643 error = m_remote_platform_sp->ConnectRemote (args); 644 else 645 error.SetErrorString ("failed to create a 'remote-gdb-server' platform"); 646 647 if (error.Fail()) 648 m_remote_platform_sp.reset(); 649 } 650 651 if (error.Success() && m_remote_platform_sp) 652 { 653 if (m_options.get()) 654 { 655 OptionGroupOptions* options = m_options.get(); 656 OptionGroupPlatformRSync* m_rsync_options = (OptionGroupPlatformRSync*)options->GetGroupWithOption('r'); 657 OptionGroupPlatformSSH* m_ssh_options = (OptionGroupPlatformSSH*)options->GetGroupWithOption('s'); 658 OptionGroupPlatformCaching* m_cache_options = (OptionGroupPlatformCaching*)options->GetGroupWithOption('c'); 659 660 if (m_rsync_options->m_rsync) 661 { 662 SetSupportsRSync(true); 663 SetRSyncOpts(m_rsync_options->m_rsync_opts.c_str()); 664 SetRSyncPrefix(m_rsync_options->m_rsync_prefix.c_str()); 665 SetIgnoresRemoteHostname(m_rsync_options->m_ignores_remote_hostname); 666 } 667 if (m_ssh_options->m_ssh) 668 { 669 SetSupportsSSH(true); 670 SetSSHOpts(m_ssh_options->m_ssh_opts.c_str()); 671 } 672 SetLocalCacheDirectory(m_cache_options->m_cache_dir.c_str()); 673 } 674 } 675 676 return error; 677 } 678 679 Error 680 PlatformDarwin::DisconnectRemote () 681 { 682 Error error; 683 684 if (IsHost()) 685 { 686 error.SetErrorStringWithFormat ("can't disconnect from the host platform '%s', always connected", GetPluginName().GetCString()); 687 } 688 else 689 { 690 if (m_remote_platform_sp) 691 error = m_remote_platform_sp->DisconnectRemote (); 692 else 693 error.SetErrorString ("the platform is not currently connected"); 694 } 695 return error; 696 } 697 698 699 bool 700 PlatformDarwin::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info) 701 { 702 bool sucess = false; 703 if (IsHost()) 704 { 705 sucess = Platform::GetProcessInfo (pid, process_info); 706 } 707 else 708 { 709 if (m_remote_platform_sp) 710 sucess = m_remote_platform_sp->GetProcessInfo (pid, process_info); 711 } 712 return sucess; 713 } 714 715 716 717 uint32_t 718 PlatformDarwin::FindProcesses (const ProcessInstanceInfoMatch &match_info, 719 ProcessInstanceInfoList &process_infos) 720 { 721 uint32_t match_count = 0; 722 if (IsHost()) 723 { 724 // Let the base class figure out the host details 725 match_count = Platform::FindProcesses (match_info, process_infos); 726 } 727 else 728 { 729 // If we are remote, we can only return results if we are connected 730 if (m_remote_platform_sp) 731 match_count = m_remote_platform_sp->FindProcesses (match_info, process_infos); 732 } 733 return match_count; 734 } 735 736 Error 737 PlatformDarwin::LaunchProcess (ProcessLaunchInfo &launch_info) 738 { 739 Error error; 740 741 if (IsHost()) 742 { 743 error = Platform::LaunchProcess (launch_info); 744 } 745 else 746 { 747 if (m_remote_platform_sp) 748 error = m_remote_platform_sp->LaunchProcess (launch_info); 749 else 750 error.SetErrorString ("the platform is not currently connected"); 751 } 752 return error; 753 } 754 755 lldb::ProcessSP 756 PlatformDarwin::DebugProcess (ProcessLaunchInfo &launch_info, 757 Debugger &debugger, 758 Target *target, // Can be NULL, if NULL create a new target, else use existing one 759 Listener &listener, 760 Error &error) 761 { 762 ProcessSP process_sp; 763 764 if (IsHost()) 765 { 766 process_sp = Platform::DebugProcess (launch_info, debugger, target, listener, error); 767 } 768 else 769 { 770 if (m_remote_platform_sp) 771 process_sp = m_remote_platform_sp->DebugProcess (launch_info, debugger, target, listener, error); 772 else 773 error.SetErrorString ("the platform is not currently connected"); 774 } 775 return process_sp; 776 777 } 778 779 780 lldb::ProcessSP 781 PlatformDarwin::Attach (ProcessAttachInfo &attach_info, 782 Debugger &debugger, 783 Target *target, 784 Listener &listener, 785 Error &error) 786 { 787 lldb::ProcessSP process_sp; 788 789 if (IsHost()) 790 { 791 if (target == NULL) 792 { 793 TargetSP new_target_sp; 794 795 error = debugger.GetTargetList().CreateTarget (debugger, 796 NULL, 797 NULL, 798 false, 799 NULL, 800 new_target_sp); 801 target = new_target_sp.get(); 802 } 803 else 804 error.Clear(); 805 806 if (target && error.Success()) 807 { 808 debugger.GetTargetList().SetSelectedTarget(target); 809 810 process_sp = target->CreateProcess (listener, attach_info.GetProcessPluginName(), NULL); 811 812 if (process_sp) 813 { 814 ListenerSP listener_sp (new Listener("lldb.PlatformDarwin.attach.hijack")); 815 attach_info.SetHijackListener(listener_sp); 816 process_sp->HijackProcessEvents(listener_sp.get()); 817 error = process_sp->Attach (attach_info); 818 } 819 } 820 } 821 else 822 { 823 if (m_remote_platform_sp) 824 process_sp = m_remote_platform_sp->Attach (attach_info, debugger, target, listener, error); 825 else 826 error.SetErrorString ("the platform is not currently connected"); 827 } 828 return process_sp; 829 } 830 831 const char * 832 PlatformDarwin::GetUserName (uint32_t uid) 833 { 834 // Check the cache in Platform in case we have already looked this uid up 835 const char *user_name = Platform::GetUserName(uid); 836 if (user_name) 837 return user_name; 838 839 if (IsRemote() && m_remote_platform_sp) 840 return m_remote_platform_sp->GetUserName(uid); 841 return NULL; 842 } 843 844 const char * 845 PlatformDarwin::GetGroupName (uint32_t gid) 846 { 847 const char *group_name = Platform::GetGroupName(gid); 848 if (group_name) 849 return group_name; 850 851 if (IsRemote() && m_remote_platform_sp) 852 return m_remote_platform_sp->GetGroupName(gid); 853 return NULL; 854 } 855 856 bool 857 PlatformDarwin::ModuleIsExcludedForNonModuleSpecificSearches (lldb_private::Target &target, const lldb::ModuleSP &module_sp) 858 { 859 if (!module_sp) 860 return false; 861 862 ObjectFile *obj_file = module_sp->GetObjectFile(); 863 if (!obj_file) 864 return false; 865 866 ObjectFile::Type obj_type = obj_file->GetType(); 867 if (obj_type == ObjectFile::eTypeDynamicLinker) 868 return true; 869 else 870 return false; 871 } 872 873 bool 874 PlatformDarwin::x86GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch) 875 { 876 ArchSpec host_arch = Host::GetArchitecture (Host::eSystemDefaultArchitecture); 877 if (host_arch.GetCore() == ArchSpec::eCore_x86_64_x86_64h) 878 { 879 switch (idx) 880 { 881 case 0: 882 arch = host_arch; 883 return true; 884 885 case 1: 886 arch.SetTriple("x86_64-apple-macosx"); 887 return true; 888 889 case 2: 890 arch = Host::GetArchitecture (Host::eSystemDefaultArchitecture32); 891 return true; 892 893 default: return false; 894 } 895 } 896 else 897 { 898 if (idx == 0) 899 { 900 arch = Host::GetArchitecture (Host::eSystemDefaultArchitecture); 901 return arch.IsValid(); 902 } 903 else if (idx == 1) 904 { 905 ArchSpec platform_arch (Host::GetArchitecture (Host::eSystemDefaultArchitecture)); 906 ArchSpec platform_arch64 (Host::GetArchitecture (Host::eSystemDefaultArchitecture64)); 907 if (platform_arch.IsExactMatch(platform_arch64)) 908 { 909 // This macosx platform supports both 32 and 64 bit. Since we already 910 // returned the 64 bit arch for idx == 0, return the 32 bit arch 911 // for idx == 1 912 arch = Host::GetArchitecture (Host::eSystemDefaultArchitecture32); 913 return arch.IsValid(); 914 } 915 } 916 } 917 return false; 918 } 919 920 // The architecture selection rules for arm processors 921 // These cpu subtypes have distinct names (e.g. armv7f) but armv7 binaries run fine on an armv7f processor. 922 923 bool 924 PlatformDarwin::ARMGetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch) 925 { 926 ArchSpec system_arch (GetSystemArchitecture()); 927 const ArchSpec::Core system_core = system_arch.GetCore(); 928 switch (system_core) 929 { 930 default: 931 switch (idx) 932 { 933 case 0: arch.SetTriple ("armv7-apple-ios"); return true; 934 case 1: arch.SetTriple ("armv7f-apple-ios"); return true; 935 case 2: arch.SetTriple ("armv7k-apple-ios"); return true; 936 case 3: arch.SetTriple ("armv7s-apple-ios"); return true; 937 case 4: arch.SetTriple ("armv7m-apple-ios"); return true; 938 case 5: arch.SetTriple ("armv7em-apple-ios"); return true; 939 case 6: arch.SetTriple ("armv6-apple-ios"); return true; 940 case 7: arch.SetTriple ("armv6m-apple-ios"); return true; 941 case 8: arch.SetTriple ("armv5-apple-ios"); return true; 942 case 9: arch.SetTriple ("armv4-apple-ios"); return true; 943 case 10: arch.SetTriple ("arm-apple-ios"); return true; 944 case 11: arch.SetTriple ("thumbv7-apple-ios"); return true; 945 case 12: arch.SetTriple ("thumbv7f-apple-ios"); return true; 946 case 13: arch.SetTriple ("thumbv7k-apple-ios"); return true; 947 case 14: arch.SetTriple ("thumbv7s-apple-ios"); return true; 948 case 15: arch.SetTriple ("thumbv7m-apple-ios"); return true; 949 case 16: arch.SetTriple ("thumbv7em-apple-ios"); return true; 950 case 17: arch.SetTriple ("thumbv6-apple-ios"); return true; 951 case 18: arch.SetTriple ("thumbv6m-apple-ios"); return true; 952 case 19: arch.SetTriple ("thumbv5-apple-ios"); return true; 953 case 20: arch.SetTriple ("thumbv4t-apple-ios"); return true; 954 case 21: arch.SetTriple ("thumb-apple-ios"); return true; 955 default: break; 956 } 957 break; 958 959 case ArchSpec::eCore_arm_armv7f: 960 switch (idx) 961 { 962 case 0: arch.SetTriple ("armv7f-apple-ios"); return true; 963 case 1: arch.SetTriple ("armv7-apple-ios"); return true; 964 case 2: arch.SetTriple ("armv6m-apple-ios"); return true; 965 case 3: arch.SetTriple ("armv6-apple-ios"); return true; 966 case 4: arch.SetTriple ("armv5-apple-ios"); return true; 967 case 5: arch.SetTriple ("armv4-apple-ios"); return true; 968 case 6: arch.SetTriple ("arm-apple-ios"); return true; 969 case 7: arch.SetTriple ("thumbv7f-apple-ios"); return true; 970 case 8: arch.SetTriple ("thumbv7-apple-ios"); return true; 971 case 9: arch.SetTriple ("thumbv6m-apple-ios"); return true; 972 case 10: arch.SetTriple ("thumbv6-apple-ios"); return true; 973 case 11: arch.SetTriple ("thumbv5-apple-ios"); return true; 974 case 12: arch.SetTriple ("thumbv4t-apple-ios"); return true; 975 case 13: arch.SetTriple ("thumb-apple-ios"); return true; 976 default: break; 977 } 978 break; 979 980 case ArchSpec::eCore_arm_armv7k: 981 switch (idx) 982 { 983 case 0: arch.SetTriple ("armv7k-apple-ios"); return true; 984 case 1: arch.SetTriple ("armv7-apple-ios"); return true; 985 case 2: arch.SetTriple ("armv6m-apple-ios"); return true; 986 case 3: arch.SetTriple ("armv6-apple-ios"); return true; 987 case 4: arch.SetTriple ("armv5-apple-ios"); return true; 988 case 5: arch.SetTriple ("armv4-apple-ios"); return true; 989 case 6: arch.SetTriple ("arm-apple-ios"); return true; 990 case 7: arch.SetTriple ("thumbv7k-apple-ios"); return true; 991 case 8: arch.SetTriple ("thumbv7-apple-ios"); return true; 992 case 9: arch.SetTriple ("thumbv6m-apple-ios"); return true; 993 case 10: arch.SetTriple ("thumbv6-apple-ios"); return true; 994 case 11: arch.SetTriple ("thumbv5-apple-ios"); return true; 995 case 12: arch.SetTriple ("thumbv4t-apple-ios"); return true; 996 case 13: arch.SetTriple ("thumb-apple-ios"); return true; 997 default: break; 998 } 999 break; 1000 1001 case ArchSpec::eCore_arm_armv7s: 1002 switch (idx) 1003 { 1004 case 0: arch.SetTriple ("armv7s-apple-ios"); return true; 1005 case 1: arch.SetTriple ("armv7-apple-ios"); return true; 1006 case 2: arch.SetTriple ("armv6m-apple-ios"); return true; 1007 case 3: arch.SetTriple ("armv6-apple-ios"); return true; 1008 case 4: arch.SetTriple ("armv5-apple-ios"); return true; 1009 case 5: arch.SetTriple ("armv4-apple-ios"); return true; 1010 case 6: arch.SetTriple ("arm-apple-ios"); return true; 1011 case 7: arch.SetTriple ("thumbv7s-apple-ios"); return true; 1012 case 8: arch.SetTriple ("thumbv7-apple-ios"); return true; 1013 case 9: arch.SetTriple ("thumbv6m-apple-ios"); return true; 1014 case 10: arch.SetTriple ("thumbv6-apple-ios"); return true; 1015 case 11: arch.SetTriple ("thumbv5-apple-ios"); return true; 1016 case 12: arch.SetTriple ("thumbv4t-apple-ios"); return true; 1017 case 13: arch.SetTriple ("thumb-apple-ios"); return true; 1018 default: break; 1019 } 1020 break; 1021 1022 case ArchSpec::eCore_arm_armv7m: 1023 switch (idx) 1024 { 1025 case 0: arch.SetTriple ("armv7m-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 ("thumbv7m-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_armv7em: 1044 switch (idx) 1045 { 1046 case 0: arch.SetTriple ("armv7em-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 ("thumbv7em-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_armv7: 1065 switch (idx) 1066 { 1067 case 0: arch.SetTriple ("armv7-apple-ios"); return true; 1068 case 1: arch.SetTriple ("armv6m-apple-ios"); return true; 1069 case 2: arch.SetTriple ("armv6-apple-ios"); return true; 1070 case 3: arch.SetTriple ("armv5-apple-ios"); return true; 1071 case 4: arch.SetTriple ("armv4-apple-ios"); return true; 1072 case 5: arch.SetTriple ("arm-apple-ios"); return true; 1073 case 6: arch.SetTriple ("thumbv7-apple-ios"); return true; 1074 case 7: arch.SetTriple ("thumbv6m-apple-ios"); return true; 1075 case 8: arch.SetTriple ("thumbv6-apple-ios"); return true; 1076 case 9: arch.SetTriple ("thumbv5-apple-ios"); return true; 1077 case 10: arch.SetTriple ("thumbv4t-apple-ios"); return true; 1078 case 11: arch.SetTriple ("thumb-apple-ios"); return true; 1079 default: break; 1080 } 1081 break; 1082 1083 case ArchSpec::eCore_arm_armv6m: 1084 switch (idx) 1085 { 1086 case 0: arch.SetTriple ("armv6m-apple-ios"); return true; 1087 case 1: arch.SetTriple ("armv6-apple-ios"); return true; 1088 case 2: arch.SetTriple ("armv5-apple-ios"); return true; 1089 case 3: arch.SetTriple ("armv4-apple-ios"); return true; 1090 case 4: arch.SetTriple ("arm-apple-ios"); return true; 1091 case 5: arch.SetTriple ("thumbv6m-apple-ios"); return true; 1092 case 6: arch.SetTriple ("thumbv6-apple-ios"); return true; 1093 case 7: arch.SetTriple ("thumbv5-apple-ios"); return true; 1094 case 8: arch.SetTriple ("thumbv4t-apple-ios"); return true; 1095 case 9: arch.SetTriple ("thumb-apple-ios"); return true; 1096 default: break; 1097 } 1098 break; 1099 1100 case ArchSpec::eCore_arm_armv6: 1101 switch (idx) 1102 { 1103 case 0: arch.SetTriple ("armv6-apple-ios"); return true; 1104 case 1: arch.SetTriple ("armv5-apple-ios"); return true; 1105 case 2: arch.SetTriple ("armv4-apple-ios"); return true; 1106 case 3: arch.SetTriple ("arm-apple-ios"); return true; 1107 case 4: arch.SetTriple ("thumbv6-apple-ios"); return true; 1108 case 5: arch.SetTriple ("thumbv5-apple-ios"); return true; 1109 case 6: arch.SetTriple ("thumbv4t-apple-ios"); return true; 1110 case 7: arch.SetTriple ("thumb-apple-ios"); return true; 1111 default: break; 1112 } 1113 break; 1114 1115 case ArchSpec::eCore_arm_armv5: 1116 switch (idx) 1117 { 1118 case 0: arch.SetTriple ("armv5-apple-ios"); return true; 1119 case 1: arch.SetTriple ("armv4-apple-ios"); return true; 1120 case 2: arch.SetTriple ("arm-apple-ios"); return true; 1121 case 3: arch.SetTriple ("thumbv5-apple-ios"); return true; 1122 case 4: arch.SetTriple ("thumbv4t-apple-ios"); return true; 1123 case 5: arch.SetTriple ("thumb-apple-ios"); return true; 1124 default: break; 1125 } 1126 break; 1127 1128 case ArchSpec::eCore_arm_armv4: 1129 switch (idx) 1130 { 1131 case 0: arch.SetTriple ("armv4-apple-ios"); return true; 1132 case 1: arch.SetTriple ("arm-apple-ios"); return true; 1133 case 2: arch.SetTriple ("thumbv4t-apple-ios"); return true; 1134 case 3: arch.SetTriple ("thumb-apple-ios"); return true; 1135 default: break; 1136 } 1137 break; 1138 } 1139 arch.Clear(); 1140 return false; 1141 } 1142 1143 1144 const char * 1145 PlatformDarwin::GetDeveloperDirectory() 1146 { 1147 if (m_developer_directory.empty()) 1148 { 1149 bool developer_dir_path_valid = false; 1150 char developer_dir_path[PATH_MAX]; 1151 FileSpec temp_file_spec; 1152 if (Host::GetLLDBPath (ePathTypeLLDBShlibDir, temp_file_spec)) 1153 { 1154 if (temp_file_spec.GetPath (developer_dir_path, sizeof(developer_dir_path))) 1155 { 1156 char *shared_frameworks = strstr (developer_dir_path, "/SharedFrameworks/LLDB.framework"); 1157 if (shared_frameworks) 1158 { 1159 ::snprintf (shared_frameworks, 1160 sizeof(developer_dir_path) - (shared_frameworks - developer_dir_path), 1161 "/Developer"); 1162 developer_dir_path_valid = true; 1163 } 1164 else 1165 { 1166 char *lib_priv_frameworks = strstr (developer_dir_path, "/Library/PrivateFrameworks/LLDB.framework"); 1167 if (lib_priv_frameworks) 1168 { 1169 *lib_priv_frameworks = '\0'; 1170 developer_dir_path_valid = true; 1171 } 1172 } 1173 } 1174 } 1175 1176 if (!developer_dir_path_valid) 1177 { 1178 std::string xcode_dir_path; 1179 const char *xcode_select_prefix_dir = getenv ("XCODE_SELECT_PREFIX_DIR"); 1180 if (xcode_select_prefix_dir) 1181 xcode_dir_path.append (xcode_select_prefix_dir); 1182 xcode_dir_path.append ("/usr/share/xcode-select/xcode_dir_path"); 1183 temp_file_spec.SetFile(xcode_dir_path.c_str(), false); 1184 size_t bytes_read = temp_file_spec.ReadFileContents(0, developer_dir_path, sizeof(developer_dir_path), NULL); 1185 if (bytes_read > 0) 1186 { 1187 developer_dir_path[bytes_read] = '\0'; 1188 while (developer_dir_path[bytes_read-1] == '\r' || 1189 developer_dir_path[bytes_read-1] == '\n') 1190 developer_dir_path[--bytes_read] = '\0'; 1191 developer_dir_path_valid = true; 1192 } 1193 } 1194 1195 if (!developer_dir_path_valid) 1196 { 1197 FileSpec xcode_select_cmd ("/usr/bin/xcode-select", false); 1198 if (xcode_select_cmd.Exists()) 1199 { 1200 int exit_status = -1; 1201 int signo = -1; 1202 std::string command_output; 1203 Error error = Host::RunShellCommand ("/usr/bin/xcode-select --print-path", 1204 NULL, // current working directory 1205 &exit_status, 1206 &signo, 1207 &command_output, 1208 2, // short timeout 1209 NULL); // don't run in a shell 1210 if (error.Success() && exit_status == 0 && !command_output.empty()) 1211 { 1212 const char *cmd_output_ptr = command_output.c_str(); 1213 developer_dir_path[sizeof (developer_dir_path) - 1] = '\0'; 1214 size_t i; 1215 for (i = 0; i < sizeof (developer_dir_path) - 1; i++) 1216 { 1217 if (cmd_output_ptr[i] == '\r' || cmd_output_ptr[i] == '\n' || cmd_output_ptr[i] == '\0') 1218 break; 1219 developer_dir_path[i] = cmd_output_ptr[i]; 1220 } 1221 developer_dir_path[i] = '\0'; 1222 1223 FileSpec devel_dir (developer_dir_path, false); 1224 if (devel_dir.Exists() && devel_dir.IsDirectory()) 1225 { 1226 developer_dir_path_valid = true; 1227 } 1228 } 1229 } 1230 } 1231 1232 if (developer_dir_path_valid) 1233 { 1234 temp_file_spec.SetFile (developer_dir_path, false); 1235 if (temp_file_spec.Exists()) 1236 { 1237 m_developer_directory.assign (developer_dir_path); 1238 return m_developer_directory.c_str(); 1239 } 1240 } 1241 // Assign a single NULL character so we know we tried to find the device 1242 // support directory and we don't keep trying to find it over and over. 1243 m_developer_directory.assign (1, '\0'); 1244 } 1245 1246 // We should have put a single NULL character into m_developer_directory 1247 // or it should have a valid path if the code gets here 1248 assert (m_developer_directory.empty() == false); 1249 if (m_developer_directory[0]) 1250 return m_developer_directory.c_str(); 1251 return NULL; 1252 } 1253 1254 1255 BreakpointSP 1256 PlatformDarwin::SetThreadCreationBreakpoint (Target &target) 1257 { 1258 BreakpointSP bp_sp; 1259 static const char *g_bp_names[] = 1260 { 1261 "start_wqthread", 1262 "_pthread_wqthread", 1263 "_pthread_start", 1264 }; 1265 1266 static const char *g_bp_modules[] = 1267 { 1268 "libsystem_c.dylib", 1269 "libSystem.B.dylib" 1270 }; 1271 1272 FileSpecList bp_modules; 1273 for (size_t i = 0; i < sizeof(g_bp_modules)/sizeof(const char *); i++) 1274 { 1275 const char *bp_module = g_bp_modules[i]; 1276 bp_modules.Append(FileSpec(bp_module, false)); 1277 } 1278 1279 bool internal = true; 1280 bool hardware = false; 1281 LazyBool skip_prologue = eLazyBoolNo; 1282 bp_sp = target.CreateBreakpoint (&bp_modules, 1283 NULL, 1284 g_bp_names, 1285 sizeof(g_bp_names)/sizeof(const char *), 1286 eFunctionNameTypeFull, 1287 skip_prologue, 1288 internal, 1289 hardware); 1290 bp_sp->SetBreakpointKind("thread-creation"); 1291 1292 return bp_sp; 1293 } 1294 1295 size_t 1296 PlatformDarwin::GetEnvironment (StringList &env) 1297 { 1298 if (IsRemote()) 1299 { 1300 if (m_remote_platform_sp) 1301 return m_remote_platform_sp->GetEnvironment(env); 1302 return 0; 1303 } 1304 return Host::GetEnvironment(env); 1305 } 1306 1307 int32_t 1308 PlatformDarwin::GetResumeCountForLaunchInfo (ProcessLaunchInfo &launch_info) 1309 { 1310 const char *shell = launch_info.GetShell(); 1311 if (shell == NULL) 1312 return 1; 1313 1314 const char *shell_name = strrchr (shell, '/'); 1315 if (shell_name == NULL) 1316 shell_name = shell; 1317 else 1318 shell_name++; 1319 1320 if (strcmp (shell_name, "sh") == 0) 1321 { 1322 // /bin/sh re-exec's itself as /bin/bash requiring another resume. 1323 // But it only does this if the COMMAND_MODE environment variable 1324 // is set to "legacy". 1325 char * const *envp = (char * const*)launch_info.GetEnvironmentEntries().GetConstArgumentVector(); 1326 if (envp != NULL) 1327 { 1328 for (int i = 0; envp[i] != NULL; i++) 1329 { 1330 if (strcmp (envp[i], "COMMAND_MODE=legacy" ) == 0) 1331 return 2; 1332 } 1333 } 1334 return 1; 1335 } 1336 else if (strcmp (shell_name, "csh") == 0 1337 || strcmp (shell_name, "tcsh") == 0 1338 || strcmp (shell_name, "zsh") == 0) 1339 { 1340 // csh and tcsh always seem to re-exec themselves. 1341 return 2; 1342 } 1343 else 1344 return 1; 1345 } 1346 1347 void 1348 PlatformDarwin::CalculateTrapHandlerSymbolNames () 1349 { 1350 m_trap_handlers.push_back (ConstString ("_sigtramp")); 1351 } 1352