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