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/Module.h" 22 #include "lldb/Core/ModuleSpec.h" 23 #include "lldb/Core/Timer.h" 24 #include "lldb/Host/Host.h" 25 #include "lldb/Host/Symbols.h" 26 #include "lldb/Symbol/ObjectFile.h" 27 #include "lldb/Symbol/SymbolFile.h" 28 #include "lldb/Symbol/SymbolVendor.h" 29 #include "lldb/Target/Target.h" 30 31 using namespace lldb; 32 using namespace lldb_private; 33 34 35 //------------------------------------------------------------------ 36 /// Default Constructor 37 //------------------------------------------------------------------ 38 PlatformDarwin::PlatformDarwin (bool is_host) : 39 Platform(is_host), // This is the local host platform 40 m_remote_platform_sp (), 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 = ModuleList::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 272 273 Error 274 PlatformDarwin::GetSharedModule (const ModuleSpec &module_spec, 275 ModuleSP &module_sp, 276 const FileSpecList *module_search_paths_ptr, 277 ModuleSP *old_module_sp_ptr, 278 bool *did_create_ptr) 279 { 280 Error error; 281 module_sp.reset(); 282 283 if (IsRemote()) 284 { 285 // If we have a remote platform always, let it try and locate 286 // the shared module first. 287 if (m_remote_platform_sp) 288 { 289 error = m_remote_platform_sp->GetSharedModule (module_spec, 290 module_sp, 291 module_search_paths_ptr, 292 old_module_sp_ptr, 293 did_create_ptr); 294 } 295 } 296 297 if (!module_sp) 298 { 299 // Fall back to the local platform and find the file locally 300 error = Platform::GetSharedModule (module_spec, 301 module_sp, 302 module_search_paths_ptr, 303 old_module_sp_ptr, 304 did_create_ptr); 305 306 const FileSpec &platform_file = module_spec.GetFileSpec(); 307 if (!module_sp && module_search_paths_ptr && platform_file) 308 { 309 // We can try to pull off part of the file path up to the bundle 310 // directory level and try any module search paths... 311 FileSpec bundle_directory; 312 if (Host::GetBundleDirectory (platform_file, bundle_directory)) 313 { 314 if (platform_file == bundle_directory) 315 { 316 ModuleSpec new_module_spec (module_spec); 317 new_module_spec.GetFileSpec() = bundle_directory; 318 if (Host::ResolveExecutableInBundle (new_module_spec.GetFileSpec())) 319 { 320 Error new_error (Platform::GetSharedModule (new_module_spec, 321 module_sp, 322 NULL, 323 old_module_sp_ptr, 324 did_create_ptr)); 325 326 if (module_sp) 327 return new_error; 328 } 329 } 330 else 331 { 332 char platform_path[PATH_MAX]; 333 char bundle_dir[PATH_MAX]; 334 platform_file.GetPath (platform_path, sizeof(platform_path)); 335 const size_t bundle_directory_len = bundle_directory.GetPath (bundle_dir, sizeof(bundle_dir)); 336 char new_path[PATH_MAX]; 337 size_t num_module_search_paths = module_search_paths_ptr->GetSize(); 338 for (size_t i=0; i<num_module_search_paths; ++i) 339 { 340 const size_t search_path_len = module_search_paths_ptr->GetFileSpecAtIndex(i).GetPath(new_path, sizeof(new_path)); 341 if (search_path_len < sizeof(new_path)) 342 { 343 snprintf (new_path + search_path_len, sizeof(new_path) - search_path_len, "/%s", platform_path + bundle_directory_len); 344 FileSpec new_file_spec (new_path, false); 345 if (new_file_spec.Exists()) 346 { 347 ModuleSpec new_module_spec (module_spec); 348 new_module_spec.GetFileSpec() = new_file_spec; 349 Error new_error (Platform::GetSharedModule (new_module_spec, 350 module_sp, 351 NULL, 352 old_module_sp_ptr, 353 did_create_ptr)); 354 355 if (module_sp) 356 { 357 module_sp->SetPlatformFileSpec(new_file_spec); 358 return new_error; 359 } 360 } 361 } 362 } 363 } 364 } 365 } 366 } 367 if (module_sp) 368 module_sp->SetPlatformFileSpec(module_spec.GetFileSpec()); 369 return error; 370 } 371 372 size_t 373 PlatformDarwin::GetSoftwareBreakpointTrapOpcode (Target &target, BreakpointSite *bp_site) 374 { 375 const uint8_t *trap_opcode = NULL; 376 uint32_t trap_opcode_size = 0; 377 bool bp_is_thumb = false; 378 379 llvm::Triple::ArchType machine = target.GetArchitecture().GetMachine(); 380 switch (machine) 381 { 382 case llvm::Triple::x86: 383 case llvm::Triple::x86_64: 384 { 385 static const uint8_t g_i386_breakpoint_opcode[] = { 0xCC }; 386 trap_opcode = g_i386_breakpoint_opcode; 387 trap_opcode_size = sizeof(g_i386_breakpoint_opcode); 388 } 389 break; 390 391 case llvm::Triple::thumb: 392 bp_is_thumb = true; // Fall through... 393 case llvm::Triple::arm: 394 { 395 static const uint8_t g_arm_breakpoint_opcode[] = { 0xFE, 0xDE, 0xFF, 0xE7 }; 396 static const uint8_t g_thumb_breakpooint_opcode[] = { 0xFE, 0xDE }; 397 398 // Auto detect arm/thumb if it wasn't explicitly specified 399 if (!bp_is_thumb) 400 { 401 lldb::BreakpointLocationSP bp_loc_sp (bp_site->GetOwnerAtIndex (0)); 402 if (bp_loc_sp) 403 bp_is_thumb = bp_loc_sp->GetAddress().GetAddressClass () == eAddressClassCodeAlternateISA; 404 } 405 if (bp_is_thumb) 406 { 407 trap_opcode = g_thumb_breakpooint_opcode; 408 trap_opcode_size = sizeof(g_thumb_breakpooint_opcode); 409 break; 410 } 411 trap_opcode = g_arm_breakpoint_opcode; 412 trap_opcode_size = sizeof(g_arm_breakpoint_opcode); 413 } 414 break; 415 416 case llvm::Triple::ppc: 417 case llvm::Triple::ppc64: 418 { 419 static const uint8_t g_ppc_breakpoint_opcode[] = { 0x7F, 0xC0, 0x00, 0x08 }; 420 trap_opcode = g_ppc_breakpoint_opcode; 421 trap_opcode_size = sizeof(g_ppc_breakpoint_opcode); 422 } 423 break; 424 425 default: 426 assert(!"Unhandled architecture in PlatformDarwin::GetSoftwareBreakpointTrapOpcode()"); 427 break; 428 } 429 430 if (trap_opcode && trap_opcode_size) 431 { 432 if (bp_site->SetTrapOpcode(trap_opcode, trap_opcode_size)) 433 return trap_opcode_size; 434 } 435 return 0; 436 437 } 438 439 bool 440 PlatformDarwin::GetRemoteOSVersion () 441 { 442 if (m_remote_platform_sp) 443 return m_remote_platform_sp->GetOSVersion (m_major_os_version, 444 m_minor_os_version, 445 m_update_os_version); 446 return false; 447 } 448 449 bool 450 PlatformDarwin::GetRemoteOSBuildString (std::string &s) 451 { 452 if (m_remote_platform_sp) 453 return m_remote_platform_sp->GetRemoteOSBuildString (s); 454 s.clear(); 455 return false; 456 } 457 458 bool 459 PlatformDarwin::GetRemoteOSKernelDescription (std::string &s) 460 { 461 if (m_remote_platform_sp) 462 return m_remote_platform_sp->GetRemoteOSKernelDescription (s); 463 s.clear(); 464 return false; 465 } 466 467 // Remote Platform subclasses need to override this function 468 ArchSpec 469 PlatformDarwin::GetRemoteSystemArchitecture () 470 { 471 if (m_remote_platform_sp) 472 return m_remote_platform_sp->GetRemoteSystemArchitecture (); 473 return ArchSpec(); 474 } 475 476 477 const char * 478 PlatformDarwin::GetHostname () 479 { 480 if (IsHost()) 481 return Platform::GetHostname(); 482 483 if (m_remote_platform_sp) 484 return m_remote_platform_sp->GetHostname (); 485 return NULL; 486 } 487 488 bool 489 PlatformDarwin::IsConnected () const 490 { 491 if (IsHost()) 492 return true; 493 else if (m_remote_platform_sp) 494 return m_remote_platform_sp->IsConnected(); 495 return false; 496 } 497 498 Error 499 PlatformDarwin::ConnectRemote (Args& args) 500 { 501 Error error; 502 if (IsHost()) 503 { 504 error.SetErrorStringWithFormat ("can't connect to the host platform '%s', always connected", GetPluginName().GetCString()); 505 } 506 else 507 { 508 if (!m_remote_platform_sp) 509 m_remote_platform_sp = Platform::Create ("remote-gdb-server", error); 510 511 if (m_remote_platform_sp) 512 { 513 if (error.Success()) 514 { 515 if (m_remote_platform_sp) 516 { 517 error = m_remote_platform_sp->ConnectRemote (args); 518 } 519 else 520 { 521 error.SetErrorString ("\"platform connect\" takes a single argument: <connect-url>"); 522 } 523 } 524 } 525 else 526 error.SetErrorString ("failed to create a 'remote-gdb-server' platform"); 527 528 if (error.Fail()) 529 m_remote_platform_sp.reset(); 530 } 531 532 return error; 533 } 534 535 Error 536 PlatformDarwin::DisconnectRemote () 537 { 538 Error error; 539 540 if (IsHost()) 541 { 542 error.SetErrorStringWithFormat ("can't disconnect from the host platform '%s', always connected", GetPluginName().GetCString()); 543 } 544 else 545 { 546 if (m_remote_platform_sp) 547 error = m_remote_platform_sp->DisconnectRemote (); 548 else 549 error.SetErrorString ("the platform is not currently connected"); 550 } 551 return error; 552 } 553 554 555 bool 556 PlatformDarwin::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info) 557 { 558 bool sucess = false; 559 if (IsHost()) 560 { 561 sucess = Platform::GetProcessInfo (pid, process_info); 562 } 563 else 564 { 565 if (m_remote_platform_sp) 566 sucess = m_remote_platform_sp->GetProcessInfo (pid, process_info); 567 } 568 return sucess; 569 } 570 571 572 573 uint32_t 574 PlatformDarwin::FindProcesses (const ProcessInstanceInfoMatch &match_info, 575 ProcessInstanceInfoList &process_infos) 576 { 577 uint32_t match_count = 0; 578 if (IsHost()) 579 { 580 // Let the base class figure out the host details 581 match_count = Platform::FindProcesses (match_info, process_infos); 582 } 583 else 584 { 585 // If we are remote, we can only return results if we are connected 586 if (m_remote_platform_sp) 587 match_count = m_remote_platform_sp->FindProcesses (match_info, process_infos); 588 } 589 return match_count; 590 } 591 592 Error 593 PlatformDarwin::LaunchProcess (ProcessLaunchInfo &launch_info) 594 { 595 Error error; 596 597 if (IsHost()) 598 { 599 error = Platform::LaunchProcess (launch_info); 600 } 601 else 602 { 603 if (m_remote_platform_sp) 604 error = m_remote_platform_sp->LaunchProcess (launch_info); 605 else 606 error.SetErrorString ("the platform is not currently connected"); 607 } 608 return error; 609 } 610 611 lldb::ProcessSP 612 PlatformDarwin::Attach (ProcessAttachInfo &attach_info, 613 Debugger &debugger, 614 Target *target, 615 Listener &listener, 616 Error &error) 617 { 618 lldb::ProcessSP process_sp; 619 620 if (IsHost()) 621 { 622 if (target == NULL) 623 { 624 TargetSP new_target_sp; 625 626 error = debugger.GetTargetList().CreateTarget (debugger, 627 NULL, 628 NULL, 629 false, 630 NULL, 631 new_target_sp); 632 target = new_target_sp.get(); 633 } 634 else 635 error.Clear(); 636 637 if (target && error.Success()) 638 { 639 debugger.GetTargetList().SetSelectedTarget(target); 640 641 process_sp = target->CreateProcess (listener, attach_info.GetProcessPluginName(), NULL); 642 643 if (process_sp) 644 error = process_sp->Attach (attach_info); 645 } 646 } 647 else 648 { 649 if (m_remote_platform_sp) 650 process_sp = m_remote_platform_sp->Attach (attach_info, debugger, target, listener, error); 651 else 652 error.SetErrorString ("the platform is not currently connected"); 653 } 654 return process_sp; 655 } 656 657 const char * 658 PlatformDarwin::GetUserName (uint32_t uid) 659 { 660 // Check the cache in Platform in case we have already looked this uid up 661 const char *user_name = Platform::GetUserName(uid); 662 if (user_name) 663 return user_name; 664 665 if (IsRemote() && m_remote_platform_sp) 666 return m_remote_platform_sp->GetUserName(uid); 667 return NULL; 668 } 669 670 const char * 671 PlatformDarwin::GetGroupName (uint32_t gid) 672 { 673 const char *group_name = Platform::GetGroupName(gid); 674 if (group_name) 675 return group_name; 676 677 if (IsRemote() && m_remote_platform_sp) 678 return m_remote_platform_sp->GetGroupName(gid); 679 return NULL; 680 } 681 682 bool 683 PlatformDarwin::ModuleIsExcludedForNonModuleSpecificSearches (lldb_private::Target &target, const lldb::ModuleSP &module_sp) 684 { 685 if (!module_sp) 686 return false; 687 688 ObjectFile *obj_file = module_sp->GetObjectFile(); 689 if (!obj_file) 690 return false; 691 692 ObjectFile::Type obj_type = obj_file->GetType(); 693 if (obj_type == ObjectFile::eTypeDynamicLinker) 694 return true; 695 else 696 return false; 697 } 698 699 700 bool 701 PlatformDarwin::x86GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch) 702 { 703 if (idx == 0) 704 { 705 arch = Host::GetArchitecture (Host::eSystemDefaultArchitecture); 706 return arch.IsValid(); 707 } 708 else if (idx == 1) 709 { 710 ArchSpec platform_arch (Host::GetArchitecture (Host::eSystemDefaultArchitecture)); 711 ArchSpec platform_arch64 (Host::GetArchitecture (Host::eSystemDefaultArchitecture64)); 712 if (platform_arch.IsExactMatch(platform_arch64)) 713 { 714 // This macosx platform supports both 32 and 64 bit. Since we already 715 // returned the 64 bit arch for idx == 0, return the 32 bit arch 716 // for idx == 1 717 arch = Host::GetArchitecture (Host::eSystemDefaultArchitecture32); 718 return arch.IsValid(); 719 } 720 } 721 return false; 722 } 723 724 // The architecture selection rules for arm processors 725 // These cpu subtypes have distinct names (e.g. armv7f) but armv7 binaries run fine on an armv7f processor. 726 727 bool 728 PlatformDarwin::ARMGetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch) 729 { 730 ArchSpec system_arch (GetSystemArchitecture()); 731 const ArchSpec::Core system_core = system_arch.GetCore(); 732 switch (system_core) 733 { 734 default: 735 switch (idx) 736 { 737 case 0: arch.SetTriple ("armv7-apple-ios"); return true; 738 case 1: arch.SetTriple ("armv7f-apple-ios"); return true; 739 case 2: arch.SetTriple ("armv7k-apple-ios"); return true; 740 case 3: arch.SetTriple ("armv7s-apple-ios"); return true; 741 case 4: arch.SetTriple ("armv7m-apple-ios"); return true; 742 case 5: arch.SetTriple ("armv7em-apple-ios"); return true; 743 case 6: arch.SetTriple ("armv6-apple-ios"); return true; 744 case 7: arch.SetTriple ("armv5-apple-ios"); return true; 745 case 8: arch.SetTriple ("armv4-apple-ios"); return true; 746 case 9: arch.SetTriple ("arm-apple-ios"); return true; 747 case 10: arch.SetTriple ("thumbv7-apple-ios"); return true; 748 case 11: arch.SetTriple ("thumbv7f-apple-ios"); return true; 749 case 12: arch.SetTriple ("thumbv7k-apple-ios"); return true; 750 case 13: arch.SetTriple ("thumbv7s-apple-ios"); return true; 751 case 14: arch.SetTriple ("thumbv7m-apple-ios"); return true; 752 case 15: arch.SetTriple ("thumbv7em-apple-ios"); return true; 753 case 16: arch.SetTriple ("thumbv6-apple-ios"); return true; 754 case 17: arch.SetTriple ("thumbv5-apple-ios"); return true; 755 case 18: arch.SetTriple ("thumbv4t-apple-ios"); return true; 756 case 19: arch.SetTriple ("thumb-apple-ios"); return true; 757 default: break; 758 } 759 break; 760 761 case ArchSpec::eCore_arm_armv7f: 762 switch (idx) 763 { 764 case 0: arch.SetTriple ("armv7f-apple-ios"); return true; 765 case 1: arch.SetTriple ("armv7-apple-ios"); return true; 766 case 2: arch.SetTriple ("armv6-apple-ios"); return true; 767 case 3: arch.SetTriple ("armv5-apple-ios"); return true; 768 case 4: arch.SetTriple ("armv4-apple-ios"); return true; 769 case 5: arch.SetTriple ("arm-apple-ios"); return true; 770 case 6: arch.SetTriple ("thumbv7f-apple-ios"); return true; 771 case 7: arch.SetTriple ("thumbv7-apple-ios"); return true; 772 case 8: arch.SetTriple ("thumbv6-apple-ios"); return true; 773 case 9: arch.SetTriple ("thumbv5-apple-ios"); return true; 774 case 10: arch.SetTriple ("thumbv4t-apple-ios"); return true; 775 case 11: arch.SetTriple ("thumb-apple-ios"); return true; 776 default: break; 777 } 778 break; 779 780 case ArchSpec::eCore_arm_armv7k: 781 switch (idx) 782 { 783 case 0: arch.SetTriple ("armv7k-apple-ios"); return true; 784 case 1: arch.SetTriple ("armv7-apple-ios"); return true; 785 case 2: arch.SetTriple ("armv6-apple-ios"); return true; 786 case 3: arch.SetTriple ("armv5-apple-ios"); return true; 787 case 4: arch.SetTriple ("armv4-apple-ios"); return true; 788 case 5: arch.SetTriple ("arm-apple-ios"); return true; 789 case 6: arch.SetTriple ("thumbv7k-apple-ios"); return true; 790 case 7: arch.SetTriple ("thumbv7-apple-ios"); return true; 791 case 8: arch.SetTriple ("thumbv6-apple-ios"); return true; 792 case 9: arch.SetTriple ("thumbv5-apple-ios"); return true; 793 case 10: arch.SetTriple ("thumbv4t-apple-ios"); return true; 794 case 11: arch.SetTriple ("thumb-apple-ios"); return true; 795 default: break; 796 } 797 break; 798 799 case ArchSpec::eCore_arm_armv7s: 800 switch (idx) 801 { 802 case 0: arch.SetTriple ("armv7s-apple-ios"); return true; 803 case 1: arch.SetTriple ("armv7-apple-ios"); return true; 804 case 2: arch.SetTriple ("armv6-apple-ios"); return true; 805 case 3: arch.SetTriple ("armv5-apple-ios"); return true; 806 case 4: arch.SetTriple ("armv4-apple-ios"); return true; 807 case 5: arch.SetTriple ("arm-apple-ios"); return true; 808 case 6: arch.SetTriple ("thumbv7s-apple-ios"); return true; 809 case 7: arch.SetTriple ("thumbv7-apple-ios"); return true; 810 case 8: arch.SetTriple ("thumbv6-apple-ios"); return true; 811 case 9: arch.SetTriple ("thumbv5-apple-ios"); return true; 812 case 10: arch.SetTriple ("thumbv4t-apple-ios"); return true; 813 case 11: arch.SetTriple ("thumb-apple-ios"); return true; 814 default: break; 815 } 816 break; 817 818 case ArchSpec::eCore_arm_armv7m: 819 switch (idx) 820 { 821 case 0: arch.SetTriple ("armv7m-apple-ios"); return true; 822 case 1: arch.SetTriple ("armv7-apple-ios"); return true; 823 case 2: arch.SetTriple ("armv6-apple-ios"); return true; 824 case 3: arch.SetTriple ("armv5-apple-ios"); return true; 825 case 4: arch.SetTriple ("armv4-apple-ios"); return true; 826 case 5: arch.SetTriple ("arm-apple-ios"); return true; 827 case 6: arch.SetTriple ("thumbv7m-apple-ios"); return true; 828 case 7: arch.SetTriple ("thumbv7-apple-ios"); return true; 829 case 8: arch.SetTriple ("thumbv6-apple-ios"); return true; 830 case 9: arch.SetTriple ("thumbv5-apple-ios"); return true; 831 case 10: arch.SetTriple ("thumbv4t-apple-ios"); return true; 832 case 11: arch.SetTriple ("thumb-apple-ios"); return true; 833 default: break; 834 } 835 break; 836 837 case ArchSpec::eCore_arm_armv7em: 838 switch (idx) 839 { 840 case 0: arch.SetTriple ("armv7em-apple-ios"); return true; 841 case 1: arch.SetTriple ("armv7-apple-ios"); return true; 842 case 2: arch.SetTriple ("armv6-apple-ios"); return true; 843 case 3: arch.SetTriple ("armv5-apple-ios"); return true; 844 case 4: arch.SetTriple ("armv4-apple-ios"); return true; 845 case 5: arch.SetTriple ("arm-apple-ios"); return true; 846 case 6: arch.SetTriple ("thumbv7em-apple-ios"); return true; 847 case 7: arch.SetTriple ("thumbv7-apple-ios"); return true; 848 case 8: arch.SetTriple ("thumbv6-apple-ios"); return true; 849 case 9: arch.SetTriple ("thumbv5-apple-ios"); return true; 850 case 10: arch.SetTriple ("thumbv4t-apple-ios"); return true; 851 case 11: arch.SetTriple ("thumb-apple-ios"); return true; 852 default: break; 853 } 854 break; 855 856 case ArchSpec::eCore_arm_armv7: 857 switch (idx) 858 { 859 case 0: arch.SetTriple ("armv7-apple-ios"); return true; 860 case 1: arch.SetTriple ("armv6-apple-ios"); return true; 861 case 2: arch.SetTriple ("armv5-apple-ios"); return true; 862 case 3: arch.SetTriple ("armv4-apple-ios"); return true; 863 case 4: arch.SetTriple ("arm-apple-ios"); return true; 864 case 5: arch.SetTriple ("thumbv7-apple-ios"); return true; 865 case 6: arch.SetTriple ("thumbv6-apple-ios"); return true; 866 case 7: arch.SetTriple ("thumbv5-apple-ios"); return true; 867 case 8: arch.SetTriple ("thumbv4t-apple-ios"); return true; 868 case 9: arch.SetTriple ("thumb-apple-ios"); return true; 869 default: break; 870 } 871 break; 872 873 case ArchSpec::eCore_arm_armv6: 874 switch (idx) 875 { 876 case 0: arch.SetTriple ("armv6-apple-ios"); return true; 877 case 1: arch.SetTriple ("armv5-apple-ios"); return true; 878 case 2: arch.SetTriple ("armv4-apple-ios"); return true; 879 case 3: arch.SetTriple ("arm-apple-ios"); return true; 880 case 4: arch.SetTriple ("thumbv6-apple-ios"); return true; 881 case 5: arch.SetTriple ("thumbv5-apple-ios"); return true; 882 case 6: arch.SetTriple ("thumbv4t-apple-ios"); return true; 883 case 7: arch.SetTriple ("thumb-apple-ios"); return true; 884 default: break; 885 } 886 break; 887 888 case ArchSpec::eCore_arm_armv5: 889 switch (idx) 890 { 891 case 0: arch.SetTriple ("armv5-apple-ios"); return true; 892 case 1: arch.SetTriple ("armv4-apple-ios"); return true; 893 case 2: arch.SetTriple ("arm-apple-ios"); return true; 894 case 3: arch.SetTriple ("thumbv5-apple-ios"); return true; 895 case 4: arch.SetTriple ("thumbv4t-apple-ios"); return true; 896 case 5: arch.SetTriple ("thumb-apple-ios"); return true; 897 default: break; 898 } 899 break; 900 901 case ArchSpec::eCore_arm_armv4: 902 switch (idx) 903 { 904 case 0: arch.SetTriple ("armv4-apple-ios"); return true; 905 case 1: arch.SetTriple ("arm-apple-ios"); return true; 906 case 2: arch.SetTriple ("thumbv4t-apple-ios"); return true; 907 case 3: arch.SetTriple ("thumb-apple-ios"); return true; 908 default: break; 909 } 910 break; 911 } 912 arch.Clear(); 913 return false; 914 } 915 916 917 const char * 918 PlatformDarwin::GetDeveloperDirectory() 919 { 920 if (m_developer_directory.empty()) 921 { 922 bool developer_dir_path_valid = false; 923 char developer_dir_path[PATH_MAX]; 924 FileSpec temp_file_spec; 925 if (Host::GetLLDBPath (ePathTypeLLDBShlibDir, temp_file_spec)) 926 { 927 if (temp_file_spec.GetPath (developer_dir_path, sizeof(developer_dir_path))) 928 { 929 char *shared_frameworks = strstr (developer_dir_path, "/SharedFrameworks/LLDB.framework"); 930 if (shared_frameworks) 931 { 932 ::snprintf (shared_frameworks, 933 sizeof(developer_dir_path) - (shared_frameworks - developer_dir_path), 934 "/Developer"); 935 developer_dir_path_valid = true; 936 } 937 else 938 { 939 char *lib_priv_frameworks = strstr (developer_dir_path, "/Library/PrivateFrameworks/LLDB.framework"); 940 if (lib_priv_frameworks) 941 { 942 *lib_priv_frameworks = '\0'; 943 developer_dir_path_valid = true; 944 } 945 } 946 } 947 } 948 949 if (!developer_dir_path_valid) 950 { 951 std::string xcode_dir_path; 952 const char *xcode_select_prefix_dir = getenv ("XCODE_SELECT_PREFIX_DIR"); 953 if (xcode_select_prefix_dir) 954 xcode_dir_path.append (xcode_select_prefix_dir); 955 xcode_dir_path.append ("/usr/share/xcode-select/xcode_dir_path"); 956 temp_file_spec.SetFile(xcode_dir_path.c_str(), false); 957 size_t bytes_read = temp_file_spec.ReadFileContents(0, developer_dir_path, sizeof(developer_dir_path), NULL); 958 if (bytes_read > 0) 959 { 960 developer_dir_path[bytes_read] = '\0'; 961 while (developer_dir_path[bytes_read-1] == '\r' || 962 developer_dir_path[bytes_read-1] == '\n') 963 developer_dir_path[--bytes_read] = '\0'; 964 developer_dir_path_valid = true; 965 } 966 } 967 968 if (!developer_dir_path_valid) 969 { 970 FileSpec xcode_select_cmd ("/usr/bin/xcode-select", false); 971 if (xcode_select_cmd.Exists()) 972 { 973 int exit_status = -1; 974 int signo = -1; 975 std::string command_output; 976 Error error = Host::RunShellCommand ("/usr/bin/xcode-select --print-path", 977 NULL, // current working directory 978 &exit_status, 979 &signo, 980 &command_output, 981 2, // short timeout 982 NULL); // don't run in a shell 983 if (error.Success() && exit_status == 0 && !command_output.empty()) 984 { 985 const char *cmd_output_ptr = command_output.c_str(); 986 developer_dir_path[sizeof (developer_dir_path) - 1] = '\0'; 987 size_t i; 988 for (i = 0; i < sizeof (developer_dir_path) - 1; i++) 989 { 990 if (cmd_output_ptr[i] == '\r' || cmd_output_ptr[i] == '\n' || cmd_output_ptr[i] == '\0') 991 break; 992 developer_dir_path[i] = cmd_output_ptr[i]; 993 } 994 developer_dir_path[i] = '\0'; 995 996 FileSpec devel_dir (developer_dir_path, false); 997 if (devel_dir.Exists() && devel_dir.IsDirectory()) 998 { 999 developer_dir_path_valid = true; 1000 } 1001 } 1002 } 1003 } 1004 1005 if (developer_dir_path_valid) 1006 { 1007 temp_file_spec.SetFile (developer_dir_path, false); 1008 if (temp_file_spec.Exists()) 1009 { 1010 m_developer_directory.assign (developer_dir_path); 1011 return m_developer_directory.c_str(); 1012 } 1013 } 1014 // Assign a single NULL character so we know we tried to find the device 1015 // support directory and we don't keep trying to find it over and over. 1016 m_developer_directory.assign (1, '\0'); 1017 } 1018 1019 // We should have put a single NULL character into m_developer_directory 1020 // or it should have a valid path if the code gets here 1021 assert (m_developer_directory.empty() == false); 1022 if (m_developer_directory[0]) 1023 return m_developer_directory.c_str(); 1024 return NULL; 1025 } 1026 1027 1028 BreakpointSP 1029 PlatformDarwin::SetThreadCreationBreakpoint (Target &target) 1030 { 1031 BreakpointSP bp_sp; 1032 static const char *g_bp_names[] = 1033 { 1034 "start_wqthread", 1035 "_pthread_wqthread", 1036 "_pthread_start", 1037 }; 1038 1039 static const char *g_bp_modules[] = 1040 { 1041 "libsystem_c.dylib", 1042 "libSystem.B.dylib" 1043 }; 1044 1045 FileSpecList bp_modules; 1046 for (size_t i = 0; i < sizeof(g_bp_modules)/sizeof(const char *); i++) 1047 { 1048 const char *bp_module = g_bp_modules[i]; 1049 bp_modules.Append(FileSpec(bp_module, false)); 1050 } 1051 1052 bool internal = true; 1053 LazyBool skip_prologue = eLazyBoolNo; 1054 bp_sp = target.CreateBreakpoint (&bp_modules, 1055 NULL, 1056 g_bp_names, 1057 sizeof(g_bp_names)/sizeof(const char *), 1058 eFunctionNameTypeFull, 1059 skip_prologue, 1060 internal); 1061 bp_sp->SetBreakpointKind("thread-creation"); 1062 1063 return bp_sp; 1064 } 1065 1066 size_t 1067 PlatformDarwin::GetEnvironment (StringList &env) 1068 { 1069 if (IsRemote()) 1070 { 1071 if (m_remote_platform_sp) 1072 return m_remote_platform_sp->GetEnvironment(env); 1073 return 0; 1074 } 1075 return Host::GetEnvironment(env); 1076 } 1077