1 //===-- HostInfoBase.cpp ----------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "lldb/Host/Config.h"
12 #include "lldb/Core/ArchSpec.h"
13 #include "lldb/Core/Log.h"
14 #include "lldb/Core/StreamString.h"
15 #include "lldb/Host/FileSystem.h"
16 #include "lldb/Host/Host.h"
17 #include "lldb/Host/HostInfo.h"
18 #include "lldb/Host/HostInfoBase.h"
20 #include "llvm/ADT/Triple.h"
21 #include "llvm/Support/Host.h"
26 using namespace lldb_private;
31 CleanupProcessSpecificLLDBTempDir()
33 // Get the process specific LLDB temporary directory and delete it.
34 FileSpec tmpdir_file_spec;
35 if (!HostInfo::GetLLDBPath(ePathTypeLLDBTempSystemDir, tmpdir_file_spec))
38 // Remove the LLDB temporary directory if we have one. Set "recurse" to
39 // true to all files that were created for the LLDB process can be cleaned up.
40 FileSystem::DeleteDirectory(tmpdir_file_spec.GetDirectory().GetCString(), true);
43 struct HostInfoBaseFields
45 uint32_t m_number_cpus;
46 std::string m_vendor_string;
47 std::string m_os_string;
48 std::string m_host_triple;
50 ArchSpec m_host_arch_32;
51 ArchSpec m_host_arch_64;
53 FileSpec m_lldb_so_dir;
54 FileSpec m_lldb_support_exe_dir;
55 FileSpec m_lldb_headers_dir;
56 FileSpec m_lldb_python_dir;
57 FileSpec m_lldb_system_plugin_dir;
58 FileSpec m_lldb_user_plugin_dir;
59 FileSpec m_lldb_tmp_dir;
62 HostInfoBaseFields *g_fields = nullptr;
65 #define COMPUTE_LLDB_PATH(compute_function, member_var) \
67 static bool is_initialized = false; \
68 static bool success = false; \
69 if (!is_initialized) \
71 is_initialized = true; \
72 success = HostInfo::compute_function(member_var); \
75 result = &member_var; \
79 HostInfoBase::Initialize()
81 g_fields = new HostInfoBaseFields();
85 HostInfoBase::GetNumberCPUS()
87 static bool is_initialized = false;
90 g_fields->m_number_cpus = std::thread::hardware_concurrency();
91 is_initialized = true;
94 return g_fields->m_number_cpus;
98 HostInfoBase::GetVendorString()
100 static bool is_initialized = false;
103 const ArchSpec &host_arch = HostInfo::GetArchitecture();
104 const llvm::StringRef &str_ref = host_arch.GetTriple().getVendorName();
105 g_fields->m_vendor_string.assign(str_ref.begin(), str_ref.end());
106 is_initialized = true;
108 return g_fields->m_vendor_string;
112 HostInfoBase::GetOSString()
114 static bool is_initialized = false;
117 const ArchSpec &host_arch = HostInfo::GetArchitecture();
118 const llvm::StringRef &str_ref = host_arch.GetTriple().getOSName();
119 g_fields->m_os_string.assign(str_ref.begin(), str_ref.end());
120 is_initialized = true;
122 return g_fields->m_os_string;
126 HostInfoBase::GetTargetTriple()
128 static bool is_initialized = false;
131 const ArchSpec &host_arch = HostInfo::GetArchitecture();
132 g_fields->m_host_triple = host_arch.GetTriple().getTriple();
133 is_initialized = true;
135 return g_fields->m_host_triple;
139 HostInfoBase::GetArchitecture(ArchitectureKind arch_kind)
141 static bool is_initialized = false;
144 HostInfo::ComputeHostArchitectureSupport(g_fields->m_host_arch_32, g_fields->m_host_arch_64);
145 is_initialized = true;
148 // If an explicit 32 or 64-bit architecture was requested, return that.
149 if (arch_kind == eArchKind32)
150 return g_fields->m_host_arch_32;
151 if (arch_kind == eArchKind64)
152 return g_fields->m_host_arch_64;
154 // Otherwise prefer the 64-bit architecture if it is valid.
155 return (g_fields->m_host_arch_64.IsValid()) ? g_fields->m_host_arch_64 : g_fields->m_host_arch_32;
159 HostInfoBase::GetLLDBPath(lldb::PathType type, FileSpec &file_spec)
163 #if defined(LLDB_DISABLE_PYTHON)
164 if (type == lldb::ePathTypePythonDir)
168 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
169 FileSpec *result = nullptr;
172 case lldb::ePathTypeLLDBShlibDir:
173 COMPUTE_LLDB_PATH(ComputeSharedLibraryDirectory, g_fields->m_lldb_so_dir)
175 log->Printf("HostInfoBase::GetLLDBPath(ePathTypeLLDBShlibDir) => '%s'", g_fields->m_lldb_so_dir.GetPath().c_str());
177 case lldb::ePathTypeSupportExecutableDir:
178 COMPUTE_LLDB_PATH(ComputeSupportExeDirectory, g_fields->m_lldb_support_exe_dir)
180 log->Printf("HostInfoBase::GetLLDBPath(ePathTypeSupportExecutableDir) => '%s'",
181 g_fields->m_lldb_support_exe_dir.GetPath().c_str());
183 case lldb::ePathTypeHeaderDir:
184 COMPUTE_LLDB_PATH(ComputeHeaderDirectory, g_fields->m_lldb_headers_dir)
186 log->Printf("HostInfoBase::GetLLDBPath(ePathTypeHeaderDir) => '%s'", g_fields->m_lldb_headers_dir.GetPath().c_str());
188 case lldb::ePathTypePythonDir:
189 COMPUTE_LLDB_PATH(ComputePythonDirectory, g_fields->m_lldb_python_dir)
191 log->Printf("HostInfoBase::GetLLDBPath(ePathTypePythonDir) => '%s'", g_fields->m_lldb_python_dir.GetPath().c_str());
193 case lldb::ePathTypeLLDBSystemPlugins:
194 COMPUTE_LLDB_PATH(ComputeSystemPluginsDirectory, g_fields->m_lldb_system_plugin_dir)
196 log->Printf("HostInfoBase::GetLLDBPath(ePathTypeLLDBSystemPlugins) => '%s'",
197 g_fields->m_lldb_system_plugin_dir.GetPath().c_str());
199 case lldb::ePathTypeLLDBUserPlugins:
200 COMPUTE_LLDB_PATH(ComputeUserPluginsDirectory, g_fields->m_lldb_user_plugin_dir)
202 log->Printf("HostInfoBase::GetLLDBPath(ePathTypeLLDBUserPlugins) => '%s'",
203 g_fields->m_lldb_user_plugin_dir.GetPath().c_str());
205 case lldb::ePathTypeLLDBTempSystemDir:
206 COMPUTE_LLDB_PATH(ComputeTempFileDirectory, g_fields->m_lldb_tmp_dir)
208 log->Printf("HostInfoBase::GetLLDBPath(ePathTypeLLDBTempSystemDir) => '%s'", g_fields->m_lldb_tmp_dir.GetPath().c_str());
219 HostInfoBase::ComputeSharedLibraryDirectory(FileSpec &file_spec)
221 // To get paths related to LLDB we get the path to the executable that
222 // contains this function. On MacOSX this will be "LLDB.framework/.../LLDB",
223 // on linux this is assumed to be the "lldb" main executable. If LLDB on
224 // linux is actually in a shared library (liblldb.so) then this function will
225 // need to be modified to "do the right thing".
227 FileSpec lldb_file_spec(
228 Host::GetModuleFileSpecForHostAddress(reinterpret_cast<void *>(reinterpret_cast<intptr_t>(HostInfoBase::GetLLDBPath))));
230 // Remove the filename so that this FileSpec only represents the directory.
231 file_spec.GetDirectory() = lldb_file_spec.GetDirectory();
233 return (bool)file_spec.GetDirectory();
237 HostInfoBase::ComputeSupportExeDirectory(FileSpec &file_spec)
239 return GetLLDBPath(lldb::ePathTypeLLDBShlibDir, file_spec);
243 HostInfoBase::ComputeTempFileDirectory(FileSpec &file_spec)
245 const char *tmpdir_cstr = getenv("TMPDIR");
246 if (tmpdir_cstr == NULL)
248 tmpdir_cstr = getenv("TMP");
249 if (tmpdir_cstr == NULL)
250 tmpdir_cstr = getenv("TEMP");
255 StreamString pid_tmpdir;
256 pid_tmpdir.Printf("%s/lldb", tmpdir_cstr);
257 if (!FileSystem::MakeDirectory(pid_tmpdir.GetString().c_str(), eFilePermissionsDirectoryDefault).Success())
260 pid_tmpdir.Printf("/%" PRIu64, Host::GetCurrentProcessID());
261 if (!FileSystem::MakeDirectory(pid_tmpdir.GetString().c_str(), eFilePermissionsDirectoryDefault).Success())
264 // Make an atexit handler to clean up the process specify LLDB temp dir
265 // and all of its contents.
266 ::atexit(CleanupProcessSpecificLLDBTempDir);
267 file_spec.GetDirectory().SetCStringWithLength(pid_tmpdir.GetString().c_str(), pid_tmpdir.GetString().size());
272 HostInfoBase::ComputeHeaderDirectory(FileSpec &file_spec)
274 // TODO(zturner): Figure out how to compute the header directory for all platforms.
279 HostInfoBase::ComputeSystemPluginsDirectory(FileSpec &file_spec)
281 // TODO(zturner): Figure out how to compute the system plugins directory for all platforms.
286 HostInfoBase::ComputeUserPluginsDirectory(FileSpec &file_spec)
288 // TODO(zturner): Figure out how to compute the user plugins directory for all platforms.
293 HostInfoBase::ComputeHostArchitectureSupport(ArchSpec &arch_32, ArchSpec &arch_64)
295 llvm::Triple triple(llvm::sys::getDefaultTargetTriple());
300 switch (triple.getArch())
303 arch_32.SetTriple(triple);
306 case llvm::Triple::x86_64:
307 arch_64.SetTriple(triple);
308 arch_32.SetTriple(triple.get32BitArchVariant());
311 case llvm::Triple::aarch64:
312 case llvm::Triple::mips64:
313 case llvm::Triple::sparcv9:
314 case llvm::Triple::ppc64:
315 arch_64.SetTriple(triple);