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   LLDB_RECORD_DUMMY(lldb::thread_t, SBHostOS, ThreadCreate,
112                     (lldb::thread_func_t, void *, SBError *), name,
113                     thread_function, thread_arg, error_ptr);
114   HostThread thread(ThreadLauncher::LaunchThread(
115       name, thread_function, thread_arg, error_ptr ? error_ptr->get() : NULL));
116   return thread.Release();
117 }
118 
119 void SBHostOS::ThreadCreated(const char *name) {
120   LLDB_RECORD_STATIC_METHOD(void, SBHostOS, ThreadCreated, (const char *),
121                             name);
122 }
123 
124 bool SBHostOS::ThreadCancel(lldb::thread_t thread, SBError *error_ptr) {
125   LLDB_RECORD_DUMMY(bool, SBHostOS, ThreadCancel,
126                             (lldb::thread_t, lldb::SBError *), thread,
127                             error_ptr);
128 
129   Status error;
130   HostThread host_thread(thread);
131   error = host_thread.Cancel();
132   if (error_ptr)
133     error_ptr->SetError(error);
134   host_thread.Release();
135   return error.Success();
136 }
137 
138 bool SBHostOS::ThreadDetach(lldb::thread_t thread, SBError *error_ptr) {
139   LLDB_RECORD_DUMMY(bool, SBHostOS, ThreadDetach,
140                             (lldb::thread_t, lldb::SBError *), thread,
141                             error_ptr);
142 
143   Status error;
144 #if defined(_WIN32)
145   if (error_ptr)
146     error_ptr->SetErrorString("ThreadDetach is not supported on this platform");
147 #else
148   HostThread host_thread(thread);
149   error = host_thread.GetNativeThread().Detach();
150   if (error_ptr)
151     error_ptr->SetError(error);
152   host_thread.Release();
153 #endif
154   return error.Success();
155 }
156 
157 bool SBHostOS::ThreadJoin(lldb::thread_t thread, lldb::thread_result_t *result,
158                           SBError *error_ptr) {
159   LLDB_RECORD_DUMMY(
160       bool, SBHostOS, ThreadJoin,
161       (lldb::thread_t, lldb::thread_result_t *, lldb::SBError *), thread,
162       result, error_ptr);
163 
164   Status error;
165   HostThread host_thread(thread);
166   error = host_thread.Join(result);
167   if (error_ptr)
168     error_ptr->SetError(error);
169   host_thread.Release();
170   return error.Success();
171 }
172 
173 namespace lldb_private {
174 namespace repro {
175 
176 template <>
177 void RegisterMethods<SBHostOS>(Registry &R) {
178   LLDB_REGISTER_STATIC_METHOD(lldb::SBFileSpec, SBHostOS, GetProgramFileSpec,
179                               ());
180   LLDB_REGISTER_STATIC_METHOD(lldb::SBFileSpec, SBHostOS, GetLLDBPythonPath,
181                               ());
182   LLDB_REGISTER_STATIC_METHOD(lldb::SBFileSpec, SBHostOS, GetLLDBPath,
183                               (lldb::PathType));
184   LLDB_REGISTER_STATIC_METHOD(lldb::SBFileSpec, SBHostOS,
185                               GetUserHomeDirectory, ());
186   LLDB_REGISTER_STATIC_METHOD(void, SBHostOS, ThreadCreated, (const char *));
187 }
188 
189 }
190 }
191