aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/lldb/source/API/SBPlatform.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/lldb/source/API/SBPlatform.cpp')
-rw-r--r--contrib/llvm-project/lldb/source/API/SBPlatform.cpp736
1 files changed, 736 insertions, 0 deletions
diff --git a/contrib/llvm-project/lldb/source/API/SBPlatform.cpp b/contrib/llvm-project/lldb/source/API/SBPlatform.cpp
new file mode 100644
index 000000000000..3623fd35bcdf
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/API/SBPlatform.cpp
@@ -0,0 +1,736 @@
+//===-- SBPlatform.cpp ----------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/API/SBPlatform.h"
+#include "lldb/API/SBDebugger.h"
+#include "lldb/API/SBEnvironment.h"
+#include "lldb/API/SBError.h"
+#include "lldb/API/SBFileSpec.h"
+#include "lldb/API/SBLaunchInfo.h"
+#include "lldb/API/SBModuleSpec.h"
+#include "lldb/API/SBPlatform.h"
+#include "lldb/API/SBProcessInfoList.h"
+#include "lldb/API/SBTarget.h"
+#include "lldb/API/SBUnixSignals.h"
+#include "lldb/Host/File.h"
+#include "lldb/Target/Platform.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Utility/ArchSpec.h"
+#include "lldb/Utility/Args.h"
+#include "lldb/Utility/Instrumentation.h"
+#include "lldb/Utility/Status.h"
+
+#include "llvm/Support/FileSystem.h"
+
+#include <functional>
+
+using namespace lldb;
+using namespace lldb_private;
+
+// PlatformConnectOptions
+struct PlatformConnectOptions {
+ PlatformConnectOptions(const char *url = nullptr) {
+ if (url && url[0])
+ m_url = url;
+ }
+
+ ~PlatformConnectOptions() = default;
+
+ std::string m_url;
+ std::string m_rsync_options;
+ std::string m_rsync_remote_path_prefix;
+ bool m_rsync_enabled = false;
+ bool m_rsync_omit_hostname_from_remote_path = false;
+ ConstString m_local_cache_directory;
+};
+
+// PlatformShellCommand
+struct PlatformShellCommand {
+ PlatformShellCommand(llvm::StringRef shell_interpreter,
+ llvm::StringRef shell_command) {
+ if (!shell_interpreter.empty())
+ m_shell = shell_interpreter.str();
+
+ if (!m_shell.empty() && !shell_command.empty())
+ m_command = shell_command.str();
+ }
+
+ PlatformShellCommand(llvm::StringRef shell_command = llvm::StringRef()) {
+ if (!shell_command.empty())
+ m_command = shell_command.str();
+ }
+
+ ~PlatformShellCommand() = default;
+
+ std::string m_shell;
+ std::string m_command;
+ std::string m_working_dir;
+ std::string m_output;
+ int m_status = 0;
+ int m_signo = 0;
+ Timeout<std::ratio<1>> m_timeout = std::nullopt;
+};
+// SBPlatformConnectOptions
+SBPlatformConnectOptions::SBPlatformConnectOptions(const char *url)
+ : m_opaque_ptr(new PlatformConnectOptions(url)) {
+ LLDB_INSTRUMENT_VA(this, url);
+}
+
+SBPlatformConnectOptions::SBPlatformConnectOptions(
+ const SBPlatformConnectOptions &rhs)
+ : m_opaque_ptr(new PlatformConnectOptions()) {
+ LLDB_INSTRUMENT_VA(this, rhs);
+
+ *m_opaque_ptr = *rhs.m_opaque_ptr;
+}
+
+SBPlatformConnectOptions::~SBPlatformConnectOptions() { delete m_opaque_ptr; }
+
+SBPlatformConnectOptions &
+SBPlatformConnectOptions::operator=(const SBPlatformConnectOptions &rhs) {
+ LLDB_INSTRUMENT_VA(this, rhs);
+
+ *m_opaque_ptr = *rhs.m_opaque_ptr;
+ return *this;
+}
+
+const char *SBPlatformConnectOptions::GetURL() {
+ LLDB_INSTRUMENT_VA(this);
+
+ if (m_opaque_ptr->m_url.empty())
+ return nullptr;
+ return ConstString(m_opaque_ptr->m_url.c_str()).GetCString();
+}
+
+void SBPlatformConnectOptions::SetURL(const char *url) {
+ LLDB_INSTRUMENT_VA(this, url);
+
+ if (url && url[0])
+ m_opaque_ptr->m_url = url;
+ else
+ m_opaque_ptr->m_url.clear();
+}
+
+bool SBPlatformConnectOptions::GetRsyncEnabled() {
+ LLDB_INSTRUMENT_VA(this);
+
+ return m_opaque_ptr->m_rsync_enabled;
+}
+
+void SBPlatformConnectOptions::EnableRsync(
+ const char *options, const char *remote_path_prefix,
+ bool omit_hostname_from_remote_path) {
+ LLDB_INSTRUMENT_VA(this, options, remote_path_prefix,
+ omit_hostname_from_remote_path);
+
+ m_opaque_ptr->m_rsync_enabled = true;
+ m_opaque_ptr->m_rsync_omit_hostname_from_remote_path =
+ omit_hostname_from_remote_path;
+ if (remote_path_prefix && remote_path_prefix[0])
+ m_opaque_ptr->m_rsync_remote_path_prefix = remote_path_prefix;
+ else
+ m_opaque_ptr->m_rsync_remote_path_prefix.clear();
+
+ if (options && options[0])
+ m_opaque_ptr->m_rsync_options = options;
+ else
+ m_opaque_ptr->m_rsync_options.clear();
+}
+
+void SBPlatformConnectOptions::DisableRsync() {
+ LLDB_INSTRUMENT_VA(this);
+
+ m_opaque_ptr->m_rsync_enabled = false;
+}
+
+const char *SBPlatformConnectOptions::GetLocalCacheDirectory() {
+ LLDB_INSTRUMENT_VA(this);
+
+ return m_opaque_ptr->m_local_cache_directory.GetCString();
+}
+
+void SBPlatformConnectOptions::SetLocalCacheDirectory(const char *path) {
+ LLDB_INSTRUMENT_VA(this, path);
+
+ if (path && path[0])
+ m_opaque_ptr->m_local_cache_directory.SetCString(path);
+ else
+ m_opaque_ptr->m_local_cache_directory = ConstString();
+}
+
+// SBPlatformShellCommand
+SBPlatformShellCommand::SBPlatformShellCommand(const char *shell_interpreter,
+ const char *shell_command)
+ : m_opaque_ptr(new PlatformShellCommand(shell_interpreter, shell_command)) {
+ LLDB_INSTRUMENT_VA(this, shell_interpreter, shell_command);
+}
+
+SBPlatformShellCommand::SBPlatformShellCommand(const char *shell_command)
+ : m_opaque_ptr(new PlatformShellCommand(shell_command)) {
+ LLDB_INSTRUMENT_VA(this, shell_command);
+}
+
+SBPlatformShellCommand::SBPlatformShellCommand(
+ const SBPlatformShellCommand &rhs)
+ : m_opaque_ptr(new PlatformShellCommand()) {
+ LLDB_INSTRUMENT_VA(this, rhs);
+
+ *m_opaque_ptr = *rhs.m_opaque_ptr;
+}
+
+SBPlatformShellCommand &
+SBPlatformShellCommand::operator=(const SBPlatformShellCommand &rhs) {
+
+ LLDB_INSTRUMENT_VA(this, rhs);
+
+ *m_opaque_ptr = *rhs.m_opaque_ptr;
+ return *this;
+}
+
+SBPlatformShellCommand::~SBPlatformShellCommand() { delete m_opaque_ptr; }
+
+void SBPlatformShellCommand::Clear() {
+ LLDB_INSTRUMENT_VA(this);
+
+ m_opaque_ptr->m_output = std::string();
+ m_opaque_ptr->m_status = 0;
+ m_opaque_ptr->m_signo = 0;
+}
+
+const char *SBPlatformShellCommand::GetShell() {
+ LLDB_INSTRUMENT_VA(this);
+
+ if (m_opaque_ptr->m_shell.empty())
+ return nullptr;
+ return ConstString(m_opaque_ptr->m_shell.c_str()).GetCString();
+}
+
+void SBPlatformShellCommand::SetShell(const char *shell_interpreter) {
+ LLDB_INSTRUMENT_VA(this, shell_interpreter);
+
+ if (shell_interpreter && shell_interpreter[0])
+ m_opaque_ptr->m_shell = shell_interpreter;
+ else
+ m_opaque_ptr->m_shell.clear();
+}
+
+const char *SBPlatformShellCommand::GetCommand() {
+ LLDB_INSTRUMENT_VA(this);
+
+ if (m_opaque_ptr->m_command.empty())
+ return nullptr;
+ return ConstString(m_opaque_ptr->m_command.c_str()).GetCString();
+}
+
+void SBPlatformShellCommand::SetCommand(const char *shell_command) {
+ LLDB_INSTRUMENT_VA(this, shell_command);
+
+ if (shell_command && shell_command[0])
+ m_opaque_ptr->m_command = shell_command;
+ else
+ m_opaque_ptr->m_command.clear();
+}
+
+const char *SBPlatformShellCommand::GetWorkingDirectory() {
+ LLDB_INSTRUMENT_VA(this);
+
+ if (m_opaque_ptr->m_working_dir.empty())
+ return nullptr;
+ return ConstString(m_opaque_ptr->m_working_dir.c_str()).GetCString();
+}
+
+void SBPlatformShellCommand::SetWorkingDirectory(const char *path) {
+ LLDB_INSTRUMENT_VA(this, path);
+
+ if (path && path[0])
+ m_opaque_ptr->m_working_dir = path;
+ else
+ m_opaque_ptr->m_working_dir.clear();
+}
+
+uint32_t SBPlatformShellCommand::GetTimeoutSeconds() {
+ LLDB_INSTRUMENT_VA(this);
+
+ if (m_opaque_ptr->m_timeout)
+ return m_opaque_ptr->m_timeout->count();
+ return UINT32_MAX;
+}
+
+void SBPlatformShellCommand::SetTimeoutSeconds(uint32_t sec) {
+ LLDB_INSTRUMENT_VA(this, sec);
+
+ if (sec == UINT32_MAX)
+ m_opaque_ptr->m_timeout = std::nullopt;
+ else
+ m_opaque_ptr->m_timeout = std::chrono::seconds(sec);
+}
+
+int SBPlatformShellCommand::GetSignal() {
+ LLDB_INSTRUMENT_VA(this);
+
+ return m_opaque_ptr->m_signo;
+}
+
+int SBPlatformShellCommand::GetStatus() {
+ LLDB_INSTRUMENT_VA(this);
+
+ return m_opaque_ptr->m_status;
+}
+
+const char *SBPlatformShellCommand::GetOutput() {
+ LLDB_INSTRUMENT_VA(this);
+
+ if (m_opaque_ptr->m_output.empty())
+ return nullptr;
+ return ConstString(m_opaque_ptr->m_output.c_str()).GetCString();
+}
+
+// SBPlatform
+SBPlatform::SBPlatform() { LLDB_INSTRUMENT_VA(this); }
+
+SBPlatform::SBPlatform(const char *platform_name) {
+ LLDB_INSTRUMENT_VA(this, platform_name);
+
+ m_opaque_sp = Platform::Create(platform_name);
+}
+
+SBPlatform::SBPlatform(const SBPlatform &rhs) {
+ LLDB_INSTRUMENT_VA(this, rhs);
+
+ m_opaque_sp = rhs.m_opaque_sp;
+}
+
+SBPlatform &SBPlatform::operator=(const SBPlatform &rhs) {
+ LLDB_INSTRUMENT_VA(this, rhs);
+
+ m_opaque_sp = rhs.m_opaque_sp;
+ return *this;
+}
+
+SBPlatform::~SBPlatform() = default;
+
+SBPlatform SBPlatform::GetHostPlatform() {
+ LLDB_INSTRUMENT();
+
+ SBPlatform host_platform;
+ host_platform.m_opaque_sp = Platform::GetHostPlatform();
+ return host_platform;
+}
+
+bool SBPlatform::IsValid() const {
+ LLDB_INSTRUMENT_VA(this);
+ return this->operator bool();
+}
+SBPlatform::operator bool() const {
+ LLDB_INSTRUMENT_VA(this);
+
+ return m_opaque_sp.get() != nullptr;
+}
+
+void SBPlatform::Clear() {
+ LLDB_INSTRUMENT_VA(this);
+
+ m_opaque_sp.reset();
+}
+
+const char *SBPlatform::GetName() {
+ LLDB_INSTRUMENT_VA(this);
+
+ PlatformSP platform_sp(GetSP());
+ if (platform_sp)
+ return ConstString(platform_sp->GetName()).AsCString();
+ return nullptr;
+}
+
+lldb::PlatformSP SBPlatform::GetSP() const { return m_opaque_sp; }
+
+void SBPlatform::SetSP(const lldb::PlatformSP &platform_sp) {
+ m_opaque_sp = platform_sp;
+}
+
+const char *SBPlatform::GetWorkingDirectory() {
+ LLDB_INSTRUMENT_VA(this);
+
+ PlatformSP platform_sp(GetSP());
+ if (platform_sp)
+ return platform_sp->GetWorkingDirectory().GetPathAsConstString().AsCString();
+ return nullptr;
+}
+
+bool SBPlatform::SetWorkingDirectory(const char *path) {
+ LLDB_INSTRUMENT_VA(this, path);
+
+ PlatformSP platform_sp(GetSP());
+ if (platform_sp) {
+ if (path)
+ platform_sp->SetWorkingDirectory(FileSpec(path));
+ else
+ platform_sp->SetWorkingDirectory(FileSpec());
+ return true;
+ }
+ return false;
+}
+
+SBError SBPlatform::ConnectRemote(SBPlatformConnectOptions &connect_options) {
+ LLDB_INSTRUMENT_VA(this, connect_options);
+
+ SBError sb_error;
+ PlatformSP platform_sp(GetSP());
+ if (platform_sp && connect_options.GetURL()) {
+ Args args;
+ args.AppendArgument(connect_options.GetURL());
+ sb_error.ref() = platform_sp->ConnectRemote(args);
+ } else {
+ sb_error.SetErrorString("invalid platform");
+ }
+ return sb_error;
+}
+
+void SBPlatform::DisconnectRemote() {
+ LLDB_INSTRUMENT_VA(this);
+
+ PlatformSP platform_sp(GetSP());
+ if (platform_sp)
+ platform_sp->DisconnectRemote();
+}
+
+bool SBPlatform::IsConnected() {
+ LLDB_INSTRUMENT_VA(this);
+
+ PlatformSP platform_sp(GetSP());
+ if (platform_sp)
+ return platform_sp->IsConnected();
+ return false;
+}
+
+const char *SBPlatform::GetTriple() {
+ LLDB_INSTRUMENT_VA(this);
+
+ PlatformSP platform_sp(GetSP());
+ if (platform_sp) {
+ ArchSpec arch(platform_sp->GetSystemArchitecture());
+ if (arch.IsValid()) {
+ // Const-ify the string so we don't need to worry about the lifetime of
+ // the string
+ return ConstString(arch.GetTriple().getTriple().c_str()).GetCString();
+ }
+ }
+ return nullptr;
+}
+
+const char *SBPlatform::GetOSBuild() {
+ LLDB_INSTRUMENT_VA(this);
+
+ PlatformSP platform_sp(GetSP());
+ if (platform_sp) {
+ std::string s = platform_sp->GetOSBuildString().value_or("");
+ if (!s.empty()) {
+ // Const-ify the string so we don't need to worry about the lifetime of
+ // the string
+ return ConstString(s).GetCString();
+ }
+ }
+ return nullptr;
+}
+
+const char *SBPlatform::GetOSDescription() {
+ LLDB_INSTRUMENT_VA(this);
+
+ PlatformSP platform_sp(GetSP());
+ if (platform_sp) {
+ std::string s = platform_sp->GetOSKernelDescription().value_or("");
+ if (!s.empty()) {
+ // Const-ify the string so we don't need to worry about the lifetime of
+ // the string
+ return ConstString(s.c_str()).GetCString();
+ }
+ }
+ return nullptr;
+}
+
+const char *SBPlatform::GetHostname() {
+ LLDB_INSTRUMENT_VA(this);
+
+ PlatformSP platform_sp(GetSP());
+ if (platform_sp)
+ return ConstString(platform_sp->GetHostname()).GetCString();
+ return nullptr;
+}
+
+uint32_t SBPlatform::GetOSMajorVersion() {
+ LLDB_INSTRUMENT_VA(this);
+
+ llvm::VersionTuple version;
+ if (PlatformSP platform_sp = GetSP())
+ version = platform_sp->GetOSVersion();
+ return version.empty() ? UINT32_MAX : version.getMajor();
+}
+
+uint32_t SBPlatform::GetOSMinorVersion() {
+ LLDB_INSTRUMENT_VA(this);
+
+ llvm::VersionTuple version;
+ if (PlatformSP platform_sp = GetSP())
+ version = platform_sp->GetOSVersion();
+ return version.getMinor().value_or(UINT32_MAX);
+}
+
+uint32_t SBPlatform::GetOSUpdateVersion() {
+ LLDB_INSTRUMENT_VA(this);
+
+ llvm::VersionTuple version;
+ if (PlatformSP platform_sp = GetSP())
+ version = platform_sp->GetOSVersion();
+ return version.getSubminor().value_or(UINT32_MAX);
+}
+
+void SBPlatform::SetSDKRoot(const char *sysroot) {
+ LLDB_INSTRUMENT_VA(this, sysroot);
+ if (PlatformSP platform_sp = GetSP())
+ platform_sp->SetSDKRootDirectory(llvm::StringRef(sysroot).str());
+}
+
+SBError SBPlatform::Get(SBFileSpec &src, SBFileSpec &dst) {
+ LLDB_INSTRUMENT_VA(this, src, dst);
+
+ SBError sb_error;
+ PlatformSP platform_sp(GetSP());
+ if (platform_sp) {
+ sb_error.ref() = platform_sp->GetFile(src.ref(), dst.ref());
+ } else {
+ sb_error.SetErrorString("invalid platform");
+ }
+ return sb_error;
+}
+
+SBError SBPlatform::Put(SBFileSpec &src, SBFileSpec &dst) {
+ LLDB_INSTRUMENT_VA(this, src, dst);
+ return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
+ if (src.Exists()) {
+ uint32_t permissions = FileSystem::Instance().GetPermissions(src.ref());
+ if (permissions == 0) {
+ if (FileSystem::Instance().IsDirectory(src.ref()))
+ permissions = eFilePermissionsDirectoryDefault;
+ else
+ permissions = eFilePermissionsFileDefault;
+ }
+
+ return platform_sp->PutFile(src.ref(), dst.ref(), permissions);
+ }
+
+ Status error;
+ error.SetErrorStringWithFormat("'src' argument doesn't exist: '%s'",
+ src.ref().GetPath().c_str());
+ return error;
+ });
+}
+
+SBError SBPlatform::Install(SBFileSpec &src, SBFileSpec &dst) {
+ LLDB_INSTRUMENT_VA(this, src, dst);
+ return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
+ if (src.Exists())
+ return platform_sp->Install(src.ref(), dst.ref());
+
+ Status error;
+ error.SetErrorStringWithFormat("'src' argument doesn't exist: '%s'",
+ src.ref().GetPath().c_str());
+ return error;
+ });
+}
+
+SBError SBPlatform::Run(SBPlatformShellCommand &shell_command) {
+ LLDB_INSTRUMENT_VA(this, shell_command);
+ return ExecuteConnected(
+ [&](const lldb::PlatformSP &platform_sp) {
+ const char *command = shell_command.GetCommand();
+ if (!command)
+ return Status("invalid shell command (empty)");
+
+ if (shell_command.GetWorkingDirectory() == nullptr) {
+ std::string platform_working_dir =
+ platform_sp->GetWorkingDirectory().GetPath();
+ if (!platform_working_dir.empty())
+ shell_command.SetWorkingDirectory(platform_working_dir.c_str());
+ }
+ return platform_sp->RunShellCommand(
+ shell_command.m_opaque_ptr->m_shell, command,
+ FileSpec(shell_command.GetWorkingDirectory()),
+ &shell_command.m_opaque_ptr->m_status,
+ &shell_command.m_opaque_ptr->m_signo,
+ &shell_command.m_opaque_ptr->m_output,
+ shell_command.m_opaque_ptr->m_timeout);
+ });
+}
+
+SBError SBPlatform::Launch(SBLaunchInfo &launch_info) {
+ LLDB_INSTRUMENT_VA(this, launch_info);
+ return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
+ ProcessLaunchInfo info = launch_info.ref();
+ Status error = platform_sp->LaunchProcess(info);
+ launch_info.set_ref(info);
+ return error;
+ });
+}
+
+SBProcess SBPlatform::Attach(SBAttachInfo &attach_info,
+ const SBDebugger &debugger, SBTarget &target,
+ SBError &error) {
+ LLDB_INSTRUMENT_VA(this, attach_info, debugger, target, error);
+
+ if (PlatformSP platform_sp = GetSP()) {
+ if (platform_sp->IsConnected()) {
+ ProcessAttachInfo &info = attach_info.ref();
+ Status status;
+ ProcessSP process_sp = platform_sp->Attach(info, debugger.ref(),
+ target.GetSP().get(), status);
+ error.SetError(status);
+ return SBProcess(process_sp);
+ }
+
+ error.SetErrorString("not connected");
+ return {};
+ }
+
+ error.SetErrorString("invalid platform");
+ return {};
+}
+
+SBProcessInfoList SBPlatform::GetAllProcesses(SBError &error) {
+ if (PlatformSP platform_sp = GetSP()) {
+ if (platform_sp->IsConnected()) {
+ ProcessInstanceInfoList list = platform_sp->GetAllProcesses();
+ return SBProcessInfoList(list);
+ }
+ error.SetErrorString("not connected");
+ return {};
+ }
+
+ error.SetErrorString("invalid platform");
+ return {};
+}
+
+SBError SBPlatform::Kill(const lldb::pid_t pid) {
+ LLDB_INSTRUMENT_VA(this, pid);
+ return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) {
+ return platform_sp->KillProcess(pid);
+ });
+}
+
+SBError SBPlatform::ExecuteConnected(
+ const std::function<Status(const lldb::PlatformSP &)> &func) {
+ SBError sb_error;
+ const auto platform_sp(GetSP());
+ if (platform_sp) {
+ if (platform_sp->IsConnected())
+ sb_error.ref() = func(platform_sp);
+ else
+ sb_error.SetErrorString("not connected");
+ } else
+ sb_error.SetErrorString("invalid platform");
+
+ return sb_error;
+}
+
+SBError SBPlatform::MakeDirectory(const char *path, uint32_t file_permissions) {
+ LLDB_INSTRUMENT_VA(this, path, file_permissions);
+
+ SBError sb_error;
+ PlatformSP platform_sp(GetSP());
+ if (platform_sp) {
+ sb_error.ref() =
+ platform_sp->MakeDirectory(FileSpec(path), file_permissions);
+ } else {
+ sb_error.SetErrorString("invalid platform");
+ }
+ return sb_error;
+}
+
+uint32_t SBPlatform::GetFilePermissions(const char *path) {
+ LLDB_INSTRUMENT_VA(this, path);
+
+ PlatformSP platform_sp(GetSP());
+ if (platform_sp) {
+ uint32_t file_permissions = 0;
+ platform_sp->GetFilePermissions(FileSpec(path), file_permissions);
+ return file_permissions;
+ }
+ return 0;
+}
+
+SBError SBPlatform::SetFilePermissions(const char *path,
+ uint32_t file_permissions) {
+ LLDB_INSTRUMENT_VA(this, path, file_permissions);
+
+ SBError sb_error;
+ PlatformSP platform_sp(GetSP());
+ if (platform_sp) {
+ sb_error.ref() =
+ platform_sp->SetFilePermissions(FileSpec(path), file_permissions);
+ } else {
+ sb_error.SetErrorString("invalid platform");
+ }
+ return sb_error;
+}
+
+SBUnixSignals SBPlatform::GetUnixSignals() const {
+ LLDB_INSTRUMENT_VA(this);
+
+ if (auto platform_sp = GetSP())
+ return SBUnixSignals{platform_sp};
+
+ return SBUnixSignals();
+}
+
+SBEnvironment SBPlatform::GetEnvironment() {
+ LLDB_INSTRUMENT_VA(this);
+ PlatformSP platform_sp(GetSP());
+
+ if (platform_sp) {
+ return SBEnvironment(platform_sp->GetEnvironment());
+ }
+
+ return SBEnvironment();
+}
+
+SBError SBPlatform::SetLocateModuleCallback(
+ lldb::SBPlatformLocateModuleCallback callback, void *callback_baton) {
+ LLDB_INSTRUMENT_VA(this, callback, callback_baton);
+ PlatformSP platform_sp(GetSP());
+ if (!platform_sp)
+ return SBError("invalid platform");
+
+ if (!callback) {
+ // Clear the callback.
+ platform_sp->SetLocateModuleCallback(nullptr);
+ return SBError();
+ }
+
+ // Platform.h does not accept lldb::SBPlatformLocateModuleCallback directly
+ // because of the SBModuleSpec and SBFileSpec dependencies. Use a lambda to
+ // convert ModuleSpec/FileSpec <--> SBModuleSpec/SBFileSpec for the callback
+ // arguments.
+ platform_sp->SetLocateModuleCallback(
+ [callback, callback_baton](const ModuleSpec &module_spec,
+ FileSpec &module_file_spec,
+ FileSpec &symbol_file_spec) {
+ SBModuleSpec module_spec_sb(module_spec);
+ SBFileSpec module_file_spec_sb;
+ SBFileSpec symbol_file_spec_sb;
+
+ SBError error = callback(callback_baton, module_spec_sb,
+ module_file_spec_sb, symbol_file_spec_sb);
+
+ if (error.Success()) {
+ module_file_spec = module_file_spec_sb.ref();
+ symbol_file_spec = symbol_file_spec_sb.ref();
+ }
+
+ return error.ref();
+ });
+ return SBError();
+}