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" 1342ff0ad8SZachary Turner #include "lldb/Core/Log.h" 1442ff0ad8SZachary Turner #include "lldb/Core/StreamString.h" 1542ff0ad8SZachary 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 2842ff0ad8SZachary Turner namespace 2942ff0ad8SZachary Turner { 3042ff0ad8SZachary Turner void 3142ff0ad8SZachary Turner CleanupProcessSpecificLLDBTempDir() 3242ff0ad8SZachary Turner { 3342ff0ad8SZachary Turner // Get the process specific LLDB temporary directory and delete it. 3442ff0ad8SZachary Turner FileSpec tmpdir_file_spec; 3542ff0ad8SZachary Turner if (!HostInfo::GetLLDBPath(ePathTypeLLDBTempSystemDir, tmpdir_file_spec)) 3642ff0ad8SZachary Turner return; 3742ff0ad8SZachary Turner 3842ff0ad8SZachary Turner // Remove the LLDB temporary directory if we have one. Set "recurse" to 3942ff0ad8SZachary Turner // true to all files that were created for the LLDB process can be cleaned up. 4042ff0ad8SZachary Turner FileSystem::DeleteDirectory(tmpdir_file_spec.GetDirectory().GetCString(), true); 4142ff0ad8SZachary Turner } 42673b6e4fSZachary Turner 43673b6e4fSZachary Turner struct HostInfoBaseFields 44673b6e4fSZachary Turner { 45673b6e4fSZachary Turner uint32_t m_number_cpus; 46673b6e4fSZachary Turner std::string m_vendor_string; 47673b6e4fSZachary Turner std::string m_os_string; 48673b6e4fSZachary Turner std::string m_host_triple; 49673b6e4fSZachary Turner 50673b6e4fSZachary Turner ArchSpec m_host_arch_32; 51673b6e4fSZachary Turner ArchSpec m_host_arch_64; 52673b6e4fSZachary Turner 53673b6e4fSZachary Turner FileSpec m_lldb_so_dir; 54673b6e4fSZachary Turner FileSpec m_lldb_support_exe_dir; 55673b6e4fSZachary Turner FileSpec m_lldb_headers_dir; 56673b6e4fSZachary Turner FileSpec m_lldb_python_dir; 57673b6e4fSZachary Turner FileSpec m_lldb_system_plugin_dir; 58673b6e4fSZachary Turner FileSpec m_lldb_user_plugin_dir; 59673b6e4fSZachary Turner FileSpec m_lldb_tmp_dir; 60673b6e4fSZachary Turner }; 61673b6e4fSZachary Turner 62673b6e4fSZachary Turner HostInfoBaseFields *g_fields = nullptr; 6342ff0ad8SZachary Turner } 6442ff0ad8SZachary Turner 6542ff0ad8SZachary Turner #define COMPUTE_LLDB_PATH(compute_function, member_var) \ 6642ff0ad8SZachary Turner { \ 6742ff0ad8SZachary Turner static bool is_initialized = false; \ 6842ff0ad8SZachary Turner static bool success = false; \ 6942ff0ad8SZachary Turner if (!is_initialized) \ 7042ff0ad8SZachary Turner { \ 7142ff0ad8SZachary Turner is_initialized = true; \ 7242ff0ad8SZachary Turner success = HostInfo::compute_function(member_var); \ 7342ff0ad8SZachary Turner } \ 7442ff0ad8SZachary Turner if (success) \ 7542ff0ad8SZachary Turner result = &member_var; \ 7642ff0ad8SZachary Turner } 7742ff0ad8SZachary Turner 78673b6e4fSZachary Turner void 79673b6e4fSZachary Turner HostInfoBase::Initialize() 80673b6e4fSZachary Turner { 81673b6e4fSZachary Turner g_fields = new HostInfoBaseFields(); 82673b6e4fSZachary Turner } 8342ff0ad8SZachary Turner 8497a14e60SZachary Turner uint32_t 8597a14e60SZachary Turner HostInfoBase::GetNumberCPUS() 8697a14e60SZachary Turner { 8797a14e60SZachary Turner static bool is_initialized = false; 8897a14e60SZachary Turner if (!is_initialized) 8997a14e60SZachary Turner { 90673b6e4fSZachary Turner g_fields->m_number_cpus = std::thread::hardware_concurrency(); 9197a14e60SZachary Turner is_initialized = true; 9297a14e60SZachary Turner } 9397a14e60SZachary Turner 94673b6e4fSZachary Turner return g_fields->m_number_cpus; 9597a14e60SZachary Turner } 9697a14e60SZachary Turner 9797a14e60SZachary Turner llvm::StringRef 9897a14e60SZachary Turner HostInfoBase::GetVendorString() 9997a14e60SZachary Turner { 10097a14e60SZachary Turner static bool is_initialized = false; 10197a14e60SZachary Turner if (!is_initialized) 10297a14e60SZachary Turner { 10313b18261SZachary Turner const ArchSpec &host_arch = HostInfo::GetArchitecture(); 10497a14e60SZachary Turner const llvm::StringRef &str_ref = host_arch.GetTriple().getVendorName(); 105673b6e4fSZachary Turner g_fields->m_vendor_string.assign(str_ref.begin(), str_ref.end()); 10697a14e60SZachary Turner is_initialized = true; 10797a14e60SZachary Turner } 108673b6e4fSZachary Turner return g_fields->m_vendor_string; 10997a14e60SZachary Turner } 11097a14e60SZachary Turner 11197a14e60SZachary Turner llvm::StringRef 11297a14e60SZachary Turner HostInfoBase::GetOSString() 11397a14e60SZachary Turner { 11497a14e60SZachary Turner static bool is_initialized = false; 11597a14e60SZachary Turner if (!is_initialized) 11697a14e60SZachary Turner { 11713b18261SZachary Turner const ArchSpec &host_arch = HostInfo::GetArchitecture(); 11897a14e60SZachary Turner const llvm::StringRef &str_ref = host_arch.GetTriple().getOSName(); 119673b6e4fSZachary Turner g_fields->m_os_string.assign(str_ref.begin(), str_ref.end()); 12097a14e60SZachary Turner is_initialized = true; 12197a14e60SZachary Turner } 122673b6e4fSZachary Turner return g_fields->m_os_string; 12397a14e60SZachary Turner } 12497a14e60SZachary Turner 12597a14e60SZachary Turner llvm::StringRef 12697a14e60SZachary Turner HostInfoBase::GetTargetTriple() 12797a14e60SZachary Turner { 12897a14e60SZachary Turner static bool is_initialized = false; 12997a14e60SZachary Turner if (!is_initialized) 13097a14e60SZachary Turner { 13113b18261SZachary Turner const ArchSpec &host_arch = HostInfo::GetArchitecture(); 132673b6e4fSZachary Turner g_fields->m_host_triple = host_arch.GetTriple().getTriple(); 13397a14e60SZachary Turner is_initialized = true; 13497a14e60SZachary Turner } 135673b6e4fSZachary Turner return g_fields->m_host_triple; 13697a14e60SZachary Turner } 13713b18261SZachary Turner 13813b18261SZachary Turner const ArchSpec & 13913b18261SZachary Turner HostInfoBase::GetArchitecture(ArchitectureKind arch_kind) 14013b18261SZachary Turner { 14113b18261SZachary Turner static bool is_initialized = false; 14213b18261SZachary Turner if (!is_initialized) 14313b18261SZachary Turner { 144673b6e4fSZachary Turner HostInfo::ComputeHostArchitectureSupport(g_fields->m_host_arch_32, g_fields->m_host_arch_64); 14513b18261SZachary Turner is_initialized = true; 14613b18261SZachary Turner } 14713b18261SZachary Turner 14813b18261SZachary Turner // If an explicit 32 or 64-bit architecture was requested, return that. 14913b18261SZachary Turner if (arch_kind == eArchKind32) 150673b6e4fSZachary Turner return g_fields->m_host_arch_32; 15113b18261SZachary Turner if (arch_kind == eArchKind64) 152673b6e4fSZachary Turner return g_fields->m_host_arch_64; 15313b18261SZachary Turner 15413b18261SZachary Turner // Otherwise prefer the 64-bit architecture if it is valid. 155673b6e4fSZachary Turner return (g_fields->m_host_arch_64.IsValid()) ? g_fields->m_host_arch_64 : g_fields->m_host_arch_32; 15613b18261SZachary Turner } 15713b18261SZachary Turner 15842ff0ad8SZachary Turner bool 15942ff0ad8SZachary Turner HostInfoBase::GetLLDBPath(lldb::PathType type, FileSpec &file_spec) 16042ff0ad8SZachary Turner { 16142ff0ad8SZachary Turner file_spec.Clear(); 16242ff0ad8SZachary Turner 16342ff0ad8SZachary Turner #if defined(LLDB_DISABLE_PYTHON) 16442ff0ad8SZachary Turner if (type == lldb::ePathTypePythonDir) 16542ff0ad8SZachary Turner return false; 16642ff0ad8SZachary Turner #endif 16742ff0ad8SZachary Turner 16842ff0ad8SZachary Turner Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); 16942ff0ad8SZachary Turner FileSpec *result = nullptr; 17042ff0ad8SZachary Turner switch (type) 17142ff0ad8SZachary Turner { 17242ff0ad8SZachary Turner case lldb::ePathTypeLLDBShlibDir: 173673b6e4fSZachary Turner COMPUTE_LLDB_PATH(ComputeSharedLibraryDirectory, g_fields->m_lldb_so_dir) 17442ff0ad8SZachary Turner if (log) 175673b6e4fSZachary Turner log->Printf("HostInfoBase::GetLLDBPath(ePathTypeLLDBShlibDir) => '%s'", g_fields->m_lldb_so_dir.GetPath().c_str()); 17642ff0ad8SZachary Turner break; 17742ff0ad8SZachary Turner case lldb::ePathTypeSupportExecutableDir: 178673b6e4fSZachary Turner COMPUTE_LLDB_PATH(ComputeSupportExeDirectory, g_fields->m_lldb_support_exe_dir) 17942ff0ad8SZachary Turner if (log) 180673b6e4fSZachary Turner log->Printf("HostInfoBase::GetLLDBPath(ePathTypeSupportExecutableDir) => '%s'", 181673b6e4fSZachary Turner g_fields->m_lldb_support_exe_dir.GetPath().c_str()); 18242ff0ad8SZachary Turner break; 18342ff0ad8SZachary Turner case lldb::ePathTypeHeaderDir: 184673b6e4fSZachary Turner COMPUTE_LLDB_PATH(ComputeHeaderDirectory, g_fields->m_lldb_headers_dir) 18542ff0ad8SZachary Turner if (log) 186673b6e4fSZachary Turner log->Printf("HostInfoBase::GetLLDBPath(ePathTypeHeaderDir) => '%s'", g_fields->m_lldb_headers_dir.GetPath().c_str()); 18742ff0ad8SZachary Turner break; 18842ff0ad8SZachary Turner case lldb::ePathTypePythonDir: 189673b6e4fSZachary Turner COMPUTE_LLDB_PATH(ComputePythonDirectory, g_fields->m_lldb_python_dir) 19042ff0ad8SZachary Turner if (log) 191673b6e4fSZachary Turner log->Printf("HostInfoBase::GetLLDBPath(ePathTypePythonDir) => '%s'", g_fields->m_lldb_python_dir.GetPath().c_str()); 19242ff0ad8SZachary Turner break; 19342ff0ad8SZachary Turner case lldb::ePathTypeLLDBSystemPlugins: 194673b6e4fSZachary Turner COMPUTE_LLDB_PATH(ComputeSystemPluginsDirectory, g_fields->m_lldb_system_plugin_dir) 19542ff0ad8SZachary Turner if (log) 196673b6e4fSZachary Turner log->Printf("HostInfoBase::GetLLDBPath(ePathTypeLLDBSystemPlugins) => '%s'", 197673b6e4fSZachary Turner g_fields->m_lldb_system_plugin_dir.GetPath().c_str()); 19842ff0ad8SZachary Turner break; 19942ff0ad8SZachary Turner case lldb::ePathTypeLLDBUserPlugins: 200673b6e4fSZachary Turner COMPUTE_LLDB_PATH(ComputeUserPluginsDirectory, g_fields->m_lldb_user_plugin_dir) 20142ff0ad8SZachary Turner if (log) 202673b6e4fSZachary Turner log->Printf("HostInfoBase::GetLLDBPath(ePathTypeLLDBUserPlugins) => '%s'", 203673b6e4fSZachary Turner g_fields->m_lldb_user_plugin_dir.GetPath().c_str()); 20442ff0ad8SZachary Turner break; 20542ff0ad8SZachary Turner case lldb::ePathTypeLLDBTempSystemDir: 206673b6e4fSZachary Turner COMPUTE_LLDB_PATH(ComputeTempFileDirectory, g_fields->m_lldb_tmp_dir) 20742ff0ad8SZachary Turner if (log) 208673b6e4fSZachary Turner log->Printf("HostInfoBase::GetLLDBPath(ePathTypeLLDBTempSystemDir) => '%s'", g_fields->m_lldb_tmp_dir.GetPath().c_str()); 20942ff0ad8SZachary Turner break; 21042ff0ad8SZachary Turner } 21142ff0ad8SZachary Turner 21242ff0ad8SZachary Turner if (!result) 21342ff0ad8SZachary Turner return false; 21442ff0ad8SZachary Turner file_spec = *result; 21542ff0ad8SZachary Turner return true; 21642ff0ad8SZachary Turner } 21742ff0ad8SZachary Turner 21842ff0ad8SZachary Turner bool 21942ff0ad8SZachary Turner HostInfoBase::ComputeSharedLibraryDirectory(FileSpec &file_spec) 22042ff0ad8SZachary Turner { 22142ff0ad8SZachary Turner // To get paths related to LLDB we get the path to the executable that 22242ff0ad8SZachary Turner // contains this function. On MacOSX this will be "LLDB.framework/.../LLDB", 22342ff0ad8SZachary Turner // on linux this is assumed to be the "lldb" main executable. If LLDB on 22442ff0ad8SZachary Turner // linux is actually in a shared library (liblldb.so) then this function will 22542ff0ad8SZachary Turner // need to be modified to "do the right thing". 22642ff0ad8SZachary Turner 22742ff0ad8SZachary Turner FileSpec lldb_file_spec( 22842ff0ad8SZachary Turner Host::GetModuleFileSpecForHostAddress(reinterpret_cast<void *>(reinterpret_cast<intptr_t>(HostInfoBase::GetLLDBPath)))); 22942ff0ad8SZachary Turner 23042ff0ad8SZachary Turner // Remove the filename so that this FileSpec only represents the directory. 2310d8400c8SGreg Clayton file_spec.GetDirectory() = lldb_file_spec.GetDirectory(); 23242ff0ad8SZachary Turner 23342ff0ad8SZachary Turner return (bool)file_spec.GetDirectory(); 23442ff0ad8SZachary Turner } 23542ff0ad8SZachary Turner 23642ff0ad8SZachary Turner bool 23742ff0ad8SZachary Turner HostInfoBase::ComputeSupportExeDirectory(FileSpec &file_spec) 23842ff0ad8SZachary Turner { 23942ff0ad8SZachary Turner return GetLLDBPath(lldb::ePathTypeLLDBShlibDir, file_spec); 24042ff0ad8SZachary Turner } 24142ff0ad8SZachary Turner 24242ff0ad8SZachary Turner bool 24342ff0ad8SZachary Turner HostInfoBase::ComputeTempFileDirectory(FileSpec &file_spec) 24442ff0ad8SZachary Turner { 24542ff0ad8SZachary Turner const char *tmpdir_cstr = getenv("TMPDIR"); 24642ff0ad8SZachary Turner if (tmpdir_cstr == NULL) 24742ff0ad8SZachary Turner { 24842ff0ad8SZachary Turner tmpdir_cstr = getenv("TMP"); 24942ff0ad8SZachary Turner if (tmpdir_cstr == NULL) 25042ff0ad8SZachary Turner tmpdir_cstr = getenv("TEMP"); 25142ff0ad8SZachary Turner } 25242ff0ad8SZachary Turner if (!tmpdir_cstr) 25342ff0ad8SZachary Turner return false; 25442ff0ad8SZachary Turner 25542ff0ad8SZachary Turner StreamString pid_tmpdir; 25642ff0ad8SZachary Turner pid_tmpdir.Printf("%s/lldb", tmpdir_cstr); 25742ff0ad8SZachary Turner if (!FileSystem::MakeDirectory(pid_tmpdir.GetString().c_str(), eFilePermissionsDirectoryDefault).Success()) 25842ff0ad8SZachary Turner return false; 25942ff0ad8SZachary Turner 26042ff0ad8SZachary Turner pid_tmpdir.Printf("/%" PRIu64, Host::GetCurrentProcessID()); 26142ff0ad8SZachary Turner if (!FileSystem::MakeDirectory(pid_tmpdir.GetString().c_str(), eFilePermissionsDirectoryDefault).Success()) 26242ff0ad8SZachary Turner return false; 26342ff0ad8SZachary Turner 26442ff0ad8SZachary Turner // Make an atexit handler to clean up the process specify LLDB temp dir 26542ff0ad8SZachary Turner // and all of its contents. 26642ff0ad8SZachary Turner ::atexit(CleanupProcessSpecificLLDBTempDir); 2670d8400c8SGreg Clayton file_spec.GetDirectory().SetCStringWithLength(pid_tmpdir.GetString().c_str(), pid_tmpdir.GetString().size()); 26842ff0ad8SZachary Turner return true; 26942ff0ad8SZachary Turner } 27042ff0ad8SZachary Turner 27142ff0ad8SZachary Turner bool 27242ff0ad8SZachary Turner HostInfoBase::ComputeHeaderDirectory(FileSpec &file_spec) 27342ff0ad8SZachary Turner { 27442ff0ad8SZachary Turner // TODO(zturner): Figure out how to compute the header directory for all platforms. 27542ff0ad8SZachary Turner return false; 27642ff0ad8SZachary Turner } 27742ff0ad8SZachary Turner 27842ff0ad8SZachary Turner bool 27942ff0ad8SZachary Turner HostInfoBase::ComputeSystemPluginsDirectory(FileSpec &file_spec) 28042ff0ad8SZachary Turner { 28142ff0ad8SZachary Turner // TODO(zturner): Figure out how to compute the system plugins directory for all platforms. 28242ff0ad8SZachary Turner return false; 28342ff0ad8SZachary Turner } 28442ff0ad8SZachary Turner 28542ff0ad8SZachary Turner bool 28642ff0ad8SZachary Turner HostInfoBase::ComputeUserPluginsDirectory(FileSpec &file_spec) 28742ff0ad8SZachary Turner { 28842ff0ad8SZachary Turner // TODO(zturner): Figure out how to compute the user plugins directory for all platforms. 28942ff0ad8SZachary Turner return false; 29042ff0ad8SZachary Turner } 29142ff0ad8SZachary Turner 29213b18261SZachary Turner void 29313b18261SZachary Turner HostInfoBase::ComputeHostArchitectureSupport(ArchSpec &arch_32, ArchSpec &arch_64) 29413b18261SZachary Turner { 29513b18261SZachary Turner llvm::Triple triple(llvm::sys::getDefaultTargetTriple()); 29613b18261SZachary Turner 29713b18261SZachary Turner arch_32.Clear(); 29813b18261SZachary Turner arch_64.Clear(); 29913b18261SZachary Turner 30013b18261SZachary Turner switch (triple.getArch()) 30113b18261SZachary Turner { 30213b18261SZachary Turner default: 30313b18261SZachary Turner arch_32.SetTriple(triple); 30413b18261SZachary Turner break; 30513b18261SZachary Turner 30613b18261SZachary Turner case llvm::Triple::x86_64: 30713b18261SZachary Turner arch_64.SetTriple(triple); 30813b18261SZachary Turner arch_32.SetTriple(triple.get32BitArchVariant()); 30913b18261SZachary Turner break; 31013b18261SZachary Turner 311*e4d6922cSTodd Fiala case llvm::Triple::aarch64: 31213b18261SZachary Turner case llvm::Triple::mips64: 31313b18261SZachary Turner case llvm::Triple::sparcv9: 31413b18261SZachary Turner case llvm::Triple::ppc64: 31513b18261SZachary Turner arch_64.SetTriple(triple); 31613b18261SZachary Turner break; 31713b18261SZachary Turner } 31813b18261SZachary Turner } 319