1//===-- RemoteAwarePlatform.cpp ---------------------------------*- C++ -*-===//
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/Target/RemoteAwarePlatform.h"
10#include "lldb/Host/FileCache.h"
11#include "lldb/Host/FileSystem.h"
12#include "lldb/Host/Host.h"
13#include "lldb/Host/HostInfo.h"
14
15using namespace lldb_private;
16
17bool RemoteAwarePlatform::GetModuleSpec(const FileSpec &module_file_spec,
18                                        const ArchSpec &arch,
19                                        ModuleSpec &module_spec) {
20  if (m_remote_platform_sp)
21    return m_remote_platform_sp->GetModuleSpec(module_file_spec, arch,
22                                               module_spec);
23
24  return Platform::GetModuleSpec(module_file_spec, arch, module_spec);
25}
26
27Status RemoteAwarePlatform::RunShellCommand(
28    const char *command, const FileSpec &working_dir, int *status_ptr,
29    int *signo_ptr, std::string *command_output,
30    const Timeout<std::micro> &timeout) {
31  if (IsHost())
32    return Host::RunShellCommand(command, working_dir, status_ptr, signo_ptr,
33                                 command_output, timeout);
34  if (m_remote_platform_sp)
35    return m_remote_platform_sp->RunShellCommand(
36        command, working_dir, status_ptr, signo_ptr, command_output, timeout);
37  return Status("unable to run a remote command without a platform");
38}
39
40Status RemoteAwarePlatform::MakeDirectory(const FileSpec &file_spec,
41                                          uint32_t file_permissions) {
42  if (m_remote_platform_sp)
43    return m_remote_platform_sp->MakeDirectory(file_spec, file_permissions);
44  return Platform::MakeDirectory(file_spec, file_permissions);
45}
46
47Status RemoteAwarePlatform::GetFilePermissions(const FileSpec &file_spec,
48                                               uint32_t &file_permissions) {
49  if (m_remote_platform_sp)
50    return m_remote_platform_sp->GetFilePermissions(file_spec,
51                                                    file_permissions);
52  return Platform::GetFilePermissions(file_spec, file_permissions);
53}
54
55Status RemoteAwarePlatform::SetFilePermissions(const FileSpec &file_spec,
56                                               uint32_t file_permissions) {
57  if (m_remote_platform_sp)
58    return m_remote_platform_sp->SetFilePermissions(file_spec,
59                                                    file_permissions);
60  return Platform::SetFilePermissions(file_spec, file_permissions);
61}
62
63lldb::user_id_t RemoteAwarePlatform::OpenFile(const FileSpec &file_spec,
64                                              File::OpenOptions flags,
65                                              uint32_t mode, Status &error) {
66  if (IsHost())
67    return FileCache::GetInstance().OpenFile(file_spec, flags, mode, error);
68  if (m_remote_platform_sp)
69    return m_remote_platform_sp->OpenFile(file_spec, flags, mode, error);
70  return Platform::OpenFile(file_spec, flags, mode, error);
71}
72
73bool RemoteAwarePlatform::CloseFile(lldb::user_id_t fd, Status &error) {
74  if (IsHost())
75    return FileCache::GetInstance().CloseFile(fd, error);
76  if (m_remote_platform_sp)
77    return m_remote_platform_sp->CloseFile(fd, error);
78  return Platform::CloseFile(fd, error);
79}
80
81uint64_t RemoteAwarePlatform::ReadFile(lldb::user_id_t fd, uint64_t offset,
82                                       void *dst, uint64_t dst_len,
83                                       Status &error) {
84  if (IsHost())
85    return FileCache::GetInstance().ReadFile(fd, offset, dst, dst_len, error);
86  if (m_remote_platform_sp)
87    return m_remote_platform_sp->ReadFile(fd, offset, dst, dst_len, error);
88  return Platform::ReadFile(fd, offset, dst, dst_len, error);
89}
90
91uint64_t RemoteAwarePlatform::WriteFile(lldb::user_id_t fd, uint64_t offset,
92                                        const void *src, uint64_t src_len,
93                                        Status &error) {
94  if (IsHost())
95    return FileCache::GetInstance().WriteFile(fd, offset, src, src_len, error);
96  if (m_remote_platform_sp)
97    return m_remote_platform_sp->WriteFile(fd, offset, src, src_len, error);
98  return Platform::WriteFile(fd, offset, src, src_len, error);
99}
100
101lldb::user_id_t RemoteAwarePlatform::GetFileSize(const FileSpec &file_spec) {
102  if (IsHost()) {
103    uint64_t Size;
104    if (llvm::sys::fs::file_size(file_spec.GetPath(), Size))
105      return 0;
106    return Size;
107  }
108  if (m_remote_platform_sp)
109    return m_remote_platform_sp->GetFileSize(file_spec);
110  return Platform::GetFileSize(file_spec);
111}
112
113Status RemoteAwarePlatform::CreateSymlink(const FileSpec &src,
114                                          const FileSpec &dst) {
115  if (IsHost())
116    return FileSystem::Instance().Symlink(src, dst);
117  if (m_remote_platform_sp)
118    return m_remote_platform_sp->CreateSymlink(src, dst);
119  return Platform::CreateSymlink(src, dst);
120}
121
122bool RemoteAwarePlatform::GetFileExists(const FileSpec &file_spec) {
123  if (IsHost())
124    return FileSystem::Instance().Exists(file_spec);
125  if (m_remote_platform_sp)
126    return m_remote_platform_sp->GetFileExists(file_spec);
127  return Platform::GetFileExists(file_spec);
128}
129
130Status RemoteAwarePlatform::Unlink(const FileSpec &file_spec) {
131  if (IsHost())
132    return llvm::sys::fs::remove(file_spec.GetPath());
133  if (m_remote_platform_sp)
134    return m_remote_platform_sp->Unlink(file_spec);
135  return Platform::Unlink(file_spec);
136}
137
138bool RemoteAwarePlatform::CalculateMD5(const FileSpec &file_spec, uint64_t &low,
139                                       uint64_t &high) {
140  if (IsHost())
141    return Platform::CalculateMD5(file_spec, low, high);
142  if (m_remote_platform_sp)
143    return m_remote_platform_sp->CalculateMD5(file_spec, low, high);
144  return false;
145}
146
147FileSpec RemoteAwarePlatform::GetRemoteWorkingDirectory() {
148  if (IsRemote() && m_remote_platform_sp)
149    return m_remote_platform_sp->GetRemoteWorkingDirectory();
150  return Platform::GetRemoteWorkingDirectory();
151}
152
153bool RemoteAwarePlatform::SetRemoteWorkingDirectory(
154    const FileSpec &working_dir) {
155  if (IsRemote() && m_remote_platform_sp)
156    return m_remote_platform_sp->SetRemoteWorkingDirectory(working_dir);
157  return Platform::SetRemoteWorkingDirectory(working_dir);
158}
159
160Status RemoteAwarePlatform::GetFileWithUUID(const FileSpec &platform_file,
161                                            const UUID *uuid_ptr,
162                                            FileSpec &local_file) {
163  if (IsRemote() && m_remote_platform_sp)
164    return m_remote_platform_sp->GetFileWithUUID(platform_file, uuid_ptr,
165                                                 local_file);
166
167  // Default to the local case
168  local_file = platform_file;
169  return Status();
170}
171
172bool RemoteAwarePlatform::GetRemoteOSVersion() {
173  if (m_remote_platform_sp) {
174    m_os_version = m_remote_platform_sp->GetOSVersion();
175    return !m_os_version.empty();
176  }
177  return false;
178}
179
180bool RemoteAwarePlatform::GetRemoteOSBuildString(std::string &s) {
181  if (m_remote_platform_sp)
182    return m_remote_platform_sp->GetRemoteOSBuildString(s);
183  s.clear();
184  return false;
185}
186
187bool RemoteAwarePlatform::GetRemoteOSKernelDescription(std::string &s) {
188  if (m_remote_platform_sp)
189    return m_remote_platform_sp->GetRemoteOSKernelDescription(s);
190  s.clear();
191  return false;
192}
193
194ArchSpec RemoteAwarePlatform::GetRemoteSystemArchitecture() {
195  if (m_remote_platform_sp)
196    return m_remote_platform_sp->GetRemoteSystemArchitecture();
197  return ArchSpec();
198}
199
200const char *RemoteAwarePlatform::GetHostname() {
201  if (IsHost())
202    return Platform::GetHostname();
203  if (m_remote_platform_sp)
204    return m_remote_platform_sp->GetHostname();
205  return nullptr;
206}
207
208UserIDResolver &RemoteAwarePlatform::GetUserIDResolver() {
209  if (IsHost())
210    return HostInfo::GetUserIDResolver();
211  if (m_remote_platform_sp)
212    return m_remote_platform_sp->GetUserIDResolver();
213  return UserIDResolver::GetNoopResolver();
214}
215
216Environment RemoteAwarePlatform::GetEnvironment() {
217  if (IsRemote()) {
218    if (m_remote_platform_sp)
219      return m_remote_platform_sp->GetEnvironment();
220    return Environment();
221  }
222  return Host::GetEnvironment();
223}
224
225bool RemoteAwarePlatform::IsConnected() const {
226  if (IsHost())
227    return true;
228  else if (m_remote_platform_sp)
229    return m_remote_platform_sp->IsConnected();
230  return false;
231}
232
233bool RemoteAwarePlatform::GetProcessInfo(lldb::pid_t pid,
234                                         ProcessInstanceInfo &process_info) {
235  if (IsHost())
236    return Platform::GetProcessInfo(pid, process_info);
237  if (m_remote_platform_sp)
238    return m_remote_platform_sp->GetProcessInfo(pid, process_info);
239  return false;
240}
241
242uint32_t
243RemoteAwarePlatform::FindProcesses(const ProcessInstanceInfoMatch &match_info,
244                                   ProcessInstanceInfoList &process_infos) {
245  if (IsHost())
246    return Platform::FindProcesses(match_info, process_infos);
247  if (m_remote_platform_sp)
248    return m_remote_platform_sp->FindProcesses(match_info, process_infos);
249  return 0;
250}
251
252lldb::ProcessSP RemoteAwarePlatform::ConnectProcess(llvm::StringRef connect_url,
253                                                    llvm::StringRef plugin_name,
254                                                    Debugger &debugger,
255                                                    Target *target,
256                                                    Status &error) {
257  if (m_remote_platform_sp)
258    return m_remote_platform_sp->ConnectProcess(connect_url, plugin_name,
259                                                debugger, target, error);
260  return Platform::ConnectProcess(connect_url, plugin_name, debugger, target,
261                                  error);
262}
263
264Status RemoteAwarePlatform::LaunchProcess(ProcessLaunchInfo &launch_info) {
265  Status error;
266
267  if (IsHost()) {
268    error = Platform::LaunchProcess(launch_info);
269  } else {
270    if (m_remote_platform_sp)
271      error = m_remote_platform_sp->LaunchProcess(launch_info);
272    else
273      error.SetErrorString("the platform is not currently connected");
274  }
275  return error;
276}
277
278Status RemoteAwarePlatform::KillProcess(const lldb::pid_t pid) {
279  if (IsHost())
280    return Platform::KillProcess(pid);
281  if (m_remote_platform_sp)
282    return m_remote_platform_sp->KillProcess(pid);
283  return Status("the platform is not currently connected");
284}
285