HostInfoBase.cpp revision 296417
1275072Semaste//===-- HostInfoBase.cpp ----------------------------------------*- C++ -*-===// 2275072Semaste// 3275072Semaste// The LLVM Compiler Infrastructure 4275072Semaste// 5275072Semaste// This file is distributed under the University of Illinois Open Source 6275072Semaste// License. See LICENSE.TXT for details. 7275072Semaste// 8275072Semaste//===----------------------------------------------------------------------===// 9275072Semaste 10275072Semaste#include "lldb/Host/Config.h" 11275072Semaste 12275072Semaste#include "lldb/Core/ArchSpec.h" 13275072Semaste#include "lldb/Core/Log.h" 14275072Semaste#include "lldb/Core/StreamString.h" 15275072Semaste#include "lldb/Host/FileSystem.h" 16275072Semaste#include "lldb/Host/Host.h" 17275072Semaste#include "lldb/Host/HostInfo.h" 18275072Semaste#include "lldb/Host/HostInfoBase.h" 19275072Semaste 20275072Semaste#include "llvm/ADT/Triple.h" 21280031Sdim#include "llvm/ADT/StringExtras.h" 22275072Semaste#include "llvm/Support/Host.h" 23296417Sdim#include "llvm/Support/Path.h" 24280031Sdim#include "llvm/Support/raw_ostream.h" 25275072Semaste 26275072Semaste#include <thread> 27288943Sdim#include <mutex> // std::once 28275072Semaste 29275072Semasteusing namespace lldb; 30275072Semasteusing namespace lldb_private; 31275072Semaste 32275072Semastenamespace 33275072Semaste{ 34288943Sdim void 35288943Sdim CleanupProcessSpecificLLDBTempDir() 36288943Sdim { 37288943Sdim // Get the process specific LLDB temporary directory and delete it. 38288943Sdim FileSpec tmpdir_file_spec; 39288943Sdim if (!HostInfo::GetLLDBPath(ePathTypeLLDBTempSystemDir, tmpdir_file_spec)) 40288943Sdim return; 41275072Semaste 42288943Sdim // Remove the LLDB temporary directory if we have one. Set "recurse" to 43288943Sdim // true to all files that were created for the LLDB process can be cleaned up. 44288943Sdim FileSystem::DeleteDirectory(tmpdir_file_spec, true); 45288943Sdim } 46275072Semaste 47288943Sdim //---------------------------------------------------------------------- 48288943Sdim // The HostInfoBaseFields is a work around for windows not supporting 49288943Sdim // static variables correctly in a thread safe way. Really each of the 50288943Sdim // variables in HostInfoBaseFields should live in the functions in which 51288943Sdim // they are used and each one should be static, but the work around is 52288943Sdim // in place to avoid this restriction. Ick. 53288943Sdim //---------------------------------------------------------------------- 54275072Semaste 55288943Sdim struct HostInfoBaseFields 56288943Sdim { 57288943Sdim uint32_t m_number_cpus; 58288943Sdim std::string m_vendor_string; 59288943Sdim std::string m_os_string; 60288943Sdim std::string m_host_triple; 61275072Semaste 62288943Sdim ArchSpec m_host_arch_32; 63288943Sdim ArchSpec m_host_arch_64; 64275072Semaste 65288943Sdim FileSpec m_lldb_so_dir; 66288943Sdim FileSpec m_lldb_support_exe_dir; 67288943Sdim FileSpec m_lldb_headers_dir; 68288943Sdim FileSpec m_lldb_python_dir; 69288943Sdim FileSpec m_lldb_clang_resource_dir; 70288943Sdim FileSpec m_lldb_system_plugin_dir; 71288943Sdim FileSpec m_lldb_user_plugin_dir; 72288943Sdim FileSpec m_lldb_process_tmp_dir; 73288943Sdim FileSpec m_lldb_global_tmp_dir; 74288943Sdim }; 75288943Sdim 76288943Sdim HostInfoBaseFields *g_fields = nullptr; 77275072Semaste} 78275072Semaste 79275072Semastevoid 80275072SemasteHostInfoBase::Initialize() 81275072Semaste{ 82275072Semaste g_fields = new HostInfoBaseFields(); 83275072Semaste} 84275072Semaste 85275072Semasteuint32_t 86275072SemasteHostInfoBase::GetNumberCPUS() 87275072Semaste{ 88288943Sdim static std::once_flag g_once_flag; 89288943Sdim std::call_once(g_once_flag, []() { 90275072Semaste g_fields->m_number_cpus = std::thread::hardware_concurrency(); 91288943Sdim }); 92275072Semaste return g_fields->m_number_cpus; 93275072Semaste} 94275072Semaste 95280031Sdimuint32_t 96280031SdimHostInfoBase::GetMaxThreadNameLength() 97280031Sdim{ 98280031Sdim return 0; 99280031Sdim} 100280031Sdim 101275072Semastellvm::StringRef 102275072SemasteHostInfoBase::GetVendorString() 103275072Semaste{ 104288943Sdim static std::once_flag g_once_flag; 105288943Sdim std::call_once(g_once_flag, []() { 106296417Sdim g_fields->m_vendor_string = HostInfo::GetArchitecture().GetTriple().getVendorName().str(); 107288943Sdim }); 108275072Semaste return g_fields->m_vendor_string; 109275072Semaste} 110275072Semaste 111275072Semastellvm::StringRef 112275072SemasteHostInfoBase::GetOSString() 113275072Semaste{ 114288943Sdim static std::once_flag g_once_flag; 115288943Sdim std::call_once(g_once_flag, []() { 116288943Sdim g_fields->m_os_string = std::move(HostInfo::GetArchitecture().GetTriple().getOSName()); 117288943Sdim }); 118275072Semaste return g_fields->m_os_string; 119275072Semaste} 120275072Semaste 121275072Semastellvm::StringRef 122275072SemasteHostInfoBase::GetTargetTriple() 123275072Semaste{ 124288943Sdim static std::once_flag g_once_flag; 125288943Sdim std::call_once(g_once_flag, []() { 126288943Sdim g_fields->m_host_triple = HostInfo::GetArchitecture().GetTriple().getTriple(); 127288943Sdim }); 128275072Semaste return g_fields->m_host_triple; 129275072Semaste} 130275072Semaste 131275072Semasteconst ArchSpec & 132275072SemasteHostInfoBase::GetArchitecture(ArchitectureKind arch_kind) 133275072Semaste{ 134288943Sdim static std::once_flag g_once_flag; 135288943Sdim std::call_once(g_once_flag, []() { 136275072Semaste HostInfo::ComputeHostArchitectureSupport(g_fields->m_host_arch_32, g_fields->m_host_arch_64); 137288943Sdim }); 138275072Semaste 139275072Semaste // If an explicit 32 or 64-bit architecture was requested, return that. 140275072Semaste if (arch_kind == eArchKind32) 141275072Semaste return g_fields->m_host_arch_32; 142275072Semaste if (arch_kind == eArchKind64) 143275072Semaste return g_fields->m_host_arch_64; 144275072Semaste 145275072Semaste // Otherwise prefer the 64-bit architecture if it is valid. 146275072Semaste return (g_fields->m_host_arch_64.IsValid()) ? g_fields->m_host_arch_64 : g_fields->m_host_arch_32; 147275072Semaste} 148275072Semaste 149275072Semastebool 150275072SemasteHostInfoBase::GetLLDBPath(lldb::PathType type, FileSpec &file_spec) 151275072Semaste{ 152275072Semaste file_spec.Clear(); 153275072Semaste 154275072Semaste#if defined(LLDB_DISABLE_PYTHON) 155275072Semaste if (type == lldb::ePathTypePythonDir) 156275072Semaste return false; 157275072Semaste#endif 158275072Semaste 159275072Semaste FileSpec *result = nullptr; 160275072Semaste switch (type) 161275072Semaste { 162275072Semaste case lldb::ePathTypeLLDBShlibDir: 163288943Sdim { 164288943Sdim static std::once_flag g_once_flag; 165288943Sdim static bool success = false; 166288943Sdim std::call_once(g_once_flag, []() { 167288943Sdim success = HostInfo::ComputeSharedLibraryDirectory (g_fields->m_lldb_so_dir); 168288943Sdim Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); 169288943Sdim if (log) 170288943Sdim log->Printf("HostInfoBase::GetLLDBPath(ePathTypeLLDBShlibDir) => '%s'", g_fields->m_lldb_so_dir.GetPath().c_str()); 171288943Sdim }); 172288943Sdim if (success) 173288943Sdim result = &g_fields->m_lldb_so_dir; 174288943Sdim } 175275072Semaste break; 176275072Semaste case lldb::ePathTypeSupportExecutableDir: 177288943Sdim { 178288943Sdim static std::once_flag g_once_flag; 179288943Sdim static bool success = false; 180288943Sdim std::call_once(g_once_flag, []() { 181288943Sdim success = HostInfo::ComputeSupportExeDirectory (g_fields->m_lldb_support_exe_dir); 182288943Sdim Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); 183288943Sdim if (log) 184288943Sdim log->Printf("HostInfoBase::GetLLDBPath(ePathTypeSupportExecutableDir) => '%s'", 185288943Sdim g_fields->m_lldb_support_exe_dir.GetPath().c_str()); 186288943Sdim }); 187288943Sdim if (success) 188288943Sdim result = &g_fields->m_lldb_support_exe_dir; 189288943Sdim } 190275072Semaste break; 191275072Semaste case lldb::ePathTypeHeaderDir: 192288943Sdim { 193288943Sdim static std::once_flag g_once_flag; 194288943Sdim static bool success = false; 195288943Sdim std::call_once(g_once_flag, []() { 196288943Sdim success = HostInfo::ComputeHeaderDirectory (g_fields->m_lldb_headers_dir); 197288943Sdim Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); 198288943Sdim if (log) 199288943Sdim log->Printf("HostInfoBase::GetLLDBPath(ePathTypeHeaderDir) => '%s'", g_fields->m_lldb_headers_dir.GetPath().c_str()); 200288943Sdim }); 201288943Sdim if (success) 202288943Sdim result = &g_fields->m_lldb_headers_dir; 203288943Sdim } 204275072Semaste break; 205275072Semaste case lldb::ePathTypePythonDir: 206288943Sdim { 207288943Sdim static std::once_flag g_once_flag; 208288943Sdim static bool success = false; 209288943Sdim std::call_once(g_once_flag, []() { 210288943Sdim success = HostInfo::ComputePythonDirectory (g_fields->m_lldb_python_dir); 211288943Sdim Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); 212288943Sdim if (log) 213288943Sdim log->Printf("HostInfoBase::GetLLDBPath(ePathTypePythonDir) => '%s'", g_fields->m_lldb_python_dir.GetPath().c_str()); 214288943Sdim }); 215288943Sdim if (success) 216288943Sdim result = &g_fields->m_lldb_python_dir; 217288943Sdim } 218275072Semaste break; 219280031Sdim case lldb::ePathTypeClangDir: 220288943Sdim { 221288943Sdim static std::once_flag g_once_flag; 222288943Sdim static bool success = false; 223288943Sdim std::call_once(g_once_flag, []() { 224288943Sdim success = HostInfo::ComputeClangDirectory (g_fields->m_lldb_clang_resource_dir); 225288943Sdim Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); 226288943Sdim if (log) 227288943Sdim log->Printf("HostInfoBase::GetLLDBPath(ePathTypeClangResourceDir) => '%s'", g_fields->m_lldb_clang_resource_dir.GetPath().c_str()); 228288943Sdim }); 229288943Sdim if (success) 230288943Sdim result = &g_fields->m_lldb_clang_resource_dir; 231288943Sdim } 232280031Sdim break; 233275072Semaste case lldb::ePathTypeLLDBSystemPlugins: 234288943Sdim { 235288943Sdim static std::once_flag g_once_flag; 236288943Sdim static bool success = false; 237288943Sdim std::call_once(g_once_flag, []() { 238288943Sdim success = HostInfo::ComputeSystemPluginsDirectory (g_fields->m_lldb_system_plugin_dir); 239288943Sdim Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); 240288943Sdim if (log) 241288943Sdim log->Printf("HostInfoBase::GetLLDBPath(ePathTypeLLDBSystemPlugins) => '%s'", 242288943Sdim g_fields->m_lldb_system_plugin_dir.GetPath().c_str()); 243288943Sdim }); 244288943Sdim if (success) 245288943Sdim result = &g_fields->m_lldb_system_plugin_dir; 246288943Sdim } 247275072Semaste break; 248275072Semaste case lldb::ePathTypeLLDBUserPlugins: 249288943Sdim { 250288943Sdim static std::once_flag g_once_flag; 251288943Sdim static bool success = false; 252288943Sdim std::call_once(g_once_flag, []() { 253288943Sdim success = HostInfo::ComputeUserPluginsDirectory (g_fields->m_lldb_user_plugin_dir); 254288943Sdim Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); 255288943Sdim if (log) 256288943Sdim log->Printf("HostInfoBase::GetLLDBPath(ePathTypeLLDBUserPlugins) => '%s'", 257288943Sdim g_fields->m_lldb_user_plugin_dir.GetPath().c_str()); 258288943Sdim }); 259288943Sdim if (success) 260288943Sdim result = &g_fields->m_lldb_user_plugin_dir; 261288943Sdim } 262275072Semaste break; 263275072Semaste case lldb::ePathTypeLLDBTempSystemDir: 264288943Sdim { 265288943Sdim static std::once_flag g_once_flag; 266288943Sdim static bool success = false; 267288943Sdim std::call_once(g_once_flag, []() { 268288943Sdim success = HostInfo::ComputeProcessTempFileDirectory (g_fields->m_lldb_process_tmp_dir); 269288943Sdim Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); 270288943Sdim if (log) 271288943Sdim log->Printf("HostInfoBase::GetLLDBPath(ePathTypeLLDBTempSystemDir) => '%s'", g_fields->m_lldb_process_tmp_dir.GetPath().c_str()); 272288943Sdim }); 273288943Sdim if (success) 274288943Sdim result = &g_fields->m_lldb_process_tmp_dir; 275288943Sdim } 276275072Semaste break; 277288943Sdim case lldb::ePathTypeGlobalLLDBTempSystemDir: 278288943Sdim { 279288943Sdim static std::once_flag g_once_flag; 280288943Sdim static bool success = false; 281288943Sdim std::call_once(g_once_flag, []() { 282288943Sdim success = HostInfo::ComputeGlobalTempFileDirectory (g_fields->m_lldb_global_tmp_dir); 283288943Sdim Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); 284288943Sdim if (log) 285288943Sdim log->Printf("HostInfoBase::GetLLDBPath(ePathTypeGlobalLLDBTempSystemDir) => '%s'", g_fields->m_lldb_global_tmp_dir.GetPath().c_str()); 286288943Sdim }); 287288943Sdim if (success) 288288943Sdim result = &g_fields->m_lldb_global_tmp_dir; 289288943Sdim } 290288943Sdim break; 291275072Semaste } 292275072Semaste 293275072Semaste if (!result) 294275072Semaste return false; 295275072Semaste file_spec = *result; 296275072Semaste return true; 297275072Semaste} 298275072Semaste 299275072Semastebool 300275072SemasteHostInfoBase::ComputeSharedLibraryDirectory(FileSpec &file_spec) 301275072Semaste{ 302275072Semaste // To get paths related to LLDB we get the path to the executable that 303275072Semaste // contains this function. On MacOSX this will be "LLDB.framework/.../LLDB", 304275072Semaste // on linux this is assumed to be the "lldb" main executable. If LLDB on 305275072Semaste // linux is actually in a shared library (liblldb.so) then this function will 306275072Semaste // need to be modified to "do the right thing". 307275072Semaste 308275072Semaste FileSpec lldb_file_spec( 309275072Semaste Host::GetModuleFileSpecForHostAddress(reinterpret_cast<void *>(reinterpret_cast<intptr_t>(HostInfoBase::GetLLDBPath)))); 310296417Sdim 311296417Sdim // This is necessary because when running the testsuite the shlib might be a symbolic link inside the Python resource dir. 312296417Sdim FileSystem::ResolveSymbolicLink(lldb_file_spec, lldb_file_spec); 313296417Sdim 314275072Semaste // Remove the filename so that this FileSpec only represents the directory. 315275072Semaste file_spec.GetDirectory() = lldb_file_spec.GetDirectory(); 316275072Semaste 317275072Semaste return (bool)file_spec.GetDirectory(); 318275072Semaste} 319275072Semaste 320275072Semastebool 321275072SemasteHostInfoBase::ComputeSupportExeDirectory(FileSpec &file_spec) 322275072Semaste{ 323275072Semaste return GetLLDBPath(lldb::ePathTypeLLDBShlibDir, file_spec); 324275072Semaste} 325275072Semaste 326275072Semastebool 327288943SdimHostInfoBase::ComputeProcessTempFileDirectory(FileSpec &file_spec) 328275072Semaste{ 329288943Sdim FileSpec temp_file_spec; 330288943Sdim if (!HostInfo::ComputeGlobalTempFileDirectory(temp_file_spec)) 331288943Sdim return false; 332288943Sdim 333288943Sdim std::string pid_str{std::to_string(Host::GetCurrentProcessID())}; 334288943Sdim temp_file_spec.AppendPathComponent(pid_str); 335288943Sdim if (!FileSystem::MakeDirectory(temp_file_spec, eFilePermissionsDirectoryDefault).Success()) 336288943Sdim return false; 337288943Sdim 338288943Sdim // Make an atexit handler to clean up the process specify LLDB temp dir 339288943Sdim // and all of its contents. 340288943Sdim ::atexit(CleanupProcessSpecificLLDBTempDir); 341288943Sdim file_spec.GetDirectory().SetCString(temp_file_spec.GetCString()); 342288943Sdim return true; 343288943Sdim} 344288943Sdim 345288943Sdimbool 346288943SdimHostInfoBase::ComputeTempFileBaseDirectory(FileSpec &file_spec) 347288943Sdim{ 348296417Sdim llvm::SmallVector<char, 16> tmpdir; 349296417Sdim llvm::sys::path::system_temp_directory(/*ErasedOnReboot*/ true, tmpdir); 350296417Sdim file_spec = FileSpec(std::string(tmpdir.data(), tmpdir.size()), true); 351288943Sdim return true; 352288943Sdim} 353288943Sdim 354288943Sdimbool 355288943SdimHostInfoBase::ComputeGlobalTempFileDirectory(FileSpec &file_spec) 356288943Sdim{ 357288943Sdim file_spec.Clear(); 358288943Sdim 359288943Sdim FileSpec temp_file_spec; 360288943Sdim if (!HostInfo::ComputeTempFileBaseDirectory(temp_file_spec)) 361275072Semaste return false; 362275072Semaste 363288943Sdim temp_file_spec.AppendPathComponent("lldb"); 364288943Sdim if (!FileSystem::MakeDirectory(temp_file_spec, eFilePermissionsDirectoryDefault).Success()) 365275072Semaste return false; 366275072Semaste 367288943Sdim file_spec.GetDirectory().SetCString(temp_file_spec.GetCString()); 368275072Semaste return true; 369275072Semaste} 370275072Semaste 371275072Semastebool 372275072SemasteHostInfoBase::ComputeHeaderDirectory(FileSpec &file_spec) 373275072Semaste{ 374275072Semaste // TODO(zturner): Figure out how to compute the header directory for all platforms. 375275072Semaste return false; 376275072Semaste} 377275072Semaste 378275072Semastebool 379275072SemasteHostInfoBase::ComputeSystemPluginsDirectory(FileSpec &file_spec) 380275072Semaste{ 381275072Semaste // TODO(zturner): Figure out how to compute the system plugins directory for all platforms. 382275072Semaste return false; 383275072Semaste} 384275072Semaste 385275072Semastebool 386280031SdimHostInfoBase::ComputeClangDirectory(FileSpec &file_spec) 387280031Sdim{ 388280031Sdim return false; 389280031Sdim} 390280031Sdim 391280031Sdimbool 392275072SemasteHostInfoBase::ComputeUserPluginsDirectory(FileSpec &file_spec) 393275072Semaste{ 394275072Semaste // TODO(zturner): Figure out how to compute the user plugins directory for all platforms. 395275072Semaste return false; 396275072Semaste} 397275072Semaste 398275072Semastevoid 399275072SemasteHostInfoBase::ComputeHostArchitectureSupport(ArchSpec &arch_32, ArchSpec &arch_64) 400275072Semaste{ 401288943Sdim llvm::Triple triple(llvm::sys::getProcessTriple()); 402275072Semaste 403275072Semaste arch_32.Clear(); 404275072Semaste arch_64.Clear(); 405275072Semaste 406275072Semaste switch (triple.getArch()) 407275072Semaste { 408275072Semaste default: 409275072Semaste arch_32.SetTriple(triple); 410275072Semaste break; 411275072Semaste 412296417Sdim case llvm::Triple::aarch64: 413288943Sdim case llvm::Triple::ppc64: 414275072Semaste case llvm::Triple::x86_64: 415275072Semaste arch_64.SetTriple(triple); 416275072Semaste arch_32.SetTriple(triple.get32BitArchVariant()); 417275072Semaste break; 418275072Semaste 419275072Semaste case llvm::Triple::mips64: 420288943Sdim case llvm::Triple::mips64el: 421275072Semaste case llvm::Triple::sparcv9: 422275072Semaste arch_64.SetTriple(triple); 423275072Semaste break; 424275072Semaste } 425275072Semaste} 426