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