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