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 97*39de3110SZachary Turner uint32_t 98*39de3110SZachary Turner HostInfoBase::GetMaxThreadNameLength() 99*39de3110SZachary Turner { 100*39de3110SZachary Turner return 0; 101*39de3110SZachary Turner } 102*39de3110SZachary Turner 10397a14e60SZachary Turner llvm::StringRef 10497a14e60SZachary Turner HostInfoBase::GetVendorString() 10597a14e60SZachary Turner { 10697a14e60SZachary Turner static bool is_initialized = false; 10797a14e60SZachary Turner if (!is_initialized) 10897a14e60SZachary Turner { 10913b18261SZachary Turner const ArchSpec &host_arch = HostInfo::GetArchitecture(); 11097a14e60SZachary Turner const llvm::StringRef &str_ref = host_arch.GetTriple().getVendorName(); 111673b6e4fSZachary Turner g_fields->m_vendor_string.assign(str_ref.begin(), str_ref.end()); 11297a14e60SZachary Turner is_initialized = true; 11397a14e60SZachary Turner } 114673b6e4fSZachary Turner return g_fields->m_vendor_string; 11597a14e60SZachary Turner } 11697a14e60SZachary Turner 11797a14e60SZachary Turner llvm::StringRef 11897a14e60SZachary Turner HostInfoBase::GetOSString() 11997a14e60SZachary Turner { 12097a14e60SZachary Turner static bool is_initialized = false; 12197a14e60SZachary Turner if (!is_initialized) 12297a14e60SZachary Turner { 12313b18261SZachary Turner const ArchSpec &host_arch = HostInfo::GetArchitecture(); 12497a14e60SZachary Turner const llvm::StringRef &str_ref = host_arch.GetTriple().getOSName(); 125673b6e4fSZachary Turner g_fields->m_os_string.assign(str_ref.begin(), str_ref.end()); 12697a14e60SZachary Turner is_initialized = true; 12797a14e60SZachary Turner } 128673b6e4fSZachary Turner return g_fields->m_os_string; 12997a14e60SZachary Turner } 13097a14e60SZachary Turner 13197a14e60SZachary Turner llvm::StringRef 13297a14e60SZachary Turner HostInfoBase::GetTargetTriple() 13397a14e60SZachary Turner { 13497a14e60SZachary Turner static bool is_initialized = false; 13597a14e60SZachary Turner if (!is_initialized) 13697a14e60SZachary Turner { 13713b18261SZachary Turner const ArchSpec &host_arch = HostInfo::GetArchitecture(); 138673b6e4fSZachary Turner g_fields->m_host_triple = host_arch.GetTriple().getTriple(); 13997a14e60SZachary Turner is_initialized = true; 14097a14e60SZachary Turner } 141673b6e4fSZachary Turner return g_fields->m_host_triple; 14297a14e60SZachary Turner } 14313b18261SZachary Turner 14413b18261SZachary Turner const ArchSpec & 14513b18261SZachary Turner HostInfoBase::GetArchitecture(ArchitectureKind arch_kind) 14613b18261SZachary Turner { 14713b18261SZachary Turner static bool is_initialized = false; 14813b18261SZachary Turner if (!is_initialized) 14913b18261SZachary Turner { 150673b6e4fSZachary Turner HostInfo::ComputeHostArchitectureSupport(g_fields->m_host_arch_32, g_fields->m_host_arch_64); 15113b18261SZachary Turner is_initialized = true; 15213b18261SZachary Turner } 15313b18261SZachary Turner 15413b18261SZachary Turner // If an explicit 32 or 64-bit architecture was requested, return that. 15513b18261SZachary Turner if (arch_kind == eArchKind32) 156673b6e4fSZachary Turner return g_fields->m_host_arch_32; 15713b18261SZachary Turner if (arch_kind == eArchKind64) 158673b6e4fSZachary Turner return g_fields->m_host_arch_64; 15913b18261SZachary Turner 16013b18261SZachary Turner // Otherwise prefer the 64-bit architecture if it is valid. 161673b6e4fSZachary Turner return (g_fields->m_host_arch_64.IsValid()) ? g_fields->m_host_arch_64 : g_fields->m_host_arch_32; 16213b18261SZachary Turner } 16313b18261SZachary Turner 16442ff0ad8SZachary Turner bool 16542ff0ad8SZachary Turner HostInfoBase::GetLLDBPath(lldb::PathType type, FileSpec &file_spec) 16642ff0ad8SZachary Turner { 16742ff0ad8SZachary Turner file_spec.Clear(); 16842ff0ad8SZachary Turner 16942ff0ad8SZachary Turner #if defined(LLDB_DISABLE_PYTHON) 17042ff0ad8SZachary Turner if (type == lldb::ePathTypePythonDir) 17142ff0ad8SZachary Turner return false; 17242ff0ad8SZachary Turner #endif 17342ff0ad8SZachary Turner 17442ff0ad8SZachary Turner Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); 17542ff0ad8SZachary Turner FileSpec *result = nullptr; 17642ff0ad8SZachary Turner switch (type) 17742ff0ad8SZachary Turner { 17842ff0ad8SZachary Turner case lldb::ePathTypeLLDBShlibDir: 179673b6e4fSZachary Turner COMPUTE_LLDB_PATH(ComputeSharedLibraryDirectory, g_fields->m_lldb_so_dir) 18042ff0ad8SZachary Turner if (log) 181673b6e4fSZachary Turner log->Printf("HostInfoBase::GetLLDBPath(ePathTypeLLDBShlibDir) => '%s'", g_fields->m_lldb_so_dir.GetPath().c_str()); 18242ff0ad8SZachary Turner break; 18342ff0ad8SZachary Turner case lldb::ePathTypeSupportExecutableDir: 184673b6e4fSZachary Turner COMPUTE_LLDB_PATH(ComputeSupportExeDirectory, g_fields->m_lldb_support_exe_dir) 18542ff0ad8SZachary Turner if (log) 186673b6e4fSZachary Turner log->Printf("HostInfoBase::GetLLDBPath(ePathTypeSupportExecutableDir) => '%s'", 187673b6e4fSZachary Turner g_fields->m_lldb_support_exe_dir.GetPath().c_str()); 18842ff0ad8SZachary Turner break; 18942ff0ad8SZachary Turner case lldb::ePathTypeHeaderDir: 190673b6e4fSZachary Turner COMPUTE_LLDB_PATH(ComputeHeaderDirectory, g_fields->m_lldb_headers_dir) 19142ff0ad8SZachary Turner if (log) 192673b6e4fSZachary Turner log->Printf("HostInfoBase::GetLLDBPath(ePathTypeHeaderDir) => '%s'", g_fields->m_lldb_headers_dir.GetPath().c_str()); 19342ff0ad8SZachary Turner break; 19442ff0ad8SZachary Turner case lldb::ePathTypePythonDir: 195673b6e4fSZachary Turner COMPUTE_LLDB_PATH(ComputePythonDirectory, g_fields->m_lldb_python_dir) 19642ff0ad8SZachary Turner if (log) 197673b6e4fSZachary Turner log->Printf("HostInfoBase::GetLLDBPath(ePathTypePythonDir) => '%s'", g_fields->m_lldb_python_dir.GetPath().c_str()); 19842ff0ad8SZachary Turner break; 19942ff0ad8SZachary Turner case lldb::ePathTypeLLDBSystemPlugins: 200673b6e4fSZachary Turner COMPUTE_LLDB_PATH(ComputeSystemPluginsDirectory, g_fields->m_lldb_system_plugin_dir) 20142ff0ad8SZachary Turner if (log) 202673b6e4fSZachary Turner log->Printf("HostInfoBase::GetLLDBPath(ePathTypeLLDBSystemPlugins) => '%s'", 203673b6e4fSZachary Turner g_fields->m_lldb_system_plugin_dir.GetPath().c_str()); 20442ff0ad8SZachary Turner break; 20542ff0ad8SZachary Turner case lldb::ePathTypeLLDBUserPlugins: 206673b6e4fSZachary Turner COMPUTE_LLDB_PATH(ComputeUserPluginsDirectory, g_fields->m_lldb_user_plugin_dir) 20742ff0ad8SZachary Turner if (log) 208673b6e4fSZachary Turner log->Printf("HostInfoBase::GetLLDBPath(ePathTypeLLDBUserPlugins) => '%s'", 209673b6e4fSZachary Turner g_fields->m_lldb_user_plugin_dir.GetPath().c_str()); 21042ff0ad8SZachary Turner break; 21142ff0ad8SZachary Turner case lldb::ePathTypeLLDBTempSystemDir: 212673b6e4fSZachary Turner COMPUTE_LLDB_PATH(ComputeTempFileDirectory, g_fields->m_lldb_tmp_dir) 21342ff0ad8SZachary Turner if (log) 214673b6e4fSZachary Turner log->Printf("HostInfoBase::GetLLDBPath(ePathTypeLLDBTempSystemDir) => '%s'", g_fields->m_lldb_tmp_dir.GetPath().c_str()); 21542ff0ad8SZachary Turner break; 21642ff0ad8SZachary Turner } 21742ff0ad8SZachary Turner 21842ff0ad8SZachary Turner if (!result) 21942ff0ad8SZachary Turner return false; 22042ff0ad8SZachary Turner file_spec = *result; 22142ff0ad8SZachary Turner return true; 22242ff0ad8SZachary Turner } 22342ff0ad8SZachary Turner 22442ff0ad8SZachary Turner bool 22542ff0ad8SZachary Turner HostInfoBase::ComputeSharedLibraryDirectory(FileSpec &file_spec) 22642ff0ad8SZachary Turner { 22742ff0ad8SZachary Turner // To get paths related to LLDB we get the path to the executable that 22842ff0ad8SZachary Turner // contains this function. On MacOSX this will be "LLDB.framework/.../LLDB", 22942ff0ad8SZachary Turner // on linux this is assumed to be the "lldb" main executable. If LLDB on 23042ff0ad8SZachary Turner // linux is actually in a shared library (liblldb.so) then this function will 23142ff0ad8SZachary Turner // need to be modified to "do the right thing". 23242ff0ad8SZachary Turner 23342ff0ad8SZachary Turner FileSpec lldb_file_spec( 23442ff0ad8SZachary Turner Host::GetModuleFileSpecForHostAddress(reinterpret_cast<void *>(reinterpret_cast<intptr_t>(HostInfoBase::GetLLDBPath)))); 23542ff0ad8SZachary Turner 23642ff0ad8SZachary Turner // Remove the filename so that this FileSpec only represents the directory. 2370d8400c8SGreg Clayton file_spec.GetDirectory() = lldb_file_spec.GetDirectory(); 23842ff0ad8SZachary Turner 23942ff0ad8SZachary Turner return (bool)file_spec.GetDirectory(); 24042ff0ad8SZachary Turner } 24142ff0ad8SZachary Turner 24242ff0ad8SZachary Turner bool 24342ff0ad8SZachary Turner HostInfoBase::ComputeSupportExeDirectory(FileSpec &file_spec) 24442ff0ad8SZachary Turner { 24542ff0ad8SZachary Turner return GetLLDBPath(lldb::ePathTypeLLDBShlibDir, file_spec); 24642ff0ad8SZachary Turner } 24742ff0ad8SZachary Turner 24842ff0ad8SZachary Turner bool 24942ff0ad8SZachary Turner HostInfoBase::ComputeTempFileDirectory(FileSpec &file_spec) 25042ff0ad8SZachary Turner { 25142ff0ad8SZachary Turner const char *tmpdir_cstr = getenv("TMPDIR"); 25242ff0ad8SZachary Turner if (tmpdir_cstr == NULL) 25342ff0ad8SZachary Turner { 25442ff0ad8SZachary Turner tmpdir_cstr = getenv("TMP"); 25542ff0ad8SZachary Turner if (tmpdir_cstr == NULL) 25642ff0ad8SZachary Turner tmpdir_cstr = getenv("TEMP"); 25742ff0ad8SZachary Turner } 25842ff0ad8SZachary Turner if (!tmpdir_cstr) 25942ff0ad8SZachary Turner return false; 26042ff0ad8SZachary Turner 26142ff0ad8SZachary Turner StreamString pid_tmpdir; 26242ff0ad8SZachary Turner pid_tmpdir.Printf("%s/lldb", tmpdir_cstr); 26342ff0ad8SZachary Turner if (!FileSystem::MakeDirectory(pid_tmpdir.GetString().c_str(), eFilePermissionsDirectoryDefault).Success()) 26442ff0ad8SZachary Turner return false; 26542ff0ad8SZachary Turner 26642ff0ad8SZachary Turner pid_tmpdir.Printf("/%" PRIu64, Host::GetCurrentProcessID()); 26742ff0ad8SZachary Turner if (!FileSystem::MakeDirectory(pid_tmpdir.GetString().c_str(), eFilePermissionsDirectoryDefault).Success()) 26842ff0ad8SZachary Turner return false; 26942ff0ad8SZachary Turner 27042ff0ad8SZachary Turner // Make an atexit handler to clean up the process specify LLDB temp dir 27142ff0ad8SZachary Turner // and all of its contents. 27242ff0ad8SZachary Turner ::atexit(CleanupProcessSpecificLLDBTempDir); 2730d8400c8SGreg Clayton file_spec.GetDirectory().SetCStringWithLength(pid_tmpdir.GetString().c_str(), pid_tmpdir.GetString().size()); 27442ff0ad8SZachary Turner return true; 27542ff0ad8SZachary Turner } 27642ff0ad8SZachary Turner 27742ff0ad8SZachary Turner bool 27842ff0ad8SZachary Turner HostInfoBase::ComputeHeaderDirectory(FileSpec &file_spec) 27942ff0ad8SZachary Turner { 28042ff0ad8SZachary Turner // TODO(zturner): Figure out how to compute the header directory for all platforms. 28142ff0ad8SZachary Turner return false; 28242ff0ad8SZachary Turner } 28342ff0ad8SZachary Turner 28442ff0ad8SZachary Turner bool 28542ff0ad8SZachary Turner HostInfoBase::ComputeSystemPluginsDirectory(FileSpec &file_spec) 28642ff0ad8SZachary Turner { 28742ff0ad8SZachary Turner // TODO(zturner): Figure out how to compute the system plugins directory for all platforms. 28842ff0ad8SZachary Turner return false; 28942ff0ad8SZachary Turner } 29042ff0ad8SZachary Turner 29142ff0ad8SZachary Turner bool 29242ff0ad8SZachary Turner HostInfoBase::ComputeUserPluginsDirectory(FileSpec &file_spec) 29342ff0ad8SZachary Turner { 29442ff0ad8SZachary Turner // TODO(zturner): Figure out how to compute the user plugins directory for all platforms. 29542ff0ad8SZachary Turner return false; 29642ff0ad8SZachary Turner } 29742ff0ad8SZachary Turner 29813b18261SZachary Turner void 29913b18261SZachary Turner HostInfoBase::ComputeHostArchitectureSupport(ArchSpec &arch_32, ArchSpec &arch_64) 30013b18261SZachary Turner { 30113b18261SZachary Turner llvm::Triple triple(llvm::sys::getDefaultTargetTriple()); 30213b18261SZachary Turner 30313b18261SZachary Turner arch_32.Clear(); 30413b18261SZachary Turner arch_64.Clear(); 30513b18261SZachary Turner 30613b18261SZachary Turner switch (triple.getArch()) 30713b18261SZachary Turner { 30813b18261SZachary Turner default: 30913b18261SZachary Turner arch_32.SetTriple(triple); 31013b18261SZachary Turner break; 31113b18261SZachary Turner 31213b18261SZachary Turner case llvm::Triple::x86_64: 31313b18261SZachary Turner arch_64.SetTriple(triple); 31413b18261SZachary Turner arch_32.SetTriple(triple.get32BitArchVariant()); 31513b18261SZachary Turner break; 31613b18261SZachary Turner 317e4d6922cSTodd Fiala case llvm::Triple::aarch64: 31813b18261SZachary Turner case llvm::Triple::mips64: 31913b18261SZachary Turner case llvm::Triple::sparcv9: 32013b18261SZachary Turner case llvm::Triple::ppc64: 32113b18261SZachary Turner arch_64.SetTriple(triple); 32213b18261SZachary Turner break; 32313b18261SZachary Turner } 32413b18261SZachary Turner } 325