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; 57*b1e1c62fSSean Callanan FileSpec m_lldb_clang_resource_dir; 58673b6e4fSZachary Turner FileSpec m_lldb_system_plugin_dir; 59673b6e4fSZachary Turner FileSpec m_lldb_user_plugin_dir; 60673b6e4fSZachary Turner FileSpec m_lldb_tmp_dir; 61673b6e4fSZachary Turner }; 62673b6e4fSZachary Turner 63673b6e4fSZachary Turner HostInfoBaseFields *g_fields = nullptr; 6442ff0ad8SZachary Turner } 6542ff0ad8SZachary Turner 6642ff0ad8SZachary Turner #define COMPUTE_LLDB_PATH(compute_function, member_var) \ 6742ff0ad8SZachary Turner { \ 6842ff0ad8SZachary Turner static bool is_initialized = false; \ 6942ff0ad8SZachary Turner static bool success = false; \ 7042ff0ad8SZachary Turner if (!is_initialized) \ 7142ff0ad8SZachary Turner { \ 7242ff0ad8SZachary Turner is_initialized = true; \ 7342ff0ad8SZachary Turner success = HostInfo::compute_function(member_var); \ 7442ff0ad8SZachary Turner } \ 7542ff0ad8SZachary Turner if (success) \ 7642ff0ad8SZachary Turner result = &member_var; \ 7742ff0ad8SZachary Turner } 7842ff0ad8SZachary Turner 79673b6e4fSZachary Turner void 80673b6e4fSZachary Turner HostInfoBase::Initialize() 81673b6e4fSZachary Turner { 82673b6e4fSZachary Turner g_fields = new HostInfoBaseFields(); 83673b6e4fSZachary Turner } 8442ff0ad8SZachary Turner 8597a14e60SZachary Turner uint32_t 8697a14e60SZachary Turner HostInfoBase::GetNumberCPUS() 8797a14e60SZachary Turner { 8897a14e60SZachary Turner static bool is_initialized = false; 8997a14e60SZachary Turner if (!is_initialized) 9097a14e60SZachary Turner { 91673b6e4fSZachary Turner g_fields->m_number_cpus = std::thread::hardware_concurrency(); 9297a14e60SZachary Turner is_initialized = true; 9397a14e60SZachary Turner } 9497a14e60SZachary Turner 95673b6e4fSZachary Turner return g_fields->m_number_cpus; 9697a14e60SZachary Turner } 9797a14e60SZachary Turner 9839de3110SZachary Turner uint32_t 9939de3110SZachary Turner HostInfoBase::GetMaxThreadNameLength() 10039de3110SZachary Turner { 10139de3110SZachary Turner return 0; 10239de3110SZachary Turner } 10339de3110SZachary Turner 10497a14e60SZachary Turner llvm::StringRef 10597a14e60SZachary Turner HostInfoBase::GetVendorString() 10697a14e60SZachary Turner { 10797a14e60SZachary Turner static bool is_initialized = false; 10897a14e60SZachary Turner if (!is_initialized) 10997a14e60SZachary Turner { 11013b18261SZachary Turner const ArchSpec &host_arch = HostInfo::GetArchitecture(); 11197a14e60SZachary Turner const llvm::StringRef &str_ref = host_arch.GetTriple().getVendorName(); 112673b6e4fSZachary Turner g_fields->m_vendor_string.assign(str_ref.begin(), str_ref.end()); 11397a14e60SZachary Turner is_initialized = true; 11497a14e60SZachary Turner } 115673b6e4fSZachary Turner return g_fields->m_vendor_string; 11697a14e60SZachary Turner } 11797a14e60SZachary Turner 11897a14e60SZachary Turner llvm::StringRef 11997a14e60SZachary Turner HostInfoBase::GetOSString() 12097a14e60SZachary Turner { 12197a14e60SZachary Turner static bool is_initialized = false; 12297a14e60SZachary Turner if (!is_initialized) 12397a14e60SZachary Turner { 12413b18261SZachary Turner const ArchSpec &host_arch = HostInfo::GetArchitecture(); 12597a14e60SZachary Turner const llvm::StringRef &str_ref = host_arch.GetTriple().getOSName(); 126673b6e4fSZachary Turner g_fields->m_os_string.assign(str_ref.begin(), str_ref.end()); 12797a14e60SZachary Turner is_initialized = true; 12897a14e60SZachary Turner } 129673b6e4fSZachary Turner return g_fields->m_os_string; 13097a14e60SZachary Turner } 13197a14e60SZachary Turner 13297a14e60SZachary Turner llvm::StringRef 13397a14e60SZachary Turner HostInfoBase::GetTargetTriple() 13497a14e60SZachary Turner { 13597a14e60SZachary Turner static bool is_initialized = false; 13697a14e60SZachary Turner if (!is_initialized) 13797a14e60SZachary Turner { 13813b18261SZachary Turner const ArchSpec &host_arch = HostInfo::GetArchitecture(); 139673b6e4fSZachary Turner g_fields->m_host_triple = host_arch.GetTriple().getTriple(); 14097a14e60SZachary Turner is_initialized = true; 14197a14e60SZachary Turner } 142673b6e4fSZachary Turner return g_fields->m_host_triple; 14397a14e60SZachary Turner } 14413b18261SZachary Turner 14513b18261SZachary Turner const ArchSpec & 14613b18261SZachary Turner HostInfoBase::GetArchitecture(ArchitectureKind arch_kind) 14713b18261SZachary Turner { 14813b18261SZachary Turner static bool is_initialized = false; 14913b18261SZachary Turner if (!is_initialized) 15013b18261SZachary Turner { 151673b6e4fSZachary Turner HostInfo::ComputeHostArchitectureSupport(g_fields->m_host_arch_32, g_fields->m_host_arch_64); 15213b18261SZachary Turner is_initialized = true; 15313b18261SZachary Turner } 15413b18261SZachary Turner 15513b18261SZachary Turner // If an explicit 32 or 64-bit architecture was requested, return that. 15613b18261SZachary Turner if (arch_kind == eArchKind32) 157673b6e4fSZachary Turner return g_fields->m_host_arch_32; 15813b18261SZachary Turner if (arch_kind == eArchKind64) 159673b6e4fSZachary Turner return g_fields->m_host_arch_64; 16013b18261SZachary Turner 16113b18261SZachary Turner // Otherwise prefer the 64-bit architecture if it is valid. 162673b6e4fSZachary Turner return (g_fields->m_host_arch_64.IsValid()) ? g_fields->m_host_arch_64 : g_fields->m_host_arch_32; 16313b18261SZachary Turner } 16413b18261SZachary Turner 16542ff0ad8SZachary Turner bool 16642ff0ad8SZachary Turner HostInfoBase::GetLLDBPath(lldb::PathType type, FileSpec &file_spec) 16742ff0ad8SZachary Turner { 16842ff0ad8SZachary Turner file_spec.Clear(); 16942ff0ad8SZachary Turner 17042ff0ad8SZachary Turner #if defined(LLDB_DISABLE_PYTHON) 17142ff0ad8SZachary Turner if (type == lldb::ePathTypePythonDir) 17242ff0ad8SZachary Turner return false; 17342ff0ad8SZachary Turner #endif 17442ff0ad8SZachary Turner 17542ff0ad8SZachary Turner Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); 17642ff0ad8SZachary Turner FileSpec *result = nullptr; 17742ff0ad8SZachary Turner switch (type) 17842ff0ad8SZachary Turner { 17942ff0ad8SZachary Turner case lldb::ePathTypeLLDBShlibDir: 180673b6e4fSZachary Turner COMPUTE_LLDB_PATH(ComputeSharedLibraryDirectory, g_fields->m_lldb_so_dir) 18142ff0ad8SZachary Turner if (log) 182673b6e4fSZachary Turner log->Printf("HostInfoBase::GetLLDBPath(ePathTypeLLDBShlibDir) => '%s'", g_fields->m_lldb_so_dir.GetPath().c_str()); 18342ff0ad8SZachary Turner break; 18442ff0ad8SZachary Turner case lldb::ePathTypeSupportExecutableDir: 185673b6e4fSZachary Turner COMPUTE_LLDB_PATH(ComputeSupportExeDirectory, g_fields->m_lldb_support_exe_dir) 18642ff0ad8SZachary Turner if (log) 187673b6e4fSZachary Turner log->Printf("HostInfoBase::GetLLDBPath(ePathTypeSupportExecutableDir) => '%s'", 188673b6e4fSZachary Turner g_fields->m_lldb_support_exe_dir.GetPath().c_str()); 18942ff0ad8SZachary Turner break; 19042ff0ad8SZachary Turner case lldb::ePathTypeHeaderDir: 191673b6e4fSZachary Turner COMPUTE_LLDB_PATH(ComputeHeaderDirectory, g_fields->m_lldb_headers_dir) 19242ff0ad8SZachary Turner if (log) 193673b6e4fSZachary Turner log->Printf("HostInfoBase::GetLLDBPath(ePathTypeHeaderDir) => '%s'", g_fields->m_lldb_headers_dir.GetPath().c_str()); 19442ff0ad8SZachary Turner break; 19542ff0ad8SZachary Turner case lldb::ePathTypePythonDir: 196673b6e4fSZachary Turner COMPUTE_LLDB_PATH(ComputePythonDirectory, g_fields->m_lldb_python_dir) 19742ff0ad8SZachary Turner if (log) 198673b6e4fSZachary Turner log->Printf("HostInfoBase::GetLLDBPath(ePathTypePythonDir) => '%s'", g_fields->m_lldb_python_dir.GetPath().c_str()); 19942ff0ad8SZachary Turner break; 200*b1e1c62fSSean Callanan case lldb::ePathTypeClangDir: 201*b1e1c62fSSean Callanan COMPUTE_LLDB_PATH(ComputeClangDirectory, g_fields->m_lldb_clang_resource_dir) 202*b1e1c62fSSean Callanan if (log) 203*b1e1c62fSSean Callanan log->Printf("HostInfoBase::GetLLDBPath(ePathTypeClangResourceDir) => '%s'", g_fields->m_lldb_clang_resource_dir.GetPath().c_str()); 204*b1e1c62fSSean Callanan break; 20542ff0ad8SZachary Turner case lldb::ePathTypeLLDBSystemPlugins: 206673b6e4fSZachary Turner COMPUTE_LLDB_PATH(ComputeSystemPluginsDirectory, g_fields->m_lldb_system_plugin_dir) 20742ff0ad8SZachary Turner if (log) 208673b6e4fSZachary Turner log->Printf("HostInfoBase::GetLLDBPath(ePathTypeLLDBSystemPlugins) => '%s'", 209673b6e4fSZachary Turner g_fields->m_lldb_system_plugin_dir.GetPath().c_str()); 21042ff0ad8SZachary Turner break; 21142ff0ad8SZachary Turner case lldb::ePathTypeLLDBUserPlugins: 212673b6e4fSZachary Turner COMPUTE_LLDB_PATH(ComputeUserPluginsDirectory, g_fields->m_lldb_user_plugin_dir) 21342ff0ad8SZachary Turner if (log) 214673b6e4fSZachary Turner log->Printf("HostInfoBase::GetLLDBPath(ePathTypeLLDBUserPlugins) => '%s'", 215673b6e4fSZachary Turner g_fields->m_lldb_user_plugin_dir.GetPath().c_str()); 21642ff0ad8SZachary Turner break; 21742ff0ad8SZachary Turner case lldb::ePathTypeLLDBTempSystemDir: 218673b6e4fSZachary Turner COMPUTE_LLDB_PATH(ComputeTempFileDirectory, g_fields->m_lldb_tmp_dir) 21942ff0ad8SZachary Turner if (log) 220673b6e4fSZachary Turner log->Printf("HostInfoBase::GetLLDBPath(ePathTypeLLDBTempSystemDir) => '%s'", g_fields->m_lldb_tmp_dir.GetPath().c_str()); 22142ff0ad8SZachary Turner break; 22242ff0ad8SZachary Turner } 22342ff0ad8SZachary Turner 22442ff0ad8SZachary Turner if (!result) 22542ff0ad8SZachary Turner return false; 22642ff0ad8SZachary Turner file_spec = *result; 22742ff0ad8SZachary Turner return true; 22842ff0ad8SZachary Turner } 22942ff0ad8SZachary Turner 23042ff0ad8SZachary Turner bool 23142ff0ad8SZachary Turner HostInfoBase::ComputeSharedLibraryDirectory(FileSpec &file_spec) 23242ff0ad8SZachary Turner { 23342ff0ad8SZachary Turner // To get paths related to LLDB we get the path to the executable that 23442ff0ad8SZachary Turner // contains this function. On MacOSX this will be "LLDB.framework/.../LLDB", 23542ff0ad8SZachary Turner // on linux this is assumed to be the "lldb" main executable. If LLDB on 23642ff0ad8SZachary Turner // linux is actually in a shared library (liblldb.so) then this function will 23742ff0ad8SZachary Turner // need to be modified to "do the right thing". 23842ff0ad8SZachary Turner 23942ff0ad8SZachary Turner FileSpec lldb_file_spec( 24042ff0ad8SZachary Turner Host::GetModuleFileSpecForHostAddress(reinterpret_cast<void *>(reinterpret_cast<intptr_t>(HostInfoBase::GetLLDBPath)))); 24142ff0ad8SZachary Turner 24242ff0ad8SZachary Turner // Remove the filename so that this FileSpec only represents the directory. 2430d8400c8SGreg Clayton file_spec.GetDirectory() = lldb_file_spec.GetDirectory(); 24442ff0ad8SZachary Turner 24542ff0ad8SZachary Turner return (bool)file_spec.GetDirectory(); 24642ff0ad8SZachary Turner } 24742ff0ad8SZachary Turner 24842ff0ad8SZachary Turner bool 24942ff0ad8SZachary Turner HostInfoBase::ComputeSupportExeDirectory(FileSpec &file_spec) 25042ff0ad8SZachary Turner { 25142ff0ad8SZachary Turner return GetLLDBPath(lldb::ePathTypeLLDBShlibDir, file_spec); 25242ff0ad8SZachary Turner } 25342ff0ad8SZachary Turner 25442ff0ad8SZachary Turner bool 25542ff0ad8SZachary Turner HostInfoBase::ComputeTempFileDirectory(FileSpec &file_spec) 25642ff0ad8SZachary Turner { 25742ff0ad8SZachary Turner const char *tmpdir_cstr = getenv("TMPDIR"); 25842ff0ad8SZachary Turner if (tmpdir_cstr == NULL) 25942ff0ad8SZachary Turner { 26042ff0ad8SZachary Turner tmpdir_cstr = getenv("TMP"); 26142ff0ad8SZachary Turner if (tmpdir_cstr == NULL) 26242ff0ad8SZachary Turner tmpdir_cstr = getenv("TEMP"); 26342ff0ad8SZachary Turner } 26442ff0ad8SZachary Turner if (!tmpdir_cstr) 26542ff0ad8SZachary Turner return false; 26642ff0ad8SZachary Turner 26742ff0ad8SZachary Turner StreamString pid_tmpdir; 26842ff0ad8SZachary Turner pid_tmpdir.Printf("%s/lldb", tmpdir_cstr); 26942ff0ad8SZachary Turner if (!FileSystem::MakeDirectory(pid_tmpdir.GetString().c_str(), eFilePermissionsDirectoryDefault).Success()) 27042ff0ad8SZachary Turner return false; 27142ff0ad8SZachary Turner 27242ff0ad8SZachary Turner pid_tmpdir.Printf("/%" PRIu64, Host::GetCurrentProcessID()); 27342ff0ad8SZachary Turner if (!FileSystem::MakeDirectory(pid_tmpdir.GetString().c_str(), eFilePermissionsDirectoryDefault).Success()) 27442ff0ad8SZachary Turner return false; 27542ff0ad8SZachary Turner 27642ff0ad8SZachary Turner // Make an atexit handler to clean up the process specify LLDB temp dir 27742ff0ad8SZachary Turner // and all of its contents. 27842ff0ad8SZachary Turner ::atexit(CleanupProcessSpecificLLDBTempDir); 2790d8400c8SGreg Clayton file_spec.GetDirectory().SetCStringWithLength(pid_tmpdir.GetString().c_str(), pid_tmpdir.GetString().size()); 28042ff0ad8SZachary Turner return true; 28142ff0ad8SZachary Turner } 28242ff0ad8SZachary Turner 28342ff0ad8SZachary Turner bool 28442ff0ad8SZachary Turner HostInfoBase::ComputeHeaderDirectory(FileSpec &file_spec) 28542ff0ad8SZachary Turner { 28642ff0ad8SZachary Turner // TODO(zturner): Figure out how to compute the header directory for all platforms. 28742ff0ad8SZachary Turner return false; 28842ff0ad8SZachary Turner } 28942ff0ad8SZachary Turner 29042ff0ad8SZachary Turner bool 29142ff0ad8SZachary Turner HostInfoBase::ComputeSystemPluginsDirectory(FileSpec &file_spec) 29242ff0ad8SZachary Turner { 29342ff0ad8SZachary Turner // TODO(zturner): Figure out how to compute the system plugins directory for all platforms. 29442ff0ad8SZachary Turner return false; 29542ff0ad8SZachary Turner } 29642ff0ad8SZachary Turner 29742ff0ad8SZachary Turner bool 298*b1e1c62fSSean Callanan HostInfoBase::ComputeClangDirectory(FileSpec &file_spec) 299*b1e1c62fSSean Callanan { 300*b1e1c62fSSean Callanan return false; 301*b1e1c62fSSean Callanan } 302*b1e1c62fSSean Callanan 303*b1e1c62fSSean Callanan bool 30442ff0ad8SZachary Turner HostInfoBase::ComputeUserPluginsDirectory(FileSpec &file_spec) 30542ff0ad8SZachary Turner { 30642ff0ad8SZachary Turner // TODO(zturner): Figure out how to compute the user plugins directory for all platforms. 30742ff0ad8SZachary Turner return false; 30842ff0ad8SZachary Turner } 30942ff0ad8SZachary Turner 31013b18261SZachary Turner void 31113b18261SZachary Turner HostInfoBase::ComputeHostArchitectureSupport(ArchSpec &arch_32, ArchSpec &arch_64) 31213b18261SZachary Turner { 31313b18261SZachary Turner llvm::Triple triple(llvm::sys::getDefaultTargetTriple()); 31413b18261SZachary Turner 31513b18261SZachary Turner arch_32.Clear(); 31613b18261SZachary Turner arch_64.Clear(); 31713b18261SZachary Turner 31813b18261SZachary Turner switch (triple.getArch()) 31913b18261SZachary Turner { 32013b18261SZachary Turner default: 32113b18261SZachary Turner arch_32.SetTriple(triple); 32213b18261SZachary Turner break; 32313b18261SZachary Turner 32413b18261SZachary Turner case llvm::Triple::x86_64: 32513b18261SZachary Turner arch_64.SetTriple(triple); 32613b18261SZachary Turner arch_32.SetTriple(triple.get32BitArchVariant()); 32713b18261SZachary Turner break; 32813b18261SZachary Turner 329e4d6922cSTodd Fiala case llvm::Triple::aarch64: 33013b18261SZachary Turner case llvm::Triple::mips64: 33113b18261SZachary Turner case llvm::Triple::sparcv9: 33213b18261SZachary Turner case llvm::Triple::ppc64: 33313b18261SZachary Turner arch_64.SetTriple(triple); 33413b18261SZachary Turner break; 33513b18261SZachary Turner } 33613b18261SZachary Turner } 337