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