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