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 
15 using namespace lldb_private;
16 
17 bool 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 
27 Status 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 
40 Status 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 
47 Status 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 
55 Status 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 
63 lldb::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 
73 bool 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 
81 uint64_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 
91 uint64_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 
101 lldb::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 
113 Status 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 
122 bool 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 
130 Status 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 
138 bool 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 
147 FileSpec RemoteAwarePlatform::GetRemoteWorkingDirectory() {
148   if (IsRemote() && m_remote_platform_sp)
149     return m_remote_platform_sp->GetRemoteWorkingDirectory();
150   return Platform::GetRemoteWorkingDirectory();
151 }
152 
153 bool 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 
160 Status 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 
172 bool 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 
180 bool 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 
187 bool 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 
194 ArchSpec RemoteAwarePlatform::GetRemoteSystemArchitecture() {
195   if (m_remote_platform_sp)
196     return m_remote_platform_sp->GetRemoteSystemArchitecture();
197   return ArchSpec();
198 }
199 
200 const 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 
208 UserIDResolver &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 
216 Environment 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 
225 bool 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 
233 bool 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 
242 uint32_t
243 RemoteAwarePlatform::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 
252 lldb::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 
264 Status 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 
278 Status 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