brintos

brintos / llvm-project-archived public Read only

0
0
Text · 54.0 KiB · bfbd85e Raw
1495 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9#include "PlatformDarwin.h"10 11#include <cstring>12 13#include <algorithm>14#include <memory>15#include <mutex>16#include <optional>17 18#include "lldb/Breakpoint/BreakpointLocation.h"19#include "lldb/Breakpoint/BreakpointSite.h"20#include "lldb/Core/Debugger.h"21#include "lldb/Core/Module.h"22#include "lldb/Core/ModuleSpec.h"23#include "lldb/Core/PluginManager.h"24#include "lldb/Core/Section.h"25#include "lldb/Host/Host.h"26#include "lldb/Host/HostInfo.h"27#include "lldb/Host/XML.h"28#include "lldb/Interpreter/CommandInterpreter.h"29#include "lldb/Interpreter/OptionValueProperties.h"30#include "lldb/Interpreter/OptionValueString.h"31#include "lldb/Interpreter/Options.h"32#include "lldb/Symbol/CompileUnit.h"33#include "lldb/Symbol/ObjectFile.h"34#include "lldb/Symbol/SymbolFile.h"35#include "lldb/Symbol/SymbolVendor.h"36#include "lldb/Target/Platform.h"37#include "lldb/Target/Process.h"38#include "lldb/Target/Target.h"39#include "lldb/Utility/LLDBLog.h"40#include "lldb/Utility/Log.h"41#include "lldb/Utility/ProcessInfo.h"42#include "lldb/Utility/Status.h"43#include "lldb/Utility/Timer.h"44#include "llvm/ADT/STLExtras.h"45#include "llvm/ADT/StringTable.h"46#include "llvm/Support/Error.h"47#include "llvm/Support/FileSystem.h"48#include "llvm/Support/Threading.h"49#include "llvm/Support/VersionTuple.h"50 51#if defined(__APPLE__)52#include <TargetConditionals.h>53#endif54 55using namespace lldb;56using namespace lldb_private;57 58#define OPTTABLE_STR_TABLE_CODE59#include "clang/Options/Options.inc"60#undef OPTTABLE_STR_TABLE_CODE61 62static Status ExceptionMaskValidator(const char *string, void *unused) {63  Status error;64  llvm::StringRef str_ref(string);65  llvm::SmallVector<llvm::StringRef> candidates;66  str_ref.split(candidates, '|');67  for (auto candidate : candidates) {68    if (!(candidate == "EXC_BAD_ACCESS"69          || candidate == "EXC_BAD_INSTRUCTION"70          || candidate == "EXC_ARITHMETIC"71          || candidate == "EXC_RESOURCE"72          || candidate == "EXC_GUARD"73          || candidate == "EXC_SYSCALL")) {74      error = Status::FromErrorStringWithFormat("invalid exception type: '%s'",75                                                candidate.str().c_str());76      return error;77    }78  }79  return {};80}81 82/// Destructor.83///84/// The destructor is virtual since this class is designed to be85/// inherited from by the plug-in instance.86PlatformDarwin::~PlatformDarwin() = default;87 88// Static Variables89static uint32_t g_initialize_count = 0;90 91void PlatformDarwin::Initialize() {92  Platform::Initialize();93 94  if (g_initialize_count++ == 0) {95    PluginManager::RegisterPlugin(PlatformDarwin::GetPluginNameStatic(),96                                  PlatformDarwin::GetDescriptionStatic(),97                                  PlatformDarwin::CreateInstance,98                                  PlatformDarwin::DebuggerInitialize);99  }100}101 102void PlatformDarwin::Terminate() {103  if (g_initialize_count > 0) {104    if (--g_initialize_count == 0) {105      PluginManager::UnregisterPlugin(PlatformDarwin::CreateInstance);106    }107  }108 109  Platform::Terminate();110}111 112llvm::StringRef PlatformDarwin::GetDescriptionStatic() {113  return "Darwin platform plug-in.";114}115 116PlatformSP PlatformDarwin::CreateInstance(bool force, const ArchSpec *arch) {117   // We only create subclasses of the PlatformDarwin plugin.118   return PlatformSP();119}120 121#define LLDB_PROPERTIES_platformdarwin122#include "PlatformMacOSXProperties.inc"123 124#define LLDB_PROPERTIES_platformdarwin125enum {126#include "PlatformMacOSXPropertiesEnum.inc"127};128 129class PlatformDarwinProperties : public Properties {130public:131  static llvm::StringRef GetSettingName() {132    static constexpr llvm::StringLiteral g_setting_name("darwin");133    return g_setting_name;134  }135 136  PlatformDarwinProperties() : Properties() {137    m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());138    m_collection_sp->Initialize(g_platformdarwin_properties);139  }140 141  ~PlatformDarwinProperties() override = default;142 143  const char *GetIgnoredExceptions() const {144    const uint32_t idx = ePropertyIgnoredExceptions;145    const OptionValueString *option_value =146        m_collection_sp->GetPropertyAtIndexAsOptionValueString(idx);147    assert(option_value);148    return option_value->GetCurrentValue();149  }150 151  OptionValueString *GetIgnoredExceptionValue() {152    const uint32_t idx = ePropertyIgnoredExceptions;153    OptionValueString *option_value =154        m_collection_sp->GetPropertyAtIndexAsOptionValueString(idx);155    assert(option_value);156    return option_value;157  }158};159 160static PlatformDarwinProperties &GetGlobalProperties() {161  static PlatformDarwinProperties g_settings;162  return g_settings;163}164 165void PlatformDarwin::DebuggerInitialize(166    lldb_private::Debugger &debugger) {167  if (!PluginManager::GetSettingForPlatformPlugin(168          debugger, PlatformDarwinProperties::GetSettingName())) {169    const bool is_global_setting = false;170    PluginManager::CreateSettingForPlatformPlugin(171        debugger, GetGlobalProperties().GetValueProperties(),172        "Properties for the Darwin platform plug-in.", is_global_setting);173    OptionValueString *value = GetGlobalProperties().GetIgnoredExceptionValue();174    value->SetValidator(ExceptionMaskValidator);175  }176}177 178Args179PlatformDarwin::GetExtraStartupCommands() {180  std::string ignored_exceptions181      = GetGlobalProperties().GetIgnoredExceptions();182  if (ignored_exceptions.empty())183    return {};184  Args ret_args;185  std::string packet = "QSetIgnoredExceptions:";186  packet.append(ignored_exceptions);187  ret_args.AppendArgument(packet);188  return ret_args;189}190 191lldb_private::Status192PlatformDarwin::PutFile(const lldb_private::FileSpec &source,193                        const lldb_private::FileSpec &destination, uint32_t uid,194                        uint32_t gid) {195  // Unconditionally unlink the destination. If it is an executable,196  // simply opening it and truncating its contents would invalidate197  // its cached code signature.198  Unlink(destination);199  return PlatformPOSIX::PutFile(source, destination, uid, gid);200}201 202FileSpecList PlatformDarwin::LocateExecutableScriptingResources(203    Target *target, Module &module, Stream &feedback_stream) {204  FileSpecList file_list;205  if (target &&206      target->GetDebugger().GetScriptLanguage() == eScriptLanguagePython) {207    // NB some extensions might be meaningful and should not be stripped -208    // "this.binary.file"209    // should not lose ".file" but GetFileNameStrippingExtension() will do210    // precisely that. Ideally, we should have a per-platform list of211    // extensions (".exe", ".app", ".dSYM", ".framework") which should be212    // stripped while leaving "this.binary.file" as-is.213 214    FileSpec module_spec = module.GetFileSpec();215 216    if (module_spec) {217      if (SymbolFile *symfile = module.GetSymbolFile()) {218        ObjectFile *objfile = symfile->GetObjectFile();219        if (objfile) {220          FileSpec symfile_spec(objfile->GetFileSpec());221          if (symfile_spec &&222              llvm::StringRef(symfile_spec.GetPath())223                  .contains_insensitive(".dSYM/Contents/Resources/DWARF") &&224              FileSystem::Instance().Exists(symfile_spec)) {225            while (module_spec.GetFilename()) {226              std::string module_basename(227                  module_spec.GetFilename().GetCString());228              std::string original_module_basename(module_basename);229 230              bool was_keyword = false;231 232              // FIXME: for Python, we cannot allow certain characters in233              // module234              // filenames we import. Theoretically, different scripting235              // languages may have different sets of forbidden tokens in236              // filenames, and that should be dealt with by each237              // ScriptInterpreter. For now, we just replace dots with238              // underscores, but if we ever support anything other than239              // Python we will need to rework this240              llvm::replace(module_basename, '.', '_');241              llvm::replace(module_basename, ' ', '_');242              llvm::replace(module_basename, '-', '_');243              ScriptInterpreter *script_interpreter =244                  target->GetDebugger().GetScriptInterpreter();245              if (script_interpreter &&246                  script_interpreter->IsReservedWord(module_basename.c_str())) {247                module_basename.insert(module_basename.begin(), '_');248                was_keyword = true;249              }250 251              StreamString path_string;252              StreamString original_path_string;253              // for OSX we are going to be in254              // .dSYM/Contents/Resources/DWARF/<basename> let us go to255              // .dSYM/Contents/Resources/Python/<basename>.py and see if the256              // file exists257              path_string.Printf("%s/../Python/%s.py",258                                 symfile_spec.GetDirectory().GetCString(),259                                 module_basename.c_str());260              original_path_string.Printf(261                  "%s/../Python/%s.py",262                  symfile_spec.GetDirectory().GetCString(),263                  original_module_basename.c_str());264              FileSpec script_fspec(path_string.GetString());265              FileSystem::Instance().Resolve(script_fspec);266              FileSpec orig_script_fspec(original_path_string.GetString());267              FileSystem::Instance().Resolve(orig_script_fspec);268 269              // if we did some replacements of reserved characters, and a270              // file with the untampered name exists, then warn the user271              // that the file as-is shall not be loaded272              if (module_basename != original_module_basename &&273                  FileSystem::Instance().Exists(orig_script_fspec)) {274                const char *reason_for_complaint =275                    was_keyword ? "conflicts with a keyword"276                                : "contains reserved characters";277                if (FileSystem::Instance().Exists(script_fspec))278                  feedback_stream.Printf(279                      "warning: the symbol file '%s' contains a debug "280                      "script. However, its name"281                      " '%s' %s and as such cannot be loaded. LLDB will"282                      " load '%s' instead. Consider removing the file with "283                      "the malformed name to"284                      " eliminate this warning.\n",285                      symfile_spec.GetPath().c_str(),286                      original_path_string.GetData(), reason_for_complaint,287                      path_string.GetData());288                else289                  feedback_stream.Printf(290                      "warning: the symbol file '%s' contains a debug "291                      "script. However, its name"292                      " %s and as such cannot be loaded. If you intend"293                      " to have this script loaded, please rename '%s' to "294                      "'%s' and retry.\n",295                      symfile_spec.GetPath().c_str(), reason_for_complaint,296                      original_path_string.GetData(), path_string.GetData());297              }298 299              if (FileSystem::Instance().Exists(script_fspec)) {300                file_list.Append(script_fspec);301                break;302              }303 304              // If we didn't find the python file, then keep stripping the305              // extensions and try again306              ConstString filename_no_extension(307                  module_spec.GetFileNameStrippingExtension());308              if (module_spec.GetFilename() == filename_no_extension)309                break;310 311              module_spec.SetFilename(filename_no_extension);312            }313          }314        }315      }316    }317  }318  return file_list;319}320 321Status PlatformDarwin::ResolveSymbolFile(Target &target,322                                         const ModuleSpec &sym_spec,323                                         FileSpec &sym_file) {324  sym_file = sym_spec.GetSymbolFileSpec();325  if (FileSystem::Instance().IsDirectory(sym_file)) {326    sym_file = PluginManager::FindSymbolFileInBundle(327        sym_file, sym_spec.GetUUIDPtr(), sym_spec.GetArchitecturePtr());328  }329  return {};330}331 332Status PlatformDarwin::GetSharedModule(333    const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp,334    llvm::SmallVectorImpl<ModuleSP> *old_modules, bool *did_create_ptr) {335  Status error;336  module_sp.reset();337 338  if (IsRemote()) {339    // If we have a remote platform always, let it try and locate the shared340    // module first.341    if (m_remote_platform_sp) {342      error = m_remote_platform_sp->GetSharedModule(343          module_spec, process, module_sp, old_modules, did_create_ptr);344    }345  }346 347  if (!module_sp) {348    // Fall back to the local platform and find the file locally349    error = Platform::GetSharedModule(module_spec, process, module_sp,350                                      old_modules, did_create_ptr);351 352    const FileSpec &platform_file = module_spec.GetFileSpec();353    // Get module search paths from the target if available.354    TargetSP target_sp = module_spec.GetTargetSP();355    FileSpecList module_search_paths;356    if (target_sp)357      module_search_paths = target_sp->GetExecutableSearchPaths();358    if (!module_sp && !module_search_paths.IsEmpty() && platform_file) {359      // We can try to pull off part of the file path up to the bundle360      // directory level and try any module search paths...361      FileSpec bundle_directory;362      if (Host::GetBundleDirectory(platform_file, bundle_directory)) {363        if (platform_file == bundle_directory) {364          ModuleSpec new_module_spec(module_spec);365          new_module_spec.GetFileSpec() = bundle_directory;366          if (Host::ResolveExecutableInBundle(new_module_spec.GetFileSpec())) {367            Status new_error(Platform::GetSharedModule(new_module_spec, process,368                                                       module_sp, old_modules,369                                                       did_create_ptr));370 371            if (module_sp)372              return new_error;373          }374        } else {375          char platform_path[PATH_MAX];376          char bundle_dir[PATH_MAX];377          platform_file.GetPath(platform_path, sizeof(platform_path));378          const size_t bundle_directory_len =379              bundle_directory.GetPath(bundle_dir, sizeof(bundle_dir));380          char new_path[PATH_MAX];381          size_t num_module_search_paths = module_search_paths.GetSize();382          for (size_t i = 0; i < num_module_search_paths; ++i) {383            const size_t search_path_len =384                module_search_paths.GetFileSpecAtIndex(i).GetPath(385                    new_path, sizeof(new_path));386            if (search_path_len < sizeof(new_path)) {387              snprintf(new_path + search_path_len,388                       sizeof(new_path) - search_path_len, "/%s",389                       platform_path + bundle_directory_len);390              FileSpec new_file_spec(new_path);391              if (FileSystem::Instance().Exists(new_file_spec)) {392                ModuleSpec new_module_spec(module_spec);393                new_module_spec.GetFileSpec() = new_file_spec;394                Status new_error(Platform::GetSharedModule(395                    new_module_spec, process, module_sp, old_modules,396                    did_create_ptr));397 398                if (module_sp) {399                  module_sp->SetPlatformFileSpec(new_file_spec);400                  return new_error;401                }402              }403            }404          }405        }406      }407    }408  }409  if (module_sp)410    module_sp->SetPlatformFileSpec(module_spec.GetFileSpec());411  return error;412}413 414size_t415PlatformDarwin::GetSoftwareBreakpointTrapOpcode(Target &target,416                                                BreakpointSite *bp_site) {417  const uint8_t *trap_opcode = nullptr;418  uint32_t trap_opcode_size = 0;419  bool bp_is_thumb = false;420 421  llvm::Triple::ArchType machine = target.GetArchitecture().GetMachine();422  switch (machine) {423  case llvm::Triple::aarch64_32:424  case llvm::Triple::aarch64: {425    // 'brk #0' or 0xd4200000 in BE byte order426    static const uint8_t g_arm64_breakpoint_opcode[] = {0x00, 0x00, 0x20, 0xD4};427    trap_opcode = g_arm64_breakpoint_opcode;428    trap_opcode_size = sizeof(g_arm64_breakpoint_opcode);429  } break;430 431  case llvm::Triple::thumb:432    bp_is_thumb = true;433    [[fallthrough]];434  case llvm::Triple::arm: {435    static const uint8_t g_arm_breakpoint_opcode[] = {0xFE, 0xDE, 0xFF, 0xE7};436    static const uint8_t g_thumb_breakpooint_opcode[] = {0xFE, 0xDE};437 438    // Auto detect arm/thumb if it wasn't explicitly specified439    if (!bp_is_thumb) {440      lldb::BreakpointLocationSP bp_loc_sp(bp_site->GetConstituentAtIndex(0));441      if (bp_loc_sp)442        bp_is_thumb = bp_loc_sp->GetAddress().GetAddressClass() ==443                      AddressClass::eCodeAlternateISA;444    }445    if (bp_is_thumb) {446      trap_opcode = g_thumb_breakpooint_opcode;447      trap_opcode_size = sizeof(g_thumb_breakpooint_opcode);448      break;449    }450    trap_opcode = g_arm_breakpoint_opcode;451    trap_opcode_size = sizeof(g_arm_breakpoint_opcode);452  } break;453 454  case llvm::Triple::ppc:455  case llvm::Triple::ppc64: {456    static const uint8_t g_ppc_breakpoint_opcode[] = {0x7F, 0xC0, 0x00, 0x08};457    trap_opcode = g_ppc_breakpoint_opcode;458    trap_opcode_size = sizeof(g_ppc_breakpoint_opcode);459  } break;460 461  default:462    return Platform::GetSoftwareBreakpointTrapOpcode(target, bp_site);463  }464 465  if (trap_opcode && trap_opcode_size) {466    if (bp_site->SetTrapOpcode(trap_opcode, trap_opcode_size))467      return trap_opcode_size;468  }469  return 0;470}471 472bool PlatformDarwin::ModuleIsExcludedForUnconstrainedSearches(473    lldb_private::Target &target, const lldb::ModuleSP &module_sp) {474  if (!module_sp)475    return false;476 477  ObjectFile *obj_file = module_sp->GetObjectFile();478  if (!obj_file)479    return false;480 481  ObjectFile::Type obj_type = obj_file->GetType();482  return obj_type == ObjectFile::eTypeDynamicLinker;483}484 485void PlatformDarwin::x86GetSupportedArchitectures(486    std::vector<ArchSpec> &archs) {487  ArchSpec host_arch = HostInfo::GetArchitecture(HostInfo::eArchKindDefault);488  archs.push_back(host_arch);489 490  if (host_arch.GetCore() == ArchSpec::eCore_x86_64_x86_64h) {491    archs.push_back(ArchSpec("x86_64-apple-macosx"));492    archs.push_back(HostInfo::GetArchitecture(HostInfo::eArchKind32));493  } else {494    ArchSpec host_arch64 = HostInfo::GetArchitecture(HostInfo::eArchKind64);495    if (host_arch.IsExactMatch(host_arch64))496      archs.push_back(HostInfo::GetArchitecture(HostInfo::eArchKind32));497  }498}499 500static llvm::ArrayRef<const char *> GetCompatibleArchs(ArchSpec::Core core) {501  switch (core) {502  default:503    [[fallthrough]];504  case ArchSpec::eCore_arm_arm64e: {505    static const char *g_arm64e_compatible_archs[] = {506        "arm64e",    "arm64",    "armv7",    "armv7f",   "armv7k",   "armv7s",507        "armv7m",    "armv7em",  "armv6m",   "armv6",    "armv5",    "armv4",508        "arm",       "thumbv7",  "thumbv7f", "thumbv7k", "thumbv7s", "thumbv7m",509        "thumbv7em", "thumbv6m", "thumbv6",  "thumbv5",  "thumbv4t", "thumb",510    };511    return {g_arm64e_compatible_archs};512  }513  case ArchSpec::eCore_arm_arm64: {514    static const char *g_arm64_compatible_archs[] = {515        "arm64",    "armv7",    "armv7f",   "armv7k",   "armv7s",   "armv7m",516        "armv7em",  "armv6m",   "armv6",    "armv5",    "armv4",    "arm",517        "thumbv7",  "thumbv7f", "thumbv7k", "thumbv7s", "thumbv7m", "thumbv7em",518        "thumbv6m", "thumbv6",  "thumbv5",  "thumbv4t", "thumb",519    };520    return {g_arm64_compatible_archs};521  }522  case ArchSpec::eCore_arm_armv7: {523    static const char *g_armv7_compatible_archs[] = {524        "armv7",   "armv6m",   "armv6",   "armv5",   "armv4",    "arm",525        "thumbv7", "thumbv6m", "thumbv6", "thumbv5", "thumbv4t", "thumb",526    };527    return {g_armv7_compatible_archs};528  }529  case ArchSpec::eCore_arm_armv7f: {530    static const char *g_armv7f_compatible_archs[] = {531        "armv7f",  "armv7",   "armv6m",   "armv6",   "armv5",532        "armv4",   "arm",     "thumbv7f", "thumbv7", "thumbv6m",533        "thumbv6", "thumbv5", "thumbv4t", "thumb",534    };535    return {g_armv7f_compatible_archs};536  }537  case ArchSpec::eCore_arm_armv7k: {538    static const char *g_armv7k_compatible_archs[] = {539        "armv7k",  "armv7",   "armv6m",   "armv6",   "armv5",540        "armv4",   "arm",     "thumbv7k", "thumbv7", "thumbv6m",541        "thumbv6", "thumbv5", "thumbv4t", "thumb",542    };543    return {g_armv7k_compatible_archs};544  }545  case ArchSpec::eCore_arm_armv7s: {546    static const char *g_armv7s_compatible_archs[] = {547        "armv7s",  "armv7",   "armv6m",   "armv6",   "armv5",548        "armv4",   "arm",     "thumbv7s", "thumbv7", "thumbv6m",549        "thumbv6", "thumbv5", "thumbv4t", "thumb",550    };551    return {g_armv7s_compatible_archs};552  }553  case ArchSpec::eCore_arm_armv7m: {554    static const char *g_armv7m_compatible_archs[] = {555        "armv7m",  "armv7",   "armv6m",   "armv6",   "armv5",556        "armv4",   "arm",     "thumbv7m", "thumbv7", "thumbv6m",557        "thumbv6", "thumbv5", "thumbv4t", "thumb",558    };559    return {g_armv7m_compatible_archs};560  }561  case ArchSpec::eCore_arm_armv7em: {562    static const char *g_armv7em_compatible_archs[] = {563        "armv7em", "armv7",   "armv6m",    "armv6",   "armv5",564        "armv4",   "arm",     "thumbv7em", "thumbv7", "thumbv6m",565        "thumbv6", "thumbv5", "thumbv4t",  "thumb",566    };567    return {g_armv7em_compatible_archs};568  }569  case ArchSpec::eCore_arm_armv6m: {570    static const char *g_armv6m_compatible_archs[] = {571        "armv6m",   "armv6",   "armv5",   "armv4",    "arm",572        "thumbv6m", "thumbv6", "thumbv5", "thumbv4t", "thumb",573    };574    return {g_armv6m_compatible_archs};575  }576  case ArchSpec::eCore_arm_armv6: {577    static const char *g_armv6_compatible_archs[] = {578        "armv6",   "armv5",   "armv4",    "arm",579        "thumbv6", "thumbv5", "thumbv4t", "thumb",580    };581    return {g_armv6_compatible_archs};582  }583  case ArchSpec::eCore_arm_armv5: {584    static const char *g_armv5_compatible_archs[] = {585        "armv5", "armv4", "arm", "thumbv5", "thumbv4t", "thumb",586    };587    return {g_armv5_compatible_archs};588  }589  case ArchSpec::eCore_arm_armv4: {590    static const char *g_armv4_compatible_archs[] = {591        "armv4",592        "arm",593        "thumbv4t",594        "thumb",595    };596    return {g_armv4_compatible_archs};597  }598  }599  return {};600}601 602/// The architecture selection rules for arm processors These cpu subtypes have603/// distinct names (e.g. armv7f) but armv7 binaries run fine on an armv7f604/// processor.605void PlatformDarwin::ARMGetSupportedArchitectures(606    std::vector<ArchSpec> &archs, std::optional<llvm::Triple::OSType> os) {607  const ArchSpec system_arch = GetSystemArchitecture();608  const ArchSpec::Core system_core = system_arch.GetCore();609  for (const char *arch : GetCompatibleArchs(system_core)) {610    llvm::Triple triple;611    triple.setArchName(arch);612    triple.setVendor(llvm::Triple::VendorType::Apple);613    if (os)614      triple.setOS(*os);615    archs.push_back(ArchSpec(triple));616  }617}618 619static FileSpec GetXcodeSelectPath() {620  static FileSpec g_xcode_select_filespec;621 622  if (!g_xcode_select_filespec) {623    FileSpec xcode_select_cmd("/usr/bin/xcode-select");624    if (FileSystem::Instance().Exists(xcode_select_cmd)) {625      int exit_status = -1;626      int signo = -1;627      std::string command_output;628      Status status =629          Host::RunShellCommand("/usr/bin/xcode-select --print-path",630                                FileSpec(), // current working directory631                                &exit_status, &signo, &command_output,632                                std::chrono::seconds(2), // short timeout633                                false);                  // don't run in a shell634      if (status.Success() && exit_status == 0 && !command_output.empty()) {635        size_t first_non_newline = command_output.find_last_not_of("\r\n");636        if (first_non_newline != std::string::npos) {637          command_output.erase(first_non_newline + 1);638        }639        g_xcode_select_filespec = FileSpec(command_output);640      }641    }642  }643 644  return g_xcode_select_filespec;645}646 647BreakpointSP PlatformDarwin::SetThreadCreationBreakpoint(Target &target) {648  BreakpointSP bp_sp;649  static const char *g_bp_names[] = {650      "start_wqthread", "_pthread_wqthread", "_pthread_start",651  };652 653  static const char *g_bp_modules[] = {"libsystem_c.dylib", "libSystem.B.dylib",654                                       "libsystem_pthread.dylib"};655 656  FileSpecList bp_modules;657  for (size_t i = 0; i < std::size(g_bp_modules); i++) {658    const char *bp_module = g_bp_modules[i];659    bp_modules.EmplaceBack(bp_module);660  }661 662  bool internal = true;663  bool hardware = false;664  LazyBool skip_prologue = eLazyBoolNo;665  bp_sp = target.CreateBreakpoint(&bp_modules, nullptr, g_bp_names,666                                  std::size(g_bp_names), eFunctionNameTypeFull,667                                  eLanguageTypeUnknown, 0, skip_prologue,668                                  internal, hardware);669  bp_sp->SetBreakpointKind("thread-creation");670 671  return bp_sp;672}673 674uint32_t675PlatformDarwin::GetResumeCountForLaunchInfo(ProcessLaunchInfo &launch_info) {676  const FileSpec &shell = launch_info.GetShell();677  if (!shell)678    return 1;679 680  std::string shell_string = shell.GetPath();681  const char *shell_name = strrchr(shell_string.c_str(), '/');682  if (shell_name == nullptr)683    shell_name = shell_string.c_str();684  else685    shell_name++;686 687  if (strcmp(shell_name, "sh") == 0) {688    // /bin/sh re-exec's itself as /bin/bash requiring another resume. But it689    // only does this if the COMMAND_MODE environment variable is set to690    // "legacy".691    if (launch_info.GetEnvironment().lookup("COMMAND_MODE") == "legacy")692      return 2;693    return 1;694  } else if (strcmp(shell_name, "csh") == 0 ||695             strcmp(shell_name, "tcsh") == 0 ||696             strcmp(shell_name, "zsh") == 0) {697    // csh and tcsh always seem to re-exec themselves.698    return 2;699  } else700    return 1;701}702 703lldb::ProcessSP PlatformDarwin::DebugProcess(ProcessLaunchInfo &launch_info,704                                             Debugger &debugger, Target &target,705                                             Status &error) {706  ProcessSP process_sp;707 708  if (IsHost()) {709    // We are going to hand this process off to debugserver which will be in710    // charge of setting the exit status.  However, we still need to reap it711    // from lldb. So, make sure we use a exit callback which does not set exit712    // status.713    launch_info.SetMonitorProcessCallback(714        &ProcessLaunchInfo::NoOpMonitorCallback);715    process_sp = Platform::DebugProcess(launch_info, debugger, target, error);716  } else {717    if (m_remote_platform_sp)718      process_sp = m_remote_platform_sp->DebugProcess(launch_info, debugger,719                                                      target, error);720    else721      error =722          Status::FromErrorString("the platform is not currently connected");723  }724  return process_sp;725}726 727void PlatformDarwin::CalculateTrapHandlerSymbolNames() {728  m_trap_handlers.push_back(ConstString("_sigtramp"));729}730 731static FileSpec GetCommandLineToolsLibraryPath() {732  static FileSpec g_command_line_tools_filespec;733 734  if (!g_command_line_tools_filespec) {735    FileSpec command_line_tools_path(GetXcodeSelectPath());736    command_line_tools_path.AppendPathComponent("Library");737    if (FileSystem::Instance().Exists(command_line_tools_path)) {738      g_command_line_tools_filespec = command_line_tools_path;739    }740  }741 742  return g_command_line_tools_filespec;743}744 745FileSystem::EnumerateDirectoryResult PlatformDarwin::DirectoryEnumerator(746    void *baton, llvm::sys::fs::file_type file_type, llvm::StringRef path) {747  SDKEnumeratorInfo *enumerator_info = static_cast<SDKEnumeratorInfo *>(baton);748 749  FileSpec spec(path);750  if (XcodeSDK::SDKSupportsModules(enumerator_info->sdk_type, spec)) {751    enumerator_info->found_path = spec;752    return FileSystem::EnumerateDirectoryResult::eEnumerateDirectoryResultNext;753  }754 755  return FileSystem::EnumerateDirectoryResult::eEnumerateDirectoryResultNext;756}757 758FileSpec PlatformDarwin::FindSDKInXcodeForModules(XcodeSDK::Type sdk_type,759                                                  const FileSpec &sdks_spec) {760  // Look inside Xcode for the required installed iOS SDK version761 762  if (!FileSystem::Instance().IsDirectory(sdks_spec)) {763    return FileSpec();764  }765 766  const bool find_directories = true;767  const bool find_files = false;768  const bool find_other = true; // include symlinks769 770  SDKEnumeratorInfo enumerator_info;771 772  enumerator_info.sdk_type = sdk_type;773 774  FileSystem::Instance().EnumerateDirectory(775      sdks_spec.GetPath(), find_directories, find_files, find_other,776      DirectoryEnumerator, &enumerator_info);777 778  if (FileSystem::Instance().IsDirectory(enumerator_info.found_path))779    return enumerator_info.found_path;780  else781    return FileSpec();782}783 784FileSpec PlatformDarwin::GetSDKDirectoryForModules(XcodeSDK::Type sdk_type) {785  FileSpec sdks_spec = HostInfo::GetXcodeContentsDirectory();786  sdks_spec.AppendPathComponent("Developer");787  sdks_spec.AppendPathComponent("Platforms");788 789  switch (sdk_type) {790  case XcodeSDK::Type::MacOSX:791    sdks_spec.AppendPathComponent("MacOSX.platform");792    break;793  case XcodeSDK::Type::iPhoneSimulator:794    sdks_spec.AppendPathComponent("iPhoneSimulator.platform");795    break;796  case XcodeSDK::Type::iPhoneOS:797    sdks_spec.AppendPathComponent("iPhoneOS.platform");798    break;799  case XcodeSDK::Type::WatchSimulator:800    sdks_spec.AppendPathComponent("WatchSimulator.platform");801    break;802  case XcodeSDK::Type::AppleTVSimulator:803    sdks_spec.AppendPathComponent("AppleTVSimulator.platform");804    break;805  case XcodeSDK::Type::XRSimulator:806    sdks_spec.AppendPathComponent("XRSimulator.platform");807    break;808  default:809    llvm_unreachable("unsupported sdk");810  }811 812  sdks_spec.AppendPathComponent("Developer");813  sdks_spec.AppendPathComponent("SDKs");814 815  if (sdk_type == XcodeSDK::Type::MacOSX) {816    llvm::VersionTuple version = HostInfo::GetOSVersion();817 818    if (!version.empty()) {819      if (XcodeSDK::SDKSupportsModules(XcodeSDK::Type::MacOSX, version)) {820        // If the Xcode SDKs are not available then try to use the821        // Command Line Tools one which is only for MacOSX.822        if (!FileSystem::Instance().Exists(sdks_spec)) {823          sdks_spec = GetCommandLineToolsLibraryPath();824          sdks_spec.AppendPathComponent("SDKs");825        }826 827        // We slightly prefer the exact SDK for this machine.  See if it is828        // there.829 830        FileSpec native_sdk_spec = sdks_spec;831        StreamString native_sdk_name;832        native_sdk_name.Printf("MacOSX%u.%u.sdk", version.getMajor(),833                               version.getMinor().value_or(0));834        native_sdk_spec.AppendPathComponent(native_sdk_name.GetString());835 836        if (FileSystem::Instance().Exists(native_sdk_spec)) {837          return native_sdk_spec;838        }839      }840    }841  }842 843  return FindSDKInXcodeForModules(sdk_type, sdks_spec);844}845 846std::tuple<llvm::VersionTuple, llvm::StringRef>847PlatformDarwin::ParseVersionBuildDir(llvm::StringRef dir) {848  llvm::StringRef build;849  llvm::StringRef version_str;850  llvm::StringRef build_str;851  std::tie(version_str, build_str) = dir.split(' ');852  llvm::VersionTuple version;853  if (!version.tryParse(version_str) ||854      build_str.empty()) {855    if (build_str.consume_front("(")) {856      size_t pos = build_str.find(')');857      build = build_str.slice(0, pos);858    }859  }860 861  return std::make_tuple(version, build);862}863 864llvm::Expected<StructuredData::DictionarySP>865PlatformDarwin::FetchExtendedCrashInformation(Process &process) {866  static constexpr llvm::StringLiteral crash_info_key("Crash-Info Annotations");867  static constexpr llvm::StringLiteral asi_info_key(868      "Application Specific Information");869 870  // We cache the information we find in the process extended info dict:871  StructuredData::DictionarySP process_dict_sp =872      process.GetExtendedCrashInfoDict();873  StructuredData::Array *annotations = nullptr;874  StructuredData::ArraySP new_annotations_sp;875  if (!process_dict_sp->GetValueForKeyAsArray(crash_info_key, annotations)) {876    new_annotations_sp = ExtractCrashInfoAnnotations(process);877    if (new_annotations_sp && new_annotations_sp->GetSize()) {878      process_dict_sp->AddItem(crash_info_key, new_annotations_sp);879      annotations = new_annotations_sp.get();880    }881  }882 883  StructuredData::Dictionary *app_specific_info;884  StructuredData::DictionarySP new_app_specific_info_sp;885  if (!process_dict_sp->GetValueForKeyAsDictionary(asi_info_key,886                                                   app_specific_info)) {887    new_app_specific_info_sp = ExtractAppSpecificInfo(process);888    if (new_app_specific_info_sp && new_app_specific_info_sp->GetSize()) {889      process_dict_sp->AddItem(asi_info_key, new_app_specific_info_sp);890      app_specific_info = new_app_specific_info_sp.get();891    }892  }893 894  // Now get anything else that was in the process info dict, and add it to the895  // return here:896  return process_dict_sp->GetSize() ? process_dict_sp : nullptr;897}898 899StructuredData::ArraySP900PlatformDarwin::ExtractCrashInfoAnnotations(Process &process) {901  Log *log = GetLog(LLDBLog::Process);902 903  ConstString section_name("__crash_info");904  Target &target = process.GetTarget();905  StructuredData::ArraySP array_sp = std::make_shared<StructuredData::Array>();906 907  for (ModuleSP module : target.GetImages().Modules()) {908    SectionList *sections = module->GetSectionList();909 910    std::string module_name = module->GetSpecificationDescription();911 912    // The DYDL module is skipped since it's always loaded when running the913    // binary.914    if (module_name == "/usr/lib/dyld")915      continue;916 917    if (!sections) {918      LLDB_LOG(log, "Module {0} doesn't have any section!", module_name);919      continue;920    }921 922    SectionSP crash_info = sections->FindSectionByName(section_name);923    if (!crash_info) {924      LLDB_LOG(log, "Module {0} doesn't have section {1}!", module_name,925               section_name);926      continue;927    }928 929    addr_t load_addr = crash_info->GetLoadBaseAddress(&target);930 931    if (load_addr == LLDB_INVALID_ADDRESS) {932      LLDB_LOG(log, "Module {0} has an invalid '{1}' section load address: {2}",933               module_name, section_name, load_addr);934      continue;935    }936 937    Status error;938    CrashInfoAnnotations annotations;939    size_t expected_size = sizeof(CrashInfoAnnotations);940    size_t bytes_read = process.ReadMemoryFromInferior(load_addr, &annotations,941                                                       expected_size, error);942 943    if (expected_size != bytes_read || error.Fail()) {944      LLDB_LOG(log, "Failed to read {0} section from memory in module {1}: {2}",945               section_name, module_name, error);946      continue;947    }948 949    // initial support added for version 5950    if (annotations.version < 5) {951      LLDB_LOG(log,952               "Annotation version lower than 5 unsupported! Module {0} has "953               "version {1} instead.",954               module_name, annotations.version);955      continue;956    }957 958    if (!annotations.message) {959      LLDB_LOG(log, "No message available for module {0}.", module_name);960      continue;961    }962 963    std::string message;964    bytes_read =965        process.ReadCStringFromMemory(annotations.message, message, error);966 967    if (message.empty() || bytes_read != message.size() || error.Fail()) {968      LLDB_LOG(log, "Failed to read the message from memory in module {0}: {1}",969               module_name, error);970      continue;971    }972 973    // Remove trailing newline from message974    if (message.back() == '\n')975      message.pop_back();976 977    if (!annotations.message2)978      LLDB_LOG(log, "No message2 available for module {0}.", module_name);979 980    std::string message2;981    bytes_read =982        process.ReadCStringFromMemory(annotations.message2, message2, error);983 984    if (!message2.empty() && bytes_read == message2.size() && error.Success())985      if (message2.back() == '\n')986        message2.pop_back();987 988    StructuredData::DictionarySP entry_sp =989        std::make_shared<StructuredData::Dictionary>();990 991    entry_sp->AddStringItem("image", module->GetFileSpec().GetPath(false));992    entry_sp->AddStringItem("uuid", module->GetUUID().GetAsString());993    entry_sp->AddStringItem("message", message);994    entry_sp->AddStringItem("message2", message2);995    entry_sp->AddIntegerItem("abort-cause", annotations.abort_cause);996 997    array_sp->AddItem(entry_sp);998  }999 1000  return array_sp;1001}1002 1003StructuredData::DictionarySP1004PlatformDarwin::ExtractAppSpecificInfo(Process &process) {1005  StructuredData::DictionarySP metadata_sp = process.GetMetadata();1006 1007  if (!metadata_sp || !metadata_sp->GetSize() || !metadata_sp->HasKey("asi"))1008    return {};1009 1010  StructuredData::Dictionary *asi;1011  if (!metadata_sp->GetValueForKeyAsDictionary("asi", asi))1012    return {};1013 1014  StructuredData::DictionarySP dict_sp =1015      std::make_shared<StructuredData::Dictionary>();1016 1017  auto flatten_asi_dict = [&dict_sp](llvm::StringRef key,1018                                     StructuredData::Object *val) -> bool {1019    if (!val)1020      return false;1021 1022    StructuredData::Array *arr = val->GetAsArray();1023    if (!arr || !arr->GetSize())1024      return false;1025 1026    dict_sp->AddItem(key, arr->GetItemAtIndex(0));1027    return true;1028  };1029 1030  asi->ForEach(flatten_asi_dict);1031 1032  return dict_sp;1033}1034 1035static llvm::Expected<lldb_private::FileSpec>1036ResolveSDKPathFromDebugInfo(lldb_private::Target *target) {1037 1038  ModuleSP exe_module_sp = target->GetExecutableModule();1039  if (!exe_module_sp)1040    return llvm::createStringError("Failed to get module from target");1041 1042  SymbolFile *sym_file = exe_module_sp->GetSymbolFile();1043  if (!sym_file)1044    return llvm::createStringError("Failed to get symbol file from executable");1045 1046  if (sym_file->GetNumCompileUnits() == 0)1047    return llvm::createStringError(1048        "Failed to resolve SDK for target: executable's symbol file has no "1049        "compile units");1050 1051  XcodeSDK merged_sdk;1052  for (unsigned i = 0; i < sym_file->GetNumCompileUnits(); ++i) {1053    if (auto cu_sp = sym_file->GetCompileUnitAtIndex(i)) {1054      auto cu_sdk = sym_file->ParseXcodeSDK(*cu_sp);1055      merged_sdk.Merge(cu_sdk);1056    }1057  }1058 1059  // TODO: The result of this loop is almost equivalent to deriving the SDK1060  // from the target triple, which would be a lot cheaper.1061  FileSpec sdk_path = merged_sdk.GetSysroot();1062  if (FileSystem::Instance().Exists(sdk_path)) {1063    return sdk_path;1064  }1065  auto path_or_err = HostInfo::GetSDKRoot(HostInfo::SDKOptions{merged_sdk});1066  if (!path_or_err)1067    return llvm::createStringError(1068        llvm::formatv("Failed to resolve SDK path: {0}",1069                      llvm::toString(path_or_err.takeError())));1070 1071  return FileSpec(*path_or_err);1072}1073 1074void PlatformDarwin::AddClangModuleCompilationOptionsForSDKType(1075    Target *target, std::vector<std::string> &options, XcodeSDK::Type sdk_type) {1076  const std::vector<std::string> apple_arguments = {1077      "-x",       "objective-c++", "-fobjc-arc",1078      "-fblocks", "-D_ISO646_H",   "-D__ISO646_H",1079      "-fgnuc-version=4.2.1"};1080 1081  options.insert(options.end(), apple_arguments.begin(), apple_arguments.end());1082 1083  StreamString minimum_version_option;1084  bool use_current_os_version = false;1085  // If the SDK type is for the host OS, use its version number.1086  auto get_host_os = []() { return HostInfo::GetTargetTriple().getOS(); };1087  switch (sdk_type) {1088  case XcodeSDK::Type::MacOSX:1089    use_current_os_version = get_host_os() == llvm::Triple::MacOSX;1090    break;1091  case XcodeSDK::Type::iPhoneOS:1092    use_current_os_version = get_host_os() == llvm::Triple::IOS;1093    break;1094  case XcodeSDK::Type::AppleTVOS:1095    use_current_os_version = get_host_os() == llvm::Triple::TvOS;1096    break;1097  case XcodeSDK::Type::watchOS:1098    use_current_os_version = get_host_os() == llvm::Triple::WatchOS;1099    break;1100  case XcodeSDK::Type::XROS:1101    use_current_os_version = get_host_os() == llvm::Triple::XROS;1102    break;1103  default:1104    break;1105  }1106 1107  llvm::VersionTuple version;1108  if (use_current_os_version)1109    version = GetOSVersion();1110  else if (target) {1111    // Our OS doesn't match our executable so we need to get the min OS version1112    // from the object file1113    ModuleSP exe_module_sp = target->GetExecutableModule();1114    if (exe_module_sp) {1115      ObjectFile *object_file = exe_module_sp->GetObjectFile();1116      if (object_file)1117        version = object_file->GetMinimumOSVersion();1118    }1119  }1120  // Only add the version-min options if we got a version from somewhere.1121  // clang has no version-min clang flag for XROS.1122  if (!version.empty() && sdk_type != XcodeSDK::Type::Linux &&1123      sdk_type != XcodeSDK::Type::XROS) {1124#define OPTION(PREFIX_OFFSET, NAME_OFFSET, VAR, ...)                           \1125  llvm::StringRef opt_##VAR = OptionStrTable[NAME_OFFSET];                     \1126  (void)opt_##VAR;1127#include "clang/Options/Options.inc"1128#undef OPTION1129    minimum_version_option << '-';1130    switch (sdk_type) {1131    case XcodeSDK::Type::MacOSX:1132      minimum_version_option << opt_mmacos_version_min_EQ;1133      break;1134    case XcodeSDK::Type::iPhoneSimulator:1135      minimum_version_option << opt_mios_simulator_version_min_EQ;1136      break;1137    case XcodeSDK::Type::iPhoneOS:1138      minimum_version_option << opt_mios_version_min_EQ;1139      break;1140    case XcodeSDK::Type::AppleTVSimulator:1141      minimum_version_option << opt_mtvos_simulator_version_min_EQ;1142      break;1143    case XcodeSDK::Type::AppleTVOS:1144      minimum_version_option << opt_mtvos_version_min_EQ;1145      break;1146    case XcodeSDK::Type::WatchSimulator:1147      minimum_version_option << opt_mwatchos_simulator_version_min_EQ;1148      break;1149    case XcodeSDK::Type::watchOS:1150      minimum_version_option << opt_mwatchos_version_min_EQ;1151      break;1152    case XcodeSDK::Type::XRSimulator:1153    case XcodeSDK::Type::XROS:1154      // FIXME: Pass the right argument once it exists.1155    case XcodeSDK::Type::BridgeOS:1156    case XcodeSDK::Type::Linux:1157    case XcodeSDK::Type::unknown:1158      if (Log *log = GetLog(LLDBLog::Host)) {1159        XcodeSDK::Info info;1160        info.type = sdk_type;1161        LLDB_LOGF(log, "Clang modules on %s are not supported",1162                  XcodeSDK::GetCanonicalName(info).c_str());1163      }1164      return;1165    }1166    minimum_version_option << version.getAsString();1167    options.emplace_back(std::string(minimum_version_option.GetString()));1168  }1169 1170  FileSpec sysroot_spec;1171 1172  if (target) {1173    auto sysroot_spec_or_err = ::ResolveSDKPathFromDebugInfo(target);1174    if (!sysroot_spec_or_err) {1175      LLDB_LOG_ERROR(GetLog(LLDBLog::Types | LLDBLog::Host),1176                     sysroot_spec_or_err.takeError(),1177                     "Failed to resolve sysroot: {0}");1178    } else {1179      sysroot_spec = *sysroot_spec_or_err;1180    }1181  }1182 1183  if (!FileSystem::Instance().IsDirectory(sysroot_spec.GetPath())) {1184    std::lock_guard<std::mutex> guard(m_mutex);1185    sysroot_spec = GetSDKDirectoryForModules(sdk_type);1186  }1187 1188  if (FileSystem::Instance().IsDirectory(sysroot_spec.GetPath())) {1189    options.push_back("-isysroot");1190    options.push_back(sysroot_spec.GetPath());1191  }1192}1193 1194ConstString PlatformDarwin::GetFullNameForDylib(ConstString basename) {1195  if (basename.IsEmpty())1196    return basename;1197 1198  StreamString stream;1199  stream.Printf("lib%s.dylib", basename.GetCString());1200  return ConstString(stream.GetString());1201}1202 1203llvm::VersionTuple PlatformDarwin::GetOSVersion(Process *process) {1204  if (process && GetPluginName().contains("-simulator")) {1205    lldb_private::ProcessInstanceInfo proc_info;1206    if (Host::GetProcessInfo(process->GetID(), proc_info)) {1207      const Environment &env = proc_info.GetEnvironment();1208 1209      llvm::VersionTuple result;1210      if (!result.tryParse(env.lookup("SIMULATOR_RUNTIME_VERSION")))1211        return result;1212 1213      std::string dyld_root_path = env.lookup("DYLD_ROOT_PATH");1214      if (!dyld_root_path.empty()) {1215        dyld_root_path += "/System/Library/CoreServices/SystemVersion.plist";1216        ApplePropertyList system_version_plist(dyld_root_path.c_str());1217        std::string product_version;1218        if (system_version_plist.GetValueAsString("ProductVersion",1219                                                  product_version)) {1220          if (!result.tryParse(product_version))1221            return result;1222        }1223      }1224    }1225    // For simulator platforms, do NOT call back through1226    // Platform::GetOSVersion() as it might call Process::GetHostOSVersion()1227    // which we don't want as it will be incorrect1228    return llvm::VersionTuple();1229  }1230 1231  return Platform::GetOSVersion(process);1232}1233 1234lldb_private::FileSpec PlatformDarwin::LocateExecutable(const char *basename) {1235  // A collection of SBFileSpec whose SBFileSpec.m_directory members are filled1236  // in with any executable directories that should be searched.1237  static std::vector<FileSpec> g_executable_dirs;1238 1239  // Find the global list of directories that we will search for executables1240  // once so we don't keep doing the work over and over.1241  static llvm::once_flag g_once_flag;1242  llvm::call_once(g_once_flag, []() {1243 1244    // When locating executables, trust the DEVELOPER_DIR first if it is set1245    FileSpec xcode_contents_dir = HostInfo::GetXcodeContentsDirectory();1246    if (xcode_contents_dir) {1247      FileSpec xcode_lldb_resources = xcode_contents_dir;1248      xcode_lldb_resources.AppendPathComponent("SharedFrameworks");1249      xcode_lldb_resources.AppendPathComponent("LLDB.framework");1250      xcode_lldb_resources.AppendPathComponent("Resources");1251      if (FileSystem::Instance().Exists(xcode_lldb_resources)) {1252        FileSpec dir;1253        dir.SetDirectory(xcode_lldb_resources.GetPathAsConstString());1254        g_executable_dirs.push_back(dir);1255      }1256    }1257    // Xcode might not be installed so we also check for the Command Line Tools.1258    FileSpec command_line_tools_dir = GetCommandLineToolsLibraryPath();1259    if (command_line_tools_dir) {1260      FileSpec cmd_line_lldb_resources = command_line_tools_dir;1261      cmd_line_lldb_resources.AppendPathComponent("PrivateFrameworks");1262      cmd_line_lldb_resources.AppendPathComponent("LLDB.framework");1263      cmd_line_lldb_resources.AppendPathComponent("Resources");1264      if (FileSystem::Instance().Exists(cmd_line_lldb_resources)) {1265        FileSpec dir;1266        dir.SetDirectory(cmd_line_lldb_resources.GetPathAsConstString());1267        g_executable_dirs.push_back(dir);1268      }1269    }1270  });1271 1272  // Now search the global list of executable directories for the executable we1273  // are looking for1274  for (const auto &executable_dir : g_executable_dirs) {1275    FileSpec executable_file;1276    executable_file.SetDirectory(executable_dir.GetDirectory());1277    executable_file.SetFilename(basename);1278    if (FileSystem::Instance().Exists(executable_file))1279      return executable_file;1280  }1281 1282  return FileSpec();1283}1284 1285lldb_private::Status1286PlatformDarwin::LaunchProcess(lldb_private::ProcessLaunchInfo &launch_info) {1287  // Starting in Fall 2016 OSes, NSLog messages only get mirrored to stderr if1288  // the OS_ACTIVITY_DT_MODE environment variable is set.  (It doesn't require1289  // any specific value; rather, it just needs to exist). We will set it here1290  // as long as the IDE_DISABLED_OS_ACTIVITY_DT_MODE flag is not set.  Xcode1291  // makes use of IDE_DISABLED_OS_ACTIVITY_DT_MODE to tell1292  // LLDB *not* to muck with the OS_ACTIVITY_DT_MODE flag when they1293  // specifically want it unset.1294  const char *disable_env_var = "IDE_DISABLED_OS_ACTIVITY_DT_MODE";1295  auto &env_vars = launch_info.GetEnvironment();1296  if (!env_vars.count(disable_env_var)) {1297    // We want to make sure that OS_ACTIVITY_DT_MODE is set so that we get1298    // os_log and NSLog messages mirrored to the target process stderr.1299    env_vars.try_emplace("OS_ACTIVITY_DT_MODE", "enable");1300  }1301 1302  // Let our parent class do the real launching.1303  return PlatformPOSIX::LaunchProcess(launch_info);1304}1305 1306lldb_private::Status PlatformDarwin::FindBundleBinaryInExecSearchPaths(1307    const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp,1308    llvm::SmallVectorImpl<ModuleSP> *old_modules, bool *did_create_ptr) {1309  const FileSpec &platform_file = module_spec.GetFileSpec();1310  TargetSP target_sp = module_spec.GetTargetSP();1311  FileSpecList module_search_paths;1312  if (target_sp)1313    module_search_paths = target_sp->GetExecutableSearchPaths();1314  // See if the file is present in any of the module_search_paths1315  // directories.1316  if (!module_sp && !module_search_paths.IsEmpty() && platform_file) {1317    // create a vector of all the file / directory names in platform_file e.g.1318    // this might be1319    // /System/Library/PrivateFrameworks/UIFoundation.framework/UIFoundation1320    //1321    // We'll need to look in the module_search_paths_ptr directories for both1322    // "UIFoundation" and "UIFoundation.framework" -- most likely the latter1323    // will be the one we find there.1324 1325    std::vector<llvm::StringRef> path_parts = platform_file.GetComponents();1326    // We want the components in reverse order.1327    std::reverse(path_parts.begin(), path_parts.end());1328    const size_t path_parts_size = path_parts.size();1329 1330    size_t num_module_search_paths = module_search_paths.GetSize();1331    for (size_t i = 0; i < num_module_search_paths; ++i) {1332      Log *log_verbose = GetLog(LLDBLog::Host);1333      LLDB_LOGF(1334          log_verbose,1335          "PlatformRemoteDarwinDevice::GetSharedModule searching for binary in "1336          "search-path %s",1337          module_search_paths.GetFileSpecAtIndex(i).GetPath().c_str());1338      // Create a new FileSpec with this module_search_paths_ptr plus just the1339      // filename ("UIFoundation"), then the parent dir plus filename1340      // ("UIFoundation.framework/UIFoundation") etc - up to four names (to1341      // handle "Foo.framework/Contents/MacOS/Foo")1342 1343      for (size_t j = 0; j < 4 && j < path_parts_size - 1; ++j) {1344        FileSpec path_to_try(module_search_paths.GetFileSpecAtIndex(i));1345 1346        // Add the components backwards.  For1347        // .../PrivateFrameworks/UIFoundation.framework/UIFoundation path_parts1348        // is1349        //   [0] UIFoundation1350        //   [1] UIFoundation.framework1351        //   [2] PrivateFrameworks1352        //1353        // and if 'j' is 2, we want to append path_parts[1] and then1354        // path_parts[0], aka 'UIFoundation.framework/UIFoundation', to the1355        // module_search_paths_ptr path.1356 1357        for (int k = j; k >= 0; --k) {1358          path_to_try.AppendPathComponent(path_parts[k]);1359        }1360 1361        if (FileSystem::Instance().Exists(path_to_try)) {1362          ModuleSpec new_module_spec(module_spec);1363          new_module_spec.GetFileSpec() = path_to_try;1364          Status new_error(Platform::GetSharedModule(new_module_spec, process,1365                                                     module_sp, old_modules,1366                                                     did_create_ptr));1367 1368          if (module_sp) {1369            module_sp->SetPlatformFileSpec(path_to_try);1370            return new_error;1371          }1372        }1373      }1374    }1375  }1376  return Status();1377}1378 1379llvm::Triple::OSType PlatformDarwin::GetHostOSType() {1380#if !defined(__APPLE__)1381  return llvm::Triple::MacOSX;1382#else1383#if TARGET_OS_OSX1384  return llvm::Triple::MacOSX;1385#elif TARGET_OS_IOS1386  return llvm::Triple::IOS;1387#elif TARGET_OS_WATCH1388  return llvm::Triple::WatchOS;1389#elif TARGET_OS_TV1390  return llvm::Triple::TvOS;1391#elif TARGET_OS_BRIDGE1392  return llvm::Triple::BridgeOS;1393#elif TARGET_OS_XR1394  return llvm::Triple::XROS;1395#else1396#error "LLDB being compiled for an unrecognized Darwin OS"1397#endif1398#endif // __APPLE__1399}1400 1401llvm::Expected<std::pair<XcodeSDK, bool>>1402PlatformDarwin::GetSDKPathFromDebugInfo(Module &module) {1403  SymbolFile *sym_file = module.GetSymbolFile();1404  if (!sym_file)1405    return llvm::createStringError(1406        llvm::inconvertibleErrorCode(),1407        llvm::formatv("No symbol file available for module '{0}'",1408                      module.GetFileSpec().GetFilename().AsCString("")));1409 1410  if (sym_file->GetNumCompileUnits() == 0)1411    return llvm::createStringError(1412        llvm::formatv("Could not resolve SDK for module '{0}'. Symbol file has "1413                      "no compile units.",1414                      module.GetFileSpec()));1415 1416  bool found_public_sdk = false;1417  bool found_internal_sdk = false;1418  XcodeSDK merged_sdk;1419  for (unsigned i = 0; i < sym_file->GetNumCompileUnits(); ++i) {1420    if (auto cu_sp = sym_file->GetCompileUnitAtIndex(i)) {1421      auto cu_sdk = sym_file->ParseXcodeSDK(*cu_sp);1422      bool is_internal_sdk = cu_sdk.IsAppleInternalSDK();1423      found_public_sdk |= !is_internal_sdk;1424      found_internal_sdk |= is_internal_sdk;1425 1426      merged_sdk.Merge(cu_sdk);1427    }1428  }1429 1430  const bool found_mismatch = found_internal_sdk && found_public_sdk;1431 1432  return std::pair{std::move(merged_sdk), found_mismatch};1433}1434 1435llvm::Expected<std::string>1436PlatformDarwin::ResolveSDKPathFromDebugInfo(Module &module) {1437  auto sdk_or_err = GetSDKPathFromDebugInfo(module);1438  if (!sdk_or_err)1439    return llvm::createStringError(1440        llvm::inconvertibleErrorCode(),1441        llvm::formatv("Failed to parse SDK path from debug-info: {0}",1442                      llvm::toString(sdk_or_err.takeError())));1443 1444  auto [sdk, _] = std::move(*sdk_or_err);1445 1446  if (FileSystem::Instance().Exists(sdk.GetSysroot()))1447    return sdk.GetSysroot().GetPath();1448 1449  auto path_or_err = HostInfo::GetSDKRoot(HostInfo::SDKOptions{sdk});1450  if (!path_or_err)1451    return llvm::createStringError(1452        llvm::inconvertibleErrorCode(),1453        llvm::formatv("Error while searching for SDK (XcodeSDK '{0}'): {1}",1454                      sdk.GetString(),1455                      llvm::toString(path_or_err.takeError())));1456 1457  return path_or_err->str();1458}1459 1460llvm::Expected<XcodeSDK>1461PlatformDarwin::GetSDKPathFromDebugInfo(CompileUnit &unit) {1462  ModuleSP module_sp = unit.CalculateSymbolContextModule();1463  if (!module_sp)1464    return llvm::createStringError("compile unit has no module");1465  SymbolFile *sym_file = module_sp->GetSymbolFile();1466  if (!sym_file)1467    return llvm::createStringError(1468        llvm::formatv("No symbol file available for module '{0}'",1469                      module_sp->GetFileSpec().GetFilename()));1470 1471  return sym_file->ParseXcodeSDK(unit);1472}1473 1474llvm::Expected<std::string>1475PlatformDarwin::ResolveSDKPathFromDebugInfo(CompileUnit &unit) {1476  auto sdk_or_err = GetSDKPathFromDebugInfo(unit);1477  if (!sdk_or_err)1478    return llvm::createStringError(1479        llvm::inconvertibleErrorCode(),1480        llvm::formatv("Failed to parse SDK path from debug-info: {0}",1481                      llvm::toString(sdk_or_err.takeError())));1482 1483  auto sdk = std::move(*sdk_or_err);1484 1485  auto path_or_err = HostInfo::GetSDKRoot(HostInfo::SDKOptions{sdk});1486  if (!path_or_err)1487    return llvm::createStringError(1488        llvm::inconvertibleErrorCode(),1489        llvm::formatv("Error while searching for SDK (XcodeSDK '{0}'): {1}",1490                      sdk.GetString(),1491                      llvm::toString(path_or_err.takeError())));1492 1493  return path_or_err->str();1494}1495