15ffd83dbSDimitry Andric //===-- SBHostOS.cpp ------------------------------------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
9480093f4SDimitry Andric #include "lldb/API/SBHostOS.h"
100b57cec5SDimitry Andric #include "SBReproducerPrivate.h"
110b57cec5SDimitry Andric #include "lldb/API/SBError.h"
12480093f4SDimitry Andric #include "lldb/Host/Config.h"
130b57cec5SDimitry Andric #include "lldb/Host/FileSystem.h"
140b57cec5SDimitry Andric #include "lldb/Host/Host.h"
150b57cec5SDimitry Andric #include "lldb/Host/HostInfo.h"
160b57cec5SDimitry Andric #include "lldb/Host/HostNativeThread.h"
170b57cec5SDimitry Andric #include "lldb/Host/HostThread.h"
180b57cec5SDimitry Andric #include "lldb/Host/ThreadLauncher.h"
190b57cec5SDimitry Andric #include "lldb/Utility/FileSpec.h"
200b57cec5SDimitry Andric 
210b57cec5SDimitry Andric #include "Plugins/ExpressionParser/Clang/ClangHost.h"
22480093f4SDimitry Andric #if LLDB_ENABLE_PYTHON
230b57cec5SDimitry Andric #include "Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h"
240b57cec5SDimitry Andric #endif
250b57cec5SDimitry Andric 
260b57cec5SDimitry Andric #include "llvm/ADT/SmallString.h"
270b57cec5SDimitry Andric #include "llvm/Support/Path.h"
280b57cec5SDimitry Andric 
290b57cec5SDimitry Andric using namespace lldb;
300b57cec5SDimitry Andric using namespace lldb_private;
310b57cec5SDimitry Andric 
320b57cec5SDimitry Andric SBFileSpec SBHostOS::GetProgramFileSpec() {
330b57cec5SDimitry Andric   LLDB_RECORD_STATIC_METHOD_NO_ARGS(lldb::SBFileSpec, SBHostOS,
340b57cec5SDimitry Andric                                     GetProgramFileSpec);
350b57cec5SDimitry Andric 
360b57cec5SDimitry Andric   SBFileSpec sb_filespec;
370b57cec5SDimitry Andric   sb_filespec.SetFileSpec(HostInfo::GetProgramFileSpec());
380b57cec5SDimitry Andric   return LLDB_RECORD_RESULT(sb_filespec);
390b57cec5SDimitry Andric }
400b57cec5SDimitry Andric 
410b57cec5SDimitry Andric SBFileSpec SBHostOS::GetLLDBPythonPath() {
420b57cec5SDimitry Andric   LLDB_RECORD_STATIC_METHOD_NO_ARGS(lldb::SBFileSpec, SBHostOS,
430b57cec5SDimitry Andric                                     GetLLDBPythonPath);
440b57cec5SDimitry Andric 
450b57cec5SDimitry Andric   return LLDB_RECORD_RESULT(GetLLDBPath(ePathTypePythonDir));
460b57cec5SDimitry Andric }
470b57cec5SDimitry Andric 
480b57cec5SDimitry Andric SBFileSpec SBHostOS::GetLLDBPath(lldb::PathType path_type) {
490b57cec5SDimitry Andric   LLDB_RECORD_STATIC_METHOD(lldb::SBFileSpec, SBHostOS, GetLLDBPath,
500b57cec5SDimitry Andric                             (lldb::PathType), path_type);
510b57cec5SDimitry Andric 
520b57cec5SDimitry Andric   FileSpec fspec;
530b57cec5SDimitry Andric   switch (path_type) {
540b57cec5SDimitry Andric   case ePathTypeLLDBShlibDir:
550b57cec5SDimitry Andric     fspec = HostInfo::GetShlibDir();
560b57cec5SDimitry Andric     break;
570b57cec5SDimitry Andric   case ePathTypeSupportExecutableDir:
580b57cec5SDimitry Andric     fspec = HostInfo::GetSupportExeDir();
590b57cec5SDimitry Andric     break;
600b57cec5SDimitry Andric   case ePathTypeHeaderDir:
610b57cec5SDimitry Andric     fspec = HostInfo::GetHeaderDir();
620b57cec5SDimitry Andric     break;
630b57cec5SDimitry Andric   case ePathTypePythonDir:
64480093f4SDimitry Andric #if LLDB_ENABLE_PYTHON
650b57cec5SDimitry Andric     fspec = ScriptInterpreterPython::GetPythonDir();
660b57cec5SDimitry Andric #endif
670b57cec5SDimitry Andric     break;
680b57cec5SDimitry Andric   case ePathTypeLLDBSystemPlugins:
690b57cec5SDimitry Andric     fspec = HostInfo::GetSystemPluginDir();
700b57cec5SDimitry Andric     break;
710b57cec5SDimitry Andric   case ePathTypeLLDBUserPlugins:
720b57cec5SDimitry Andric     fspec = HostInfo::GetUserPluginDir();
730b57cec5SDimitry Andric     break;
740b57cec5SDimitry Andric   case ePathTypeLLDBTempSystemDir:
750b57cec5SDimitry Andric     fspec = HostInfo::GetProcessTempDir();
760b57cec5SDimitry Andric     break;
770b57cec5SDimitry Andric   case ePathTypeGlobalLLDBTempSystemDir:
780b57cec5SDimitry Andric     fspec = HostInfo::GetGlobalTempDir();
790b57cec5SDimitry Andric     break;
800b57cec5SDimitry Andric   case ePathTypeClangDir:
810b57cec5SDimitry Andric     fspec = GetClangResourceDir();
820b57cec5SDimitry Andric     break;
830b57cec5SDimitry Andric   }
840b57cec5SDimitry Andric 
850b57cec5SDimitry Andric   SBFileSpec sb_fspec;
860b57cec5SDimitry Andric   sb_fspec.SetFileSpec(fspec);
870b57cec5SDimitry Andric   return LLDB_RECORD_RESULT(sb_fspec);
880b57cec5SDimitry Andric }
890b57cec5SDimitry Andric 
900b57cec5SDimitry Andric SBFileSpec SBHostOS::GetUserHomeDirectory() {
910b57cec5SDimitry Andric   LLDB_RECORD_STATIC_METHOD_NO_ARGS(lldb::SBFileSpec, SBHostOS,
920b57cec5SDimitry Andric                                     GetUserHomeDirectory);
930b57cec5SDimitry Andric 
94e8d8bef9SDimitry Andric   FileSpec homedir;
95e8d8bef9SDimitry Andric   FileSystem::Instance().GetHomeDirectory(homedir);
960b57cec5SDimitry Andric   FileSystem::Instance().Resolve(homedir);
970b57cec5SDimitry Andric 
98e8d8bef9SDimitry Andric   SBFileSpec sb_fspec;
990b57cec5SDimitry Andric   sb_fspec.SetFileSpec(homedir);
100e8d8bef9SDimitry Andric 
1010b57cec5SDimitry Andric   return LLDB_RECORD_RESULT(sb_fspec);
1020b57cec5SDimitry Andric }
1030b57cec5SDimitry Andric 
1040b57cec5SDimitry Andric lldb::thread_t SBHostOS::ThreadCreate(const char *name,
1050b57cec5SDimitry Andric                                       lldb::thread_func_t thread_function,
1060b57cec5SDimitry Andric                                       void *thread_arg, SBError *error_ptr) {
1070b57cec5SDimitry Andric   LLDB_RECORD_DUMMY(lldb::thread_t, SBHostOS, ThreadCreate,
1080b57cec5SDimitry Andric                     (lldb::thread_func_t, void *, SBError *), name,
1090b57cec5SDimitry Andric                     thread_function, thread_arg, error_ptr);
1100b57cec5SDimitry Andric   llvm::Expected<HostThread> thread =
1110b57cec5SDimitry Andric       ThreadLauncher::LaunchThread(name, thread_function, thread_arg);
1120b57cec5SDimitry Andric   if (!thread) {
1130b57cec5SDimitry Andric     if (error_ptr)
1140b57cec5SDimitry Andric       error_ptr->SetError(Status(thread.takeError()));
1150b57cec5SDimitry Andric     else
1160b57cec5SDimitry Andric       llvm::consumeError(thread.takeError());
1170b57cec5SDimitry Andric     return LLDB_INVALID_HOST_THREAD;
1180b57cec5SDimitry Andric   }
1190b57cec5SDimitry Andric 
1200b57cec5SDimitry Andric   return thread->Release();
1210b57cec5SDimitry Andric }
1220b57cec5SDimitry Andric 
1230b57cec5SDimitry Andric void SBHostOS::ThreadCreated(const char *name) {
1240b57cec5SDimitry Andric   LLDB_RECORD_STATIC_METHOD(void, SBHostOS, ThreadCreated, (const char *),
1250b57cec5SDimitry Andric                             name);
1260b57cec5SDimitry Andric }
1270b57cec5SDimitry Andric 
1280b57cec5SDimitry Andric bool SBHostOS::ThreadCancel(lldb::thread_t thread, SBError *error_ptr) {
1290b57cec5SDimitry Andric   LLDB_RECORD_DUMMY(bool, SBHostOS, ThreadCancel,
1300b57cec5SDimitry Andric                             (lldb::thread_t, lldb::SBError *), thread,
1310b57cec5SDimitry Andric                             error_ptr);
1320b57cec5SDimitry Andric 
1330b57cec5SDimitry Andric   Status error;
1340b57cec5SDimitry Andric   HostThread host_thread(thread);
1350b57cec5SDimitry Andric   error = host_thread.Cancel();
1360b57cec5SDimitry Andric   if (error_ptr)
1370b57cec5SDimitry Andric     error_ptr->SetError(error);
1380b57cec5SDimitry Andric   host_thread.Release();
1390b57cec5SDimitry Andric   return error.Success();
1400b57cec5SDimitry Andric }
1410b57cec5SDimitry Andric 
1420b57cec5SDimitry Andric bool SBHostOS::ThreadDetach(lldb::thread_t thread, SBError *error_ptr) {
1430b57cec5SDimitry Andric   LLDB_RECORD_DUMMY(bool, SBHostOS, ThreadDetach,
1440b57cec5SDimitry Andric                             (lldb::thread_t, lldb::SBError *), thread,
1450b57cec5SDimitry Andric                             error_ptr);
1460b57cec5SDimitry Andric 
1470b57cec5SDimitry Andric   Status error;
1480b57cec5SDimitry Andric #if defined(_WIN32)
1490b57cec5SDimitry Andric   if (error_ptr)
1500b57cec5SDimitry Andric     error_ptr->SetErrorString("ThreadDetach is not supported on this platform");
1510b57cec5SDimitry Andric #else
1520b57cec5SDimitry Andric   HostThread host_thread(thread);
1530b57cec5SDimitry Andric   error = host_thread.GetNativeThread().Detach();
1540b57cec5SDimitry Andric   if (error_ptr)
1550b57cec5SDimitry Andric     error_ptr->SetError(error);
1560b57cec5SDimitry Andric   host_thread.Release();
1570b57cec5SDimitry Andric #endif
1580b57cec5SDimitry Andric   return error.Success();
1590b57cec5SDimitry Andric }
1600b57cec5SDimitry Andric 
1610b57cec5SDimitry Andric bool SBHostOS::ThreadJoin(lldb::thread_t thread, lldb::thread_result_t *result,
1620b57cec5SDimitry Andric                           SBError *error_ptr) {
1630b57cec5SDimitry Andric   LLDB_RECORD_DUMMY(
1640b57cec5SDimitry Andric       bool, SBHostOS, ThreadJoin,
1650b57cec5SDimitry Andric       (lldb::thread_t, lldb::thread_result_t *, lldb::SBError *), thread,
1660b57cec5SDimitry Andric       result, error_ptr);
1670b57cec5SDimitry Andric 
1680b57cec5SDimitry Andric   Status error;
1690b57cec5SDimitry Andric   HostThread host_thread(thread);
1700b57cec5SDimitry Andric   error = host_thread.Join(result);
1710b57cec5SDimitry Andric   if (error_ptr)
1720b57cec5SDimitry Andric     error_ptr->SetError(error);
1730b57cec5SDimitry Andric   host_thread.Release();
1740b57cec5SDimitry Andric   return error.Success();
1750b57cec5SDimitry Andric }
1760b57cec5SDimitry Andric 
1770b57cec5SDimitry Andric namespace lldb_private {
1780b57cec5SDimitry Andric namespace repro {
1790b57cec5SDimitry Andric 
1800b57cec5SDimitry Andric template <>
1810b57cec5SDimitry Andric void RegisterMethods<SBHostOS>(Registry &R) {
1820b57cec5SDimitry Andric   LLDB_REGISTER_STATIC_METHOD(lldb::SBFileSpec, SBHostOS, GetProgramFileSpec,
1830b57cec5SDimitry Andric                               ());
1840b57cec5SDimitry Andric   LLDB_REGISTER_STATIC_METHOD(lldb::SBFileSpec, SBHostOS, GetLLDBPythonPath,
1850b57cec5SDimitry Andric                               ());
1860b57cec5SDimitry Andric   LLDB_REGISTER_STATIC_METHOD(lldb::SBFileSpec, SBHostOS, GetLLDBPath,
1870b57cec5SDimitry Andric                               (lldb::PathType));
1880b57cec5SDimitry Andric   LLDB_REGISTER_STATIC_METHOD(lldb::SBFileSpec, SBHostOS,
1890b57cec5SDimitry Andric                               GetUserHomeDirectory, ());
1900b57cec5SDimitry Andric   LLDB_REGISTER_STATIC_METHOD(void, SBHostOS, ThreadCreated, (const char *));
1910b57cec5SDimitry Andric }
1920b57cec5SDimitry Andric 
1930b57cec5SDimitry Andric }
1940b57cec5SDimitry Andric }
195