HostInfoBase.cpp revision 327952
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/Host/FileSystem.h" 13275072Semaste#include "lldb/Host/Host.h" 14275072Semaste#include "lldb/Host/HostInfo.h" 15275072Semaste#include "lldb/Host/HostInfoBase.h" 16327952Sdim#include "lldb/Utility/ArchSpec.h" 17321369Sdim#include "lldb/Utility/Log.h" 18321369Sdim#include "lldb/Utility/StreamString.h" 19275072Semaste 20314564Sdim#include "llvm/ADT/StringExtras.h" 21275072Semaste#include "llvm/ADT/Triple.h" 22275072Semaste#include "llvm/Support/Host.h" 23296417Sdim#include "llvm/Support/Path.h" 24314564Sdim#include "llvm/Support/ScopedPrinter.h" 25321369Sdim#include "llvm/Support/Threading.h" 26280031Sdim#include "llvm/Support/raw_ostream.h" 27275072Semaste 28321369Sdim#include <mutex> 29275072Semaste#include <thread> 30275072Semaste 31275072Semasteusing namespace lldb; 32275072Semasteusing namespace lldb_private; 33275072Semaste 34314564Sdimnamespace { 35314564Sdim//---------------------------------------------------------------------- 36314564Sdim// The HostInfoBaseFields is a work around for windows not supporting 37314564Sdim// static variables correctly in a thread safe way. Really each of the 38314564Sdim// variables in HostInfoBaseFields should live in the functions in which 39314564Sdim// they are used and each one should be static, but the work around is 40314564Sdim// in place to avoid this restriction. Ick. 41314564Sdim//---------------------------------------------------------------------- 42275072Semaste 43314564Sdimstruct HostInfoBaseFields { 44314564Sdim ~HostInfoBaseFields() { 45314564Sdim if (m_lldb_process_tmp_dir.Exists()) { 46314564Sdim // Remove the LLDB temporary directory if we have one. Set "recurse" to 47314564Sdim // true to all files that were created for the LLDB process can be cleaned 48314564Sdim // up. 49321369Sdim llvm::sys::fs::remove_directories(m_lldb_process_tmp_dir.GetPath()); 50314564Sdim } 51314564Sdim } 52309124Sdim 53314564Sdim std::string m_host_triple; 54275072Semaste 55314564Sdim ArchSpec m_host_arch_32; 56314564Sdim ArchSpec m_host_arch_64; 57275072Semaste 58314564Sdim FileSpec m_lldb_so_dir; 59314564Sdim FileSpec m_lldb_support_exe_dir; 60314564Sdim FileSpec m_lldb_headers_dir; 61314564Sdim FileSpec m_lldb_python_dir; 62314564Sdim FileSpec m_lldb_clang_resource_dir; 63314564Sdim FileSpec m_lldb_system_plugin_dir; 64314564Sdim FileSpec m_lldb_user_plugin_dir; 65314564Sdim FileSpec m_lldb_process_tmp_dir; 66314564Sdim FileSpec m_lldb_global_tmp_dir; 67314564Sdim}; 68275072Semaste 69314564SdimHostInfoBaseFields *g_fields = nullptr; 70275072Semaste} 71275072Semaste 72314564Sdimvoid HostInfoBase::Initialize() { g_fields = new HostInfoBaseFields(); } 73309124Sdim 74314564Sdimvoid HostInfoBase::Terminate() { 75314564Sdim delete g_fields; 76314564Sdim g_fields = nullptr; 77275072Semaste} 78275072Semaste 79314564Sdimllvm::StringRef HostInfoBase::GetTargetTriple() { 80321369Sdim static llvm::once_flag g_once_flag; 81321369Sdim llvm::call_once(g_once_flag, []() { 82314564Sdim g_fields->m_host_triple = 83314564Sdim HostInfo::GetArchitecture().GetTriple().getTriple(); 84314564Sdim }); 85314564Sdim return g_fields->m_host_triple; 86275072Semaste} 87275072Semaste 88314564Sdimconst ArchSpec &HostInfoBase::GetArchitecture(ArchitectureKind arch_kind) { 89321369Sdim static llvm::once_flag g_once_flag; 90321369Sdim llvm::call_once(g_once_flag, []() { 91314564Sdim HostInfo::ComputeHostArchitectureSupport(g_fields->m_host_arch_32, 92314564Sdim g_fields->m_host_arch_64); 93314564Sdim }); 94275072Semaste 95314564Sdim // If an explicit 32 or 64-bit architecture was requested, return that. 96314564Sdim if (arch_kind == eArchKind32) 97314564Sdim return g_fields->m_host_arch_32; 98314564Sdim if (arch_kind == eArchKind64) 99314564Sdim return g_fields->m_host_arch_64; 100275072Semaste 101314564Sdim // Otherwise prefer the 64-bit architecture if it is valid. 102314564Sdim return (g_fields->m_host_arch_64.IsValid()) ? g_fields->m_host_arch_64 103314564Sdim : g_fields->m_host_arch_32; 104275072Semaste} 105275072Semaste 106327952Sdimllvm::Optional<HostInfoBase::ArchitectureKind> HostInfoBase::ParseArchitectureKind(llvm::StringRef kind) { 107327952Sdim return llvm::StringSwitch<llvm::Optional<ArchitectureKind>>(kind) 108327952Sdim .Case(LLDB_ARCH_DEFAULT, eArchKindDefault) 109327952Sdim .Case(LLDB_ARCH_DEFAULT_32BIT, eArchKind32) 110327952Sdim .Case(LLDB_ARCH_DEFAULT_64BIT, eArchKind64) 111327952Sdim .Default(llvm::None); 112327952Sdim} 113327952Sdim 114314564Sdimbool HostInfoBase::GetLLDBPath(lldb::PathType type, FileSpec &file_spec) { 115314564Sdim file_spec.Clear(); 116275072Semaste 117275072Semaste#if defined(LLDB_DISABLE_PYTHON) 118314564Sdim if (type == lldb::ePathTypePythonDir) 119314564Sdim return false; 120275072Semaste#endif 121275072Semaste 122314564Sdim FileSpec *result = nullptr; 123314564Sdim switch (type) { 124314564Sdim case lldb::ePathTypeLLDBShlibDir: { 125321369Sdim static llvm::once_flag g_once_flag; 126314564Sdim static bool success = false; 127321369Sdim llvm::call_once(g_once_flag, []() { 128314564Sdim success = 129314564Sdim HostInfo::ComputeSharedLibraryDirectory(g_fields->m_lldb_so_dir); 130314564Sdim Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); 131314564Sdim if (log) 132314564Sdim log->Printf("HostInfoBase::GetLLDBPath(ePathTypeLLDBShlibDir) => '%s'", 133314564Sdim g_fields->m_lldb_so_dir.GetPath().c_str()); 134314564Sdim }); 135314564Sdim if (success) 136314564Sdim result = &g_fields->m_lldb_so_dir; 137314564Sdim } break; 138314564Sdim case lldb::ePathTypeSupportExecutableDir: { 139321369Sdim static llvm::once_flag g_once_flag; 140314564Sdim static bool success = false; 141321369Sdim llvm::call_once(g_once_flag, []() { 142314564Sdim success = HostInfo::ComputeSupportExeDirectory( 143314564Sdim g_fields->m_lldb_support_exe_dir); 144314564Sdim Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); 145314564Sdim if (log) 146314564Sdim log->Printf( 147314564Sdim "HostInfoBase::GetLLDBPath(ePathTypeSupportExecutableDir) => '%s'", 148314564Sdim g_fields->m_lldb_support_exe_dir.GetPath().c_str()); 149314564Sdim }); 150314564Sdim if (success) 151314564Sdim result = &g_fields->m_lldb_support_exe_dir; 152314564Sdim } break; 153314564Sdim case lldb::ePathTypeHeaderDir: { 154321369Sdim static llvm::once_flag g_once_flag; 155314564Sdim static bool success = false; 156321369Sdim llvm::call_once(g_once_flag, []() { 157314564Sdim success = HostInfo::ComputeHeaderDirectory(g_fields->m_lldb_headers_dir); 158314564Sdim Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); 159314564Sdim if (log) 160314564Sdim log->Printf("HostInfoBase::GetLLDBPath(ePathTypeHeaderDir) => '%s'", 161314564Sdim g_fields->m_lldb_headers_dir.GetPath().c_str()); 162314564Sdim }); 163314564Sdim if (success) 164314564Sdim result = &g_fields->m_lldb_headers_dir; 165314564Sdim } break; 166314564Sdim case lldb::ePathTypePythonDir: { 167321369Sdim static llvm::once_flag g_once_flag; 168314564Sdim static bool success = false; 169321369Sdim llvm::call_once(g_once_flag, []() { 170314564Sdim success = HostInfo::ComputePythonDirectory(g_fields->m_lldb_python_dir); 171314564Sdim Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); 172314564Sdim if (log) 173314564Sdim log->Printf("HostInfoBase::GetLLDBPath(ePathTypePythonDir) => '%s'", 174314564Sdim g_fields->m_lldb_python_dir.GetPath().c_str()); 175314564Sdim }); 176314564Sdim if (success) 177314564Sdim result = &g_fields->m_lldb_python_dir; 178314564Sdim } break; 179314564Sdim case lldb::ePathTypeClangDir: { 180321369Sdim static llvm::once_flag g_once_flag; 181314564Sdim static bool success = false; 182321369Sdim llvm::call_once(g_once_flag, []() { 183314564Sdim success = 184314564Sdim HostInfo::ComputeClangDirectory(g_fields->m_lldb_clang_resource_dir); 185314564Sdim Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); 186314564Sdim if (log) 187314564Sdim log->Printf( 188314564Sdim "HostInfoBase::GetLLDBPath(ePathTypeClangResourceDir) => '%s'", 189314564Sdim g_fields->m_lldb_clang_resource_dir.GetPath().c_str()); 190314564Sdim }); 191314564Sdim if (success) 192314564Sdim result = &g_fields->m_lldb_clang_resource_dir; 193314564Sdim } break; 194314564Sdim case lldb::ePathTypeLLDBSystemPlugins: { 195321369Sdim static llvm::once_flag g_once_flag; 196314564Sdim static bool success = false; 197321369Sdim llvm::call_once(g_once_flag, []() { 198314564Sdim success = HostInfo::ComputeSystemPluginsDirectory( 199314564Sdim g_fields->m_lldb_system_plugin_dir); 200314564Sdim Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); 201314564Sdim if (log) 202314564Sdim log->Printf( 203314564Sdim "HostInfoBase::GetLLDBPath(ePathTypeLLDBSystemPlugins) => '%s'", 204314564Sdim g_fields->m_lldb_system_plugin_dir.GetPath().c_str()); 205314564Sdim }); 206314564Sdim if (success) 207314564Sdim result = &g_fields->m_lldb_system_plugin_dir; 208314564Sdim } break; 209314564Sdim case lldb::ePathTypeLLDBUserPlugins: { 210321369Sdim static llvm::once_flag g_once_flag; 211314564Sdim static bool success = false; 212321369Sdim llvm::call_once(g_once_flag, []() { 213314564Sdim success = HostInfo::ComputeUserPluginsDirectory( 214314564Sdim g_fields->m_lldb_user_plugin_dir); 215314564Sdim Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); 216314564Sdim if (log) 217314564Sdim log->Printf( 218314564Sdim "HostInfoBase::GetLLDBPath(ePathTypeLLDBUserPlugins) => '%s'", 219314564Sdim g_fields->m_lldb_user_plugin_dir.GetPath().c_str()); 220314564Sdim }); 221314564Sdim if (success) 222314564Sdim result = &g_fields->m_lldb_user_plugin_dir; 223314564Sdim } break; 224314564Sdim case lldb::ePathTypeLLDBTempSystemDir: { 225321369Sdim static llvm::once_flag g_once_flag; 226314564Sdim static bool success = false; 227321369Sdim llvm::call_once(g_once_flag, []() { 228314564Sdim success = HostInfo::ComputeProcessTempFileDirectory( 229314564Sdim g_fields->m_lldb_process_tmp_dir); 230314564Sdim Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); 231314564Sdim if (log) 232314564Sdim log->Printf( 233314564Sdim "HostInfoBase::GetLLDBPath(ePathTypeLLDBTempSystemDir) => '%s'", 234314564Sdim g_fields->m_lldb_process_tmp_dir.GetPath().c_str()); 235314564Sdim }); 236314564Sdim if (success) 237314564Sdim result = &g_fields->m_lldb_process_tmp_dir; 238314564Sdim } break; 239314564Sdim case lldb::ePathTypeGlobalLLDBTempSystemDir: { 240321369Sdim static llvm::once_flag g_once_flag; 241314564Sdim static bool success = false; 242321369Sdim llvm::call_once(g_once_flag, []() { 243314564Sdim success = HostInfo::ComputeGlobalTempFileDirectory( 244314564Sdim g_fields->m_lldb_global_tmp_dir); 245314564Sdim Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); 246314564Sdim if (log) 247314564Sdim log->Printf("HostInfoBase::GetLLDBPath(" 248314564Sdim "ePathTypeGlobalLLDBTempSystemDir) => '%s'", 249314564Sdim g_fields->m_lldb_global_tmp_dir.GetPath().c_str()); 250314564Sdim }); 251314564Sdim if (success) 252314564Sdim result = &g_fields->m_lldb_global_tmp_dir; 253314564Sdim } break; 254314564Sdim } 255275072Semaste 256314564Sdim if (!result) 257314564Sdim return false; 258314564Sdim file_spec = *result; 259314564Sdim return true; 260275072Semaste} 261275072Semaste 262327952SdimArchSpec HostInfoBase::GetAugmentedArchSpec(llvm::StringRef triple) { 263327952Sdim if (triple.empty()) 264327952Sdim return ArchSpec(); 265327952Sdim llvm::Triple normalized_triple(llvm::Triple::normalize(triple)); 266327952Sdim if (!ArchSpec::ContainsOnlyArch(normalized_triple)) 267327952Sdim return ArchSpec(triple); 268327952Sdim 269327952Sdim if (auto kind = HostInfo::ParseArchitectureKind(triple)) 270327952Sdim return HostInfo::GetArchitecture(*kind); 271327952Sdim 272327952Sdim llvm::Triple host_triple(llvm::sys::getDefaultTargetTriple()); 273327952Sdim 274327952Sdim if (normalized_triple.getVendorName().empty()) 275327952Sdim normalized_triple.setVendor(host_triple.getVendor()); 276327952Sdim if (normalized_triple.getOSName().empty()) 277327952Sdim normalized_triple.setOS(host_triple.getOS()); 278327952Sdim if (normalized_triple.getEnvironmentName().empty()) 279327952Sdim normalized_triple.setEnvironment(host_triple.getEnvironment()); 280327952Sdim return ArchSpec(normalized_triple); 281327952Sdim} 282327952Sdim 283314564Sdimbool HostInfoBase::ComputeSharedLibraryDirectory(FileSpec &file_spec) { 284314564Sdim // To get paths related to LLDB we get the path to the executable that 285314564Sdim // contains this function. On MacOSX this will be "LLDB.framework/.../LLDB", 286314564Sdim // on linux this is assumed to be the "lldb" main executable. If LLDB on 287314564Sdim // linux is actually in a shared library (liblldb.so) then this function will 288314564Sdim // need to be modified to "do the right thing". 289275072Semaste 290314564Sdim FileSpec lldb_file_spec( 291314564Sdim Host::GetModuleFileSpecForHostAddress(reinterpret_cast<void *>( 292314564Sdim reinterpret_cast<intptr_t>(HostInfoBase::GetLLDBPath)))); 293275072Semaste 294314564Sdim // This is necessary because when running the testsuite the shlib might be a 295314564Sdim // symbolic link inside the Python resource dir. 296314564Sdim FileSystem::ResolveSymbolicLink(lldb_file_spec, lldb_file_spec); 297314564Sdim 298314564Sdim // Remove the filename so that this FileSpec only represents the directory. 299314564Sdim file_spec.GetDirectory() = lldb_file_spec.GetDirectory(); 300314564Sdim 301314564Sdim return (bool)file_spec.GetDirectory(); 302275072Semaste} 303275072Semaste 304314564Sdimbool HostInfoBase::ComputeSupportExeDirectory(FileSpec &file_spec) { 305314564Sdim return GetLLDBPath(lldb::ePathTypeLLDBShlibDir, file_spec); 306275072Semaste} 307275072Semaste 308314564Sdimbool HostInfoBase::ComputeProcessTempFileDirectory(FileSpec &file_spec) { 309314564Sdim FileSpec temp_file_spec; 310314564Sdim if (!HostInfo::ComputeGlobalTempFileDirectory(temp_file_spec)) 311314564Sdim return false; 312288943Sdim 313314564Sdim std::string pid_str{llvm::to_string(Host::GetCurrentProcessID())}; 314314564Sdim temp_file_spec.AppendPathComponent(pid_str); 315321369Sdim if (llvm::sys::fs::create_directory(temp_file_spec.GetPath())) 316314564Sdim return false; 317288943Sdim 318314564Sdim file_spec.GetDirectory().SetCString(temp_file_spec.GetCString()); 319314564Sdim return true; 320288943Sdim} 321288943Sdim 322314564Sdimbool HostInfoBase::ComputeTempFileBaseDirectory(FileSpec &file_spec) { 323314564Sdim llvm::SmallVector<char, 16> tmpdir; 324314564Sdim llvm::sys::path::system_temp_directory(/*ErasedOnReboot*/ true, tmpdir); 325314564Sdim file_spec = FileSpec(std::string(tmpdir.data(), tmpdir.size()), true); 326314564Sdim return true; 327288943Sdim} 328288943Sdim 329314564Sdimbool HostInfoBase::ComputeGlobalTempFileDirectory(FileSpec &file_spec) { 330314564Sdim file_spec.Clear(); 331288943Sdim 332314564Sdim FileSpec temp_file_spec; 333314564Sdim if (!HostInfo::ComputeTempFileBaseDirectory(temp_file_spec)) 334314564Sdim return false; 335275072Semaste 336314564Sdim temp_file_spec.AppendPathComponent("lldb"); 337321369Sdim if (llvm::sys::fs::create_directory(temp_file_spec.GetPath())) 338314564Sdim return false; 339275072Semaste 340314564Sdim file_spec.GetDirectory().SetCString(temp_file_spec.GetCString()); 341314564Sdim return true; 342275072Semaste} 343275072Semaste 344314564Sdimbool HostInfoBase::ComputeHeaderDirectory(FileSpec &file_spec) { 345314564Sdim // TODO(zturner): Figure out how to compute the header directory for all 346314564Sdim // platforms. 347314564Sdim return false; 348275072Semaste} 349275072Semaste 350314564Sdimbool HostInfoBase::ComputeSystemPluginsDirectory(FileSpec &file_spec) { 351314564Sdim // TODO(zturner): Figure out how to compute the system plugins directory for 352314564Sdim // all platforms. 353314564Sdim return false; 354275072Semaste} 355275072Semaste 356314564Sdimbool HostInfoBase::ComputeClangDirectory(FileSpec &file_spec) { return false; } 357280031Sdim 358314564Sdimbool HostInfoBase::ComputeUserPluginsDirectory(FileSpec &file_spec) { 359314564Sdim // TODO(zturner): Figure out how to compute the user plugins directory for all 360314564Sdim // platforms. 361314564Sdim return false; 362275072Semaste} 363275072Semaste 364314564Sdimvoid HostInfoBase::ComputeHostArchitectureSupport(ArchSpec &arch_32, 365314564Sdim ArchSpec &arch_64) { 366314564Sdim llvm::Triple triple(llvm::sys::getProcessTriple()); 367275072Semaste 368314564Sdim arch_32.Clear(); 369314564Sdim arch_64.Clear(); 370275072Semaste 371314564Sdim switch (triple.getArch()) { 372314564Sdim default: 373314564Sdim arch_32.SetTriple(triple); 374314564Sdim break; 375275072Semaste 376314564Sdim case llvm::Triple::aarch64: 377314564Sdim case llvm::Triple::ppc64: 378314564Sdim case llvm::Triple::x86_64: 379314564Sdim arch_64.SetTriple(triple); 380314564Sdim arch_32.SetTriple(triple.get32BitArchVariant()); 381314564Sdim break; 382275072Semaste 383314564Sdim case llvm::Triple::mips64: 384314564Sdim case llvm::Triple::mips64el: 385314564Sdim case llvm::Triple::sparcv9: 386314564Sdim case llvm::Triple::systemz: 387314564Sdim arch_64.SetTriple(triple); 388314564Sdim break; 389314564Sdim } 390275072Semaste} 391