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   if (!thread) {
107     if (error_ptr)
108       error_ptr->SetError(Status(thread.takeError()));
109     else
110       llvm::consumeError(thread.takeError());
111     return LLDB_INVALID_HOST_THREAD;
112   }
113 
114   return thread->Release();
115 }
116 
117 void SBHostOS::ThreadCreated(const char *name) { LLDB_INSTRUMENT_VA(name); }
118 
119 bool SBHostOS::ThreadCancel(lldb::thread_t thread, SBError *error_ptr) {
120   LLDB_INSTRUMENT_VA(thread, error_ptr);
121 
122   Status error;
123   HostThread host_thread(thread);
124   error = host_thread.Cancel();
125   if (error_ptr)
126     error_ptr->SetError(error);
127   host_thread.Release();
128   return error.Success();
129 }
130 
131 bool SBHostOS::ThreadDetach(lldb::thread_t thread, SBError *error_ptr) {
132   LLDB_INSTRUMENT_VA(thread, error_ptr);
133 
134   Status error;
135 #if defined(_WIN32)
136   if (error_ptr)
137     error_ptr->SetErrorString("ThreadDetach is not supported on this platform");
138 #else
139   HostThread host_thread(thread);
140   error = host_thread.GetNativeThread().Detach();
141   if (error_ptr)
142     error_ptr->SetError(error);
143   host_thread.Release();
144 #endif
145   return error.Success();
146 }
147 
148 bool SBHostOS::ThreadJoin(lldb::thread_t thread, lldb::thread_result_t *result,
149                           SBError *error_ptr) {
150   LLDB_INSTRUMENT_VA(thread, result, error_ptr);
151 
152   Status error;
153   HostThread host_thread(thread);
154   error = host_thread.Join(result);
155   if (error_ptr)
156     error_ptr->SetError(error);
157   host_thread.Release();
158   return error.Success();
159 }
160