1 //===-- SBHostOS.cpp --------------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLDB_DISABLE_PYTHON
10 #include "Plugins/ScriptInterpreter/Python/lldb-python.h"
11 #endif
12 
13 #include "SBReproducerPrivate.h"
14 #include "lldb/API/SBError.h"
15 #include "lldb/API/SBHostOS.h"
16 #include "lldb/Host/FileSystem.h"
17 #include "lldb/Host/Host.h"
18 #include "lldb/Host/HostInfo.h"
19 #include "lldb/Host/HostNativeThread.h"
20 #include "lldb/Host/HostThread.h"
21 #include "lldb/Host/ThreadLauncher.h"
22 #include "lldb/Utility/FileSpec.h"
23 
24 #include "Plugins/ExpressionParser/Clang/ClangHost.h"
25 #ifndef LLDB_DISABLE_PYTHON
26 #include "Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h"
27 #endif
28 
29 #include "llvm/ADT/SmallString.h"
30 #include "llvm/Support/Path.h"
31 
32 using namespace lldb;
33 using namespace lldb_private;
34 
35 SBFileSpec SBHostOS::GetProgramFileSpec() {
36   LLDB_RECORD_STATIC_METHOD_NO_ARGS(lldb::SBFileSpec, SBHostOS,
37                                     GetProgramFileSpec);
38 
39   SBFileSpec sb_filespec;
40   sb_filespec.SetFileSpec(HostInfo::GetProgramFileSpec());
41   return LLDB_RECORD_RESULT(sb_filespec);
42 }
43 
44 SBFileSpec SBHostOS::GetLLDBPythonPath() {
45   LLDB_RECORD_STATIC_METHOD_NO_ARGS(lldb::SBFileSpec, SBHostOS,
46                                     GetLLDBPythonPath);
47 
48   return LLDB_RECORD_RESULT(GetLLDBPath(ePathTypePythonDir));
49 }
50 
51 SBFileSpec SBHostOS::GetLLDBPath(lldb::PathType path_type) {
52   LLDB_RECORD_STATIC_METHOD(lldb::SBFileSpec, SBHostOS, GetLLDBPath,
53                             (lldb::PathType), path_type);
54 
55   FileSpec fspec;
56   switch (path_type) {
57   case ePathTypeLLDBShlibDir:
58     fspec = HostInfo::GetShlibDir();
59     break;
60   case ePathTypeSupportExecutableDir:
61     fspec = HostInfo::GetSupportExeDir();
62     break;
63   case ePathTypeHeaderDir:
64     fspec = HostInfo::GetHeaderDir();
65     break;
66   case ePathTypePythonDir:
67 #ifndef LLDB_DISABLE_PYTHON
68     fspec = ScriptInterpreterPython::GetPythonDir();
69 #endif
70     break;
71   case ePathTypeLLDBSystemPlugins:
72     fspec = HostInfo::GetSystemPluginDir();
73     break;
74   case ePathTypeLLDBUserPlugins:
75     fspec = HostInfo::GetUserPluginDir();
76     break;
77   case ePathTypeLLDBTempSystemDir:
78     fspec = HostInfo::GetProcessTempDir();
79     break;
80   case ePathTypeGlobalLLDBTempSystemDir:
81     fspec = HostInfo::GetGlobalTempDir();
82     break;
83   case ePathTypeClangDir:
84     fspec = GetClangResourceDir();
85     break;
86   }
87 
88   SBFileSpec sb_fspec;
89   sb_fspec.SetFileSpec(fspec);
90   return LLDB_RECORD_RESULT(sb_fspec);
91 }
92 
93 SBFileSpec SBHostOS::GetUserHomeDirectory() {
94   LLDB_RECORD_STATIC_METHOD_NO_ARGS(lldb::SBFileSpec, SBHostOS,
95                                     GetUserHomeDirectory);
96 
97   SBFileSpec sb_fspec;
98 
99   llvm::SmallString<64> home_dir_path;
100   llvm::sys::path::home_directory(home_dir_path);
101   FileSpec homedir(home_dir_path.c_str());
102   FileSystem::Instance().Resolve(homedir);
103 
104   sb_fspec.SetFileSpec(homedir);
105   return LLDB_RECORD_RESULT(sb_fspec);
106 }
107 
108 lldb::thread_t SBHostOS::ThreadCreate(const char *name,
109                                       lldb::thread_func_t thread_function,
110                                       void *thread_arg, SBError *error_ptr) {
111   HostThread thread(ThreadLauncher::LaunchThread(
112       name, thread_function, thread_arg, error_ptr ? error_ptr->get() : NULL));
113   return thread.Release();
114 }
115 
116 void SBHostOS::ThreadCreated(const char *name) {
117   LLDB_RECORD_STATIC_METHOD(void, SBHostOS, ThreadCreated, (const char *),
118                             name);
119 }
120 
121 bool SBHostOS::ThreadCancel(lldb::thread_t thread, SBError *error_ptr) {
122   LLDB_RECORD_STATIC_METHOD(bool, SBHostOS, ThreadCancel,
123                             (lldb::thread_t, lldb::SBError *), thread,
124                             error_ptr);
125 
126   Status error;
127   HostThread host_thread(thread);
128   error = host_thread.Cancel();
129   if (error_ptr)
130     error_ptr->SetError(error);
131   host_thread.Release();
132   return error.Success();
133 }
134 
135 bool SBHostOS::ThreadDetach(lldb::thread_t thread, SBError *error_ptr) {
136   LLDB_RECORD_STATIC_METHOD(bool, SBHostOS, ThreadDetach,
137                             (lldb::thread_t, lldb::SBError *), thread,
138                             error_ptr);
139 
140   Status error;
141 #if defined(_WIN32)
142   if (error_ptr)
143     error_ptr->SetErrorString("ThreadDetach is not supported on this platform");
144 #else
145   HostThread host_thread(thread);
146   error = host_thread.GetNativeThread().Detach();
147   if (error_ptr)
148     error_ptr->SetError(error);
149   host_thread.Release();
150 #endif
151   return error.Success();
152 }
153 
154 bool SBHostOS::ThreadJoin(lldb::thread_t thread, lldb::thread_result_t *result,
155                           SBError *error_ptr) {
156   LLDB_RECORD_STATIC_METHOD(
157       bool, SBHostOS, ThreadJoin,
158       (lldb::thread_t, lldb::thread_result_t *, lldb::SBError *), thread,
159       result, error_ptr);
160 
161   Status error;
162   HostThread host_thread(thread);
163   error = host_thread.Join(result);
164   if (error_ptr)
165     error_ptr->SetError(error);
166   host_thread.Release();
167   return error.Success();
168 }
169