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/ADT/Triple.h"
22#include "llvm/Support/Host.h"
23#include "llvm/Support/Path.h"
24#include "llvm/Support/ScopedPrinter.h"
25#include "llvm/Support/Threading.h"
26#include "llvm/Support/raw_ostream.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_LOGF(log,
229 "HostInfo::%s() attempting to "
230 "derive the path %s relative to liblldb install path: %s",
231 __FUNCTION__, dir.data(), raw_path.c_str());
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_LOGF(log,
237 "HostInfo::%s() failed to find liblldb within the shared "
238 "lib path",
239 __FUNCTION__);
240 return false;
241 }
242
243 raw_path = (parent_path + dir).str();
244 LLDB_LOGF(log, "HostInfo::%s() derived the path as: %s", __FUNCTION__,
245 raw_path.c_str());
246 file_spec.SetDirectory(raw_path);
247 return (bool)file_spec.GetDirectory();
248}
249
251 // To get paths related to LLDB we get the path to the executable that
252 // contains this function. On MacOSX this will be "LLDB.framework/.../LLDB".
253 // On other posix systems, we will get .../lib(64|32)?/liblldb.so.
254
256 reinterpret_cast<void *>(HostInfoBase::ComputeSharedLibraryDirectory)));
257
259 g_shlib_dir_helper(lldb_file_spec);
260
261 // Remove the filename so that this FileSpec only represents the directory.
262 file_spec.SetDirectory(lldb_file_spec.GetDirectory());
263
264 return (bool)file_spec.GetDirectory();
265}
266
268 file_spec = GetShlibDir();
269 return bool(file_spec);
270}
271
273 FileSpec temp_file_spec;
274 if (!HostInfo::ComputeGlobalTempFileDirectory(temp_file_spec))
275 return false;
276
277 std::string pid_str{llvm::to_string(Host::GetCurrentProcessID())};
278 temp_file_spec.AppendPathComponent(pid_str);
279 if (llvm::sys::fs::create_directory(temp_file_spec.GetPath()))
280 return false;
281
282 file_spec.SetDirectory(temp_file_spec.GetPathAsConstString());
283 return true;
284}
285
287 llvm::SmallVector<char, 16> tmpdir;
288 llvm::sys::path::system_temp_directory(/*ErasedOnReboot*/ true, tmpdir);
289 file_spec = FileSpec(std::string(tmpdir.data(), tmpdir.size()));
290 FileSystem::Instance().Resolve(file_spec);
291 return true;
292}
293
295 file_spec.Clear();
296
297 FileSpec temp_file_spec;
298 if (!HostInfo::ComputeTempFileBaseDirectory(temp_file_spec))
299 return false;
300
301 temp_file_spec.AppendPathComponent("lldb");
302 if (llvm::sys::fs::create_directory(temp_file_spec.GetPath()))
303 return false;
304
305 file_spec.SetDirectory(temp_file_spec.GetPathAsConstString());
306 return true;
307}
308
310 // TODO(zturner): Figure out how to compute the header directory for all
311 // platforms.
312 return false;
313}
314
316 // TODO(zturner): Figure out how to compute the system plugins directory for
317 // all platforms.
318 return false;
319}
320
322 // TODO(zturner): Figure out how to compute the user plugins directory for
323 // all platforms.
324 return false;
325}
326
328 ArchSpec &arch_64) {
329 llvm::Triple triple(llvm::sys::getProcessTriple());
330
331 arch_32.Clear();
332 arch_64.Clear();
333
334 switch (triple.getArch()) {
335 default:
336 arch_32.SetTriple(triple);
337 break;
338
339 case llvm::Triple::aarch64:
340 case llvm::Triple::ppc64:
341 case llvm::Triple::ppc64le:
342 case llvm::Triple::x86_64:
343 case llvm::Triple::riscv64:
344 case llvm::Triple::loongarch64:
345 arch_64.SetTriple(triple);
346 arch_32.SetTriple(triple.get32BitArchVariant());
347 break;
348
349 case llvm::Triple::mips64:
350 case llvm::Triple::mips64el:
351 case llvm::Triple::sparcv9:
352 case llvm::Triple::systemz:
353 arch_64.SetTriple(triple);
354 break;
355 }
356}
static HostInfoBase::SharedLibraryDirectoryHelper * g_shlib_dir_helper
static HostInfoBaseFields * g_fields
#define LLDB_LOGF(log,...)
Definition: Log.h:344
constexpr lldb_private::HostInfo::SharedLibraryDirectoryHelper * g_shlib_dir_helper
An architecture specification class.
Definition: ArchSpec.h:32
void Clear()
Clears the object state.
Definition: ArchSpec.cpp:536
bool SetTriple(const llvm::Triple &triple)
Architecture triple setter.
Definition: ArchSpec.cpp:750
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:805
A file utility class.
Definition: FileSpec.h:56
void AppendPathComponent(llvm::StringRef component)
Definition: FileSpec.cpp:453
void SetDirectory(ConstString directory)
Directory string set accessor.
Definition: FileSpec.cpp:334
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:366
void Clear()
Clears the object state.
Definition: FileSpec.cpp:258
ConstString GetPathAsConstString(bool denormalize=true) const
Get the full path as a ConstString.
Definition: FileSpec.cpp:382
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:45
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:94
#define LLDB_ARCH_DEFAULT
CPU Type definitions.
Definition: lldb-defines.h:92
#define LLDB_ARCH_DEFAULT_32BIT
Definition: lldb-defines.h:93
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:309
Definition: SBAddress.h:15