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