LLDB mainline
HostInfoBase.cpp
Go to the documentation of this file.
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-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "lldb/Host/Config.h"
10
12#include "lldb/Host/Host.h"
13#include "lldb/Host/HostInfo.h"
17#include "lldb/Utility/Log.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" to
41 // true to all files that were created for the LLDB process can be
42 // 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_plugin_dir_once;
65 FileSpec m_lldb_user_plugin_dir;
66 llvm::once_flag m_lldb_process_tmp_dir_once;
67 FileSpec m_lldb_process_tmp_dir;
68 llvm::once_flag m_lldb_global_tmp_dir_once;
69 FileSpec m_lldb_global_tmp_dir;
70};
71} // namespace
72
73static HostInfoBaseFields *g_fields = nullptr;
75
77 g_shlib_dir_helper = helper;
78 g_fields = new HostInfoBaseFields();
79}
80
82 g_shlib_dir_helper = nullptr;
83 delete g_fields;
84 g_fields = nullptr;
85}
86
88 llvm::call_once(g_fields->m_host_triple_once, []() {
89 g_fields->m_host_triple = HostInfo::GetArchitecture().GetTriple();
90 });
91 return g_fields->m_host_triple;
92}
93
95 llvm::call_once(g_fields->m_host_arch_once, []() {
96 HostInfo::ComputeHostArchitectureSupport(g_fields->m_host_arch_32,
97 g_fields->m_host_arch_64);
98 });
99
100 // If an explicit 32 or 64-bit architecture was requested, return that.
101 if (arch_kind == eArchKind32)
102 return g_fields->m_host_arch_32;
103 if (arch_kind == eArchKind64)
104 return g_fields->m_host_arch_64;
105
106 // Otherwise prefer the 64-bit architecture if it is valid.
107 return (g_fields->m_host_arch_64.IsValid()) ? g_fields->m_host_arch_64
108 : g_fields->m_host_arch_32;
109}
110
111std::optional<HostInfoBase::ArchitectureKind>
113 return llvm::StringSwitch<std::optional<ArchitectureKind>>(kind)
117 .Default(std::nullopt);
118}
119
121 llvm::call_once(g_fields->m_lldb_so_dir_once, []() {
122 if (!HostInfo::ComputeSharedLibraryDirectory(g_fields->m_lldb_so_dir))
123 g_fields->m_lldb_so_dir = FileSpec();
124 Log *log = GetLog(LLDBLog::Host);
125 LLDB_LOG(log, "shlib dir -> `{0}`", g_fields->m_lldb_so_dir);
126 });
127 return g_fields->m_lldb_so_dir;
128}
129
131 llvm::call_once(g_fields->m_lldb_support_exe_dir_once, []() {
132 if (!HostInfo::ComputeSupportExeDirectory(g_fields->m_lldb_support_exe_dir))
133 g_fields->m_lldb_support_exe_dir = FileSpec();
134 Log *log = GetLog(LLDBLog::Host);
135 LLDB_LOG(log, "support exe dir -> `{0}`", g_fields->m_lldb_support_exe_dir);
136 });
137 return g_fields->m_lldb_support_exe_dir;
138}
139
141 llvm::call_once(g_fields->m_lldb_headers_dir_once, []() {
142 if (!HostInfo::ComputeHeaderDirectory(g_fields->m_lldb_headers_dir))
143 g_fields->m_lldb_headers_dir = FileSpec();
144 Log *log = GetLog(LLDBLog::Host);
145 LLDB_LOG(log, "header dir -> `{0}`", g_fields->m_lldb_headers_dir);
146 });
147 return g_fields->m_lldb_headers_dir;
148}
149
151 llvm::call_once(g_fields->m_lldb_system_plugin_dir_once, []() {
152 if (!HostInfo::ComputeSystemPluginsDirectory(
153 g_fields->m_lldb_system_plugin_dir))
154 g_fields->m_lldb_system_plugin_dir = FileSpec();
155 Log *log = GetLog(LLDBLog::Host);
156 LLDB_LOG(log, "system plugin dir -> `{0}`",
157 g_fields->m_lldb_system_plugin_dir);
158 });
159 return g_fields->m_lldb_system_plugin_dir;
160}
161
163 llvm::call_once(g_fields->m_lldb_user_plugin_dir_once, []() {
164 if (!HostInfo::ComputeUserPluginsDirectory(
165 g_fields->m_lldb_user_plugin_dir))
166 g_fields->m_lldb_user_plugin_dir = FileSpec();
167 Log *log = GetLog(LLDBLog::Host);
168 LLDB_LOG(log, "user plugin dir -> `{0}`", g_fields->m_lldb_user_plugin_dir);
169 });
170 return g_fields->m_lldb_user_plugin_dir;
171}
172
174 llvm::call_once(g_fields->m_lldb_process_tmp_dir_once, []() {
175 if (!HostInfo::ComputeProcessTempFileDirectory(
176 g_fields->m_lldb_process_tmp_dir))
177 g_fields->m_lldb_process_tmp_dir = FileSpec();
178 Log *log = GetLog(LLDBLog::Host);
179 LLDB_LOG(log, "process temp dir -> `{0}`",
180 g_fields->m_lldb_process_tmp_dir);
181 });
182 return g_fields->m_lldb_process_tmp_dir;
183}
184
186 llvm::call_once(g_fields->m_lldb_global_tmp_dir_once, []() {
187 if (!HostInfo::ComputeGlobalTempFileDirectory(
188 g_fields->m_lldb_global_tmp_dir))
189 g_fields->m_lldb_global_tmp_dir = FileSpec();
190
191 Log *log = GetLog(LLDBLog::Host);
192 LLDB_LOG(log, "global temp dir -> `{0}`", g_fields->m_lldb_global_tmp_dir);
193 });
194 return g_fields->m_lldb_global_tmp_dir;
195}
196
198 if (triple.empty())
199 return ArchSpec();
200 llvm::Triple normalized_triple(llvm::Triple::normalize(triple));
201 if (!ArchSpec::ContainsOnlyArch(normalized_triple))
202 return ArchSpec(triple);
203
204 if (auto kind = HostInfo::ParseArchitectureKind(triple))
205 return HostInfo::GetArchitecture(*kind);
206
207 llvm::Triple host_triple(llvm::sys::getDefaultTargetTriple());
208
209 if (normalized_triple.getVendorName().empty())
210 normalized_triple.setVendor(host_triple.getVendor());
211 if (normalized_triple.getOSName().empty())
212 normalized_triple.setOS(host_triple.getOS());
213 if (normalized_triple.getEnvironmentName().empty() &&
214 !host_triple.getEnvironmentName().empty())
215 normalized_triple.setEnvironment(host_triple.getEnvironment());
216 return ArchSpec(normalized_triple);
217}
218
220 llvm::StringRef dir) {
221 Log *log = GetLog(LLDBLog::Host);
222
223 FileSpec lldb_file_spec = GetShlibDir();
224 if (!lldb_file_spec)
225 return false;
226
227 std::string raw_path = lldb_file_spec.GetPath();
228 LLDB_LOG(
229 log,
230 "Attempting to derive the path {0} relative to liblldb install path: {1}",
231 dir, raw_path);
232
233 // Drop bin (windows) or lib
234 llvm::StringRef parent_path = llvm::sys::path::parent_path(raw_path);
235 if (parent_path.empty()) {
236 LLDB_LOG(log, "Failed to find liblldb within the shared lib path");
237 return false;
238 }
239
240 raw_path = (parent_path + dir).str();
241 LLDB_LOG(log, "Derived the path as: {0}", raw_path);
242 file_spec.SetDirectory(raw_path);
243 return (bool)file_spec.GetDirectory();
244}
245
247 // To get paths related to LLDB we get the path to the executable that
248 // contains this function. On MacOSX this will be "LLDB.framework/.../LLDB".
249 // On other posix systems, we will get .../lib(64|32)?/liblldb.so.
250
252 reinterpret_cast<void *>(HostInfoBase::ComputeSharedLibraryDirectory)));
253
255 g_shlib_dir_helper(lldb_file_spec);
256
257 // Remove the filename so that this FileSpec only represents the directory.
258 file_spec.SetDirectory(lldb_file_spec.GetDirectory());
259
260 return (bool)file_spec.GetDirectory();
261}
262
264 file_spec = GetShlibDir();
265 return bool(file_spec);
266}
267
269 FileSpec temp_file_spec;
270 if (!HostInfo::ComputeGlobalTempFileDirectory(temp_file_spec))
271 return false;
272
273 std::string pid_str{llvm::to_string(Host::GetCurrentProcessID())};
274 temp_file_spec.AppendPathComponent(pid_str);
275 if (llvm::sys::fs::create_directory(temp_file_spec.GetPath()))
276 return false;
277
278 file_spec.SetDirectory(temp_file_spec.GetPathAsConstString());
279 return true;
280}
281
283 llvm::SmallVector<char, 16> tmpdir;
284 llvm::sys::path::system_temp_directory(/*ErasedOnReboot*/ true, tmpdir);
285 file_spec = FileSpec(std::string(tmpdir.data(), tmpdir.size()));
286 FileSystem::Instance().Resolve(file_spec);
287 return true;
288}
289
291 file_spec.Clear();
292
293 FileSpec temp_file_spec;
294 if (!HostInfo::ComputeTempFileBaseDirectory(temp_file_spec))
295 return false;
296
297 temp_file_spec.AppendPathComponent("lldb");
298 if (llvm::sys::fs::create_directory(temp_file_spec.GetPath()))
299 return false;
300
301 file_spec.SetDirectory(temp_file_spec.GetPathAsConstString());
302 return true;
303}
304
306 // TODO(zturner): Figure out how to compute the header directory for all
307 // platforms.
308 return false;
309}
310
312 // TODO(zturner): Figure out how to compute the system plugins directory for
313 // all platforms.
314 return false;
315}
316
318 // TODO(zturner): Figure out how to compute the user plugins directory for
319 // all platforms.
320 return false;
321}
322
324 ArchSpec &arch_64) {
325 llvm::Triple triple(llvm::sys::getProcessTriple());
326
327 arch_32.Clear();
328 arch_64.Clear();
329
330 switch (triple.getArch()) {
331 default:
332 arch_32.SetTriple(triple);
333 break;
334
335 case llvm::Triple::aarch64:
336 case llvm::Triple::ppc64:
337 case llvm::Triple::ppc64le:
338 case llvm::Triple::x86_64:
339 case llvm::Triple::riscv64:
340 case llvm::Triple::loongarch64:
341 arch_64.SetTriple(triple);
342 arch_32.SetTriple(triple.get32BitArchVariant());
343 break;
344
345 case llvm::Triple::mips64:
346 case llvm::Triple::mips64el:
347 case llvm::Triple::sparcv9:
348 case llvm::Triple::systemz:
349 arch_64.SetTriple(triple);
350 break;
351 }
352}
static HostInfoBase::SharedLibraryDirectoryHelper * g_shlib_dir_helper
static HostInfoBaseFields * g_fields
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
Definition: Log.h:342
constexpr lldb_private::HostInfo::SharedLibraryDirectoryHelper * g_shlib_dir_helper
An architecture specification class.
Definition: ArchSpec.h:31
void Clear()
Clears the object state.
Definition: ArchSpec.cpp:542
bool SetTriple(const llvm::Triple &triple)
Architecture triple setter.
Definition: ArchSpec.cpp:747
static bool ContainsOnlyArch(const llvm::Triple &normalized_triple)
Returns true if the OS, vendor and environment fields of the triple are unset.
Definition: ArchSpec.cpp:802
A file utility class.
Definition: FileSpec.h:56
void AppendPathComponent(llvm::StringRef component)
Definition: FileSpec.cpp:447
void SetDirectory(ConstString directory)
Directory string set accessor.
Definition: FileSpec.cpp:335
const ConstString & GetDirectory() const
Directory string const get accessor.
Definition: FileSpec.h:223
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
Definition: FileSpec.cpp:367
void Clear()
Clears the object state.
Definition: FileSpec.cpp:259
ConstString GetPathAsConstString(bool denormalize=true) const
Get the full path as a ConstString.
Definition: FileSpec.cpp:383
void Resolve(llvm::SmallVectorImpl< char > &path)
Resolve path to make it canonical.
static FileSystem & Instance()
static FileSpec GetGlobalTempDir()
Returns the global temporary directory.
static void ComputeHostArchitectureSupport(ArchSpec &arch_32, ArchSpec &arch_64)
void(FileSpec &this_file) SharedLibraryDirectoryHelper
A helper function for determining the liblldb location.
Definition: HostInfoBase.h:63
static bool ComputeSharedLibraryDirectory(FileSpec &file_spec)
static bool ComputeSupportExeDirectory(FileSpec &file_spec)
static ArchSpec GetAugmentedArchSpec(llvm::StringRef triple)
If the triple does not specify the vendor, os, and environment parts, we "augment" these using inform...
static FileSpec GetHeaderDir()
Returns the directory containing the lldb headers.
static const ArchSpec & GetArchitecture(ArchitectureKind arch_kind=eArchKindDefault)
static std::optional< ArchitectureKind > ParseArchitectureKind(llvm::StringRef kind)
static llvm::Triple GetTargetTriple()
Gets the host target triple.
static bool ComputePathRelativeToLibrary(FileSpec &file_spec, llvm::StringRef dir)
static bool ComputeTempFileBaseDirectory(FileSpec &file_spec)
static FileSpec GetSupportExeDir()
Returns the directory containing the support executables (debugserver, ...).
static bool ComputeUserPluginsDirectory(FileSpec &file_spec)
static FileSpec GetProcessTempDir()
Returns the proces temporary directory.
static bool ComputeHeaderDirectory(FileSpec &file_spec)
static FileSpec GetShlibDir()
Returns the directory containing the lldb shared library.
static FileSpec GetSystemPluginDir()
Returns the directory containing the system plugins.
static bool ComputeGlobalTempFileDirectory(FileSpec &file_spec)
static bool ComputeProcessTempFileDirectory(FileSpec &file_spec)
static FileSpec GetUserPluginDir()
Returns the directory containing the user plugins.
static bool ComputeSystemPluginsDirectory(FileSpec &file_spec)
static void Initialize(SharedLibraryDirectoryHelper *helper=nullptr)
static lldb::pid_t GetCurrentProcessID()
Get the process ID for the calling process.
static FileSpec GetModuleFileSpecForHostAddress(const void *host_addr)
Given an address in the current process (the process that is running the LLDB code),...
#define LLDB_ARCH_DEFAULT_64BIT
Definition: lldb-defines.h:103
#define LLDB_ARCH_DEFAULT
CPU Type definitions.
Definition: lldb-defines.h:101
#define LLDB_ARCH_DEFAULT_32BIT
Definition: lldb-defines.h:102
A class that represents a running process on the host machine.
Definition: SBAttachInfo.h:14
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition: Log.h:314
Definition: SBAddress.h:15