1 //===-- SBHostOS.cpp ------------------------------------------------------===//
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 #include "lldb/API/SBHostOS.h"
10 #include "lldb/API/SBError.h"
11 #include "lldb/Host/Config.h"
12 #include "lldb/Host/FileSystem.h"
13 #include "lldb/Host/Host.h"
14 #include "lldb/Host/HostInfo.h"
15 #include "lldb/Host/HostNativeThread.h"
16 #include "lldb/Host/HostThread.h"
17 #include "lldb/Host/ThreadLauncher.h"
18 #include "lldb/Utility/FileSpec.h"
19 #include "lldb/Utility/Instrumentation.h"
20 
21 #include "Plugins/ExpressionParser/Clang/ClangHost.h"
22 #if LLDB_ENABLE_PYTHON
23 #include "Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h"
24 #endif
25 
26 #include "llvm/ADT/SmallString.h"
27 #include "llvm/Support/Path.h"
28 
29 using namespace lldb;
30 using namespace lldb_private;
31 
32 SBFileSpec SBHostOS::GetProgramFileSpec() {
33   LLDB_INSTRUMENT();
34 
35   SBFileSpec sb_filespec;
36   sb_filespec.SetFileSpec(HostInfo::GetProgramFileSpec());
37   return sb_filespec;
38 }
39 
40 SBFileSpec SBHostOS::GetLLDBPythonPath() {
41   LLDB_INSTRUMENT();
42 
43   return GetLLDBPath(ePathTypePythonDir);
44 }
45 
46 SBFileSpec SBHostOS::GetLLDBPath(lldb::PathType path_type) {
47   LLDB_INSTRUMENT_VA(path_type);
48 
49   FileSpec fspec;
50   switch (path_type) {
51   case ePathTypeLLDBShlibDir:
52     fspec = HostInfo::GetShlibDir();
53     break;
54   case ePathTypeSupportExecutableDir:
55     fspec = HostInfo::GetSupportExeDir();
56     break;
57   case ePathTypeHeaderDir:
58     fspec = HostInfo::GetHeaderDir();
59     break;
60   case ePathTypePythonDir:
61 #if LLDB_ENABLE_PYTHON
62     fspec = ScriptInterpreterPython::GetPythonDir();
63 #endif
64     break;
65   case ePathTypeLLDBSystemPlugins:
66     fspec = HostInfo::GetSystemPluginDir();
67     break;
68   case ePathTypeLLDBUserPlugins:
69     fspec = HostInfo::GetUserPluginDir();
70     break;
71   case ePathTypeLLDBTempSystemDir:
72     fspec = HostInfo::GetProcessTempDir();
73     break;
74   case ePathTypeGlobalLLDBTempSystemDir:
75     fspec = HostInfo::GetGlobalTempDir();
76     break;
77   case ePathTypeClangDir:
78     fspec = GetClangResourceDir();
79     break;
80   }
81 
82   SBFileSpec sb_fspec;
83   sb_fspec.SetFileSpec(fspec);
84   return sb_fspec;
85 }
86 
87 SBFileSpec SBHostOS::GetUserHomeDirectory() {
88   LLDB_INSTRUMENT();
89 
90   FileSpec homedir;
91   FileSystem::Instance().GetHomeDirectory(homedir);
92   FileSystem::Instance().Resolve(homedir);
93 
94   SBFileSpec sb_fspec;
95   sb_fspec.SetFileSpec(homedir);
96 
97   return sb_fspec;
98 }
99 
100 lldb::thread_t SBHostOS::ThreadCreate(const char *name,
101                                       lldb::thread_func_t thread_function,
102                                       void *thread_arg, SBError *error_ptr) {
103   LLDB_INSTRUMENT_VA(name, thread_function, thread_arg, error_ptr);
104   llvm::Expected<HostThread> thread =
105       ThreadLauncher::LaunchThread(name, [thread_function, thread_arg] {
106         return thread_function(thread_arg);
107       });
108   if (!thread) {
109     if (error_ptr)
110       error_ptr->SetError(Status(thread.takeError()));
111     else
112       llvm::consumeError(thread.takeError());
113     return LLDB_INVALID_HOST_THREAD;
114   }
115 
116   return thread->Release();
117 }
118 
119 void SBHostOS::ThreadCreated(const char *name) { LLDB_INSTRUMENT_VA(name); }
120 
121 bool SBHostOS::ThreadCancel(lldb::thread_t thread, SBError *error_ptr) {
122   LLDB_INSTRUMENT_VA(thread, error_ptr);
123 
124   Status error;
125   HostThread host_thread(thread);
126   error = host_thread.Cancel();
127   if (error_ptr)
128     error_ptr->SetError(error);
129   host_thread.Release();
130   return error.Success();
131 }
132 
133 bool SBHostOS::ThreadDetach(lldb::thread_t thread, SBError *error_ptr) {
134   LLDB_INSTRUMENT_VA(thread, error_ptr);
135 
136   Status error;
137 #if defined(_WIN32)
138   if (error_ptr)
139     error_ptr->SetErrorString("ThreadDetach is not supported on this platform");
140 #else
141   HostThread host_thread(thread);
142   error = host_thread.GetNativeThread().Detach();
143   if (error_ptr)
144     error_ptr->SetError(error);
145   host_thread.Release();
146 #endif
147   return error.Success();
148 }
149 
150 bool SBHostOS::ThreadJoin(lldb::thread_t thread, lldb::thread_result_t *result,
151                           SBError *error_ptr) {
152   LLDB_INSTRUMENT_VA(thread, result, error_ptr);
153 
154   Status error;
155   HostThread host_thread(thread);
156   error = host_thread.Join(result);
157   if (error_ptr)
158     error_ptr->SetError(error);
159   host_thread.Release();
160   return error.Success();
161 }
162