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