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