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" 21*270e99abSZachary Turner #include "llvm/ADT/StringExtras.h" 2213b18261SZachary Turner #include "llvm/Support/Host.h" 23*270e99abSZachary Turner #include "llvm/Support/raw_ostream.h" 2497a14e60SZachary Turner 2597a14e60SZachary Turner #include <thread> 2697a14e60SZachary Turner 2797a14e60SZachary Turner using namespace lldb; 2897a14e60SZachary Turner using namespace lldb_private; 2997a14e60SZachary Turner 3042ff0ad8SZachary Turner namespace 3142ff0ad8SZachary Turner { 3242ff0ad8SZachary Turner void 3342ff0ad8SZachary Turner CleanupProcessSpecificLLDBTempDir() 3442ff0ad8SZachary Turner { 3542ff0ad8SZachary Turner // Get the process specific LLDB temporary directory and delete it. 3642ff0ad8SZachary Turner FileSpec tmpdir_file_spec; 3742ff0ad8SZachary Turner if (!HostInfo::GetLLDBPath(ePathTypeLLDBTempSystemDir, tmpdir_file_spec)) 3842ff0ad8SZachary Turner return; 3942ff0ad8SZachary Turner 4042ff0ad8SZachary Turner // Remove the LLDB temporary directory if we have one. Set "recurse" to 4142ff0ad8SZachary Turner // true to all files that were created for the LLDB process can be cleaned up. 4242ff0ad8SZachary Turner FileSystem::DeleteDirectory(tmpdir_file_spec.GetDirectory().GetCString(), true); 4342ff0ad8SZachary Turner } 44673b6e4fSZachary Turner 45673b6e4fSZachary Turner struct HostInfoBaseFields 46673b6e4fSZachary Turner { 47673b6e4fSZachary Turner uint32_t m_number_cpus; 48673b6e4fSZachary Turner std::string m_vendor_string; 49673b6e4fSZachary Turner std::string m_os_string; 50673b6e4fSZachary Turner std::string m_host_triple; 51673b6e4fSZachary Turner 52673b6e4fSZachary Turner ArchSpec m_host_arch_32; 53673b6e4fSZachary Turner ArchSpec m_host_arch_64; 54673b6e4fSZachary Turner 55673b6e4fSZachary Turner FileSpec m_lldb_so_dir; 56673b6e4fSZachary Turner FileSpec m_lldb_support_exe_dir; 57673b6e4fSZachary Turner FileSpec m_lldb_headers_dir; 58673b6e4fSZachary Turner FileSpec m_lldb_python_dir; 59b1e1c62fSSean Callanan FileSpec m_lldb_clang_resource_dir; 60673b6e4fSZachary Turner FileSpec m_lldb_system_plugin_dir; 61673b6e4fSZachary Turner FileSpec m_lldb_user_plugin_dir; 62673b6e4fSZachary Turner FileSpec m_lldb_tmp_dir; 63673b6e4fSZachary Turner }; 64673b6e4fSZachary Turner 65673b6e4fSZachary Turner HostInfoBaseFields *g_fields = nullptr; 6642ff0ad8SZachary Turner } 6742ff0ad8SZachary Turner 6842ff0ad8SZachary Turner #define COMPUTE_LLDB_PATH(compute_function, member_var) \ 6942ff0ad8SZachary Turner { \ 7042ff0ad8SZachary Turner static bool is_initialized = false; \ 7142ff0ad8SZachary Turner static bool success = false; \ 7242ff0ad8SZachary Turner if (!is_initialized) \ 7342ff0ad8SZachary Turner { \ 7442ff0ad8SZachary Turner is_initialized = true; \ 7542ff0ad8SZachary Turner success = HostInfo::compute_function(member_var); \ 7642ff0ad8SZachary Turner } \ 7742ff0ad8SZachary Turner if (success) \ 7842ff0ad8SZachary Turner result = &member_var; \ 7942ff0ad8SZachary Turner } 8042ff0ad8SZachary Turner 81673b6e4fSZachary Turner void 82673b6e4fSZachary Turner HostInfoBase::Initialize() 83673b6e4fSZachary Turner { 84673b6e4fSZachary Turner g_fields = new HostInfoBaseFields(); 85673b6e4fSZachary Turner } 8642ff0ad8SZachary Turner 8797a14e60SZachary Turner uint32_t 8897a14e60SZachary Turner HostInfoBase::GetNumberCPUS() 8997a14e60SZachary Turner { 9097a14e60SZachary Turner static bool is_initialized = false; 9197a14e60SZachary Turner if (!is_initialized) 9297a14e60SZachary Turner { 93673b6e4fSZachary Turner g_fields->m_number_cpus = std::thread::hardware_concurrency(); 9497a14e60SZachary Turner is_initialized = true; 9597a14e60SZachary Turner } 9697a14e60SZachary Turner 97673b6e4fSZachary Turner return g_fields->m_number_cpus; 9897a14e60SZachary Turner } 9997a14e60SZachary Turner 10039de3110SZachary Turner uint32_t 10139de3110SZachary Turner HostInfoBase::GetMaxThreadNameLength() 10239de3110SZachary Turner { 10339de3110SZachary Turner return 0; 10439de3110SZachary Turner } 10539de3110SZachary Turner 10697a14e60SZachary Turner llvm::StringRef 10797a14e60SZachary Turner HostInfoBase::GetVendorString() 10897a14e60SZachary Turner { 10997a14e60SZachary Turner static bool is_initialized = false; 11097a14e60SZachary Turner if (!is_initialized) 11197a14e60SZachary Turner { 11213b18261SZachary Turner const ArchSpec &host_arch = HostInfo::GetArchitecture(); 11397a14e60SZachary Turner const llvm::StringRef &str_ref = host_arch.GetTriple().getVendorName(); 114673b6e4fSZachary Turner g_fields->m_vendor_string.assign(str_ref.begin(), str_ref.end()); 11597a14e60SZachary Turner is_initialized = true; 11697a14e60SZachary Turner } 117673b6e4fSZachary Turner return g_fields->m_vendor_string; 11897a14e60SZachary Turner } 11997a14e60SZachary Turner 12097a14e60SZachary Turner llvm::StringRef 12197a14e60SZachary Turner HostInfoBase::GetOSString() 12297a14e60SZachary Turner { 12397a14e60SZachary Turner static bool is_initialized = false; 12497a14e60SZachary Turner if (!is_initialized) 12597a14e60SZachary Turner { 12613b18261SZachary Turner const ArchSpec &host_arch = HostInfo::GetArchitecture(); 12797a14e60SZachary Turner const llvm::StringRef &str_ref = host_arch.GetTriple().getOSName(); 128673b6e4fSZachary Turner g_fields->m_os_string.assign(str_ref.begin(), str_ref.end()); 12997a14e60SZachary Turner is_initialized = true; 13097a14e60SZachary Turner } 131673b6e4fSZachary Turner return g_fields->m_os_string; 13297a14e60SZachary Turner } 13397a14e60SZachary Turner 13497a14e60SZachary Turner llvm::StringRef 13597a14e60SZachary Turner HostInfoBase::GetTargetTriple() 13697a14e60SZachary Turner { 13797a14e60SZachary Turner static bool is_initialized = false; 13897a14e60SZachary Turner if (!is_initialized) 13997a14e60SZachary Turner { 14013b18261SZachary Turner const ArchSpec &host_arch = HostInfo::GetArchitecture(); 141673b6e4fSZachary Turner g_fields->m_host_triple = host_arch.GetTriple().getTriple(); 14297a14e60SZachary Turner is_initialized = true; 14397a14e60SZachary Turner } 144673b6e4fSZachary Turner return g_fields->m_host_triple; 14597a14e60SZachary Turner } 14613b18261SZachary Turner 14713b18261SZachary Turner const ArchSpec & 14813b18261SZachary Turner HostInfoBase::GetArchitecture(ArchitectureKind arch_kind) 14913b18261SZachary Turner { 15013b18261SZachary Turner static bool is_initialized = false; 15113b18261SZachary Turner if (!is_initialized) 15213b18261SZachary Turner { 153673b6e4fSZachary Turner HostInfo::ComputeHostArchitectureSupport(g_fields->m_host_arch_32, g_fields->m_host_arch_64); 15413b18261SZachary Turner is_initialized = true; 15513b18261SZachary Turner } 15613b18261SZachary Turner 15713b18261SZachary Turner // If an explicit 32 or 64-bit architecture was requested, return that. 15813b18261SZachary Turner if (arch_kind == eArchKind32) 159673b6e4fSZachary Turner return g_fields->m_host_arch_32; 16013b18261SZachary Turner if (arch_kind == eArchKind64) 161673b6e4fSZachary Turner return g_fields->m_host_arch_64; 16213b18261SZachary Turner 16313b18261SZachary Turner // Otherwise prefer the 64-bit architecture if it is valid. 164673b6e4fSZachary Turner return (g_fields->m_host_arch_64.IsValid()) ? g_fields->m_host_arch_64 : g_fields->m_host_arch_32; 16513b18261SZachary Turner } 16613b18261SZachary Turner 16742ff0ad8SZachary Turner bool 16842ff0ad8SZachary Turner HostInfoBase::GetLLDBPath(lldb::PathType type, FileSpec &file_spec) 16942ff0ad8SZachary Turner { 17042ff0ad8SZachary Turner file_spec.Clear(); 17142ff0ad8SZachary Turner 17242ff0ad8SZachary Turner #if defined(LLDB_DISABLE_PYTHON) 17342ff0ad8SZachary Turner if (type == lldb::ePathTypePythonDir) 17442ff0ad8SZachary Turner return false; 17542ff0ad8SZachary Turner #endif 17642ff0ad8SZachary Turner 17742ff0ad8SZachary Turner Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); 17842ff0ad8SZachary Turner FileSpec *result = nullptr; 17942ff0ad8SZachary Turner switch (type) 18042ff0ad8SZachary Turner { 18142ff0ad8SZachary Turner case lldb::ePathTypeLLDBShlibDir: 182673b6e4fSZachary Turner COMPUTE_LLDB_PATH(ComputeSharedLibraryDirectory, g_fields->m_lldb_so_dir) 18342ff0ad8SZachary Turner if (log) 184673b6e4fSZachary Turner log->Printf("HostInfoBase::GetLLDBPath(ePathTypeLLDBShlibDir) => '%s'", g_fields->m_lldb_so_dir.GetPath().c_str()); 18542ff0ad8SZachary Turner break; 18642ff0ad8SZachary Turner case lldb::ePathTypeSupportExecutableDir: 187673b6e4fSZachary Turner COMPUTE_LLDB_PATH(ComputeSupportExeDirectory, g_fields->m_lldb_support_exe_dir) 18842ff0ad8SZachary Turner if (log) 189673b6e4fSZachary Turner log->Printf("HostInfoBase::GetLLDBPath(ePathTypeSupportExecutableDir) => '%s'", 190673b6e4fSZachary Turner g_fields->m_lldb_support_exe_dir.GetPath().c_str()); 19142ff0ad8SZachary Turner break; 19242ff0ad8SZachary Turner case lldb::ePathTypeHeaderDir: 193673b6e4fSZachary Turner COMPUTE_LLDB_PATH(ComputeHeaderDirectory, g_fields->m_lldb_headers_dir) 19442ff0ad8SZachary Turner if (log) 195673b6e4fSZachary Turner log->Printf("HostInfoBase::GetLLDBPath(ePathTypeHeaderDir) => '%s'", g_fields->m_lldb_headers_dir.GetPath().c_str()); 19642ff0ad8SZachary Turner break; 19742ff0ad8SZachary Turner case lldb::ePathTypePythonDir: 198673b6e4fSZachary Turner COMPUTE_LLDB_PATH(ComputePythonDirectory, g_fields->m_lldb_python_dir) 19942ff0ad8SZachary Turner if (log) 200673b6e4fSZachary Turner log->Printf("HostInfoBase::GetLLDBPath(ePathTypePythonDir) => '%s'", g_fields->m_lldb_python_dir.GetPath().c_str()); 20142ff0ad8SZachary Turner break; 202b1e1c62fSSean Callanan case lldb::ePathTypeClangDir: 203b1e1c62fSSean Callanan COMPUTE_LLDB_PATH(ComputeClangDirectory, g_fields->m_lldb_clang_resource_dir) 204b1e1c62fSSean Callanan if (log) 205b1e1c62fSSean Callanan log->Printf("HostInfoBase::GetLLDBPath(ePathTypeClangResourceDir) => '%s'", g_fields->m_lldb_clang_resource_dir.GetPath().c_str()); 206b1e1c62fSSean Callanan break; 20742ff0ad8SZachary Turner case lldb::ePathTypeLLDBSystemPlugins: 208673b6e4fSZachary Turner COMPUTE_LLDB_PATH(ComputeSystemPluginsDirectory, g_fields->m_lldb_system_plugin_dir) 20942ff0ad8SZachary Turner if (log) 210673b6e4fSZachary Turner log->Printf("HostInfoBase::GetLLDBPath(ePathTypeLLDBSystemPlugins) => '%s'", 211673b6e4fSZachary Turner g_fields->m_lldb_system_plugin_dir.GetPath().c_str()); 21242ff0ad8SZachary Turner break; 21342ff0ad8SZachary Turner case lldb::ePathTypeLLDBUserPlugins: 214673b6e4fSZachary Turner COMPUTE_LLDB_PATH(ComputeUserPluginsDirectory, g_fields->m_lldb_user_plugin_dir) 21542ff0ad8SZachary Turner if (log) 216673b6e4fSZachary Turner log->Printf("HostInfoBase::GetLLDBPath(ePathTypeLLDBUserPlugins) => '%s'", 217673b6e4fSZachary Turner g_fields->m_lldb_user_plugin_dir.GetPath().c_str()); 21842ff0ad8SZachary Turner break; 21942ff0ad8SZachary Turner case lldb::ePathTypeLLDBTempSystemDir: 220673b6e4fSZachary Turner COMPUTE_LLDB_PATH(ComputeTempFileDirectory, g_fields->m_lldb_tmp_dir) 22142ff0ad8SZachary Turner if (log) 222673b6e4fSZachary Turner log->Printf("HostInfoBase::GetLLDBPath(ePathTypeLLDBTempSystemDir) => '%s'", g_fields->m_lldb_tmp_dir.GetPath().c_str()); 22342ff0ad8SZachary Turner break; 22442ff0ad8SZachary Turner } 22542ff0ad8SZachary Turner 22642ff0ad8SZachary Turner if (!result) 22742ff0ad8SZachary Turner return false; 22842ff0ad8SZachary Turner file_spec = *result; 22942ff0ad8SZachary Turner return true; 23042ff0ad8SZachary Turner } 23142ff0ad8SZachary Turner 23242ff0ad8SZachary Turner bool 23342ff0ad8SZachary Turner HostInfoBase::ComputeSharedLibraryDirectory(FileSpec &file_spec) 23442ff0ad8SZachary Turner { 23542ff0ad8SZachary Turner // To get paths related to LLDB we get the path to the executable that 23642ff0ad8SZachary Turner // contains this function. On MacOSX this will be "LLDB.framework/.../LLDB", 23742ff0ad8SZachary Turner // on linux this is assumed to be the "lldb" main executable. If LLDB on 23842ff0ad8SZachary Turner // linux is actually in a shared library (liblldb.so) then this function will 23942ff0ad8SZachary Turner // need to be modified to "do the right thing". 24042ff0ad8SZachary Turner 24142ff0ad8SZachary Turner FileSpec lldb_file_spec( 24242ff0ad8SZachary Turner Host::GetModuleFileSpecForHostAddress(reinterpret_cast<void *>(reinterpret_cast<intptr_t>(HostInfoBase::GetLLDBPath)))); 24342ff0ad8SZachary Turner 24442ff0ad8SZachary Turner // Remove the filename so that this FileSpec only represents the directory. 2450d8400c8SGreg Clayton file_spec.GetDirectory() = lldb_file_spec.GetDirectory(); 24642ff0ad8SZachary Turner 24742ff0ad8SZachary Turner return (bool)file_spec.GetDirectory(); 24842ff0ad8SZachary Turner } 24942ff0ad8SZachary Turner 25042ff0ad8SZachary Turner bool 25142ff0ad8SZachary Turner HostInfoBase::ComputeSupportExeDirectory(FileSpec &file_spec) 25242ff0ad8SZachary Turner { 25342ff0ad8SZachary Turner return GetLLDBPath(lldb::ePathTypeLLDBShlibDir, file_spec); 25442ff0ad8SZachary Turner } 25542ff0ad8SZachary Turner 25642ff0ad8SZachary Turner bool 25742ff0ad8SZachary Turner HostInfoBase::ComputeTempFileDirectory(FileSpec &file_spec) 25842ff0ad8SZachary Turner { 25942ff0ad8SZachary Turner const char *tmpdir_cstr = getenv("TMPDIR"); 26042ff0ad8SZachary Turner if (tmpdir_cstr == NULL) 26142ff0ad8SZachary Turner { 26242ff0ad8SZachary Turner tmpdir_cstr = getenv("TMP"); 26342ff0ad8SZachary Turner if (tmpdir_cstr == NULL) 26442ff0ad8SZachary Turner tmpdir_cstr = getenv("TEMP"); 26542ff0ad8SZachary Turner } 26642ff0ad8SZachary Turner if (!tmpdir_cstr) 26742ff0ad8SZachary Turner return false; 26842ff0ad8SZachary Turner 269*270e99abSZachary Turner FileSpec temp_file_spec(tmpdir_cstr, false); 270*270e99abSZachary Turner temp_file_spec.AppendPathComponent("lldb"); 271*270e99abSZachary Turner if (!FileSystem::MakeDirectory(temp_file_spec.GetPath().c_str(), eFilePermissionsDirectoryDefault).Success()) 27242ff0ad8SZachary Turner return false; 27342ff0ad8SZachary Turner 274*270e99abSZachary Turner std::string pid_str; 275*270e99abSZachary Turner llvm::raw_string_ostream pid_stream(pid_str); 276*270e99abSZachary Turner pid_stream << Host::GetCurrentProcessID(); 277*270e99abSZachary Turner temp_file_spec.AppendPathComponent(pid_stream.str().c_str()); 278*270e99abSZachary Turner std::string final_path = temp_file_spec.GetPath(); 279*270e99abSZachary Turner if (!FileSystem::MakeDirectory(final_path.c_str(), eFilePermissionsDirectoryDefault).Success()) 28042ff0ad8SZachary Turner return false; 28142ff0ad8SZachary Turner 28242ff0ad8SZachary Turner // Make an atexit handler to clean up the process specify LLDB temp dir 28342ff0ad8SZachary Turner // and all of its contents. 28442ff0ad8SZachary Turner ::atexit(CleanupProcessSpecificLLDBTempDir); 285*270e99abSZachary Turner file_spec.GetDirectory().SetCStringWithLength(final_path.c_str(), final_path.size()); 28642ff0ad8SZachary Turner return true; 28742ff0ad8SZachary Turner } 28842ff0ad8SZachary Turner 28942ff0ad8SZachary Turner bool 29042ff0ad8SZachary Turner HostInfoBase::ComputeHeaderDirectory(FileSpec &file_spec) 29142ff0ad8SZachary Turner { 29242ff0ad8SZachary Turner // TODO(zturner): Figure out how to compute the header directory for all platforms. 29342ff0ad8SZachary Turner return false; 29442ff0ad8SZachary Turner } 29542ff0ad8SZachary Turner 29642ff0ad8SZachary Turner bool 29742ff0ad8SZachary Turner HostInfoBase::ComputeSystemPluginsDirectory(FileSpec &file_spec) 29842ff0ad8SZachary Turner { 29942ff0ad8SZachary Turner // TODO(zturner): Figure out how to compute the system plugins directory for all platforms. 30042ff0ad8SZachary Turner return false; 30142ff0ad8SZachary Turner } 30242ff0ad8SZachary Turner 30342ff0ad8SZachary Turner bool 304b1e1c62fSSean Callanan HostInfoBase::ComputeClangDirectory(FileSpec &file_spec) 305b1e1c62fSSean Callanan { 306b1e1c62fSSean Callanan return false; 307b1e1c62fSSean Callanan } 308b1e1c62fSSean Callanan 309b1e1c62fSSean Callanan bool 31042ff0ad8SZachary Turner HostInfoBase::ComputeUserPluginsDirectory(FileSpec &file_spec) 31142ff0ad8SZachary Turner { 31242ff0ad8SZachary Turner // TODO(zturner): Figure out how to compute the user plugins directory for all platforms. 31342ff0ad8SZachary Turner return false; 31442ff0ad8SZachary Turner } 31542ff0ad8SZachary Turner 31613b18261SZachary Turner void 31713b18261SZachary Turner HostInfoBase::ComputeHostArchitectureSupport(ArchSpec &arch_32, ArchSpec &arch_64) 31813b18261SZachary Turner { 31913b18261SZachary Turner llvm::Triple triple(llvm::sys::getDefaultTargetTriple()); 32013b18261SZachary Turner 32113b18261SZachary Turner arch_32.Clear(); 32213b18261SZachary Turner arch_64.Clear(); 32313b18261SZachary Turner 32413b18261SZachary Turner switch (triple.getArch()) 32513b18261SZachary Turner { 32613b18261SZachary Turner default: 32713b18261SZachary Turner arch_32.SetTriple(triple); 32813b18261SZachary Turner break; 32913b18261SZachary Turner 33013b18261SZachary Turner case llvm::Triple::x86_64: 33113b18261SZachary Turner arch_64.SetTriple(triple); 33213b18261SZachary Turner arch_32.SetTriple(triple.get32BitArchVariant()); 33313b18261SZachary Turner break; 33413b18261SZachary Turner 335e4d6922cSTodd Fiala case llvm::Triple::aarch64: 33613b18261SZachary Turner case llvm::Triple::mips64: 33713b18261SZachary Turner case llvm::Triple::sparcv9: 33813b18261SZachary Turner case llvm::Triple::ppc64: 33913b18261SZachary Turner arch_64.SetTriple(triple); 34013b18261SZachary Turner break; 34113b18261SZachary Turner } 34213b18261SZachary Turner } 343