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();
80}
81
84 g_shlib_dir_helper = nullptr;
85 delete g_fields;
86 g_fields = nullptr;
87}
88
90 llvm::call_once(g_fields->m_host_triple_once, []() {
91 g_fields->m_host_triple = HostInfo::GetArchitecture().GetTriple();
92 });
93 return g_fields->m_host_triple;
94}
95
97 llvm::call_once(g_fields->m_host_arch_once, []() {
98 HostInfo::ComputeHostArchitectureSupport(g_fields->m_host_arch_32,
99 g_fields->m_host_arch_64);
100 });
101
102 // If an explicit 32 or 64-bit architecture was requested, return that.
103 if (arch_kind == eArchKind32)
104 return g_fields->m_host_arch_32;
105 if (arch_kind == eArchKind64)
106 return g_fields->m_host_arch_64;
107
108 // Otherwise prefer the 64-bit architecture if it is valid.
109 return (g_fields->m_host_arch_64.IsValid()) ? g_fields->m_host_arch_64
110 : g_fields->m_host_arch_32;
111}
112
113std::optional<HostInfoBase::ArchitectureKind>
115 return llvm::StringSwitch<std::optional<ArchitectureKind>>(kind)
119 .Default(std::nullopt);
120}
121
123 llvm::call_once(g_fields->m_lldb_so_dir_once, []() {
124 if (!HostInfo::ComputeSharedLibraryDirectory(g_fields->m_lldb_so_dir))
125 g_fields->m_lldb_so_dir = FileSpec();
126 Log *log = GetLog(LLDBLog::Host);
127 LLDB_LOG(log, "shlib dir -> `{0}`", g_fields->m_lldb_so_dir);
128 });
129 return g_fields->m_lldb_so_dir;
130}
131
133 llvm::call_once(g_fields->m_lldb_support_exe_dir_once, []() {
134 if (!HostInfo::ComputeSupportExeDirectory(g_fields->m_lldb_support_exe_dir))
135 g_fields->m_lldb_support_exe_dir = FileSpec();
136 Log *log = GetLog(LLDBLog::Host);
137 LLDB_LOG(log, "support exe dir -> `{0}`", g_fields->m_lldb_support_exe_dir);
138 });
139 return g_fields->m_lldb_support_exe_dir;
140}
141
143 llvm::call_once(g_fields->m_lldb_headers_dir_once, []() {
144 if (!HostInfo::ComputeHeaderDirectory(g_fields->m_lldb_headers_dir))
145 g_fields->m_lldb_headers_dir = FileSpec();
146 Log *log = GetLog(LLDBLog::Host);
147 LLDB_LOG(log, "header dir -> `{0}`", g_fields->m_lldb_headers_dir);
148 });
149 return g_fields->m_lldb_headers_dir;
150}
151
153 llvm::call_once(g_fields->m_lldb_system_plugin_dir_once, []() {
154 if (!HostInfo::ComputeSystemPluginsDirectory(
155 g_fields->m_lldb_system_plugin_dir))
156 g_fields->m_lldb_system_plugin_dir = FileSpec();
157 Log *log = GetLog(LLDBLog::Host);
158 LLDB_LOG(log, "system plugin dir -> `{0}`",
159 g_fields->m_lldb_system_plugin_dir);
160 });
161 return g_fields->m_lldb_system_plugin_dir;
162}
163
165 llvm::call_once(g_fields->m_lldb_user_plugin_dir_once, []() {
166 if (!HostInfo::ComputeUserPluginsDirectory(
167 g_fields->m_lldb_user_plugin_dir))
168 g_fields->m_lldb_user_plugin_dir = FileSpec();
169 Log *log = GetLog(LLDBLog::Host);
170 LLDB_LOG(log, "user plugin dir -> `{0}`", g_fields->m_lldb_user_plugin_dir);
171 });
172 return g_fields->m_lldb_user_plugin_dir;
173}
174
176 llvm::call_once(g_fields->m_lldb_process_tmp_dir_once, []() {
177 if (!HostInfo::ComputeProcessTempFileDirectory(
178 g_fields->m_lldb_process_tmp_dir))
179 g_fields->m_lldb_process_tmp_dir = FileSpec();
180 Log *log = GetLog(LLDBLog::Host);
181 LLDB_LOG(log, "process temp dir -> `{0}`",
182 g_fields->m_lldb_process_tmp_dir);
183 });
184 return g_fields->m_lldb_process_tmp_dir;
185}
186
188 llvm::call_once(g_fields->m_lldb_global_tmp_dir_once, []() {
189 if (!HostInfo::ComputeGlobalTempFileDirectory(
190 g_fields->m_lldb_global_tmp_dir))
191 g_fields->m_lldb_global_tmp_dir = FileSpec();
192
193 Log *log = GetLog(LLDBLog::Host);
194 LLDB_LOG(log, "global temp dir -> `{0}`", g_fields->m_lldb_global_tmp_dir);
195 });
196 return g_fields->m_lldb_global_tmp_dir;
197}
198
200 if (triple.empty())
201 return ArchSpec();
202 llvm::Triple normalized_triple(llvm::Triple::normalize(triple));
203 if (!ArchSpec::ContainsOnlyArch(normalized_triple))
204 return ArchSpec(triple);
205
206 if (auto kind = HostInfo::ParseArchitectureKind(triple))
207 return HostInfo::GetArchitecture(*kind);
208
209 llvm::Triple host_triple(llvm::sys::getDefaultTargetTriple());
210
211 if (normalized_triple.getVendorName().empty())
212 normalized_triple.setVendor(host_triple.getVendor());
213 if (normalized_triple.getOSName().empty())
214 normalized_triple.setOS(host_triple.getOS());
215 if (normalized_triple.getEnvironmentName().empty() &&
216 !host_triple.getEnvironmentName().empty())
217 normalized_triple.setEnvironment(host_triple.getEnvironment());
218 return ArchSpec(normalized_triple);
219}
220
222 llvm::StringRef dir) {
223 Log *log = GetLog(LLDBLog::Host);
224
225 FileSpec lldb_file_spec = GetShlibDir();
226 if (!lldb_file_spec)
227 return false;
228
229 std::string raw_path = lldb_file_spec.GetPath();
230 LLDB_LOG(
231 log,
232 "Attempting to derive the path {0} relative to liblldb install path: {1}",
233 dir, raw_path);
234
235 // Drop bin (windows) or lib
236 llvm::StringRef parent_path = llvm::sys::path::parent_path(raw_path);
237 if (parent_path.empty()) {
238 LLDB_LOG(log, "Failed to find liblldb within the shared lib path");
239 return false;
240 }
241
242 raw_path = (parent_path + dir).str();
243 LLDB_LOG(log, "Derived the path as: {0}", raw_path);
244 file_spec.SetDirectory(raw_path);
245 return (bool)file_spec.GetDirectory();
246}
247
249 // To get paths related to LLDB we get the path to the executable that
250 // contains this function. On MacOSX this will be "LLDB.framework/.../LLDB".
251 // On other posix systems, we will get .../lib(64|32)?/liblldb.so.
252
254 reinterpret_cast<void *>(HostInfoBase::ComputeSharedLibraryDirectory)));
255
257 g_shlib_dir_helper(lldb_file_spec);
258
259 // Remove the filename so that this FileSpec only represents the directory.
260 file_spec.SetDirectory(lldb_file_spec.GetDirectory());
261
262 return (bool)file_spec.GetDirectory();
263}
264
266 file_spec = GetShlibDir();
267 return bool(file_spec);
268}
269
271 FileSpec temp_file_spec;
272 if (!HostInfo::ComputeGlobalTempFileDirectory(temp_file_spec))
273 return false;
274
275 std::string pid_str{llvm::to_string(Host::GetCurrentProcessID())};
276 temp_file_spec.AppendPathComponent(pid_str);
277 if (llvm::sys::fs::create_directory(temp_file_spec.GetPath()))
278 return false;
279
280 file_spec.SetDirectory(temp_file_spec.GetPathAsConstString());
281 return true;
282}
283
285 llvm::SmallVector<char, 16> tmpdir;
286 llvm::sys::path::system_temp_directory(/*ErasedOnReboot*/ true, tmpdir);
287 file_spec = FileSpec(std::string(tmpdir.data(), tmpdir.size()));
288 FileSystem::Instance().Resolve(file_spec);
289 return true;
290}
291
293 file_spec.Clear();
294
295 FileSpec temp_file_spec;
296 if (!HostInfo::ComputeTempFileBaseDirectory(temp_file_spec))
297 return false;
298
299 temp_file_spec.AppendPathComponent("lldb");
300 if (llvm::sys::fs::create_directory(temp_file_spec.GetPath()))
301 return false;
302
303 file_spec.SetDirectory(temp_file_spec.GetPathAsConstString());
304 return true;
305}
306
308 // TODO(zturner): Figure out how to compute the header directory for all
309 // platforms.
310 return false;
311}
312
314 // TODO(zturner): Figure out how to compute the system plugins directory for
315 // all platforms.
316 return false;
317}
318
320 // TODO(zturner): Figure out how to compute the user plugins directory for
321 // all platforms.
322 return false;
323}
324
326 ArchSpec &arch_64) {
327 llvm::Triple triple(llvm::sys::getProcessTriple());
328
329 arch_32.Clear();
330 arch_64.Clear();
331
332 switch (triple.getArch()) {
333 default:
334 arch_32.SetTriple(triple);
335 break;
336
337 case llvm::Triple::aarch64:
338 case llvm::Triple::ppc64:
339 case llvm::Triple::ppc64le:
340 case llvm::Triple::x86_64:
341 case llvm::Triple::riscv64:
342 case llvm::Triple::loongarch64:
343 arch_64.SetTriple(triple);
344 arch_32.SetTriple(triple.get32BitArchVariant());
345 break;
346
347 case llvm::Triple::mips64:
348 case llvm::Triple::mips64el:
349 case llvm::Triple::sparcv9:
350 case llvm::Triple::systemz:
351 arch_64.SetTriple(triple);
352 break;
353 }
354}
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:369
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:560
bool SetTriple(const llvm::Triple &triple)
Architecture triple setter.
Definition: ArchSpec.cpp:765
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:820
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.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition: Log.h:332
Definition: SBAddress.h:15