Coverage Report

Created: 2023-09-21 18:56

/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/source/Host/common/HostInfoBase.cpp
Line
Count
Source (jump to first uncovered line)
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
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
32
using namespace lldb;
33
using namespace lldb_private;
34
35
namespace {
36
/// Contains the state of the HostInfoBase plugin.
37
struct HostInfoBaseFields {
38
4.14k
  ~HostInfoBaseFields() {
39
4.14k
    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
985
      llvm::sys::fs::remove_directories(m_lldb_process_tmp_dir.GetPath());
44
985
    }
45
4.14k
  }
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
73
static HostInfoBaseFields *g_fields = nullptr;
74
static HostInfoBase::SharedLibraryDirectoryHelper *g_shlib_dir_helper = nullptr;
75
76
4.16k
void HostInfoBase::Initialize(SharedLibraryDirectoryHelper *helper) {
77
4.16k
  g_shlib_dir_helper = helper;
78
4.16k
  g_fields = new HostInfoBaseFields();
79
4.16k
}
80
81
4.15k
void HostInfoBase::Terminate() {
82
4.15k
  g_shlib_dir_helper = nullptr;
83
4.15k
  delete g_fields;
84
4.15k
  g_fields = nullptr;
85
4.15k
}
86
87
1.30k
llvm::Triple HostInfoBase::GetTargetTriple() {
88
1.30k
  llvm::call_once(g_fields->m_host_triple_once, []() {
89
541
    g_fields->m_host_triple = HostInfo::GetArchitecture().GetTriple();
90
541
  });
91
1.30k
  return g_fields->m_host_triple;
92
1.30k
}
93
94
147k
const ArchSpec &HostInfoBase::GetArchitecture(ArchitectureKind arch_kind) {
95
147k
  llvm::call_once(g_fields->m_host_arch_once, []() {
96
4.04k
    HostInfo::ComputeHostArchitectureSupport(g_fields->m_host_arch_32,
97
4.04k
                                             g_fields->m_host_arch_64);
98
4.04k
  });
99
100
  // If an explicit 32 or 64-bit architecture was requested, return that.
101
147k
  if (arch_kind == eArchKind32)
102
7.79k
    return g_fields->m_host_arch_32;
103
139k
  if (arch_kind == eArchKind64)
104
7.79k
    return g_fields->m_host_arch_64;
105
106
  // Otherwise prefer the 64-bit architecture if it is valid.
107
132k
  return (g_fields->m_host_arch_64.IsValid()) ? g_fields->m_host_arch_64
108
132k
                                              : 
g_fields->m_host_arch_320
;
109
139k
}
110
111
std::optional<HostInfoBase::ArchitectureKind>
112
16
HostInfoBase::ParseArchitectureKind(llvm::StringRef kind) {
113
16
  return llvm::StringSwitch<std::optional<ArchitectureKind>>(kind)
114
16
      .Case(LLDB_ARCH_DEFAULT, eArchKindDefault)
115
16
      .Case(LLDB_ARCH_DEFAULT_32BIT, eArchKind32)
116
16
      .Case(LLDB_ARCH_DEFAULT_64BIT, eArchKind64)
117
16
      .Default(std::nullopt);
118
16
}
119
120
15.3k
FileSpec HostInfoBase::GetShlibDir() {
121
15.3k
  llvm::call_once(g_fields->m_lldb_so_dir_once, []() {
122
4.02k
    if (!HostInfo::ComputeSharedLibraryDirectory(g_fields->m_lldb_so_dir))
123
0
      g_fields->m_lldb_so_dir = FileSpec();
124
4.02k
    Log *log = GetLog(LLDBLog::Host);
125
4.02k
    LLDB_LOG(log, "shlib dir -> `{0}`", g_fields->m_lldb_so_dir);
126
4.02k
  });
127
15.3k
  return g_fields->m_lldb_so_dir;
128
15.3k
}
129
130
1.50k
FileSpec HostInfoBase::GetSupportExeDir() {
131
1.50k
  llvm::call_once(g_fields->m_lldb_support_exe_dir_once, []() {
132
809
    if (!HostInfo::ComputeSupportExeDirectory(g_fields->m_lldb_support_exe_dir))
133
0
      g_fields->m_lldb_support_exe_dir = FileSpec();
134
809
    Log *log = GetLog(LLDBLog::Host);
135
809
    LLDB_LOG(log, "support exe dir -> `{0}`", g_fields->m_lldb_support_exe_dir);
136
809
  });
137
1.50k
  return g_fields->m_lldb_support_exe_dir;
138
1.50k
}
139
140
1
FileSpec HostInfoBase::GetHeaderDir() {
141
1
  llvm::call_once(g_fields->m_lldb_headers_dir_once, []() {
142
1
    if (!HostInfo::ComputeHeaderDirectory(g_fields->m_lldb_headers_dir))
143
0
      g_fields->m_lldb_headers_dir = FileSpec();
144
1
    Log *log = GetLog(LLDBLog::Host);
145
1
    LLDB_LOG(log, "header dir -> `{0}`", g_fields->m_lldb_headers_dir);
146
1
  });
147
1
  return g_fields->m_lldb_headers_dir;
148
1
}
149
150
10.0k
FileSpec HostInfoBase::GetSystemPluginDir() {
151
10.0k
  llvm::call_once(g_fields->m_lldb_system_plugin_dir_once, []() {
152
3.97k
    if (!HostInfo::ComputeSystemPluginsDirectory(
153
3.97k
            g_fields->m_lldb_system_plugin_dir))
154
3.97k
      g_fields->m_lldb_system_plugin_dir = FileSpec();
155
3.97k
    Log *log = GetLog(LLDBLog::Host);
156
3.97k
    LLDB_LOG(log, "system plugin dir -> `{0}`",
157
3.97k
             g_fields->m_lldb_system_plugin_dir);
158
3.97k
  });
159
10.0k
  return g_fields->m_lldb_system_plugin_dir;
160
10.0k
}
161
162
10.0k
FileSpec HostInfoBase::GetUserPluginDir() {
163
10.0k
  llvm::call_once(g_fields->m_lldb_user_plugin_dir_once, []() {
164
3.97k
    if (!HostInfo::ComputeUserPluginsDirectory(
165
3.97k
            g_fields->m_lldb_user_plugin_dir))
166
0
      g_fields->m_lldb_user_plugin_dir = FileSpec();
167
3.97k
    Log *log = GetLog(LLDBLog::Host);
168
3.97k
    LLDB_LOG(log, "user plugin dir -> `{0}`", g_fields->m_lldb_user_plugin_dir);
169
3.97k
  });
170
10.0k
  return g_fields->m_lldb_user_plugin_dir;
171
10.0k
}
172
173
6.85k
FileSpec HostInfoBase::GetProcessTempDir() {
174
6.85k
  llvm::call_once(g_fields->m_lldb_process_tmp_dir_once, []() {
175
991
    if (!HostInfo::ComputeProcessTempFileDirectory(
176
991
            g_fields->m_lldb_process_tmp_dir))
177
0
      g_fields->m_lldb_process_tmp_dir = FileSpec();
178
991
    Log *log = GetLog(LLDBLog::Host);
179
991
    LLDB_LOG(log, "process temp dir -> `{0}`",
180
991
             g_fields->m_lldb_process_tmp_dir);
181
991
  });
182
6.85k
  return g_fields->m_lldb_process_tmp_dir;
183
6.85k
}
184
185
0
FileSpec HostInfoBase::GetGlobalTempDir() {
186
0
  llvm::call_once(g_fields->m_lldb_global_tmp_dir_once, []() {
187
0
    if (!HostInfo::ComputeGlobalTempFileDirectory(
188
0
            g_fields->m_lldb_global_tmp_dir))
189
0
      g_fields->m_lldb_global_tmp_dir = FileSpec();
190
191
0
    Log *log = GetLog(LLDBLog::Host);
192
0
    LLDB_LOG(log, "global temp dir -> `{0}`", g_fields->m_lldb_global_tmp_dir);
193
0
  });
194
0
  return g_fields->m_lldb_global_tmp_dir;
195
0
}
196
197
5
ArchSpec HostInfoBase::GetAugmentedArchSpec(llvm::StringRef triple) {
198
5
  if (triple.empty())
199
0
    return ArchSpec();
200
5
  llvm::Triple normalized_triple(llvm::Triple::normalize(triple));
201
5
  if (!ArchSpec::ContainsOnlyArch(normalized_triple))
202
2
    return ArchSpec(triple);
203
204
3
  if (auto kind = HostInfo::ParseArchitectureKind(triple))
205
1
    return HostInfo::GetArchitecture(*kind);
206
207
2
  llvm::Triple host_triple(llvm::sys::getDefaultTargetTriple());
208
209
2
  if (normalized_triple.getVendorName().empty())
210
2
    normalized_triple.setVendor(host_triple.getVendor());
211
2
  if (normalized_triple.getOSName().empty())
212
2
    normalized_triple.setOS(host_triple.getOS());
213
2
  if (normalized_triple.getEnvironmentName().empty() &&
214
2
      !host_triple.getEnvironmentName().empty())
215
0
    normalized_triple.setEnvironment(host_triple.getEnvironment());
216
2
  return ArchSpec(normalized_triple);
217
3
}
218
219
bool HostInfoBase::ComputePathRelativeToLibrary(FileSpec &file_spec,
220
0
                                                llvm::StringRef dir) {
221
0
  Log *log = GetLog(LLDBLog::Host);
222
223
0
  FileSpec lldb_file_spec = GetShlibDir();
224
0
  if (!lldb_file_spec)
225
0
    return false;
226
227
0
  std::string raw_path = lldb_file_spec.GetPath();
228
0
  LLDB_LOG(
229
0
      log,
230
0
      "Attempting to derive the path {0} relative to liblldb install path: {1}",
231
0
      dir, raw_path);
232
233
  // Drop bin (windows) or lib
234
0
  llvm::StringRef parent_path = llvm::sys::path::parent_path(raw_path);
235
0
  if (parent_path.empty()) {
236
0
    LLDB_LOG(log, "Failed to find liblldb within the shared lib path");
237
0
    return false;
238
0
  }
239
240
0
  raw_path = (parent_path + dir).str();
241
0
  LLDB_LOG(log, "Derived the path as: {0}", raw_path);
242
0
  file_spec.SetDirectory(raw_path);
243
0
  return (bool)file_spec.GetDirectory();
244
0
}
245
246
4.02k
bool HostInfoBase::ComputeSharedLibraryDirectory(FileSpec &file_spec) {
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
251
4.02k
  FileSpec lldb_file_spec(Host::GetModuleFileSpecForHostAddress(
252
4.02k
      reinterpret_cast<void *>(HostInfoBase::ComputeSharedLibraryDirectory)));
253
254
4.02k
  if (g_shlib_dir_helper)
255
3.82k
    g_shlib_dir_helper(lldb_file_spec);
256
257
  // Remove the filename so that this FileSpec only represents the directory.
258
4.02k
  file_spec.SetDirectory(lldb_file_spec.GetDirectory());
259
260
4.02k
  return (bool)file_spec.GetDirectory();
261
4.02k
}
262
263
0
bool HostInfoBase::ComputeSupportExeDirectory(FileSpec &file_spec) {
264
0
  file_spec = GetShlibDir();
265
0
  return bool(file_spec);
266
0
}
267
268
991
bool HostInfoBase::ComputeProcessTempFileDirectory(FileSpec &file_spec) {
269
991
  FileSpec temp_file_spec;
270
991
  if (!HostInfo::ComputeGlobalTempFileDirectory(temp_file_spec))
271
0
    return false;
272
273
991
  std::string pid_str{llvm::to_string(Host::GetCurrentProcessID())};
274
991
  temp_file_spec.AppendPathComponent(pid_str);
275
991
  if (llvm::sys::fs::create_directory(temp_file_spec.GetPath()))
276
0
    return false;
277
278
991
  file_spec.SetDirectory(temp_file_spec.GetPathAsConstString());
279
991
  return true;
280
991
}
281
282
991
bool HostInfoBase::ComputeTempFileBaseDirectory(FileSpec &file_spec) {
283
991
  llvm::SmallVector<char, 16> tmpdir;
284
991
  llvm::sys::path::system_temp_directory(/*ErasedOnReboot*/ true, tmpdir);
285
991
  file_spec = FileSpec(std::string(tmpdir.data(), tmpdir.size()));
286
991
  FileSystem::Instance().Resolve(file_spec);
287
991
  return true;
288
991
}
289
290
991
bool HostInfoBase::ComputeGlobalTempFileDirectory(FileSpec &file_spec) {
291
991
  file_spec.Clear();
292
293
991
  FileSpec temp_file_spec;
294
991
  if (!HostInfo::ComputeTempFileBaseDirectory(temp_file_spec))
295
0
    return false;
296
297
991
  temp_file_spec.AppendPathComponent("lldb");
298
991
  if (llvm::sys::fs::create_directory(temp_file_spec.GetPath()))
299
0
    return false;
300
301
991
  file_spec.SetDirectory(temp_file_spec.GetPathAsConstString());
302
991
  return true;
303
991
}
304
305
0
bool HostInfoBase::ComputeHeaderDirectory(FileSpec &file_spec) {
306
  // TODO(zturner): Figure out how to compute the header directory for all
307
  // platforms.
308
0
  return false;
309
0
}
310
311
0
bool HostInfoBase::ComputeSystemPluginsDirectory(FileSpec &file_spec) {
312
  // TODO(zturner): Figure out how to compute the system plugins directory for
313
  // all platforms.
314
0
  return false;
315
0
}
316
317
0
bool HostInfoBase::ComputeUserPluginsDirectory(FileSpec &file_spec) {
318
  // TODO(zturner): Figure out how to compute the user plugins directory for
319
  // all platforms.
320
0
  return false;
321
0
}
322
323
void HostInfoBase::ComputeHostArchitectureSupport(ArchSpec &arch_32,
324
0
                                                  ArchSpec &arch_64) {
325
0
  llvm::Triple triple(llvm::sys::getProcessTriple());
326
327
0
  arch_32.Clear();
328
0
  arch_64.Clear();
329
330
0
  switch (triple.getArch()) {
331
0
  default:
332
0
    arch_32.SetTriple(triple);
333
0
    break;
334
335
0
  case llvm::Triple::aarch64:
336
0
  case llvm::Triple::ppc64:
337
0
  case llvm::Triple::ppc64le:
338
0
  case llvm::Triple::x86_64:
339
0
  case llvm::Triple::riscv64:
340
0
  case llvm::Triple::loongarch64:
341
0
    arch_64.SetTriple(triple);
342
0
    arch_32.SetTriple(triple.get32BitArchVariant());
343
0
    break;
344
345
0
  case llvm::Triple::mips64:
346
0
  case llvm::Triple::mips64el:
347
0
  case llvm::Triple::sparcv9:
348
0
  case llvm::Triple::systemz:
349
0
    arch_64.SetTriple(triple);
350
0
    break;
351
0
  }
352
0
}