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 "PlatformDarwin.h" 11 12 // C Includes 13 // C++ Includes 14 // Other libraries and framework includes 15 // Project includes 16 #include "lldb/Breakpoint/BreakpointLocation.h" 17 #include "lldb/Core/Debugger.h" 18 #include "lldb/Core/Error.h" 19 #include "lldb/Host/Host.h" 20 #include "lldb/Target/Target.h" 21 22 using namespace lldb; 23 using namespace lldb_private; 24 25 26 //------------------------------------------------------------------ 27 /// Default Constructor 28 //------------------------------------------------------------------ 29 PlatformDarwin::PlatformDarwin (bool is_host) : 30 Platform(is_host), // This is the local host platform 31 m_remote_platform_sp (), 32 m_developer_directory () 33 { 34 } 35 36 //------------------------------------------------------------------ 37 /// Destructor. 38 /// 39 /// The destructor is virtual since this class is designed to be 40 /// inherited from by the plug-in instance. 41 //------------------------------------------------------------------ 42 PlatformDarwin::~PlatformDarwin() 43 { 44 } 45 46 47 Error 48 PlatformDarwin::ResolveExecutable (const FileSpec &exe_file, 49 const ArchSpec &exe_arch, 50 lldb::ModuleSP &exe_module_sp, 51 const FileSpecList *module_search_paths_ptr) 52 { 53 Error error; 54 // Nothing special to do here, just use the actual file and architecture 55 56 char exe_path[PATH_MAX]; 57 FileSpec resolved_exe_file (exe_file); 58 59 if (IsHost()) 60 { 61 // If we have "ls" as the exe_file, resolve the executable loation based on 62 // the current path variables 63 if (!resolved_exe_file.Exists()) 64 { 65 exe_file.GetPath (exe_path, sizeof(exe_path)); 66 resolved_exe_file.SetFile(exe_path, true); 67 } 68 69 if (!resolved_exe_file.Exists()) 70 resolved_exe_file.ResolveExecutableLocation (); 71 72 // Resolve any executable within a bundle on MacOSX 73 Host::ResolveExecutableInBundle (resolved_exe_file); 74 75 if (resolved_exe_file.Exists()) 76 error.Clear(); 77 else 78 { 79 exe_file.GetPath (exe_path, sizeof(exe_path)); 80 error.SetErrorStringWithFormat ("unable to find executable for '%s'", exe_path); 81 } 82 } 83 else 84 { 85 if (m_remote_platform_sp) 86 { 87 error = m_remote_platform_sp->ResolveExecutable (exe_file, 88 exe_arch, 89 exe_module_sp, 90 module_search_paths_ptr); 91 } 92 else 93 { 94 // We may connect to a process and use the provided executable (Don't use local $PATH). 95 96 // Resolve any executable within a bundle on MacOSX 97 Host::ResolveExecutableInBundle (resolved_exe_file); 98 99 if (resolved_exe_file.Exists()) 100 error.Clear(); 101 else 102 error.SetErrorStringWithFormat("the platform is not currently connected, and '%s' doesn't exist in the system root.", resolved_exe_file.GetFilename().AsCString("")); 103 } 104 } 105 106 107 if (error.Success()) 108 { 109 ModuleSpec module_spec (resolved_exe_file, exe_arch); 110 if (module_spec.GetArchitecture().IsValid()) 111 { 112 error = ModuleList::GetSharedModule (module_spec, 113 exe_module_sp, 114 module_search_paths_ptr, 115 NULL, 116 NULL); 117 118 if (error.Fail() || exe_module_sp.get() == NULL || exe_module_sp->GetObjectFile() == NULL) 119 { 120 exe_module_sp.reset(); 121 error.SetErrorStringWithFormat ("'%s%s%s' doesn't contain the architecture %s", 122 exe_file.GetDirectory().AsCString(""), 123 exe_file.GetDirectory() ? "/" : "", 124 exe_file.GetFilename().AsCString(""), 125 exe_arch.GetArchitectureName()); 126 } 127 } 128 else 129 { 130 // No valid architecture was specified, ask the platform for 131 // the architectures that we should be using (in the correct order) 132 // and see if we can find a match that way 133 StreamString arch_names; 134 for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, module_spec.GetArchitecture()); ++idx) 135 { 136 error = ModuleList::GetSharedModule (module_spec, 137 exe_module_sp, 138 module_search_paths_ptr, 139 NULL, 140 NULL); 141 // Did we find an executable using one of the 142 if (error.Success()) 143 { 144 if (exe_module_sp && exe_module_sp->GetObjectFile()) 145 break; 146 else 147 error.SetErrorToGenericError(); 148 } 149 150 if (idx > 0) 151 arch_names.PutCString (", "); 152 arch_names.PutCString (module_spec.GetArchitecture().GetArchitectureName()); 153 } 154 155 if (error.Fail() || !exe_module_sp) 156 { 157 error.SetErrorStringWithFormat ("'%s%s%s' doesn't contain any '%s' platform architectures: %s", 158 exe_file.GetDirectory().AsCString(""), 159 exe_file.GetDirectory() ? "/" : "", 160 exe_file.GetFilename().AsCString(""), 161 GetShortPluginName(), 162 arch_names.GetString().c_str()); 163 } 164 } 165 } 166 167 return error; 168 } 169 170 171 172 Error 173 PlatformDarwin::GetSharedModule (const ModuleSpec &module_spec, 174 ModuleSP &module_sp, 175 const FileSpecList *module_search_paths_ptr, 176 ModuleSP *old_module_sp_ptr, 177 bool *did_create_ptr) 178 { 179 Error error; 180 module_sp.reset(); 181 182 if (IsRemote()) 183 { 184 // If we have a remote platform always, let it try and locate 185 // the shared module first. 186 if (m_remote_platform_sp) 187 { 188 error = m_remote_platform_sp->GetSharedModule (module_spec, 189 module_sp, 190 module_search_paths_ptr, 191 old_module_sp_ptr, 192 did_create_ptr); 193 } 194 } 195 196 if (!module_sp) 197 { 198 // Fall back to the local platform and find the file locally 199 error = Platform::GetSharedModule (module_spec, 200 module_sp, 201 module_search_paths_ptr, 202 old_module_sp_ptr, 203 did_create_ptr); 204 205 const FileSpec &platform_file = module_spec.GetFileSpec(); 206 if (!module_sp && module_search_paths_ptr && platform_file) 207 { 208 // We can try to pull off part of the file path up to the bundle 209 // directory level and try any module search paths... 210 FileSpec bundle_directory; 211 if (Host::GetBundleDirectory (platform_file, bundle_directory)) 212 { 213 char platform_path[PATH_MAX]; 214 char bundle_dir[PATH_MAX]; 215 platform_file.GetPath (platform_path, sizeof(platform_path)); 216 const size_t bundle_directory_len = bundle_directory.GetPath (bundle_dir, sizeof(bundle_dir)); 217 char new_path[PATH_MAX]; 218 size_t num_module_search_paths = module_search_paths_ptr->GetSize(); 219 for (size_t i=0; i<num_module_search_paths; ++i) 220 { 221 const size_t search_path_len = module_search_paths_ptr->GetFileSpecAtIndex(i).GetPath(new_path, sizeof(new_path)); 222 if (search_path_len < sizeof(new_path)) 223 { 224 snprintf (new_path + search_path_len, sizeof(new_path) - search_path_len, "/%s", platform_path + bundle_directory_len); 225 FileSpec new_file_spec (new_path, false); 226 if (new_file_spec.Exists()) 227 { 228 ModuleSpec new_module_spec (module_spec); 229 new_module_spec.GetFileSpec() = new_file_spec; 230 Error new_error (Platform::GetSharedModule (new_module_spec, 231 module_sp, 232 NULL, 233 old_module_sp_ptr, 234 did_create_ptr)); 235 236 if (module_sp) 237 { 238 module_sp->SetPlatformFileSpec(new_file_spec); 239 return new_error; 240 } 241 } 242 } 243 } 244 } 245 } 246 } 247 if (module_sp) 248 module_sp->SetPlatformFileSpec(module_spec.GetFileSpec()); 249 return error; 250 } 251 252 size_t 253 PlatformDarwin::GetSoftwareBreakpointTrapOpcode (Target &target, BreakpointSite *bp_site) 254 { 255 const uint8_t *trap_opcode = NULL; 256 uint32_t trap_opcode_size = 0; 257 bool bp_is_thumb = false; 258 259 llvm::Triple::ArchType machine = target.GetArchitecture().GetMachine(); 260 switch (machine) 261 { 262 case llvm::Triple::x86: 263 case llvm::Triple::x86_64: 264 { 265 static const uint8_t g_i386_breakpoint_opcode[] = { 0xCC }; 266 trap_opcode = g_i386_breakpoint_opcode; 267 trap_opcode_size = sizeof(g_i386_breakpoint_opcode); 268 } 269 break; 270 271 case llvm::Triple::thumb: 272 bp_is_thumb = true; // Fall through... 273 case llvm::Triple::arm: 274 { 275 static const uint8_t g_arm_breakpoint_opcode[] = { 0xFE, 0xDE, 0xFF, 0xE7 }; 276 static const uint8_t g_thumb_breakpooint_opcode[] = { 0xFE, 0xDE }; 277 278 // Auto detect arm/thumb if it wasn't explicitly specified 279 if (!bp_is_thumb) 280 { 281 lldb::BreakpointLocationSP bp_loc_sp (bp_site->GetOwnerAtIndex (0)); 282 if (bp_loc_sp) 283 bp_is_thumb = bp_loc_sp->GetAddress().GetAddressClass () == eAddressClassCodeAlternateISA; 284 } 285 if (bp_is_thumb) 286 { 287 trap_opcode = g_thumb_breakpooint_opcode; 288 trap_opcode_size = sizeof(g_thumb_breakpooint_opcode); 289 break; 290 } 291 trap_opcode = g_arm_breakpoint_opcode; 292 trap_opcode_size = sizeof(g_arm_breakpoint_opcode); 293 } 294 break; 295 296 case llvm::Triple::ppc: 297 case llvm::Triple::ppc64: 298 { 299 static const uint8_t g_ppc_breakpoint_opcode[] = { 0x7F, 0xC0, 0x00, 0x08 }; 300 trap_opcode = g_ppc_breakpoint_opcode; 301 trap_opcode_size = sizeof(g_ppc_breakpoint_opcode); 302 } 303 break; 304 305 default: 306 assert(!"Unhandled architecture in PlatformDarwin::GetSoftwareBreakpointTrapOpcode()"); 307 break; 308 } 309 310 if (trap_opcode && trap_opcode_size) 311 { 312 if (bp_site->SetTrapOpcode(trap_opcode, trap_opcode_size)) 313 return trap_opcode_size; 314 } 315 return 0; 316 317 } 318 319 bool 320 PlatformDarwin::GetRemoteOSVersion () 321 { 322 if (m_remote_platform_sp) 323 return m_remote_platform_sp->GetOSVersion (m_major_os_version, 324 m_minor_os_version, 325 m_update_os_version); 326 return false; 327 } 328 329 bool 330 PlatformDarwin::GetRemoteOSBuildString (std::string &s) 331 { 332 if (m_remote_platform_sp) 333 return m_remote_platform_sp->GetRemoteOSBuildString (s); 334 s.clear(); 335 return false; 336 } 337 338 bool 339 PlatformDarwin::GetRemoteOSKernelDescription (std::string &s) 340 { 341 if (m_remote_platform_sp) 342 return m_remote_platform_sp->GetRemoteOSKernelDescription (s); 343 s.clear(); 344 return false; 345 } 346 347 // Remote Platform subclasses need to override this function 348 ArchSpec 349 PlatformDarwin::GetRemoteSystemArchitecture () 350 { 351 if (m_remote_platform_sp) 352 return m_remote_platform_sp->GetRemoteSystemArchitecture (); 353 return ArchSpec(); 354 } 355 356 357 const char * 358 PlatformDarwin::GetHostname () 359 { 360 if (IsHost()) 361 return Platform::GetHostname(); 362 363 if (m_remote_platform_sp) 364 return m_remote_platform_sp->GetHostname (); 365 return NULL; 366 } 367 368 bool 369 PlatformDarwin::IsConnected () const 370 { 371 if (IsHost()) 372 return true; 373 else if (m_remote_platform_sp) 374 return m_remote_platform_sp->IsConnected(); 375 return false; 376 } 377 378 Error 379 PlatformDarwin::ConnectRemote (Args& args) 380 { 381 Error error; 382 if (IsHost()) 383 { 384 error.SetErrorStringWithFormat ("can't connect to the host platform '%s', always connected", GetShortPluginName()); 385 } 386 else 387 { 388 if (!m_remote_platform_sp) 389 m_remote_platform_sp = Platform::Create ("remote-gdb-server", error); 390 391 if (m_remote_platform_sp) 392 { 393 if (error.Success()) 394 { 395 if (m_remote_platform_sp) 396 { 397 error = m_remote_platform_sp->ConnectRemote (args); 398 } 399 else 400 { 401 error.SetErrorString ("\"platform connect\" takes a single argument: <connect-url>"); 402 } 403 } 404 } 405 else 406 error.SetErrorString ("failed to create a 'remote-gdb-server' platform"); 407 408 if (error.Fail()) 409 m_remote_platform_sp.reset(); 410 } 411 412 return error; 413 } 414 415 Error 416 PlatformDarwin::DisconnectRemote () 417 { 418 Error error; 419 420 if (IsHost()) 421 { 422 error.SetErrorStringWithFormat ("can't disconnect from the host platform '%s', always connected", GetShortPluginName()); 423 } 424 else 425 { 426 if (m_remote_platform_sp) 427 error = m_remote_platform_sp->DisconnectRemote (); 428 else 429 error.SetErrorString ("the platform is not currently connected"); 430 } 431 return error; 432 } 433 434 435 bool 436 PlatformDarwin::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info) 437 { 438 bool sucess = false; 439 if (IsHost()) 440 { 441 sucess = Platform::GetProcessInfo (pid, process_info); 442 } 443 else 444 { 445 if (m_remote_platform_sp) 446 sucess = m_remote_platform_sp->GetProcessInfo (pid, process_info); 447 } 448 return sucess; 449 } 450 451 452 453 uint32_t 454 PlatformDarwin::FindProcesses (const ProcessInstanceInfoMatch &match_info, 455 ProcessInstanceInfoList &process_infos) 456 { 457 uint32_t match_count = 0; 458 if (IsHost()) 459 { 460 // Let the base class figure out the host details 461 match_count = Platform::FindProcesses (match_info, process_infos); 462 } 463 else 464 { 465 // If we are remote, we can only return results if we are connected 466 if (m_remote_platform_sp) 467 match_count = m_remote_platform_sp->FindProcesses (match_info, process_infos); 468 } 469 return match_count; 470 } 471 472 Error 473 PlatformDarwin::LaunchProcess (ProcessLaunchInfo &launch_info) 474 { 475 Error error; 476 477 if (IsHost()) 478 { 479 error = Platform::LaunchProcess (launch_info); 480 } 481 else 482 { 483 if (m_remote_platform_sp) 484 error = m_remote_platform_sp->LaunchProcess (launch_info); 485 else 486 error.SetErrorString ("the platform is not currently connected"); 487 } 488 return error; 489 } 490 491 lldb::ProcessSP 492 PlatformDarwin::Attach (ProcessAttachInfo &attach_info, 493 Debugger &debugger, 494 Target *target, 495 Listener &listener, 496 Error &error) 497 { 498 lldb::ProcessSP process_sp; 499 500 if (IsHost()) 501 { 502 if (target == NULL) 503 { 504 TargetSP new_target_sp; 505 FileSpec emptyFileSpec; 506 507 error = debugger.GetTargetList().CreateTarget (debugger, 508 emptyFileSpec, 509 NULL, 510 false, 511 NULL, 512 new_target_sp); 513 target = new_target_sp.get(); 514 } 515 else 516 error.Clear(); 517 518 if (target && error.Success()) 519 { 520 debugger.GetTargetList().SetSelectedTarget(target); 521 522 process_sp = target->CreateProcess (listener, attach_info.GetProcessPluginName(), NULL); 523 524 if (process_sp) 525 error = process_sp->Attach (attach_info); 526 } 527 } 528 else 529 { 530 if (m_remote_platform_sp) 531 process_sp = m_remote_platform_sp->Attach (attach_info, debugger, target, listener, error); 532 else 533 error.SetErrorString ("the platform is not currently connected"); 534 } 535 return process_sp; 536 } 537 538 const char * 539 PlatformDarwin::GetUserName (uint32_t uid) 540 { 541 // Check the cache in Platform in case we have already looked this uid up 542 const char *user_name = Platform::GetUserName(uid); 543 if (user_name) 544 return user_name; 545 546 if (IsRemote() && m_remote_platform_sp) 547 return m_remote_platform_sp->GetUserName(uid); 548 return NULL; 549 } 550 551 const char * 552 PlatformDarwin::GetGroupName (uint32_t gid) 553 { 554 const char *group_name = Platform::GetGroupName(gid); 555 if (group_name) 556 return group_name; 557 558 if (IsRemote() && m_remote_platform_sp) 559 return m_remote_platform_sp->GetGroupName(gid); 560 return NULL; 561 } 562 563 bool 564 PlatformDarwin::ModuleIsExcludedForNonModuleSpecificSearches (lldb_private::Target &target, const lldb::ModuleSP &module_sp) 565 { 566 if (!module_sp) 567 return false; 568 569 ObjectFile *obj_file = module_sp->GetObjectFile(); 570 if (!obj_file) 571 return false; 572 573 ObjectFile::Type obj_type = obj_file->GetType(); 574 if (obj_type == ObjectFile::eTypeDynamicLinker) 575 return true; 576 else 577 return false; 578 } 579 580 581 bool 582 PlatformDarwin::x86GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch) 583 { 584 if (idx == 0) 585 { 586 arch = Host::GetArchitecture (Host::eSystemDefaultArchitecture); 587 return arch.IsValid(); 588 } 589 else if (idx == 1) 590 { 591 ArchSpec platform_arch (Host::GetArchitecture (Host::eSystemDefaultArchitecture)); 592 ArchSpec platform_arch64 (Host::GetArchitecture (Host::eSystemDefaultArchitecture64)); 593 if (platform_arch == platform_arch64) 594 { 595 // This macosx platform supports both 32 and 64 bit. Since we already 596 // returned the 64 bit arch for idx == 0, return the 32 bit arch 597 // for idx == 1 598 arch = Host::GetArchitecture (Host::eSystemDefaultArchitecture32); 599 return arch.IsValid(); 600 } 601 } 602 return false; 603 } 604 605 // The architecture selection rules for arm processors 606 // These cpu subtypes have distinct names (e.g. armv7f) but armv7 binaries run fine on an armv7f processor. 607 608 bool 609 PlatformDarwin::ARMGetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch) 610 { 611 ArchSpec system_arch (GetSystemArchitecture()); 612 const ArchSpec::Core system_core = system_arch.GetCore(); 613 switch (system_core) 614 { 615 default: 616 switch (idx) 617 { 618 case 0: arch.SetTriple ("armv7-apple-ios"); return true; 619 case 1: arch.SetTriple ("armv7f-apple-ios"); return true; 620 case 2: arch.SetTriple ("armv7k-apple-ios"); return true; 621 case 3: arch.SetTriple ("armv7s-apple-ios"); return true; 622 case 4: arch.SetTriple ("armv6-apple-ios"); return true; 623 case 5: arch.SetTriple ("armv5-apple-ios"); return true; 624 case 6: arch.SetTriple ("armv4-apple-ios"); return true; 625 case 7: arch.SetTriple ("arm-apple-ios"); return true; 626 case 8: arch.SetTriple ("thumbv7-apple-ios"); return true; 627 case 9: arch.SetTriple ("thumbv7f-apple-ios"); return true; 628 case 10: arch.SetTriple ("thumbv7k-apple-ios"); return true; 629 case 11: arch.SetTriple ("thumbv7s-apple-ios"); return true; 630 case 12: arch.SetTriple ("thumbv6-apple-ios"); return true; 631 case 13: arch.SetTriple ("thumbv5-apple-ios"); return true; 632 case 14: arch.SetTriple ("thumbv4t-apple-ios"); return true; 633 case 15: arch.SetTriple ("thumb-apple-ios"); return true; 634 default: break; 635 } 636 break; 637 638 case ArchSpec::eCore_arm_armv7f: 639 switch (idx) 640 { 641 case 0: arch.SetTriple ("armv7f-apple-ios"); return true; 642 case 1: arch.SetTriple ("armv7-apple-ios"); return true; 643 case 2: arch.SetTriple ("armv6-apple-ios"); return true; 644 case 3: arch.SetTriple ("armv5-apple-ios"); return true; 645 case 4: arch.SetTriple ("armv4-apple-ios"); return true; 646 case 5: arch.SetTriple ("arm-apple-ios"); return true; 647 case 6: arch.SetTriple ("thumbv7f-apple-ios"); return true; 648 case 7: arch.SetTriple ("thumbv7-apple-ios"); return true; 649 case 8: arch.SetTriple ("thumbv6-apple-ios"); return true; 650 case 9: arch.SetTriple ("thumbv5-apple-ios"); return true; 651 case 10: arch.SetTriple ("thumbv4t-apple-ios"); return true; 652 case 11: arch.SetTriple ("thumb-apple-ios"); return true; 653 default: break; 654 } 655 break; 656 657 case ArchSpec::eCore_arm_armv7k: 658 switch (idx) 659 { 660 case 0: arch.SetTriple ("armv7k-apple-ios"); return true; 661 case 1: arch.SetTriple ("armv7-apple-ios"); return true; 662 case 2: arch.SetTriple ("armv6-apple-ios"); return true; 663 case 3: arch.SetTriple ("armv5-apple-ios"); return true; 664 case 4: arch.SetTriple ("armv4-apple-ios"); return true; 665 case 5: arch.SetTriple ("arm-apple-ios"); return true; 666 case 6: arch.SetTriple ("thumbv7k-apple-ios"); return true; 667 case 7: arch.SetTriple ("thumbv7-apple-ios"); return true; 668 case 8: arch.SetTriple ("thumbv6-apple-ios"); return true; 669 case 9: arch.SetTriple ("thumbv5-apple-ios"); return true; 670 case 10: arch.SetTriple ("thumbv4t-apple-ios"); return true; 671 case 11: arch.SetTriple ("thumb-apple-ios"); return true; 672 default: break; 673 } 674 break; 675 676 case ArchSpec::eCore_arm_armv7s: 677 switch (idx) 678 { 679 case 0: arch.SetTriple ("armv7s-apple-ios"); return true; 680 case 1: arch.SetTriple ("armv7-apple-ios"); return true; 681 case 2: arch.SetTriple ("armv6-apple-ios"); return true; 682 case 3: arch.SetTriple ("armv5-apple-ios"); return true; 683 case 4: arch.SetTriple ("armv4-apple-ios"); return true; 684 case 5: arch.SetTriple ("arm-apple-ios"); return true; 685 case 6: arch.SetTriple ("thumbv7s-apple-ios"); return true; 686 case 7: arch.SetTriple ("thumbv7-apple-ios"); return true; 687 case 8: arch.SetTriple ("thumbv6-apple-ios"); return true; 688 case 9: arch.SetTriple ("thumbv5-apple-ios"); return true; 689 case 10: arch.SetTriple ("thumbv4t-apple-ios"); return true; 690 case 11: arch.SetTriple ("thumb-apple-ios"); return true; 691 default: break; 692 } 693 break; 694 695 case ArchSpec::eCore_arm_armv7: 696 switch (idx) 697 { 698 case 0: arch.SetTriple ("armv7-apple-ios"); return true; 699 case 1: arch.SetTriple ("armv6-apple-ios"); return true; 700 case 2: arch.SetTriple ("armv5-apple-ios"); return true; 701 case 3: arch.SetTriple ("armv4-apple-ios"); return true; 702 case 4: arch.SetTriple ("arm-apple-ios"); return true; 703 case 5: arch.SetTriple ("thumbv7-apple-ios"); return true; 704 case 6: arch.SetTriple ("thumbv6-apple-ios"); return true; 705 case 7: arch.SetTriple ("thumbv5-apple-ios"); return true; 706 case 8: arch.SetTriple ("thumbv4t-apple-ios"); return true; 707 case 9: arch.SetTriple ("thumb-apple-ios"); return true; 708 default: break; 709 } 710 break; 711 712 case ArchSpec::eCore_arm_armv6: 713 switch (idx) 714 { 715 case 0: arch.SetTriple ("armv6-apple-ios"); return true; 716 case 1: arch.SetTriple ("armv5-apple-ios"); return true; 717 case 2: arch.SetTriple ("armv4-apple-ios"); return true; 718 case 3: arch.SetTriple ("arm-apple-ios"); return true; 719 case 4: arch.SetTriple ("thumbv6-apple-ios"); return true; 720 case 5: arch.SetTriple ("thumbv5-apple-ios"); return true; 721 case 6: arch.SetTriple ("thumbv4t-apple-ios"); return true; 722 case 7: arch.SetTriple ("thumb-apple-ios"); return true; 723 default: break; 724 } 725 break; 726 727 case ArchSpec::eCore_arm_armv5: 728 switch (idx) 729 { 730 case 0: arch.SetTriple ("armv5-apple-ios"); return true; 731 case 1: arch.SetTriple ("armv4-apple-ios"); return true; 732 case 2: arch.SetTriple ("arm-apple-ios"); return true; 733 case 3: arch.SetTriple ("thumbv5-apple-ios"); return true; 734 case 4: arch.SetTriple ("thumbv4t-apple-ios"); return true; 735 case 5: arch.SetTriple ("thumb-apple-ios"); return true; 736 default: break; 737 } 738 break; 739 740 case ArchSpec::eCore_arm_armv4: 741 switch (idx) 742 { 743 case 0: arch.SetTriple ("armv4-apple-ios"); return true; 744 case 1: arch.SetTriple ("arm-apple-ios"); return true; 745 case 2: arch.SetTriple ("thumbv4t-apple-ios"); return true; 746 case 3: arch.SetTriple ("thumb-apple-ios"); return true; 747 default: break; 748 } 749 break; 750 } 751 arch.Clear(); 752 return false; 753 } 754 755 756 const char * 757 PlatformDarwin::GetDeveloperDirectory() 758 { 759 if (m_developer_directory.empty()) 760 { 761 bool developer_dir_path_valid = false; 762 char developer_dir_path[PATH_MAX]; 763 FileSpec temp_file_spec; 764 if (Host::GetLLDBPath (ePathTypeLLDBShlibDir, temp_file_spec)) 765 { 766 if (temp_file_spec.GetPath (developer_dir_path, sizeof(developer_dir_path))) 767 { 768 char *shared_frameworks = strstr (developer_dir_path, "/SharedFrameworks/LLDB.framework"); 769 if (shared_frameworks) 770 { 771 ::snprintf (shared_frameworks, 772 sizeof(developer_dir_path) - (shared_frameworks - developer_dir_path), 773 "/Developer"); 774 developer_dir_path_valid = true; 775 } 776 else 777 { 778 char *lib_priv_frameworks = strstr (developer_dir_path, "/Library/PrivateFrameworks/LLDB.framework"); 779 if (lib_priv_frameworks) 780 { 781 *lib_priv_frameworks = '\0'; 782 developer_dir_path_valid = true; 783 } 784 } 785 } 786 } 787 788 if (!developer_dir_path_valid) 789 { 790 std::string xcode_dir_path; 791 const char *xcode_select_prefix_dir = getenv ("XCODE_SELECT_PREFIX_DIR"); 792 if (xcode_select_prefix_dir) 793 xcode_dir_path.append (xcode_select_prefix_dir); 794 xcode_dir_path.append ("/usr/share/xcode-select/xcode_dir_path"); 795 temp_file_spec.SetFile(xcode_dir_path.c_str(), false); 796 size_t bytes_read = temp_file_spec.ReadFileContents(0, developer_dir_path, sizeof(developer_dir_path), NULL); 797 if (bytes_read > 0) 798 { 799 developer_dir_path[bytes_read] = '\0'; 800 while (developer_dir_path[bytes_read-1] == '\r' || 801 developer_dir_path[bytes_read-1] == '\n') 802 developer_dir_path[--bytes_read] = '\0'; 803 developer_dir_path_valid = true; 804 } 805 } 806 807 if (developer_dir_path_valid) 808 { 809 temp_file_spec.SetFile (developer_dir_path, false); 810 if (temp_file_spec.Exists()) 811 { 812 m_developer_directory.assign (developer_dir_path); 813 return m_developer_directory.c_str(); 814 } 815 } 816 // Assign a single NULL character so we know we tried to find the device 817 // support directory and we don't keep trying to find it over and over. 818 m_developer_directory.assign (1, '\0'); 819 } 820 821 // We should have put a single NULL character into m_developer_directory 822 // or it should have a valid path if the code gets here 823 assert (m_developer_directory.empty() == false); 824 if (m_developer_directory[0]) 825 return m_developer_directory.c_str(); 826 return NULL; 827 } 828 829 830 BreakpointSP 831 PlatformDarwin::SetThreadCreationBreakpoint (Target &target) 832 { 833 BreakpointSP bp_sp; 834 static const char *g_bp_names[] = 835 { 836 "start_wqthread", 837 "_pthread_wqthread", 838 "_pthread_start", 839 }; 840 841 static const char *g_bp_modules[] = 842 { 843 "libsystem_c.dylib", 844 "libSystem.B.dylib" 845 }; 846 847 FileSpecList bp_modules; 848 for (int i = 0; i < sizeof(g_bp_modules)/sizeof(const char *); i++) 849 { 850 const char *bp_module = g_bp_modules[i]; 851 bp_modules.Append(FileSpec(bp_module, false)); 852 } 853 854 bool internal = true; 855 LazyBool skip_prologue = eLazyBoolNo; 856 bp_sp = target.CreateBreakpoint (&bp_modules, 857 NULL, 858 g_bp_names, 859 sizeof(g_bp_names)/sizeof(const char *), 860 eFunctionNameTypeFull, 861 skip_prologue, 862 internal); 863 864 return bp_sp; 865 } 866 867