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