197a14e60SZachary Turner //===-- HostInfoBase.cpp ----------------------------------------*- C++ -*-===// 297a14e60SZachary Turner // 397a14e60SZachary Turner // The LLVM Compiler Infrastructure 497a14e60SZachary Turner // 597a14e60SZachary Turner // This file is distributed under the University of Illinois Open Source 697a14e60SZachary Turner // License. See LICENSE.TXT for details. 797a14e60SZachary Turner // 897a14e60SZachary Turner //===----------------------------------------------------------------------===// 997a14e60SZachary Turner 1097a14e60SZachary Turner #include "lldb/Host/Config.h" 1197a14e60SZachary Turner 1297a14e60SZachary Turner #include "lldb/Core/ArchSpec.h" 13*42ff0ad8SZachary Turner #include "lldb/Core/Log.h" 14*42ff0ad8SZachary Turner #include "lldb/Core/StreamString.h" 15*42ff0ad8SZachary Turner #include "lldb/Host/FileSystem.h" 1697a14e60SZachary Turner #include "lldb/Host/Host.h" 1713b18261SZachary Turner #include "lldb/Host/HostInfo.h" 1813b18261SZachary Turner #include "lldb/Host/HostInfoBase.h" 1913b18261SZachary Turner 2013b18261SZachary Turner #include "llvm/ADT/Triple.h" 2113b18261SZachary Turner #include "llvm/Support/Host.h" 2297a14e60SZachary Turner 2397a14e60SZachary Turner #include <thread> 2497a14e60SZachary Turner 2597a14e60SZachary Turner using namespace lldb; 2697a14e60SZachary Turner using namespace lldb_private; 2797a14e60SZachary Turner 28*42ff0ad8SZachary Turner namespace 29*42ff0ad8SZachary Turner { 30*42ff0ad8SZachary Turner void 31*42ff0ad8SZachary Turner CleanupProcessSpecificLLDBTempDir() 32*42ff0ad8SZachary Turner { 33*42ff0ad8SZachary Turner // Get the process specific LLDB temporary directory and delete it. 34*42ff0ad8SZachary Turner FileSpec tmpdir_file_spec; 35*42ff0ad8SZachary Turner if (!HostInfo::GetLLDBPath(ePathTypeLLDBTempSystemDir, tmpdir_file_spec)) 36*42ff0ad8SZachary Turner return; 37*42ff0ad8SZachary Turner 38*42ff0ad8SZachary Turner // Remove the LLDB temporary directory if we have one. Set "recurse" to 39*42ff0ad8SZachary Turner // true to all files that were created for the LLDB process can be cleaned up. 40*42ff0ad8SZachary Turner FileSystem::DeleteDirectory(tmpdir_file_spec.GetDirectory().GetCString(), true); 41*42ff0ad8SZachary Turner } 42*42ff0ad8SZachary Turner } 43*42ff0ad8SZachary Turner 44*42ff0ad8SZachary Turner #define COMPUTE_LLDB_PATH(compute_function, member_var) \ 45*42ff0ad8SZachary Turner { \ 46*42ff0ad8SZachary Turner static bool is_initialized = false; \ 47*42ff0ad8SZachary Turner static bool success = false; \ 48*42ff0ad8SZachary Turner if (!is_initialized) \ 49*42ff0ad8SZachary Turner { \ 50*42ff0ad8SZachary Turner is_initialized = true; \ 51*42ff0ad8SZachary Turner success = HostInfo::compute_function(member_var); \ 52*42ff0ad8SZachary Turner } \ 53*42ff0ad8SZachary Turner if (success) \ 54*42ff0ad8SZachary Turner result = &member_var; \ 55*42ff0ad8SZachary Turner } 56*42ff0ad8SZachary Turner 5775172a95SZachary Turner uint32_t HostInfoBase::m_number_cpus = 0; 5875172a95SZachary Turner std::string HostInfoBase::m_vendor_string; 5975172a95SZachary Turner std::string HostInfoBase::m_os_string; 6075172a95SZachary Turner std::string HostInfoBase::m_host_triple; 6175172a95SZachary Turner ArchSpec HostInfoBase::m_host_arch_32; 6275172a95SZachary Turner ArchSpec HostInfoBase::m_host_arch_64; 6397a14e60SZachary Turner 64*42ff0ad8SZachary Turner FileSpec HostInfoBase::m_lldb_so_dir; 65*42ff0ad8SZachary Turner FileSpec HostInfoBase::m_lldb_support_exe_dir; 66*42ff0ad8SZachary Turner FileSpec HostInfoBase::m_lldb_headers_dir; 67*42ff0ad8SZachary Turner FileSpec HostInfoBase::m_lldb_python_dir; 68*42ff0ad8SZachary Turner FileSpec HostInfoBase::m_lldb_system_plugin_dir; 69*42ff0ad8SZachary Turner FileSpec HostInfoBase::m_lldb_user_plugin_dir; 70*42ff0ad8SZachary Turner FileSpec HostInfoBase::m_lldb_tmp_dir; 71*42ff0ad8SZachary Turner 7297a14e60SZachary Turner uint32_t 7397a14e60SZachary Turner HostInfoBase::GetNumberCPUS() 7497a14e60SZachary Turner { 7597a14e60SZachary Turner static bool is_initialized = false; 7697a14e60SZachary Turner if (!is_initialized) 7797a14e60SZachary Turner { 7875172a95SZachary Turner m_number_cpus = std::thread::hardware_concurrency(); 7997a14e60SZachary Turner is_initialized = true; 8097a14e60SZachary Turner } 8197a14e60SZachary Turner 8275172a95SZachary Turner return m_number_cpus; 8397a14e60SZachary Turner } 8497a14e60SZachary Turner 8597a14e60SZachary Turner llvm::StringRef 8697a14e60SZachary Turner HostInfoBase::GetVendorString() 8797a14e60SZachary Turner { 8897a14e60SZachary Turner static bool is_initialized = false; 8997a14e60SZachary Turner if (!is_initialized) 9097a14e60SZachary Turner { 9113b18261SZachary Turner const ArchSpec &host_arch = HostInfo::GetArchitecture(); 9297a14e60SZachary Turner const llvm::StringRef &str_ref = host_arch.GetTriple().getVendorName(); 9375172a95SZachary Turner m_vendor_string.assign(str_ref.begin(), str_ref.end()); 9497a14e60SZachary Turner is_initialized = true; 9597a14e60SZachary Turner } 9675172a95SZachary Turner return m_vendor_string; 9797a14e60SZachary Turner } 9897a14e60SZachary Turner 9997a14e60SZachary Turner llvm::StringRef 10097a14e60SZachary Turner HostInfoBase::GetOSString() 10197a14e60SZachary Turner { 10297a14e60SZachary Turner static bool is_initialized = false; 10397a14e60SZachary Turner if (!is_initialized) 10497a14e60SZachary Turner { 10513b18261SZachary Turner const ArchSpec &host_arch = HostInfo::GetArchitecture(); 10697a14e60SZachary Turner const llvm::StringRef &str_ref = host_arch.GetTriple().getOSName(); 10775172a95SZachary Turner m_os_string.assign(str_ref.begin(), str_ref.end()); 10897a14e60SZachary Turner is_initialized = true; 10997a14e60SZachary Turner } 11075172a95SZachary Turner return m_os_string; 11197a14e60SZachary Turner } 11297a14e60SZachary Turner 11397a14e60SZachary Turner llvm::StringRef 11497a14e60SZachary Turner HostInfoBase::GetTargetTriple() 11597a14e60SZachary Turner { 11697a14e60SZachary Turner static bool is_initialized = false; 11797a14e60SZachary Turner if (!is_initialized) 11897a14e60SZachary Turner { 11913b18261SZachary Turner const ArchSpec &host_arch = HostInfo::GetArchitecture(); 12075172a95SZachary Turner m_host_triple = host_arch.GetTriple().getTriple(); 12197a14e60SZachary Turner is_initialized = true; 12297a14e60SZachary Turner } 12375172a95SZachary Turner return m_host_triple; 12497a14e60SZachary Turner } 12513b18261SZachary Turner 12613b18261SZachary Turner const ArchSpec & 12713b18261SZachary Turner HostInfoBase::GetArchitecture(ArchitectureKind arch_kind) 12813b18261SZachary Turner { 12913b18261SZachary Turner static bool is_initialized = false; 13013b18261SZachary Turner if (!is_initialized) 13113b18261SZachary Turner { 13275172a95SZachary Turner HostInfo::ComputeHostArchitectureSupport(m_host_arch_32, m_host_arch_64); 13313b18261SZachary Turner is_initialized = true; 13413b18261SZachary Turner } 13513b18261SZachary Turner 13613b18261SZachary Turner // If an explicit 32 or 64-bit architecture was requested, return that. 13713b18261SZachary Turner if (arch_kind == eArchKind32) 13875172a95SZachary Turner return m_host_arch_32; 13913b18261SZachary Turner if (arch_kind == eArchKind64) 14075172a95SZachary Turner return m_host_arch_64; 14113b18261SZachary Turner 14213b18261SZachary Turner // Otherwise prefer the 64-bit architecture if it is valid. 14375172a95SZachary Turner return (m_host_arch_64.IsValid()) ? m_host_arch_64 : m_host_arch_32; 14413b18261SZachary Turner } 14513b18261SZachary Turner 146*42ff0ad8SZachary Turner bool 147*42ff0ad8SZachary Turner HostInfoBase::GetLLDBPath(lldb::PathType type, FileSpec &file_spec) 148*42ff0ad8SZachary Turner { 149*42ff0ad8SZachary Turner file_spec.Clear(); 150*42ff0ad8SZachary Turner 151*42ff0ad8SZachary Turner #if defined(LLDB_DISABLE_PYTHON) 152*42ff0ad8SZachary Turner if (type == lldb::ePathTypePythonDir) 153*42ff0ad8SZachary Turner return false; 154*42ff0ad8SZachary Turner #endif 155*42ff0ad8SZachary Turner 156*42ff0ad8SZachary Turner Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); 157*42ff0ad8SZachary Turner FileSpec *result = nullptr; 158*42ff0ad8SZachary Turner switch (type) 159*42ff0ad8SZachary Turner { 160*42ff0ad8SZachary Turner case lldb::ePathTypeLLDBShlibDir: 161*42ff0ad8SZachary Turner COMPUTE_LLDB_PATH(ComputeSharedLibraryDirectory, m_lldb_so_dir) 162*42ff0ad8SZachary Turner if (log) 163*42ff0ad8SZachary Turner log->Printf("HostInfoBase::GetLLDBPath(ePathTypeLLDBShlibDir) => '%s'", m_lldb_so_dir.GetPath().c_str()); 164*42ff0ad8SZachary Turner break; 165*42ff0ad8SZachary Turner case lldb::ePathTypeSupportExecutableDir: 166*42ff0ad8SZachary Turner COMPUTE_LLDB_PATH(ComputeSupportExeDirectory, m_lldb_support_exe_dir) 167*42ff0ad8SZachary Turner if (log) 168*42ff0ad8SZachary Turner log->Printf("HostInfoBase::GetLLDBPath(ePathTypeSupportExecutableDir) => '%s'", m_lldb_support_exe_dir.GetPath().c_str()); 169*42ff0ad8SZachary Turner break; 170*42ff0ad8SZachary Turner case lldb::ePathTypeHeaderDir: 171*42ff0ad8SZachary Turner COMPUTE_LLDB_PATH(ComputeHeaderDirectory, m_lldb_headers_dir) 172*42ff0ad8SZachary Turner if (log) 173*42ff0ad8SZachary Turner log->Printf("HostInfoBase::GetLLDBPath(ePathTypeHeaderDir) => '%s'", m_lldb_headers_dir.GetPath().c_str()); 174*42ff0ad8SZachary Turner break; 175*42ff0ad8SZachary Turner case lldb::ePathTypePythonDir: 176*42ff0ad8SZachary Turner COMPUTE_LLDB_PATH(ComputePythonDirectory, m_lldb_python_dir) 177*42ff0ad8SZachary Turner if (log) 178*42ff0ad8SZachary Turner log->Printf("HostInfoBase::GetLLDBPath(ePathTypePythonDir) => '%s'", m_lldb_python_dir.GetPath().c_str()); 179*42ff0ad8SZachary Turner break; 180*42ff0ad8SZachary Turner case lldb::ePathTypeLLDBSystemPlugins: 181*42ff0ad8SZachary Turner COMPUTE_LLDB_PATH(ComputeSystemPluginsDirectory, m_lldb_system_plugin_dir) 182*42ff0ad8SZachary Turner if (log) 183*42ff0ad8SZachary Turner log->Printf("HostInfoBase::GetLLDBPath(ePathTypeLLDBSystemPlugins) => '%s'", m_lldb_system_plugin_dir.GetPath().c_str()); 184*42ff0ad8SZachary Turner break; 185*42ff0ad8SZachary Turner case lldb::ePathTypeLLDBUserPlugins: 186*42ff0ad8SZachary Turner COMPUTE_LLDB_PATH(ComputeUserPluginsDirectory, m_lldb_user_plugin_dir) 187*42ff0ad8SZachary Turner if (log) 188*42ff0ad8SZachary Turner log->Printf("HostInfoBase::GetLLDBPath(ePathTypeLLDBUserPlugins) => '%s'", m_lldb_user_plugin_dir.GetPath().c_str()); 189*42ff0ad8SZachary Turner break; 190*42ff0ad8SZachary Turner case lldb::ePathTypeLLDBTempSystemDir: 191*42ff0ad8SZachary Turner COMPUTE_LLDB_PATH(ComputeTempFileDirectory, m_lldb_tmp_dir) 192*42ff0ad8SZachary Turner if (log) 193*42ff0ad8SZachary Turner log->Printf("HostInfoBase::GetLLDBPath(ePathTypeLLDBTempSystemDir) => '%s'", m_lldb_tmp_dir.GetPath().c_str()); 194*42ff0ad8SZachary Turner break; 195*42ff0ad8SZachary Turner } 196*42ff0ad8SZachary Turner 197*42ff0ad8SZachary Turner if (!result) 198*42ff0ad8SZachary Turner return false; 199*42ff0ad8SZachary Turner file_spec = *result; 200*42ff0ad8SZachary Turner return true; 201*42ff0ad8SZachary Turner } 202*42ff0ad8SZachary Turner 203*42ff0ad8SZachary Turner bool 204*42ff0ad8SZachary Turner HostInfoBase::ComputeSharedLibraryDirectory(FileSpec &file_spec) 205*42ff0ad8SZachary Turner { 206*42ff0ad8SZachary Turner // To get paths related to LLDB we get the path to the executable that 207*42ff0ad8SZachary Turner // contains this function. On MacOSX this will be "LLDB.framework/.../LLDB", 208*42ff0ad8SZachary Turner // on linux this is assumed to be the "lldb" main executable. If LLDB on 209*42ff0ad8SZachary Turner // linux is actually in a shared library (liblldb.so) then this function will 210*42ff0ad8SZachary Turner // need to be modified to "do the right thing". 211*42ff0ad8SZachary Turner 212*42ff0ad8SZachary Turner FileSpec lldb_file_spec( 213*42ff0ad8SZachary Turner Host::GetModuleFileSpecForHostAddress(reinterpret_cast<void *>(reinterpret_cast<intptr_t>(HostInfoBase::GetLLDBPath)))); 214*42ff0ad8SZachary Turner 215*42ff0ad8SZachary Turner // Remove the filename so that this FileSpec only represents the directory. 216*42ff0ad8SZachary Turner file_spec.SetFile(lldb_file_spec.GetDirectory().AsCString(), true); 217*42ff0ad8SZachary Turner 218*42ff0ad8SZachary Turner return (bool)file_spec.GetDirectory(); 219*42ff0ad8SZachary Turner } 220*42ff0ad8SZachary Turner 221*42ff0ad8SZachary Turner bool 222*42ff0ad8SZachary Turner HostInfoBase::ComputeSupportExeDirectory(FileSpec &file_spec) 223*42ff0ad8SZachary Turner { 224*42ff0ad8SZachary Turner return GetLLDBPath(lldb::ePathTypeLLDBShlibDir, file_spec); 225*42ff0ad8SZachary Turner } 226*42ff0ad8SZachary Turner 227*42ff0ad8SZachary Turner bool 228*42ff0ad8SZachary Turner HostInfoBase::ComputeTempFileDirectory(FileSpec &file_spec) 229*42ff0ad8SZachary Turner { 230*42ff0ad8SZachary Turner const char *tmpdir_cstr = getenv("TMPDIR"); 231*42ff0ad8SZachary Turner if (tmpdir_cstr == NULL) 232*42ff0ad8SZachary Turner { 233*42ff0ad8SZachary Turner tmpdir_cstr = getenv("TMP"); 234*42ff0ad8SZachary Turner if (tmpdir_cstr == NULL) 235*42ff0ad8SZachary Turner tmpdir_cstr = getenv("TEMP"); 236*42ff0ad8SZachary Turner } 237*42ff0ad8SZachary Turner if (!tmpdir_cstr) 238*42ff0ad8SZachary Turner return false; 239*42ff0ad8SZachary Turner 240*42ff0ad8SZachary Turner StreamString pid_tmpdir; 241*42ff0ad8SZachary Turner pid_tmpdir.Printf("%s/lldb", tmpdir_cstr); 242*42ff0ad8SZachary Turner if (!FileSystem::MakeDirectory(pid_tmpdir.GetString().c_str(), eFilePermissionsDirectoryDefault).Success()) 243*42ff0ad8SZachary Turner return false; 244*42ff0ad8SZachary Turner 245*42ff0ad8SZachary Turner pid_tmpdir.Printf("/%" PRIu64, Host::GetCurrentProcessID()); 246*42ff0ad8SZachary Turner if (!FileSystem::MakeDirectory(pid_tmpdir.GetString().c_str(), eFilePermissionsDirectoryDefault).Success()) 247*42ff0ad8SZachary Turner return false; 248*42ff0ad8SZachary Turner 249*42ff0ad8SZachary Turner // Make an atexit handler to clean up the process specify LLDB temp dir 250*42ff0ad8SZachary Turner // and all of its contents. 251*42ff0ad8SZachary Turner ::atexit(CleanupProcessSpecificLLDBTempDir); 252*42ff0ad8SZachary Turner file_spec.SetFile(pid_tmpdir.GetString().c_str(), false); 253*42ff0ad8SZachary Turner return true; 254*42ff0ad8SZachary Turner } 255*42ff0ad8SZachary Turner 256*42ff0ad8SZachary Turner bool 257*42ff0ad8SZachary Turner HostInfoBase::ComputeHeaderDirectory(FileSpec &file_spec) 258*42ff0ad8SZachary Turner { 259*42ff0ad8SZachary Turner // TODO(zturner): Figure out how to compute the header directory for all platforms. 260*42ff0ad8SZachary Turner return false; 261*42ff0ad8SZachary Turner } 262*42ff0ad8SZachary Turner 263*42ff0ad8SZachary Turner bool 264*42ff0ad8SZachary Turner HostInfoBase::ComputeSystemPluginsDirectory(FileSpec &file_spec) 265*42ff0ad8SZachary Turner { 266*42ff0ad8SZachary Turner // TODO(zturner): Figure out how to compute the system plugins directory for all platforms. 267*42ff0ad8SZachary Turner return false; 268*42ff0ad8SZachary Turner } 269*42ff0ad8SZachary Turner 270*42ff0ad8SZachary Turner bool 271*42ff0ad8SZachary Turner HostInfoBase::ComputeUserPluginsDirectory(FileSpec &file_spec) 272*42ff0ad8SZachary Turner { 273*42ff0ad8SZachary Turner // TODO(zturner): Figure out how to compute the user plugins directory for all platforms. 274*42ff0ad8SZachary Turner return false; 275*42ff0ad8SZachary Turner } 276*42ff0ad8SZachary Turner 27713b18261SZachary Turner void 27813b18261SZachary Turner HostInfoBase::ComputeHostArchitectureSupport(ArchSpec &arch_32, ArchSpec &arch_64) 27913b18261SZachary Turner { 28013b18261SZachary Turner llvm::Triple triple(llvm::sys::getDefaultTargetTriple()); 28113b18261SZachary Turner 28213b18261SZachary Turner arch_32.Clear(); 28313b18261SZachary Turner arch_64.Clear(); 28413b18261SZachary Turner 28513b18261SZachary Turner switch (triple.getArch()) 28613b18261SZachary Turner { 28713b18261SZachary Turner default: 28813b18261SZachary Turner arch_32.SetTriple(triple); 28913b18261SZachary Turner break; 29013b18261SZachary Turner 29113b18261SZachary Turner case llvm::Triple::x86_64: 29213b18261SZachary Turner arch_64.SetTriple(triple); 29313b18261SZachary Turner arch_32.SetTriple(triple.get32BitArchVariant()); 29413b18261SZachary Turner break; 29513b18261SZachary Turner 29613b18261SZachary Turner case llvm::Triple::mips64: 29713b18261SZachary Turner case llvm::Triple::sparcv9: 29813b18261SZachary Turner case llvm::Triple::ppc64: 29913b18261SZachary Turner arch_64.SetTriple(triple); 30013b18261SZachary Turner break; 30113b18261SZachary Turner } 30213b18261SZachary Turner } 303