1 //===-- PlatformDarwin.cpp ------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "PlatformDarwin.h" 10 11 #include <cstring> 12 13 #include <algorithm> 14 #include <memory> 15 #include <mutex> 16 17 #include "lldb/Breakpoint/BreakpointLocation.h" 18 #include "lldb/Breakpoint/BreakpointSite.h" 19 #include "lldb/Core/Debugger.h" 20 #include "lldb/Core/Module.h" 21 #include "lldb/Core/ModuleSpec.h" 22 #include "lldb/Core/Section.h" 23 #include "lldb/Host/Host.h" 24 #include "lldb/Host/HostInfo.h" 25 #include "lldb/Host/XML.h" 26 #include "lldb/Interpreter/CommandInterpreter.h" 27 #include "lldb/Symbol/LocateSymbolFile.h" 28 #include "lldb/Symbol/ObjectFile.h" 29 #include "lldb/Symbol/SymbolFile.h" 30 #include "lldb/Symbol/SymbolVendor.h" 31 #include "lldb/Target/Platform.h" 32 #include "lldb/Target/Process.h" 33 #include "lldb/Target/Target.h" 34 #include "lldb/Utility/LLDBLog.h" 35 #include "lldb/Utility/Log.h" 36 #include "lldb/Utility/ProcessInfo.h" 37 #include "lldb/Utility/Status.h" 38 #include "lldb/Utility/Timer.h" 39 #include "llvm/ADT/STLExtras.h" 40 #include "llvm/Support/FileSystem.h" 41 #include "llvm/Support/Threading.h" 42 #include "llvm/Support/VersionTuple.h" 43 44 #if defined(__APPLE__) 45 #include <TargetConditionals.h> 46 #endif 47 48 using namespace lldb; 49 using namespace lldb_private; 50 51 /// Destructor. 52 /// 53 /// The destructor is virtual since this class is designed to be 54 /// inherited from by the plug-in instance. 55 PlatformDarwin::~PlatformDarwin() = default; 56 57 lldb_private::Status 58 PlatformDarwin::PutFile(const lldb_private::FileSpec &source, 59 const lldb_private::FileSpec &destination, uint32_t uid, 60 uint32_t gid) { 61 // Unconditionally unlink the destination. If it is an executable, 62 // simply opening it and truncating its contents would invalidate 63 // its cached code signature. 64 Unlink(destination); 65 return PlatformPOSIX::PutFile(source, destination, uid, gid); 66 } 67 68 FileSpecList PlatformDarwin::LocateExecutableScriptingResources( 69 Target *target, Module &module, Stream *feedback_stream) { 70 FileSpecList file_list; 71 if (target && 72 target->GetDebugger().GetScriptLanguage() == eScriptLanguagePython) { 73 // NB some extensions might be meaningful and should not be stripped - 74 // "this.binary.file" 75 // should not lose ".file" but GetFileNameStrippingExtension() will do 76 // precisely that. Ideally, we should have a per-platform list of 77 // extensions (".exe", ".app", ".dSYM", ".framework") which should be 78 // stripped while leaving "this.binary.file" as-is. 79 80 FileSpec module_spec = module.GetFileSpec(); 81 82 if (module_spec) { 83 if (SymbolFile *symfile = module.GetSymbolFile()) { 84 ObjectFile *objfile = symfile->GetObjectFile(); 85 if (objfile) { 86 FileSpec symfile_spec(objfile->GetFileSpec()); 87 if (symfile_spec && 88 llvm::StringRef(symfile_spec.GetPath()) 89 .contains_insensitive(".dSYM/Contents/Resources/DWARF") && 90 FileSystem::Instance().Exists(symfile_spec)) { 91 while (module_spec.GetFilename()) { 92 std::string module_basename( 93 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 99 // module 100 // filenames we import. Theoretically, different scripting 101 // languages may have different sets of forbidden tokens in 102 // filenames, and that should be dealt with by each 103 // ScriptInterpreter. For now, we just replace dots with 104 // underscores, but if we ever support anything other than 105 // Python we will need to rework this 106 std::replace(module_basename.begin(), module_basename.end(), '.', 107 '_'); 108 std::replace(module_basename.begin(), module_basename.end(), ' ', 109 '_'); 110 std::replace(module_basename.begin(), module_basename.end(), '-', 111 '_'); 112 ScriptInterpreter *script_interpreter = 113 target->GetDebugger().GetScriptInterpreter(); 114 if (script_interpreter && 115 script_interpreter->IsReservedWord(module_basename.c_str())) { 116 module_basename.insert(module_basename.begin(), '_'); 117 was_keyword = true; 118 } 119 120 StreamString path_string; 121 StreamString original_path_string; 122 // for OSX we are going to be in 123 // .dSYM/Contents/Resources/DWARF/<basename> let us go to 124 // .dSYM/Contents/Resources/Python/<basename>.py and see if the 125 // file exists 126 path_string.Printf("%s/../Python/%s.py", 127 symfile_spec.GetDirectory().GetCString(), 128 module_basename.c_str()); 129 original_path_string.Printf( 130 "%s/../Python/%s.py", 131 symfile_spec.GetDirectory().GetCString(), 132 original_module_basename.c_str()); 133 FileSpec script_fspec(path_string.GetString()); 134 FileSystem::Instance().Resolve(script_fspec); 135 FileSpec orig_script_fspec(original_path_string.GetString()); 136 FileSystem::Instance().Resolve(orig_script_fspec); 137 138 // if we did some replacements of reserved characters, and a 139 // file with the untampered name exists, then warn the user 140 // that the file as-is shall not be loaded 141 if (feedback_stream) { 142 if (module_basename != original_module_basename && 143 FileSystem::Instance().Exists(orig_script_fspec)) { 144 const char *reason_for_complaint = 145 was_keyword ? "conflicts with a keyword" 146 : "contains reserved characters"; 147 if (FileSystem::Instance().Exists(script_fspec)) 148 feedback_stream->Printf( 149 "warning: the symbol file '%s' contains a debug " 150 "script. However, its name" 151 " '%s' %s and as such cannot be loaded. LLDB will" 152 " load '%s' instead. Consider removing the file with " 153 "the malformed name to" 154 " eliminate this warning.\n", 155 symfile_spec.GetPath().c_str(), 156 original_path_string.GetData(), reason_for_complaint, 157 path_string.GetData()); 158 else 159 feedback_stream->Printf( 160 "warning: the symbol file '%s' contains a debug " 161 "script. However, its name" 162 " %s and as such cannot be loaded. If you intend" 163 " to have this script loaded, please rename '%s' to " 164 "'%s' and retry.\n", 165 symfile_spec.GetPath().c_str(), reason_for_complaint, 166 original_path_string.GetData(), path_string.GetData()); 167 } 168 } 169 170 if (FileSystem::Instance().Exists(script_fspec)) { 171 file_list.Append(script_fspec); 172 break; 173 } 174 175 // If we didn't find the python file, then keep stripping the 176 // extensions and try again 177 ConstString filename_no_extension( 178 module_spec.GetFileNameStrippingExtension()); 179 if (module_spec.GetFilename() == filename_no_extension) 180 break; 181 182 module_spec.GetFilename() = filename_no_extension; 183 } 184 } 185 } 186 } 187 } 188 } 189 return file_list; 190 } 191 192 Status PlatformDarwin::ResolveSymbolFile(Target &target, 193 const ModuleSpec &sym_spec, 194 FileSpec &sym_file) { 195 sym_file = sym_spec.GetSymbolFileSpec(); 196 if (FileSystem::Instance().IsDirectory(sym_file)) { 197 sym_file = Symbols::FindSymbolFileInBundle(sym_file, sym_spec.GetUUIDPtr(), 198 sym_spec.GetArchitecturePtr()); 199 } 200 return {}; 201 } 202 203 Status PlatformDarwin::GetSharedModule( 204 const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp, 205 const FileSpecList *module_search_paths_ptr, 206 llvm::SmallVectorImpl<ModuleSP> *old_modules, bool *did_create_ptr) { 207 Status error; 208 module_sp.reset(); 209 210 if (IsRemote()) { 211 // If we have a remote platform always, let it try and locate the shared 212 // module first. 213 if (m_remote_platform_sp) { 214 error = m_remote_platform_sp->GetSharedModule( 215 module_spec, process, module_sp, module_search_paths_ptr, old_modules, 216 did_create_ptr); 217 } 218 } 219 220 if (!module_sp) { 221 // Fall back to the local platform and find the file locally 222 error = Platform::GetSharedModule(module_spec, process, module_sp, 223 module_search_paths_ptr, old_modules, 224 did_create_ptr); 225 226 const FileSpec &platform_file = module_spec.GetFileSpec(); 227 if (!module_sp && module_search_paths_ptr && platform_file) { 228 // We can try to pull off part of the file path up to the bundle 229 // directory level and try any module search paths... 230 FileSpec bundle_directory; 231 if (Host::GetBundleDirectory(platform_file, bundle_directory)) { 232 if (platform_file == bundle_directory) { 233 ModuleSpec new_module_spec(module_spec); 234 new_module_spec.GetFileSpec() = bundle_directory; 235 if (Host::ResolveExecutableInBundle(new_module_spec.GetFileSpec())) { 236 Status new_error(Platform::GetSharedModule( 237 new_module_spec, process, module_sp, nullptr, old_modules, 238 did_create_ptr)); 239 240 if (module_sp) 241 return new_error; 242 } 243 } else { 244 char platform_path[PATH_MAX]; 245 char bundle_dir[PATH_MAX]; 246 platform_file.GetPath(platform_path, sizeof(platform_path)); 247 const size_t bundle_directory_len = 248 bundle_directory.GetPath(bundle_dir, sizeof(bundle_dir)); 249 char new_path[PATH_MAX]; 250 size_t num_module_search_paths = module_search_paths_ptr->GetSize(); 251 for (size_t i = 0; i < num_module_search_paths; ++i) { 252 const size_t search_path_len = 253 module_search_paths_ptr->GetFileSpecAtIndex(i).GetPath( 254 new_path, sizeof(new_path)); 255 if (search_path_len < sizeof(new_path)) { 256 snprintf(new_path + search_path_len, 257 sizeof(new_path) - search_path_len, "/%s", 258 platform_path + bundle_directory_len); 259 FileSpec new_file_spec(new_path); 260 if (FileSystem::Instance().Exists(new_file_spec)) { 261 ModuleSpec new_module_spec(module_spec); 262 new_module_spec.GetFileSpec() = new_file_spec; 263 Status new_error(Platform::GetSharedModule( 264 new_module_spec, process, module_sp, nullptr, old_modules, 265 did_create_ptr)); 266 267 if (module_sp) { 268 module_sp->SetPlatformFileSpec(new_file_spec); 269 return new_error; 270 } 271 } 272 } 273 } 274 } 275 } 276 } 277 } 278 if (module_sp) 279 module_sp->SetPlatformFileSpec(module_spec.GetFileSpec()); 280 return error; 281 } 282 283 size_t 284 PlatformDarwin::GetSoftwareBreakpointTrapOpcode(Target &target, 285 BreakpointSite *bp_site) { 286 const uint8_t *trap_opcode = nullptr; 287 uint32_t trap_opcode_size = 0; 288 bool bp_is_thumb = false; 289 290 llvm::Triple::ArchType machine = target.GetArchitecture().GetMachine(); 291 switch (machine) { 292 case llvm::Triple::aarch64_32: 293 case llvm::Triple::aarch64: { 294 // 'brk #0' or 0xd4200000 in BE byte order 295 static const uint8_t g_arm64_breakpoint_opcode[] = {0x00, 0x00, 0x20, 0xD4}; 296 trap_opcode = g_arm64_breakpoint_opcode; 297 trap_opcode_size = sizeof(g_arm64_breakpoint_opcode); 298 } break; 299 300 case llvm::Triple::thumb: 301 bp_is_thumb = true; 302 LLVM_FALLTHROUGH; 303 case llvm::Triple::arm: { 304 static const uint8_t g_arm_breakpoint_opcode[] = {0xFE, 0xDE, 0xFF, 0xE7}; 305 static const uint8_t g_thumb_breakpooint_opcode[] = {0xFE, 0xDE}; 306 307 // Auto detect arm/thumb if it wasn't explicitly specified 308 if (!bp_is_thumb) { 309 lldb::BreakpointLocationSP bp_loc_sp(bp_site->GetOwnerAtIndex(0)); 310 if (bp_loc_sp) 311 bp_is_thumb = bp_loc_sp->GetAddress().GetAddressClass() == 312 AddressClass::eCodeAlternateISA; 313 } 314 if (bp_is_thumb) { 315 trap_opcode = g_thumb_breakpooint_opcode; 316 trap_opcode_size = sizeof(g_thumb_breakpooint_opcode); 317 break; 318 } 319 trap_opcode = g_arm_breakpoint_opcode; 320 trap_opcode_size = sizeof(g_arm_breakpoint_opcode); 321 } break; 322 323 case llvm::Triple::ppc: 324 case llvm::Triple::ppc64: { 325 static const uint8_t g_ppc_breakpoint_opcode[] = {0x7F, 0xC0, 0x00, 0x08}; 326 trap_opcode = g_ppc_breakpoint_opcode; 327 trap_opcode_size = sizeof(g_ppc_breakpoint_opcode); 328 } break; 329 330 default: 331 return Platform::GetSoftwareBreakpointTrapOpcode(target, bp_site); 332 } 333 334 if (trap_opcode && trap_opcode_size) { 335 if (bp_site->SetTrapOpcode(trap_opcode, trap_opcode_size)) 336 return trap_opcode_size; 337 } 338 return 0; 339 } 340 341 bool PlatformDarwin::ModuleIsExcludedForUnconstrainedSearches( 342 lldb_private::Target &target, const lldb::ModuleSP &module_sp) { 343 if (!module_sp) 344 return false; 345 346 ObjectFile *obj_file = module_sp->GetObjectFile(); 347 if (!obj_file) 348 return false; 349 350 ObjectFile::Type obj_type = obj_file->GetType(); 351 return obj_type == ObjectFile::eTypeDynamicLinker; 352 } 353 354 void PlatformDarwin::x86GetSupportedArchitectures( 355 std::vector<ArchSpec> &archs) { 356 ArchSpec host_arch = HostInfo::GetArchitecture(HostInfo::eArchKindDefault); 357 archs.push_back(host_arch); 358 359 if (host_arch.GetCore() == ArchSpec::eCore_x86_64_x86_64h) { 360 archs.push_back(ArchSpec("x86_64-apple-macosx")); 361 archs.push_back(HostInfo::GetArchitecture(HostInfo::eArchKind32)); 362 } else { 363 ArchSpec host_arch64 = HostInfo::GetArchitecture(HostInfo::eArchKind64); 364 if (host_arch.IsExactMatch(host_arch64)) 365 archs.push_back(HostInfo::GetArchitecture(HostInfo::eArchKind32)); 366 } 367 } 368 369 static llvm::ArrayRef<const char *> GetCompatibleArchs(ArchSpec::Core core) { 370 switch (core) { 371 default: 372 LLVM_FALLTHROUGH; 373 case ArchSpec::eCore_arm_arm64e: { 374 static const char *g_arm64e_compatible_archs[] = { 375 "arm64e", "arm64", "armv7", "armv7f", "armv7k", "armv7s", 376 "armv7m", "armv7em", "armv6m", "armv6", "armv5", "armv4", 377 "arm", "thumbv7", "thumbv7f", "thumbv7k", "thumbv7s", "thumbv7m", 378 "thumbv7em", "thumbv6m", "thumbv6", "thumbv5", "thumbv4t", "thumb", 379 }; 380 return {g_arm64e_compatible_archs}; 381 } 382 case ArchSpec::eCore_arm_arm64: { 383 static const char *g_arm64_compatible_archs[] = { 384 "arm64", "armv7", "armv7f", "armv7k", "armv7s", "armv7m", 385 "armv7em", "armv6m", "armv6", "armv5", "armv4", "arm", 386 "thumbv7", "thumbv7f", "thumbv7k", "thumbv7s", "thumbv7m", "thumbv7em", 387 "thumbv6m", "thumbv6", "thumbv5", "thumbv4t", "thumb", 388 }; 389 return {g_arm64_compatible_archs}; 390 } 391 case ArchSpec::eCore_arm_armv7: { 392 static const char *g_armv7_compatible_archs[] = { 393 "armv7", "armv6m", "armv6", "armv5", "armv4", "arm", 394 "thumbv7", "thumbv6m", "thumbv6", "thumbv5", "thumbv4t", "thumb", 395 }; 396 return {g_armv7_compatible_archs}; 397 } 398 case ArchSpec::eCore_arm_armv7f: { 399 static const char *g_armv7f_compatible_archs[] = { 400 "armv7f", "armv7", "armv6m", "armv6", "armv5", 401 "armv4", "arm", "thumbv7f", "thumbv7", "thumbv6m", 402 "thumbv6", "thumbv5", "thumbv4t", "thumb", 403 }; 404 return {g_armv7f_compatible_archs}; 405 } 406 case ArchSpec::eCore_arm_armv7k: { 407 static const char *g_armv7k_compatible_archs[] = { 408 "armv7k", "armv7", "armv6m", "armv6", "armv5", 409 "armv4", "arm", "thumbv7k", "thumbv7", "thumbv6m", 410 "thumbv6", "thumbv5", "thumbv4t", "thumb", 411 }; 412 return {g_armv7k_compatible_archs}; 413 } 414 case ArchSpec::eCore_arm_armv7s: { 415 static const char *g_armv7s_compatible_archs[] = { 416 "armv7s", "armv7", "armv6m", "armv6", "armv5", 417 "armv4", "arm", "thumbv7s", "thumbv7", "thumbv6m", 418 "thumbv6", "thumbv5", "thumbv4t", "thumb", 419 }; 420 return {g_armv7s_compatible_archs}; 421 } 422 case ArchSpec::eCore_arm_armv7m: { 423 static const char *g_armv7m_compatible_archs[] = { 424 "armv7m", "armv7", "armv6m", "armv6", "armv5", 425 "armv4", "arm", "thumbv7m", "thumbv7", "thumbv6m", 426 "thumbv6", "thumbv5", "thumbv4t", "thumb", 427 }; 428 return {g_armv7m_compatible_archs}; 429 } 430 case ArchSpec::eCore_arm_armv7em: { 431 static const char *g_armv7em_compatible_archs[] = { 432 "armv7em", "armv7", "armv6m", "armv6", "armv5", 433 "armv4", "arm", "thumbv7em", "thumbv7", "thumbv6m", 434 "thumbv6", "thumbv5", "thumbv4t", "thumb", 435 }; 436 return {g_armv7em_compatible_archs}; 437 } 438 case ArchSpec::eCore_arm_armv6m: { 439 static const char *g_armv6m_compatible_archs[] = { 440 "armv6m", "armv6", "armv5", "armv4", "arm", 441 "thumbv6m", "thumbv6", "thumbv5", "thumbv4t", "thumb", 442 }; 443 return {g_armv6m_compatible_archs}; 444 } 445 case ArchSpec::eCore_arm_armv6: { 446 static const char *g_armv6_compatible_archs[] = { 447 "armv6", "armv5", "armv4", "arm", 448 "thumbv6", "thumbv5", "thumbv4t", "thumb", 449 }; 450 return {g_armv6_compatible_archs}; 451 } 452 case ArchSpec::eCore_arm_armv5: { 453 static const char *g_armv5_compatible_archs[] = { 454 "armv5", "armv4", "arm", "thumbv5", "thumbv4t", "thumb", 455 }; 456 return {g_armv5_compatible_archs}; 457 } 458 case ArchSpec::eCore_arm_armv4: { 459 static const char *g_armv4_compatible_archs[] = { 460 "armv4", 461 "arm", 462 "thumbv4t", 463 "thumb", 464 }; 465 return {g_armv4_compatible_archs}; 466 } 467 } 468 return {}; 469 } 470 471 /// The architecture selection rules for arm processors These cpu subtypes have 472 /// distinct names (e.g. armv7f) but armv7 binaries run fine on an armv7f 473 /// processor. 474 void PlatformDarwin::ARMGetSupportedArchitectures( 475 std::vector<ArchSpec> &archs, llvm::Optional<llvm::Triple::OSType> os) { 476 const ArchSpec system_arch = GetSystemArchitecture(); 477 const ArchSpec::Core system_core = system_arch.GetCore(); 478 for (const char *arch : GetCompatibleArchs(system_core)) { 479 llvm::Triple triple; 480 triple.setArchName(arch); 481 triple.setVendor(llvm::Triple::VendorType::Apple); 482 if (os) 483 triple.setOS(*os); 484 archs.push_back(ArchSpec(triple)); 485 } 486 } 487 488 static FileSpec GetXcodeSelectPath() { 489 static FileSpec g_xcode_select_filespec; 490 491 if (!g_xcode_select_filespec) { 492 FileSpec xcode_select_cmd("/usr/bin/xcode-select"); 493 if (FileSystem::Instance().Exists(xcode_select_cmd)) { 494 int exit_status = -1; 495 int signo = -1; 496 std::string command_output; 497 Status status = 498 Host::RunShellCommand("/usr/bin/xcode-select --print-path", 499 FileSpec(), // current working directory 500 &exit_status, &signo, &command_output, 501 std::chrono::seconds(2), // short timeout 502 false); // don't run in a shell 503 if (status.Success() && exit_status == 0 && !command_output.empty()) { 504 size_t first_non_newline = command_output.find_last_not_of("\r\n"); 505 if (first_non_newline != std::string::npos) { 506 command_output.erase(first_non_newline + 1); 507 } 508 g_xcode_select_filespec = FileSpec(command_output); 509 } 510 } 511 } 512 513 return g_xcode_select_filespec; 514 } 515 516 BreakpointSP PlatformDarwin::SetThreadCreationBreakpoint(Target &target) { 517 BreakpointSP bp_sp; 518 static const char *g_bp_names[] = { 519 "start_wqthread", "_pthread_wqthread", "_pthread_start", 520 }; 521 522 static const char *g_bp_modules[] = {"libsystem_c.dylib", 523 "libSystem.B.dylib"}; 524 525 FileSpecList bp_modules; 526 for (size_t i = 0; i < llvm::array_lengthof(g_bp_modules); i++) { 527 const char *bp_module = g_bp_modules[i]; 528 bp_modules.EmplaceBack(bp_module); 529 } 530 531 bool internal = true; 532 bool hardware = false; 533 LazyBool skip_prologue = eLazyBoolNo; 534 bp_sp = target.CreateBreakpoint(&bp_modules, nullptr, g_bp_names, 535 llvm::array_lengthof(g_bp_names), 536 eFunctionNameTypeFull, eLanguageTypeUnknown, 537 0, skip_prologue, internal, hardware); 538 bp_sp->SetBreakpointKind("thread-creation"); 539 540 return bp_sp; 541 } 542 543 uint32_t 544 PlatformDarwin::GetResumeCountForLaunchInfo(ProcessLaunchInfo &launch_info) { 545 const FileSpec &shell = launch_info.GetShell(); 546 if (!shell) 547 return 1; 548 549 std::string shell_string = shell.GetPath(); 550 const char *shell_name = strrchr(shell_string.c_str(), '/'); 551 if (shell_name == nullptr) 552 shell_name = shell_string.c_str(); 553 else 554 shell_name++; 555 556 if (strcmp(shell_name, "sh") == 0) { 557 // /bin/sh re-exec's itself as /bin/bash requiring another resume. But it 558 // only does this if the COMMAND_MODE environment variable is set to 559 // "legacy". 560 if (launch_info.GetEnvironment().lookup("COMMAND_MODE") == "legacy") 561 return 2; 562 return 1; 563 } else if (strcmp(shell_name, "csh") == 0 || 564 strcmp(shell_name, "tcsh") == 0 || 565 strcmp(shell_name, "zsh") == 0) { 566 // csh and tcsh always seem to re-exec themselves. 567 return 2; 568 } else 569 return 1; 570 } 571 572 lldb::ProcessSP PlatformDarwin::DebugProcess(ProcessLaunchInfo &launch_info, 573 Debugger &debugger, Target &target, 574 Status &error) { 575 ProcessSP process_sp; 576 577 if (IsHost()) { 578 // We are going to hand this process off to debugserver which will be in 579 // charge of setting the exit status. However, we still need to reap it 580 // from lldb. So, make sure we use a exit callback which does not set exit 581 // status. 582 launch_info.SetMonitorProcessCallback( 583 &ProcessLaunchInfo::NoOpMonitorCallback); 584 process_sp = Platform::DebugProcess(launch_info, debugger, target, error); 585 } else { 586 if (m_remote_platform_sp) 587 process_sp = m_remote_platform_sp->DebugProcess(launch_info, debugger, 588 target, error); 589 else 590 error.SetErrorString("the platform is not currently connected"); 591 } 592 return process_sp; 593 } 594 595 void PlatformDarwin::CalculateTrapHandlerSymbolNames() { 596 m_trap_handlers.push_back(ConstString("_sigtramp")); 597 } 598 599 static FileSpec GetCommandLineToolsLibraryPath() { 600 static FileSpec g_command_line_tools_filespec; 601 602 if (!g_command_line_tools_filespec) { 603 FileSpec command_line_tools_path(GetXcodeSelectPath()); 604 command_line_tools_path.AppendPathComponent("Library"); 605 if (FileSystem::Instance().Exists(command_line_tools_path)) { 606 g_command_line_tools_filespec = command_line_tools_path; 607 } 608 } 609 610 return g_command_line_tools_filespec; 611 } 612 613 FileSystem::EnumerateDirectoryResult PlatformDarwin::DirectoryEnumerator( 614 void *baton, llvm::sys::fs::file_type file_type, llvm::StringRef path) { 615 SDKEnumeratorInfo *enumerator_info = static_cast<SDKEnumeratorInfo *>(baton); 616 617 FileSpec spec(path); 618 if (XcodeSDK::SDKSupportsModules(enumerator_info->sdk_type, spec)) { 619 enumerator_info->found_path = spec; 620 return FileSystem::EnumerateDirectoryResult::eEnumerateDirectoryResultNext; 621 } 622 623 return FileSystem::EnumerateDirectoryResult::eEnumerateDirectoryResultNext; 624 } 625 626 FileSpec PlatformDarwin::FindSDKInXcodeForModules(XcodeSDK::Type sdk_type, 627 const FileSpec &sdks_spec) { 628 // Look inside Xcode for the required installed iOS SDK version 629 630 if (!FileSystem::Instance().IsDirectory(sdks_spec)) { 631 return FileSpec(); 632 } 633 634 const bool find_directories = true; 635 const bool find_files = false; 636 const bool find_other = true; // include symlinks 637 638 SDKEnumeratorInfo enumerator_info; 639 640 enumerator_info.sdk_type = sdk_type; 641 642 FileSystem::Instance().EnumerateDirectory( 643 sdks_spec.GetPath(), find_directories, find_files, find_other, 644 DirectoryEnumerator, &enumerator_info); 645 646 if (FileSystem::Instance().IsDirectory(enumerator_info.found_path)) 647 return enumerator_info.found_path; 648 else 649 return FileSpec(); 650 } 651 652 FileSpec PlatformDarwin::GetSDKDirectoryForModules(XcodeSDK::Type sdk_type) { 653 FileSpec sdks_spec = HostInfo::GetXcodeContentsDirectory(); 654 sdks_spec.AppendPathComponent("Developer"); 655 sdks_spec.AppendPathComponent("Platforms"); 656 657 switch (sdk_type) { 658 case XcodeSDK::Type::MacOSX: 659 sdks_spec.AppendPathComponent("MacOSX.platform"); 660 break; 661 case XcodeSDK::Type::iPhoneSimulator: 662 sdks_spec.AppendPathComponent("iPhoneSimulator.platform"); 663 break; 664 case XcodeSDK::Type::iPhoneOS: 665 sdks_spec.AppendPathComponent("iPhoneOS.platform"); 666 break; 667 case XcodeSDK::Type::WatchSimulator: 668 sdks_spec.AppendPathComponent("WatchSimulator.platform"); 669 break; 670 case XcodeSDK::Type::AppleTVSimulator: 671 sdks_spec.AppendPathComponent("AppleTVSimulator.platform"); 672 break; 673 default: 674 llvm_unreachable("unsupported sdk"); 675 } 676 677 sdks_spec.AppendPathComponent("Developer"); 678 sdks_spec.AppendPathComponent("SDKs"); 679 680 if (sdk_type == XcodeSDK::Type::MacOSX) { 681 llvm::VersionTuple version = HostInfo::GetOSVersion(); 682 683 if (!version.empty()) { 684 if (XcodeSDK::SDKSupportsModules(XcodeSDK::Type::MacOSX, version)) { 685 // If the Xcode SDKs are not available then try to use the 686 // Command Line Tools one which is only for MacOSX. 687 if (!FileSystem::Instance().Exists(sdks_spec)) { 688 sdks_spec = GetCommandLineToolsLibraryPath(); 689 sdks_spec.AppendPathComponent("SDKs"); 690 } 691 692 // We slightly prefer the exact SDK for this machine. See if it is 693 // there. 694 695 FileSpec native_sdk_spec = sdks_spec; 696 StreamString native_sdk_name; 697 native_sdk_name.Printf("MacOSX%u.%u.sdk", version.getMajor(), 698 version.getMinor().getValueOr(0)); 699 native_sdk_spec.AppendPathComponent(native_sdk_name.GetString()); 700 701 if (FileSystem::Instance().Exists(native_sdk_spec)) { 702 return native_sdk_spec; 703 } 704 } 705 } 706 } 707 708 return FindSDKInXcodeForModules(sdk_type, sdks_spec); 709 } 710 711 std::tuple<llvm::VersionTuple, llvm::StringRef> 712 PlatformDarwin::ParseVersionBuildDir(llvm::StringRef dir) { 713 llvm::StringRef build; 714 llvm::StringRef version_str; 715 llvm::StringRef build_str; 716 std::tie(version_str, build_str) = dir.split(' '); 717 llvm::VersionTuple version; 718 if (!version.tryParse(version_str) || 719 build_str.empty()) { 720 if (build_str.consume_front("(")) { 721 size_t pos = build_str.find(')'); 722 build = build_str.slice(0, pos); 723 } 724 } 725 726 return std::make_tuple(version, build); 727 } 728 729 llvm::Expected<StructuredData::DictionarySP> 730 PlatformDarwin::FetchExtendedCrashInformation(Process &process) { 731 Log *log = GetLog(LLDBLog::Process); 732 733 StructuredData::ArraySP annotations = ExtractCrashInfoAnnotations(process); 734 735 if (!annotations || !annotations->GetSize()) { 736 LLDB_LOG(log, "Couldn't extract crash information annotations"); 737 return nullptr; 738 } 739 740 StructuredData::DictionarySP extended_crash_info = 741 std::make_shared<StructuredData::Dictionary>(); 742 743 extended_crash_info->AddItem("crash-info annotations", annotations); 744 745 return extended_crash_info; 746 } 747 748 StructuredData::ArraySP 749 PlatformDarwin::ExtractCrashInfoAnnotations(Process &process) { 750 Log *log = GetLog(LLDBLog::Process); 751 752 ConstString section_name("__crash_info"); 753 Target &target = process.GetTarget(); 754 StructuredData::ArraySP array_sp = std::make_shared<StructuredData::Array>(); 755 756 for (ModuleSP module : target.GetImages().Modules()) { 757 SectionList *sections = module->GetSectionList(); 758 759 std::string module_name = module->GetSpecificationDescription(); 760 761 // The DYDL module is skipped since it's always loaded when running the 762 // binary. 763 if (module_name == "/usr/lib/dyld") 764 continue; 765 766 if (!sections) { 767 LLDB_LOG(log, "Module {0} doesn't have any section!", module_name); 768 continue; 769 } 770 771 SectionSP crash_info = sections->FindSectionByName(section_name); 772 if (!crash_info) { 773 LLDB_LOG(log, "Module {0} doesn't have section {1}!", module_name, 774 section_name); 775 continue; 776 } 777 778 addr_t load_addr = crash_info->GetLoadBaseAddress(&target); 779 780 if (load_addr == LLDB_INVALID_ADDRESS) { 781 LLDB_LOG(log, "Module {0} has an invalid '{1}' section load address: {2}", 782 module_name, section_name, load_addr); 783 continue; 784 } 785 786 Status error; 787 CrashInfoAnnotations annotations; 788 size_t expected_size = sizeof(CrashInfoAnnotations); 789 size_t bytes_read = process.ReadMemoryFromInferior(load_addr, &annotations, 790 expected_size, error); 791 792 if (expected_size != bytes_read || error.Fail()) { 793 LLDB_LOG(log, "Failed to read {0} section from memory in module {1}: {2}", 794 section_name, module_name, error); 795 continue; 796 } 797 798 // initial support added for version 5 799 if (annotations.version < 5) { 800 LLDB_LOG(log, 801 "Annotation version lower than 5 unsupported! Module {0} has " 802 "version {1} instead.", 803 module_name, annotations.version); 804 continue; 805 } 806 807 if (!annotations.message) { 808 LLDB_LOG(log, "No message available for module {0}.", module_name); 809 continue; 810 } 811 812 std::string message; 813 bytes_read = 814 process.ReadCStringFromMemory(annotations.message, message, error); 815 816 if (message.empty() || bytes_read != message.size() || error.Fail()) { 817 LLDB_LOG(log, "Failed to read the message from memory in module {0}: {1}", 818 module_name, error); 819 continue; 820 } 821 822 // Remove trailing newline from message 823 if (message.back() == '\n') 824 message.pop_back(); 825 826 if (!annotations.message2) 827 LLDB_LOG(log, "No message2 available for module {0}.", module_name); 828 829 std::string message2; 830 bytes_read = 831 process.ReadCStringFromMemory(annotations.message2, message2, error); 832 833 if (!message2.empty() && bytes_read == message2.size() && error.Success()) 834 if (message2.back() == '\n') 835 message2.pop_back(); 836 837 StructuredData::DictionarySP entry_sp = 838 std::make_shared<StructuredData::Dictionary>(); 839 840 entry_sp->AddStringItem("image", module->GetFileSpec().GetPath(false)); 841 entry_sp->AddStringItem("uuid", module->GetUUID().GetAsString()); 842 entry_sp->AddStringItem("message", message); 843 entry_sp->AddStringItem("message2", message2); 844 entry_sp->AddIntegerItem("abort-cause", annotations.abort_cause); 845 846 array_sp->AddItem(entry_sp); 847 } 848 849 return array_sp; 850 } 851 852 void PlatformDarwin::AddClangModuleCompilationOptionsForSDKType( 853 Target *target, std::vector<std::string> &options, XcodeSDK::Type sdk_type) { 854 const std::vector<std::string> apple_arguments = { 855 "-x", "objective-c++", "-fobjc-arc", 856 "-fblocks", "-D_ISO646_H", "-D__ISO646_H", 857 "-fgnuc-version=4.2.1"}; 858 859 options.insert(options.end(), apple_arguments.begin(), apple_arguments.end()); 860 861 StreamString minimum_version_option; 862 bool use_current_os_version = false; 863 // If the SDK type is for the host OS, use its version number. 864 auto get_host_os = []() { return HostInfo::GetTargetTriple().getOS(); }; 865 switch (sdk_type) { 866 case XcodeSDK::Type::MacOSX: 867 use_current_os_version = get_host_os() == llvm::Triple::MacOSX; 868 break; 869 case XcodeSDK::Type::iPhoneOS: 870 use_current_os_version = get_host_os() == llvm::Triple::IOS; 871 break; 872 case XcodeSDK::Type::AppleTVOS: 873 use_current_os_version = get_host_os() == llvm::Triple::TvOS; 874 break; 875 case XcodeSDK::Type::watchOS: 876 use_current_os_version = get_host_os() == llvm::Triple::WatchOS; 877 break; 878 default: 879 break; 880 } 881 882 llvm::VersionTuple version; 883 if (use_current_os_version) 884 version = GetOSVersion(); 885 else if (target) { 886 // Our OS doesn't match our executable so we need to get the min OS version 887 // from the object file 888 ModuleSP exe_module_sp = target->GetExecutableModule(); 889 if (exe_module_sp) { 890 ObjectFile *object_file = exe_module_sp->GetObjectFile(); 891 if (object_file) 892 version = object_file->GetMinimumOSVersion(); 893 } 894 } 895 // Only add the version-min options if we got a version from somewhere 896 if (!version.empty() && sdk_type != XcodeSDK::Type::Linux) { 897 #define OPTION(PREFIX, NAME, VAR, ...) \ 898 const char *opt_##VAR = NAME; \ 899 (void)opt_##VAR; 900 #include "clang/Driver/Options.inc" 901 #undef OPTION 902 minimum_version_option << '-'; 903 switch (sdk_type) { 904 case XcodeSDK::Type::MacOSX: 905 minimum_version_option << opt_mmacosx_version_min_EQ; 906 break; 907 case XcodeSDK::Type::iPhoneSimulator: 908 minimum_version_option << opt_mios_simulator_version_min_EQ; 909 break; 910 case XcodeSDK::Type::iPhoneOS: 911 minimum_version_option << opt_mios_version_min_EQ; 912 break; 913 case XcodeSDK::Type::AppleTVSimulator: 914 minimum_version_option << opt_mtvos_simulator_version_min_EQ; 915 break; 916 case XcodeSDK::Type::AppleTVOS: 917 minimum_version_option << opt_mtvos_version_min_EQ; 918 break; 919 case XcodeSDK::Type::WatchSimulator: 920 minimum_version_option << opt_mwatchos_simulator_version_min_EQ; 921 break; 922 case XcodeSDK::Type::watchOS: 923 minimum_version_option << opt_mwatchos_version_min_EQ; 924 break; 925 case XcodeSDK::Type::bridgeOS: 926 case XcodeSDK::Type::Linux: 927 case XcodeSDK::Type::unknown: 928 if (Log *log = GetLog(LLDBLog::Host)) { 929 XcodeSDK::Info info; 930 info.type = sdk_type; 931 LLDB_LOGF(log, "Clang modules on %s are not supported", 932 XcodeSDK::GetCanonicalName(info).c_str()); 933 } 934 return; 935 } 936 minimum_version_option << version.getAsString(); 937 options.emplace_back(std::string(minimum_version_option.GetString())); 938 } 939 940 FileSpec sysroot_spec; 941 // Scope for mutex locker below 942 { 943 std::lock_guard<std::mutex> guard(m_mutex); 944 sysroot_spec = GetSDKDirectoryForModules(sdk_type); 945 } 946 947 if (FileSystem::Instance().IsDirectory(sysroot_spec.GetPath())) { 948 options.push_back("-isysroot"); 949 options.push_back(sysroot_spec.GetPath()); 950 } 951 } 952 953 ConstString PlatformDarwin::GetFullNameForDylib(ConstString basename) { 954 if (basename.IsEmpty()) 955 return basename; 956 957 StreamString stream; 958 stream.Printf("lib%s.dylib", basename.GetCString()); 959 return ConstString(stream.GetString()); 960 } 961 962 llvm::VersionTuple PlatformDarwin::GetOSVersion(Process *process) { 963 if (process && GetPluginName().contains("-simulator")) { 964 lldb_private::ProcessInstanceInfo proc_info; 965 if (Host::GetProcessInfo(process->GetID(), proc_info)) { 966 const Environment &env = proc_info.GetEnvironment(); 967 968 llvm::VersionTuple result; 969 if (!result.tryParse(env.lookup("SIMULATOR_RUNTIME_VERSION"))) 970 return result; 971 972 std::string dyld_root_path = env.lookup("DYLD_ROOT_PATH"); 973 if (!dyld_root_path.empty()) { 974 dyld_root_path += "/System/Library/CoreServices/SystemVersion.plist"; 975 ApplePropertyList system_version_plist(dyld_root_path.c_str()); 976 std::string product_version; 977 if (system_version_plist.GetValueAsString("ProductVersion", 978 product_version)) { 979 if (!result.tryParse(product_version)) 980 return result; 981 } 982 } 983 } 984 // For simulator platforms, do NOT call back through 985 // Platform::GetOSVersion() as it might call Process::GetHostOSVersion() 986 // which we don't want as it will be incorrect 987 return llvm::VersionTuple(); 988 } 989 990 return Platform::GetOSVersion(process); 991 } 992 993 lldb_private::FileSpec PlatformDarwin::LocateExecutable(const char *basename) { 994 // A collection of SBFileSpec whose SBFileSpec.m_directory members are filled 995 // in with any executable directories that should be searched. 996 static std::vector<FileSpec> g_executable_dirs; 997 998 // Find the global list of directories that we will search for executables 999 // once so we don't keep doing the work over and over. 1000 static llvm::once_flag g_once_flag; 1001 llvm::call_once(g_once_flag, []() { 1002 1003 // When locating executables, trust the DEVELOPER_DIR first if it is set 1004 FileSpec xcode_contents_dir = HostInfo::GetXcodeContentsDirectory(); 1005 if (xcode_contents_dir) { 1006 FileSpec xcode_lldb_resources = xcode_contents_dir; 1007 xcode_lldb_resources.AppendPathComponent("SharedFrameworks"); 1008 xcode_lldb_resources.AppendPathComponent("LLDB.framework"); 1009 xcode_lldb_resources.AppendPathComponent("Resources"); 1010 if (FileSystem::Instance().Exists(xcode_lldb_resources)) { 1011 FileSpec dir; 1012 dir.GetDirectory().SetCString(xcode_lldb_resources.GetPath().c_str()); 1013 g_executable_dirs.push_back(dir); 1014 } 1015 } 1016 // Xcode might not be installed so we also check for the Command Line Tools. 1017 FileSpec command_line_tools_dir = GetCommandLineToolsLibraryPath(); 1018 if (command_line_tools_dir) { 1019 FileSpec cmd_line_lldb_resources = command_line_tools_dir; 1020 cmd_line_lldb_resources.AppendPathComponent("PrivateFrameworks"); 1021 cmd_line_lldb_resources.AppendPathComponent("LLDB.framework"); 1022 cmd_line_lldb_resources.AppendPathComponent("Resources"); 1023 if (FileSystem::Instance().Exists(cmd_line_lldb_resources)) { 1024 FileSpec dir; 1025 dir.GetDirectory().SetCString( 1026 cmd_line_lldb_resources.GetPath().c_str()); 1027 g_executable_dirs.push_back(dir); 1028 } 1029 } 1030 }); 1031 1032 // Now search the global list of executable directories for the executable we 1033 // are looking for 1034 for (const auto &executable_dir : g_executable_dirs) { 1035 FileSpec executable_file; 1036 executable_file.GetDirectory() = executable_dir.GetDirectory(); 1037 executable_file.GetFilename().SetCString(basename); 1038 if (FileSystem::Instance().Exists(executable_file)) 1039 return executable_file; 1040 } 1041 1042 return FileSpec(); 1043 } 1044 1045 lldb_private::Status 1046 PlatformDarwin::LaunchProcess(lldb_private::ProcessLaunchInfo &launch_info) { 1047 // Starting in Fall 2016 OSes, NSLog messages only get mirrored to stderr if 1048 // the OS_ACTIVITY_DT_MODE environment variable is set. (It doesn't require 1049 // any specific value; rather, it just needs to exist). We will set it here 1050 // as long as the IDE_DISABLED_OS_ACTIVITY_DT_MODE flag is not set. Xcode 1051 // makes use of IDE_DISABLED_OS_ACTIVITY_DT_MODE to tell 1052 // LLDB *not* to muck with the OS_ACTIVITY_DT_MODE flag when they 1053 // specifically want it unset. 1054 const char *disable_env_var = "IDE_DISABLED_OS_ACTIVITY_DT_MODE"; 1055 auto &env_vars = launch_info.GetEnvironment(); 1056 if (!env_vars.count(disable_env_var)) { 1057 // We want to make sure that OS_ACTIVITY_DT_MODE is set so that we get 1058 // os_log and NSLog messages mirrored to the target process stderr. 1059 env_vars.try_emplace("OS_ACTIVITY_DT_MODE", "enable"); 1060 } 1061 1062 // Let our parent class do the real launching. 1063 return PlatformPOSIX::LaunchProcess(launch_info); 1064 } 1065 1066 lldb_private::Status PlatformDarwin::FindBundleBinaryInExecSearchPaths( 1067 const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp, 1068 const FileSpecList *module_search_paths_ptr, 1069 llvm::SmallVectorImpl<ModuleSP> *old_modules, bool *did_create_ptr) { 1070 const FileSpec &platform_file = module_spec.GetFileSpec(); 1071 // See if the file is present in any of the module_search_paths_ptr 1072 // directories. 1073 if (!module_sp && module_search_paths_ptr && platform_file) { 1074 // create a vector of all the file / directory names in platform_file e.g. 1075 // this might be 1076 // /System/Library/PrivateFrameworks/UIFoundation.framework/UIFoundation 1077 // 1078 // We'll need to look in the module_search_paths_ptr directories for both 1079 // "UIFoundation" and "UIFoundation.framework" -- most likely the latter 1080 // will be the one we find there. 1081 1082 FileSpec platform_pull_upart(platform_file); 1083 std::vector<std::string> path_parts; 1084 path_parts.push_back( 1085 platform_pull_upart.GetLastPathComponent().AsCString()); 1086 while (platform_pull_upart.RemoveLastPathComponent()) { 1087 ConstString part = platform_pull_upart.GetLastPathComponent(); 1088 path_parts.push_back(part.AsCString()); 1089 } 1090 const size_t path_parts_size = path_parts.size(); 1091 1092 size_t num_module_search_paths = module_search_paths_ptr->GetSize(); 1093 for (size_t i = 0; i < num_module_search_paths; ++i) { 1094 Log *log_verbose = GetLog(LLDBLog::Host); 1095 LLDB_LOGF( 1096 log_verbose, 1097 "PlatformRemoteDarwinDevice::GetSharedModule searching for binary in " 1098 "search-path %s", 1099 module_search_paths_ptr->GetFileSpecAtIndex(i).GetPath().c_str()); 1100 // Create a new FileSpec with this module_search_paths_ptr plus just the 1101 // filename ("UIFoundation"), then the parent dir plus filename 1102 // ("UIFoundation.framework/UIFoundation") etc - up to four names (to 1103 // handle "Foo.framework/Contents/MacOS/Foo") 1104 1105 for (size_t j = 0; j < 4 && j < path_parts_size - 1; ++j) { 1106 FileSpec path_to_try(module_search_paths_ptr->GetFileSpecAtIndex(i)); 1107 1108 // Add the components backwards. For 1109 // .../PrivateFrameworks/UIFoundation.framework/UIFoundation path_parts 1110 // is 1111 // [0] UIFoundation 1112 // [1] UIFoundation.framework 1113 // [2] PrivateFrameworks 1114 // 1115 // and if 'j' is 2, we want to append path_parts[1] and then 1116 // path_parts[0], aka 'UIFoundation.framework/UIFoundation', to the 1117 // module_search_paths_ptr path. 1118 1119 for (int k = j; k >= 0; --k) { 1120 path_to_try.AppendPathComponent(path_parts[k]); 1121 } 1122 1123 if (FileSystem::Instance().Exists(path_to_try)) { 1124 ModuleSpec new_module_spec(module_spec); 1125 new_module_spec.GetFileSpec() = path_to_try; 1126 Status new_error( 1127 Platform::GetSharedModule(new_module_spec, process, module_sp, 1128 nullptr, old_modules, did_create_ptr)); 1129 1130 if (module_sp) { 1131 module_sp->SetPlatformFileSpec(path_to_try); 1132 return new_error; 1133 } 1134 } 1135 } 1136 } 1137 } 1138 return Status(); 1139 } 1140 1141 std::string PlatformDarwin::FindComponentInPath(llvm::StringRef path, 1142 llvm::StringRef component) { 1143 auto begin = llvm::sys::path::begin(path); 1144 auto end = llvm::sys::path::end(path); 1145 for (auto it = begin; it != end; ++it) { 1146 if (it->contains(component)) { 1147 llvm::SmallString<128> buffer; 1148 llvm::sys::path::append(buffer, begin, ++it, 1149 llvm::sys::path::Style::posix); 1150 return buffer.str().str(); 1151 } 1152 } 1153 return {}; 1154 } 1155 1156 FileSpec PlatformDarwin::GetCurrentToolchainDirectory() { 1157 if (FileSpec fspec = HostInfo::GetShlibDir()) 1158 return FileSpec(FindComponentInPath(fspec.GetPath(), ".xctoolchain")); 1159 return {}; 1160 } 1161 1162 FileSpec PlatformDarwin::GetCurrentCommandLineToolsDirectory() { 1163 if (FileSpec fspec = HostInfo::GetShlibDir()) 1164 return FileSpec(FindComponentInPath(fspec.GetPath(), "CommandLineTools")); 1165 return {}; 1166 } 1167 1168 llvm::Triple::OSType PlatformDarwin::GetHostOSType() { 1169 #if !defined(__APPLE__) 1170 return llvm::Triple::MacOSX; 1171 #else 1172 #if TARGET_OS_OSX 1173 return llvm::Triple::MacOSX; 1174 #elif TARGET_OS_IOS 1175 return llvm::Triple::IOS; 1176 #elif TARGET_OS_WATCH 1177 return llvm::Triple::WatchOS; 1178 #elif TARGET_OS_TV 1179 return llvm::Triple::TvOS; 1180 #elif TARGET_OS_BRIDGE 1181 return llvm::Triple::BridgeOS; 1182 #else 1183 #error "LLDB being compiled for an unrecognized Darwin OS" 1184 #endif 1185 #endif // __APPLE__ 1186 } 1187