brintos

brintos / llvm-project-archived public Read only

0
0
Text · 13.0 KiB · a02ac77 Raw
393 lines · cpp
1//===-- HostInfoBase.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 "lldb/Host/Config.h"10 11#include "lldb/Host/FileSystem.h"12#include "lldb/Host/Host.h"13#include "lldb/Host/HostInfo.h"14#include "lldb/Host/HostInfoBase.h"15#include "lldb/Utility/ArchSpec.h"16#include "lldb/Utility/LLDBLog.h"17#include "lldb/Utility/Log.h"18#include "lldb/Utility/StreamString.h"19 20#include "llvm/ADT/StringExtras.h"21#include "llvm/Support/Path.h"22#include "llvm/Support/ScopedPrinter.h"23#include "llvm/Support/Threading.h"24#include "llvm/Support/raw_ostream.h"25#include "llvm/TargetParser/Host.h"26#include "llvm/TargetParser/Triple.h"27 28#include <mutex>29#include <optional>30#include <thread>31 32using namespace lldb;33using namespace lldb_private;34 35namespace {36/// Contains the state of the HostInfoBase plugin.37struct HostInfoBaseFields {38  ~HostInfoBaseFields() {39    if (FileSystem::Instance().Exists(m_lldb_process_tmp_dir)) {40      // Remove the LLDB temporary directory if we have one. Set "recurse" to41      // true to all files that were created for the LLDB process can be42      // cleaned up.43      llvm::sys::fs::remove_directories(m_lldb_process_tmp_dir.GetPath());44    }45  }46 47  llvm::once_flag m_host_triple_once;48  llvm::Triple m_host_triple;49 50  llvm::once_flag m_host_arch_once;51  ArchSpec m_host_arch_32;52  ArchSpec m_host_arch_64;53 54  llvm::once_flag m_lldb_so_dir_once;55  FileSpec m_lldb_so_dir;56  llvm::once_flag m_lldb_support_exe_dir_once;57  FileSpec m_lldb_support_exe_dir;58  llvm::once_flag m_lldb_headers_dir_once;59  FileSpec m_lldb_headers_dir;60  llvm::once_flag m_lldb_clang_resource_dir_once;61  FileSpec m_lldb_clang_resource_dir;62  llvm::once_flag m_lldb_system_plugin_dir_once;63  FileSpec m_lldb_system_plugin_dir;64  llvm::once_flag m_lldb_user_home_dir_once;65  FileSpec m_lldb_user_home_dir;66  llvm::once_flag m_lldb_user_lldb_dir_once;67  FileSpec m_lldb_user_lldb_dir;68  llvm::once_flag m_lldb_user_plugin_dir_once;69  FileSpec m_lldb_user_plugin_dir;70  llvm::once_flag m_lldb_process_tmp_dir_once;71  FileSpec m_lldb_process_tmp_dir;72  llvm::once_flag m_lldb_global_tmp_dir_once;73  FileSpec m_lldb_global_tmp_dir;74};75} // namespace76 77static HostInfoBaseFields *g_fields = nullptr;78static HostInfoBase::SharedLibraryDirectoryHelper *g_shlib_dir_helper = nullptr;79 80void HostInfoBase::Initialize(SharedLibraryDirectoryHelper *helper) {81  g_shlib_dir_helper = helper;82  g_fields = new HostInfoBaseFields();83  LogChannelSystem::Initialize();84}85 86void HostInfoBase::Terminate() {87  LogChannelSystem::Terminate();88  g_shlib_dir_helper = nullptr;89  delete g_fields;90  g_fields = nullptr;91}92 93llvm::Triple HostInfoBase::GetTargetTriple() {94  llvm::call_once(g_fields->m_host_triple_once, []() {95    g_fields->m_host_triple = HostInfo::GetArchitecture().GetTriple();96  });97  return g_fields->m_host_triple;98}99 100const ArchSpec &HostInfoBase::GetArchitecture(ArchitectureKind arch_kind) {101  llvm::call_once(g_fields->m_host_arch_once, []() {102    HostInfo::ComputeHostArchitectureSupport(g_fields->m_host_arch_32,103                                             g_fields->m_host_arch_64);104  });105 106  // If an explicit 32 or 64-bit architecture was requested, return that.107  if (arch_kind == eArchKind32)108    return g_fields->m_host_arch_32;109  if (arch_kind == eArchKind64)110    return g_fields->m_host_arch_64;111 112  // Otherwise prefer the 64-bit architecture if it is valid.113  return (g_fields->m_host_arch_64.IsValid()) ? g_fields->m_host_arch_64114                                              : g_fields->m_host_arch_32;115}116 117std::optional<HostInfoBase::ArchitectureKind>118HostInfoBase::ParseArchitectureKind(llvm::StringRef kind) {119  return llvm::StringSwitch<std::optional<ArchitectureKind>>(kind)120      .Case(LLDB_ARCH_DEFAULT, eArchKindDefault)121      .Case(LLDB_ARCH_DEFAULT_32BIT, eArchKind32)122      .Case(LLDB_ARCH_DEFAULT_64BIT, eArchKind64)123      .Default(std::nullopt);124}125 126FileSpec HostInfoBase::GetShlibDir() {127  llvm::call_once(g_fields->m_lldb_so_dir_once, []() {128    if (!HostInfo::ComputeSharedLibraryDirectory(g_fields->m_lldb_so_dir))129      g_fields->m_lldb_so_dir = FileSpec();130    Log *log = GetLog(LLDBLog::Host);131    LLDB_LOG(log, "shlib dir -> `{0}`", g_fields->m_lldb_so_dir);132  });133  return g_fields->m_lldb_so_dir;134}135 136FileSpec HostInfoBase::GetSupportExeDir() {137  llvm::call_once(g_fields->m_lldb_support_exe_dir_once, []() {138    if (!HostInfo::ComputeSupportExeDirectory(g_fields->m_lldb_support_exe_dir))139      g_fields->m_lldb_support_exe_dir = FileSpec();140    Log *log = GetLog(LLDBLog::Host);141    LLDB_LOG(log, "support exe dir -> `{0}`", g_fields->m_lldb_support_exe_dir);142  });143  return g_fields->m_lldb_support_exe_dir;144}145 146FileSpec HostInfoBase::GetHeaderDir() {147  llvm::call_once(g_fields->m_lldb_headers_dir_once, []() {148    if (!HostInfo::ComputeHeaderDirectory(g_fields->m_lldb_headers_dir))149      g_fields->m_lldb_headers_dir = FileSpec();150    Log *log = GetLog(LLDBLog::Host);151    LLDB_LOG(log, "header dir -> `{0}`", g_fields->m_lldb_headers_dir);152  });153  return g_fields->m_lldb_headers_dir;154}155 156FileSpec HostInfoBase::GetSystemPluginDir() {157  llvm::call_once(g_fields->m_lldb_system_plugin_dir_once, []() {158    if (!HostInfo::ComputeSystemPluginsDirectory(159            g_fields->m_lldb_system_plugin_dir))160      g_fields->m_lldb_system_plugin_dir = FileSpec();161    Log *log = GetLog(LLDBLog::Host);162    LLDB_LOG(log, "system plugin dir -> `{0}`",163             g_fields->m_lldb_system_plugin_dir);164  });165  return g_fields->m_lldb_system_plugin_dir;166}167 168FileSpec HostInfoBase::GetUserHomeDir() {169  llvm::call_once(g_fields->m_lldb_user_home_dir_once, []() {170    if (!HostInfo::ComputeUserHomeDirectory(g_fields->m_lldb_user_home_dir))171      g_fields->m_lldb_user_home_dir = FileSpec();172    LLDB_LOG(GetLog(LLDBLog::Host), "user home dir -> `{0}`",173             g_fields->m_lldb_user_home_dir);174  });175  return g_fields->m_lldb_user_home_dir;176}177 178FileSpec HostInfoBase::GetUserLLDBDir() {179  llvm::call_once(g_fields->m_lldb_user_lldb_dir_once, []() {180    if (!HostInfo::ComputeUserLLDBHomeDirectory(g_fields->m_lldb_user_lldb_dir))181      g_fields->m_lldb_user_lldb_dir = FileSpec();182    LLDB_LOG(GetLog(LLDBLog::Host), "user lldb home dir -> `{0}`",183             g_fields->m_lldb_user_lldb_dir);184  });185  return g_fields->m_lldb_user_lldb_dir;186}187 188FileSpec HostInfoBase::GetUserPluginDir() {189  llvm::call_once(g_fields->m_lldb_user_plugin_dir_once, []() {190    if (!HostInfo::ComputeUserPluginsDirectory(191            g_fields->m_lldb_user_plugin_dir))192      g_fields->m_lldb_user_plugin_dir = FileSpec();193    Log *log = GetLog(LLDBLog::Host);194    LLDB_LOG(log, "user plugin dir -> `{0}`", g_fields->m_lldb_user_plugin_dir);195  });196  return g_fields->m_lldb_user_plugin_dir;197}198 199FileSpec HostInfoBase::GetProcessTempDir() {200  llvm::call_once(g_fields->m_lldb_process_tmp_dir_once, []() {201    if (!HostInfo::ComputeProcessTempFileDirectory(202            g_fields->m_lldb_process_tmp_dir))203      g_fields->m_lldb_process_tmp_dir = FileSpec();204    Log *log = GetLog(LLDBLog::Host);205    LLDB_LOG(log, "process temp dir -> `{0}`",206             g_fields->m_lldb_process_tmp_dir);207  });208  return g_fields->m_lldb_process_tmp_dir;209}210 211FileSpec HostInfoBase::GetGlobalTempDir() {212  llvm::call_once(g_fields->m_lldb_global_tmp_dir_once, []() {213    if (!HostInfo::ComputeGlobalTempFileDirectory(214            g_fields->m_lldb_global_tmp_dir))215      g_fields->m_lldb_global_tmp_dir = FileSpec();216 217    Log *log = GetLog(LLDBLog::Host);218    LLDB_LOG(log, "global temp dir -> `{0}`", g_fields->m_lldb_global_tmp_dir);219  });220  return g_fields->m_lldb_global_tmp_dir;221}222 223ArchSpec HostInfoBase::GetAugmentedArchSpec(llvm::StringRef triple) {224  if (triple.empty())225    return ArchSpec();226  llvm::Triple normalized_triple(llvm::Triple::normalize(triple));227  if (!ArchSpec::ContainsOnlyArch(normalized_triple))228    return ArchSpec(triple);229 230  if (auto kind = HostInfo::ParseArchitectureKind(triple))231    return HostInfo::GetArchitecture(*kind);232 233  llvm::Triple host_triple(llvm::sys::getDefaultTargetTriple());234 235  if (normalized_triple.getVendorName().empty())236    normalized_triple.setVendor(host_triple.getVendor());237  if (normalized_triple.getOSName().empty())238    normalized_triple.setOS(host_triple.getOS());239  if (normalized_triple.getEnvironmentName().empty() &&240      !host_triple.getEnvironmentName().empty())241    normalized_triple.setEnvironment(host_triple.getEnvironment());242  return ArchSpec(normalized_triple);243}244 245bool HostInfoBase::ComputePathRelativeToLibrary(FileSpec &file_spec,246                                                llvm::StringRef dir) {247  Log *log = GetLog(LLDBLog::Host);248 249  FileSpec lldb_file_spec = GetShlibDir();250  if (!lldb_file_spec)251    return false;252 253  std::string raw_path = lldb_file_spec.GetPath();254  LLDB_LOG(255      log,256      "Attempting to derive the path {0} relative to liblldb install path: {1}",257      dir, raw_path);258 259  // Drop bin (windows) or lib260  llvm::StringRef parent_path = llvm::sys::path::parent_path(raw_path);261  if (parent_path.empty()) {262    LLDB_LOG(log, "Failed to find liblldb within the shared lib path");263    return false;264  }265 266  raw_path = (parent_path + dir).str();267  LLDB_LOG(log, "Derived the path as: {0}", raw_path);268  file_spec.SetDirectory(raw_path);269  return (bool)file_spec.GetDirectory();270}271 272bool HostInfoBase::ComputeSharedLibraryDirectory(FileSpec &file_spec) {273  // To get paths related to LLDB we get the path to the executable that274  // contains this function. On MacOSX this will be "LLDB.framework/.../LLDB".275  // On other posix systems, we will get .../lib(64|32)?/liblldb.so.276 277  FileSpec lldb_file_spec(Host::GetModuleFileSpecForHostAddress(278      reinterpret_cast<void *>(HostInfoBase::ComputeSharedLibraryDirectory)));279 280  if (g_shlib_dir_helper)281    g_shlib_dir_helper(lldb_file_spec);282 283  // Remove the filename so that this FileSpec only represents the directory.284  file_spec.SetDirectory(lldb_file_spec.GetDirectory());285 286  return (bool)file_spec.GetDirectory();287}288 289bool HostInfoBase::ComputeSupportExeDirectory(FileSpec &file_spec) {290  file_spec = GetShlibDir();291  return bool(file_spec);292}293 294bool HostInfoBase::ComputeProcessTempFileDirectory(FileSpec &file_spec) {295  FileSpec temp_file_spec;296  if (!HostInfo::ComputeGlobalTempFileDirectory(temp_file_spec))297    return false;298 299  std::string pid_str{llvm::to_string(Host::GetCurrentProcessID())};300  temp_file_spec.AppendPathComponent(pid_str);301  if (llvm::sys::fs::create_directory(temp_file_spec.GetPath()))302    return false;303 304  file_spec.SetDirectory(temp_file_spec.GetPathAsConstString());305  return true;306}307 308bool HostInfoBase::ComputeTempFileBaseDirectory(FileSpec &file_spec) {309  llvm::SmallVector<char, 16> tmpdir;310  llvm::sys::path::system_temp_directory(/*ErasedOnReboot*/ true, tmpdir);311  file_spec = FileSpec(std::string(tmpdir.data(), tmpdir.size()));312  FileSystem::Instance().Resolve(file_spec);313  return true;314}315 316bool HostInfoBase::ComputeGlobalTempFileDirectory(FileSpec &file_spec) {317  file_spec.Clear();318 319  FileSpec temp_file_spec;320  if (!HostInfo::ComputeTempFileBaseDirectory(temp_file_spec))321    return false;322 323  temp_file_spec.AppendPathComponent("lldb");324  if (llvm::sys::fs::create_directory(temp_file_spec.GetPath()))325    return false;326 327  file_spec.SetDirectory(temp_file_spec.GetPathAsConstString());328  return true;329}330 331bool HostInfoBase::ComputeHeaderDirectory(FileSpec &file_spec) {332  // TODO(zturner): Figure out how to compute the header directory for all333  // platforms.334  return false;335}336 337bool HostInfoBase::ComputeSystemPluginsDirectory(FileSpec &file_spec) {338  // TODO(zturner): Figure out how to compute the system plugins directory for339  // all platforms.340  return false;341}342 343bool HostInfoBase::ComputeUserHomeDirectory(FileSpec &file_spec) {344  FileSpec temp_file("~");345  FileSystem::Instance().Resolve(temp_file);346  file_spec.SetDirectory(temp_file.GetPathAsConstString());347  return true;348}349 350bool HostInfoBase::ComputeUserLLDBHomeDirectory(FileSpec &file_spec) {351  FileSpec home_dir_spec = GetUserHomeDir();352  home_dir_spec.AppendPathComponent(".lldb");353  file_spec.SetDirectory(home_dir_spec.GetPathAsConstString());354  return true;355}356 357bool HostInfoBase::ComputeUserPluginsDirectory(FileSpec &file_spec) {358  // TODO(zturner): Figure out how to compute the user plugins directory for359  // all platforms.360  return false;361}362 363void HostInfoBase::ComputeHostArchitectureSupport(ArchSpec &arch_32,364                                                  ArchSpec &arch_64) {365  llvm::Triple triple(llvm::sys::getProcessTriple());366 367  arch_32.Clear();368  arch_64.Clear();369 370  switch (triple.getArch()) {371  default:372    arch_32.SetTriple(triple);373    break;374 375  case llvm::Triple::aarch64:376  case llvm::Triple::ppc64:377  case llvm::Triple::ppc64le:378  case llvm::Triple::x86_64:379  case llvm::Triple::riscv64:380  case llvm::Triple::loongarch64:381    arch_64.SetTriple(triple);382    arch_32.SetTriple(triple.get32BitArchVariant());383    break;384 385  case llvm::Triple::mips64:386  case llvm::Triple::mips64el:387  case llvm::Triple::sparcv9:388  case llvm::Triple::systemz:389    arch_64.SetTriple(triple);390    break;391  }392}393