brintos

brintos / llvm-project-archived public Read only

0
0
Text · 11.6 KiB · 53fab93 Raw
315 lines · cpp
1//===-- PlatformRemoteDarwinDevice.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 "PlatformRemoteDarwinDevice.h"10 11#include "lldb/Breakpoint/BreakpointLocation.h"12#include "lldb/Core/Module.h"13#include "lldb/Core/ModuleList.h"14#include "lldb/Core/ModuleSpec.h"15#include "lldb/Core/PluginManager.h"16#include "lldb/Host/FileSystem.h"17#include "lldb/Host/Host.h"18#include "lldb/Host/HostInfo.h"19#include "lldb/Target/Process.h"20#include "lldb/Target/Target.h"21#include "lldb/Utility/FileSpec.h"22#include "lldb/Utility/LLDBLog.h"23#include "lldb/Utility/Log.h"24#include "lldb/Utility/Status.h"25#include "lldb/Utility/StreamString.h"26#include <optional>27 28using namespace lldb;29using namespace lldb_private;30 31PlatformRemoteDarwinDevice::SDKDirectoryInfo::SDKDirectoryInfo(32    const lldb_private::FileSpec &sdk_dir)33    : directory(sdk_dir), build(), user_cached(false) {34  llvm::StringRef dirname_str = sdk_dir.GetFilename().GetStringRef();35  llvm::StringRef build_str;36  std::tie(version, build_str) = ParseVersionBuildDir(dirname_str);37  build.SetString(build_str);38}39 40/// Default Constructor41PlatformRemoteDarwinDevice::PlatformRemoteDarwinDevice()42    : PlatformDarwinDevice(false) {} // This is a remote platform43 44/// Destructor.45///46/// The destructor is virtual since this class is designed to be47/// inherited from by the plug-in instance.48PlatformRemoteDarwinDevice::~PlatformRemoteDarwinDevice() = default;49 50void PlatformRemoteDarwinDevice::GetStatus(Stream &strm) {51  Platform::GetStatus(strm);52  const char *sdk_directory = GetDeviceSupportDirectoryForOSVersion();53  if (sdk_directory)54    strm.Printf("  SDK Path: \"%s\"\n", sdk_directory);55  else56    strm.PutCString("  SDK Path: <unable to locate SDK>\n");57 58  const uint32_t num_sdk_infos = m_sdk_directory_infos.size();59  for (uint32_t i = 0; i < num_sdk_infos; ++i) {60    const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i];61    strm.Printf(" SDK Roots: [%2u] \"%s\"\n", i,62                sdk_dir_info.directory.GetPath().c_str());63  }64}65 66bool PlatformRemoteDarwinDevice::GetFileInSDK(const char *platform_file_path,67                                     uint32_t sdk_idx,68                                     lldb_private::FileSpec &local_file) {69  Log *log = GetLog(LLDBLog::Host);70  if (sdk_idx < m_sdk_directory_infos.size()) {71    std::string sdkroot_path =72        m_sdk_directory_infos[sdk_idx].directory.GetPath();73    local_file.Clear();74 75    if (!sdkroot_path.empty() && platform_file_path && platform_file_path[0]) {76      // We may need to interpose "/Symbols/" or "/Symbols.Internal/" between77      // the78      // SDK root directory and the file path.79 80      const char *paths_to_try[] = {"Symbols", "", "Symbols.Internal", nullptr};81      for (size_t i = 0; paths_to_try[i] != nullptr; i++) {82        local_file.SetFile(sdkroot_path, FileSpec::Style::native);83        if (paths_to_try[i][0] != '\0')84          local_file.AppendPathComponent(paths_to_try[i]);85        local_file.AppendPathComponent(platform_file_path);86        FileSystem::Instance().Resolve(local_file);87        if (FileSystem::Instance().Exists(local_file)) {88          LLDB_LOGF(log, "Found a copy of %s in the SDK dir %s/%s",89                    platform_file_path, sdkroot_path.c_str(), paths_to_try[i]);90          return true;91        }92        local_file.Clear();93      }94    }95  }96  return false;97}98 99Status PlatformRemoteDarwinDevice::GetSymbolFile(const FileSpec &platform_file,100                                                 const UUID *uuid_ptr,101                                                 FileSpec &local_file) {102  Log *log = GetLog(LLDBLog::Host);103  Status error;104  char platform_file_path[PATH_MAX];105  if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) {106    const char *os_version_dir = GetDeviceSupportDirectoryForOSVersion();107    if (os_version_dir) {108      std::string resolved_path =109          (llvm::Twine(os_version_dir) + "/" + platform_file_path).str();110 111      local_file.SetFile(resolved_path, FileSpec::Style::native);112      FileSystem::Instance().Resolve(local_file);113      if (FileSystem::Instance().Exists(local_file)) {114        if (log) {115          LLDB_LOGF(log, "Found a copy of %s in the DeviceSupport dir %s",116                    platform_file_path, os_version_dir);117        }118        return error;119      }120 121      resolved_path = (llvm::Twine(os_version_dir) + "/Symbols.Internal/" +122                       platform_file_path)123                          .str();124 125      local_file.SetFile(resolved_path, FileSpec::Style::native);126      FileSystem::Instance().Resolve(local_file);127      if (FileSystem::Instance().Exists(local_file)) {128        LLDB_LOGF(129            log,130            "Found a copy of %s in the DeviceSupport dir %s/Symbols.Internal",131            platform_file_path, os_version_dir);132        return error;133      }134      resolved_path =135          (llvm::Twine(os_version_dir) + "/Symbols/" + platform_file_path)136              .str();137 138      local_file.SetFile(resolved_path, FileSpec::Style::native);139      FileSystem::Instance().Resolve(local_file);140      if (FileSystem::Instance().Exists(local_file)) {141        LLDB_LOGF(log, "Found a copy of %s in the DeviceSupport dir %s/Symbols",142                  platform_file_path, os_version_dir);143        return error;144      }145    }146    local_file = platform_file;147    if (FileSystem::Instance().Exists(local_file))148      return error;149 150    error = Status::FromErrorStringWithFormatv(151        "unable to locate a platform file for '{0}' in platform '{1}'",152        platform_file_path, GetPluginName());153  } else {154    error = Status::FromErrorString("invalid platform file argument");155  }156  return error;157}158 159Status PlatformRemoteDarwinDevice::GetSharedModule(160    const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp,161    llvm::SmallVectorImpl<ModuleSP> *old_modules, bool *did_create_ptr) {162  // For iOS, the SDK files are all cached locally on the host system. So first163  // we ask for the file in the cached SDK, then we attempt to get a shared164  // module for the right architecture with the right UUID.165  const FileSpec &platform_file = module_spec.GetFileSpec();166  Log *log = GetLog(LLDBLog::Host);167 168  Status error;169  char platform_file_path[PATH_MAX];170 171  if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) {172    ModuleSpec platform_module_spec(module_spec);173 174    UpdateSDKDirectoryInfosIfNeeded();175 176    const uint32_t num_sdk_infos = m_sdk_directory_infos.size();177 178    // If we are connected we migth be able to correctly deduce the SDK179    // directory using the OS build.180    const uint32_t connected_sdk_idx = GetConnectedSDKIndex();181    if (connected_sdk_idx < num_sdk_infos) {182      LLDB_LOGV(log, "Searching for {0} in sdk path {1}", platform_file,183                m_sdk_directory_infos[connected_sdk_idx].directory);184      if (GetFileInSDK(platform_file_path, connected_sdk_idx,185                       platform_module_spec.GetFileSpec())) {186        module_sp.reset();187        error = ResolveExecutable(platform_module_spec, module_sp);188        if (module_sp) {189          m_last_module_sdk_idx = connected_sdk_idx;190          error.Clear();191          return error;192        }193      }194    }195 196    // Try the last SDK index if it is set as most files from an SDK will tend197    // to be valid in that same SDK.198    if (m_last_module_sdk_idx < num_sdk_infos) {199      LLDB_LOGV(log, "Searching for {0} in sdk path {1}", platform_file,200                m_sdk_directory_infos[m_last_module_sdk_idx].directory);201      if (GetFileInSDK(platform_file_path, m_last_module_sdk_idx,202                       platform_module_spec.GetFileSpec())) {203        module_sp.reset();204        error = ResolveExecutable(platform_module_spec, module_sp);205        if (module_sp) {206          error.Clear();207          return error;208        }209      }210    }211 212    // First try for an exact match of major, minor and update: If a particalar213    // SDK version was specified via --version or --build, look for a match on214    // disk.215    const SDKDirectoryInfo *current_sdk_info =216        GetSDKDirectoryForCurrentOSVersion();217    const uint32_t current_sdk_idx =218        GetSDKIndexBySDKDirectoryInfo(current_sdk_info);219    if (current_sdk_idx < num_sdk_infos &&220        current_sdk_idx != m_last_module_sdk_idx) {221      LLDB_LOGV(log, "Searching for {0} in sdk path {1}", platform_file,222                m_sdk_directory_infos[current_sdk_idx].directory);223      if (GetFileInSDK(platform_file_path, current_sdk_idx,224                       platform_module_spec.GetFileSpec())) {225        module_sp.reset();226        error = ResolveExecutable(platform_module_spec, module_sp);227        if (module_sp) {228          m_last_module_sdk_idx = current_sdk_idx;229          error.Clear();230          return error;231        }232      }233    }234 235    // Second try all SDKs that were found.236    for (uint32_t sdk_idx = 0; sdk_idx < num_sdk_infos; ++sdk_idx) {237      if (m_last_module_sdk_idx == sdk_idx) {238        // Skip the last module SDK index if we already searched it above239        continue;240      }241      LLDB_LOGV(log, "Searching for {0} in sdk path {1}", platform_file,242                m_sdk_directory_infos[sdk_idx].directory);243      if (GetFileInSDK(platform_file_path, sdk_idx,244                       platform_module_spec.GetFileSpec())) {245        // printf ("sdk[%u]: '%s'\n", sdk_idx, local_file.GetPath().c_str());246 247        error = ResolveExecutable(platform_module_spec, module_sp);248        if (module_sp) {249          // Remember the index of the last SDK that we found a file in in case250          // the wrong SDK was selected.251          m_last_module_sdk_idx = sdk_idx;252          error.Clear();253          return error;254        }255      }256    }257  }258  // Not the module we are looking for... Nothing to see here...259  module_sp.reset();260 261  // This may not be an SDK-related module.  Try whether we can bring in the262  // thing to our local cache.263  error = GetSharedModuleWithLocalCache(module_spec, module_sp, old_modules,264                                        did_create_ptr);265  if (error.Success())266    return error;267 268  // See if the file is present in any of the module_search_paths_ptr269  // directories.270  if (!module_sp)271    error = PlatformDarwin::FindBundleBinaryInExecSearchPaths(272        module_spec, process, module_sp, old_modules, did_create_ptr);273 274  if (error.Success())275    return error;276 277  const bool always_create = false;278  error = ModuleList::GetSharedModule(module_spec, module_sp, old_modules,279                                      did_create_ptr, always_create);280 281  if (module_sp)282    module_sp->SetPlatformFileSpec(platform_file);283 284  return error;285}286 287uint32_t PlatformRemoteDarwinDevice::GetConnectedSDKIndex() {288  if (IsConnected()) {289    if (m_connected_module_sdk_idx == UINT32_MAX) {290      if (std::optional<std::string> build = GetRemoteOSBuildString()) {291        const uint32_t num_sdk_infos = m_sdk_directory_infos.size();292        for (uint32_t i = 0; i < num_sdk_infos; ++i) {293          const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i];294          if (strstr(sdk_dir_info.directory.GetFilename().AsCString(""),295                     build->c_str())) {296            m_connected_module_sdk_idx = i;297          }298        }299      }300    }301  } else {302    m_connected_module_sdk_idx = UINT32_MAX;303  }304  return m_connected_module_sdk_idx;305}306 307uint32_t PlatformRemoteDarwinDevice::GetSDKIndexBySDKDirectoryInfo(308    const SDKDirectoryInfo *sdk_info) {309  if (sdk_info == nullptr) {310    return UINT32_MAX;311  }312 313  return sdk_info - &m_sdk_directory_infos[0];314}315