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