1*0b57cec5SDimitry Andric //===-- RemoteAwarePlatform.cpp -------------------------------------------===//
2*0b57cec5SDimitry Andric //
3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0b57cec5SDimitry Andric //
7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8*0b57cec5SDimitry Andric 
9*0b57cec5SDimitry Andric #include "lldb/Target/RemoteAwarePlatform.h"
10*0b57cec5SDimitry Andric #include "lldb/Core/Module.h"
11*0b57cec5SDimitry Andric #include "lldb/Core/ModuleList.h"
12*0b57cec5SDimitry Andric #include "lldb/Core/ModuleSpec.h"
13*0b57cec5SDimitry Andric #include "lldb/Host/FileSystem.h"
14*0b57cec5SDimitry Andric #include "lldb/Host/Host.h"
15*0b57cec5SDimitry Andric #include "lldb/Host/HostInfo.h"
16*0b57cec5SDimitry Andric #include "lldb/Utility/StreamString.h"
17*0b57cec5SDimitry Andric #include <optional>
18*0b57cec5SDimitry Andric 
19*0b57cec5SDimitry Andric using namespace lldb_private;
20*0b57cec5SDimitry Andric using namespace lldb;
21*0b57cec5SDimitry Andric 
GetModuleSpec(const FileSpec & module_file_spec,const ArchSpec & arch,ModuleSpec & module_spec)22*0b57cec5SDimitry Andric bool RemoteAwarePlatform::GetModuleSpec(const FileSpec &module_file_spec,
23*0b57cec5SDimitry Andric                                         const ArchSpec &arch,
24*0b57cec5SDimitry Andric                                         ModuleSpec &module_spec) {
25*0b57cec5SDimitry Andric   if (m_remote_platform_sp)
26*0b57cec5SDimitry Andric     return m_remote_platform_sp->GetModuleSpec(module_file_spec, arch,
27*0b57cec5SDimitry Andric                                                module_spec);
28*0b57cec5SDimitry Andric 
29*0b57cec5SDimitry Andric   return false;
30*0b57cec5SDimitry Andric }
31*0b57cec5SDimitry Andric 
ResolveExecutable(const ModuleSpec & module_spec,ModuleSP & exe_module_sp,const FileSpecList * module_search_paths_ptr)32*0b57cec5SDimitry Andric Status RemoteAwarePlatform::ResolveExecutable(
33*0b57cec5SDimitry Andric     const ModuleSpec &module_spec, ModuleSP &exe_module_sp,
34*0b57cec5SDimitry Andric     const FileSpecList *module_search_paths_ptr) {
35*0b57cec5SDimitry Andric   Status error;
36*0b57cec5SDimitry Andric   // Nothing special to do here, just use the actual file and architecture
37*0b57cec5SDimitry Andric 
38*0b57cec5SDimitry Andric   char exe_path[PATH_MAX];
39*0b57cec5SDimitry Andric   ModuleSpec resolved_module_spec(module_spec);
40*0b57cec5SDimitry Andric 
41*0b57cec5SDimitry Andric   if (IsHost()) {
42*0b57cec5SDimitry Andric     // If we have "ls" as the exe_file, resolve the executable location based
43*0b57cec5SDimitry Andric     // on the current path variables
44*0b57cec5SDimitry Andric     if (!FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec())) {
45*0b57cec5SDimitry Andric       resolved_module_spec.GetFileSpec().GetPath(exe_path, sizeof(exe_path));
46*0b57cec5SDimitry Andric       resolved_module_spec.GetFileSpec().SetFile(exe_path,
47*0b57cec5SDimitry Andric                                                  FileSpec::Style::native);
48*0b57cec5SDimitry Andric       FileSystem::Instance().Resolve(resolved_module_spec.GetFileSpec());
49*0b57cec5SDimitry Andric     }
50*0b57cec5SDimitry Andric 
51*0b57cec5SDimitry Andric     if (!FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec()))
52*0b57cec5SDimitry Andric       FileSystem::Instance().ResolveExecutableLocation(
53*0b57cec5SDimitry Andric           resolved_module_spec.GetFileSpec());
54*0b57cec5SDimitry Andric 
55*0b57cec5SDimitry Andric     // Resolve any executable within a bundle on MacOSX
56*0b57cec5SDimitry Andric     Host::ResolveExecutableInBundle(resolved_module_spec.GetFileSpec());
57*0b57cec5SDimitry Andric 
58*0b57cec5SDimitry Andric     if (FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec()))
59*0b57cec5SDimitry Andric       error.Clear();
60*0b57cec5SDimitry Andric     else {
61*0b57cec5SDimitry Andric       const uint32_t permissions = FileSystem::Instance().GetPermissions(
62*0b57cec5SDimitry Andric           resolved_module_spec.GetFileSpec());
63*0b57cec5SDimitry Andric       if (permissions && (permissions & eFilePermissionsEveryoneR) == 0)
64*0b57cec5SDimitry Andric         error.SetErrorStringWithFormat(
65*0b57cec5SDimitry Andric             "executable '%s' is not readable",
66*0b57cec5SDimitry Andric             resolved_module_spec.GetFileSpec().GetPath().c_str());
67*0b57cec5SDimitry Andric       else
68*0b57cec5SDimitry Andric         error.SetErrorStringWithFormat(
69*0b57cec5SDimitry Andric             "unable to find executable for '%s'",
70*0b57cec5SDimitry Andric             resolved_module_spec.GetFileSpec().GetPath().c_str());
71*0b57cec5SDimitry Andric     }
72*0b57cec5SDimitry Andric   } else {
73*0b57cec5SDimitry Andric     if (m_remote_platform_sp) {
74*0b57cec5SDimitry Andric       return GetCachedExecutable(resolved_module_spec, exe_module_sp,
75*0b57cec5SDimitry Andric                                  module_search_paths_ptr);
76*0b57cec5SDimitry Andric     }
77*0b57cec5SDimitry Andric 
78*0b57cec5SDimitry Andric     // We may connect to a process and use the provided executable (Don't use
79*0b57cec5SDimitry Andric     // local $PATH).
80*0b57cec5SDimitry Andric 
81*0b57cec5SDimitry Andric     // Resolve any executable within a bundle on MacOSX
82*0b57cec5SDimitry Andric     Host::ResolveExecutableInBundle(resolved_module_spec.GetFileSpec());
83*0b57cec5SDimitry Andric 
84*0b57cec5SDimitry Andric     if (FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec()))
85*0b57cec5SDimitry Andric       error.Clear();
86*0b57cec5SDimitry Andric     else
87*0b57cec5SDimitry Andric       error.SetErrorStringWithFormat("the platform is not currently "
88*0b57cec5SDimitry Andric                                      "connected, and '%s' doesn't exist in "
89*0b57cec5SDimitry Andric                                      "the system root.",
90*0b57cec5SDimitry Andric                                      exe_path);
91*0b57cec5SDimitry Andric   }
92*0b57cec5SDimitry Andric 
93*0b57cec5SDimitry Andric   if (error.Success()) {
94*0b57cec5SDimitry Andric     if (resolved_module_spec.GetArchitecture().IsValid()) {
95*0b57cec5SDimitry Andric       error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
96*0b57cec5SDimitry Andric                                           module_search_paths_ptr, nullptr, nullptr);
97*0b57cec5SDimitry Andric       if (error.Fail()) {
98*0b57cec5SDimitry Andric         // If we failed, it may be because the vendor and os aren't known. If
99*0b57cec5SDimitry Andric 	// that is the case, try setting them to the host architecture and give
100*0b57cec5SDimitry Andric 	// it another try.
101*0b57cec5SDimitry Andric         llvm::Triple &module_triple =
102*0b57cec5SDimitry Andric             resolved_module_spec.GetArchitecture().GetTriple();
103*0b57cec5SDimitry Andric         bool is_vendor_specified =
104*0b57cec5SDimitry Andric             (module_triple.getVendor() != llvm::Triple::UnknownVendor);
105*0b57cec5SDimitry Andric         bool is_os_specified =
106*0b57cec5SDimitry Andric             (module_triple.getOS() != llvm::Triple::UnknownOS);
107*0b57cec5SDimitry Andric         if (!is_vendor_specified || !is_os_specified) {
108*0b57cec5SDimitry Andric           const llvm::Triple &host_triple =
109*0b57cec5SDimitry Andric               HostInfo::GetArchitecture(HostInfo::eArchKindDefault).GetTriple();
110*0b57cec5SDimitry Andric 
111*0b57cec5SDimitry Andric           if (!is_vendor_specified)
112*0b57cec5SDimitry Andric             module_triple.setVendorName(host_triple.getVendorName());
113*0b57cec5SDimitry Andric           if (!is_os_specified)
114*0b57cec5SDimitry Andric             module_triple.setOSName(host_triple.getOSName());
115*0b57cec5SDimitry Andric 
116*0b57cec5SDimitry Andric           error = ModuleList::GetSharedModule(resolved_module_spec,
117*0b57cec5SDimitry Andric                                               exe_module_sp, module_search_paths_ptr, nullptr, nullptr);
118*0b57cec5SDimitry Andric         }
119*0b57cec5SDimitry Andric       }
120*0b57cec5SDimitry Andric 
121*0b57cec5SDimitry Andric       // TODO find out why exe_module_sp might be NULL
122*0b57cec5SDimitry Andric       if (error.Fail() || !exe_module_sp || !exe_module_sp->GetObjectFile()) {
123*0b57cec5SDimitry Andric         exe_module_sp.reset();
124*0b57cec5SDimitry Andric         error.SetErrorStringWithFormat(
125*0b57cec5SDimitry Andric             "'%s' doesn't contain the architecture %s",
126*0b57cec5SDimitry Andric             resolved_module_spec.GetFileSpec().GetPath().c_str(),
127*0b57cec5SDimitry Andric             resolved_module_spec.GetArchitecture().GetArchitectureName());
128*0b57cec5SDimitry Andric       }
129*0b57cec5SDimitry Andric     } else {
130*0b57cec5SDimitry Andric       // No valid architecture was specified, ask the platform for the
131*0b57cec5SDimitry Andric       // architectures that we should be using (in the correct order) and see
132*0b57cec5SDimitry Andric       // if we can find a match that way
133*0b57cec5SDimitry Andric       StreamString arch_names;
134*0b57cec5SDimitry Andric       llvm::ListSeparator LS;
135*0b57cec5SDimitry Andric       ArchSpec process_host_arch;
136*0b57cec5SDimitry Andric       for (const ArchSpec &arch :
137*0b57cec5SDimitry Andric            GetSupportedArchitectures(process_host_arch)) {
138*0b57cec5SDimitry Andric         resolved_module_spec.GetArchitecture() = arch;
139*0b57cec5SDimitry Andric         error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
140*0b57cec5SDimitry Andric                                             module_search_paths_ptr, nullptr, nullptr);
141*0b57cec5SDimitry Andric         // Did we find an executable using one of the
142*0b57cec5SDimitry Andric         if (error.Success()) {
143*0b57cec5SDimitry Andric           if (exe_module_sp && exe_module_sp->GetObjectFile())
144*0b57cec5SDimitry Andric             break;
145*0b57cec5SDimitry Andric           else
146*0b57cec5SDimitry Andric             error.SetErrorToGenericError();
147*0b57cec5SDimitry Andric         }
148*0b57cec5SDimitry Andric 
149*0b57cec5SDimitry Andric         arch_names << LS << arch.GetArchitectureName();
150*0b57cec5SDimitry Andric       }
151*0b57cec5SDimitry Andric 
152*0b57cec5SDimitry Andric       if (error.Fail() || !exe_module_sp) {
153*0b57cec5SDimitry Andric         if (FileSystem::Instance().Readable(
154*0b57cec5SDimitry Andric                 resolved_module_spec.GetFileSpec())) {
155*0b57cec5SDimitry Andric           error.SetErrorStringWithFormatv(
156*0b57cec5SDimitry Andric               "'{0}' doesn't contain any '{1}' platform architectures: {2}",
157*0b57cec5SDimitry Andric               resolved_module_spec.GetFileSpec(), GetPluginName(),
158*0b57cec5SDimitry Andric               arch_names.GetData());
159*0b57cec5SDimitry Andric         } else {
160*0b57cec5SDimitry Andric           error.SetErrorStringWithFormat(
161*0b57cec5SDimitry Andric               "'%s' is not readable",
162*0b57cec5SDimitry Andric               resolved_module_spec.GetFileSpec().GetPath().c_str());
163*0b57cec5SDimitry Andric         }
164*0b57cec5SDimitry Andric       }
165*0b57cec5SDimitry Andric     }
166*0b57cec5SDimitry Andric   }
167*0b57cec5SDimitry Andric 
168*0b57cec5SDimitry Andric   return error;
169*0b57cec5SDimitry Andric }
170*0b57cec5SDimitry Andric 
RunShellCommand(llvm::StringRef command,const FileSpec & working_dir,int * status_ptr,int * signo_ptr,std::string * command_output,const Timeout<std::micro> & timeout)171*0b57cec5SDimitry Andric Status RemoteAwarePlatform::RunShellCommand(
172*0b57cec5SDimitry Andric     llvm::StringRef command, const FileSpec &working_dir, int *status_ptr,
173*0b57cec5SDimitry Andric     int *signo_ptr, std::string *command_output,
174*0b57cec5SDimitry Andric     const Timeout<std::micro> &timeout) {
175*0b57cec5SDimitry Andric   return RunShellCommand(llvm::StringRef(), command, working_dir, status_ptr,
176*0b57cec5SDimitry Andric                          signo_ptr, command_output, timeout);
177*0b57cec5SDimitry Andric }
178*0b57cec5SDimitry Andric 
RunShellCommand(llvm::StringRef shell,llvm::StringRef command,const FileSpec & working_dir,int * status_ptr,int * signo_ptr,std::string * command_output,const Timeout<std::micro> & timeout)179*0b57cec5SDimitry Andric Status RemoteAwarePlatform::RunShellCommand(
180*0b57cec5SDimitry Andric     llvm::StringRef shell, llvm::StringRef command, const FileSpec &working_dir,
181*0b57cec5SDimitry Andric     int *status_ptr, int *signo_ptr, std::string *command_output,
182*0b57cec5SDimitry Andric     const Timeout<std::micro> &timeout) {
183*0b57cec5SDimitry Andric   if (m_remote_platform_sp)
184*0b57cec5SDimitry Andric     return m_remote_platform_sp->RunShellCommand(shell, command, working_dir,
185*0b57cec5SDimitry Andric                                                  status_ptr, signo_ptr,
186*0b57cec5SDimitry Andric                                                  command_output, timeout);
187*0b57cec5SDimitry Andric   return Platform::RunShellCommand(shell, command, working_dir, status_ptr,
188*0b57cec5SDimitry Andric                                    signo_ptr, command_output, timeout);
189*0b57cec5SDimitry Andric }
190*0b57cec5SDimitry Andric 
MakeDirectory(const FileSpec & file_spec,uint32_t file_permissions)191*0b57cec5SDimitry Andric Status RemoteAwarePlatform::MakeDirectory(const FileSpec &file_spec,
192*0b57cec5SDimitry Andric                                           uint32_t file_permissions) {
193*0b57cec5SDimitry Andric   if (m_remote_platform_sp)
194*0b57cec5SDimitry Andric     return m_remote_platform_sp->MakeDirectory(file_spec, file_permissions);
195*0b57cec5SDimitry Andric   return Platform::MakeDirectory(file_spec, file_permissions);
196*0b57cec5SDimitry Andric }
197*0b57cec5SDimitry Andric 
GetFilePermissions(const FileSpec & file_spec,uint32_t & file_permissions)198*0b57cec5SDimitry Andric Status RemoteAwarePlatform::GetFilePermissions(const FileSpec &file_spec,
199*0b57cec5SDimitry Andric                                                uint32_t &file_permissions) {
200*0b57cec5SDimitry Andric   if (m_remote_platform_sp)
201*0b57cec5SDimitry Andric     return m_remote_platform_sp->GetFilePermissions(file_spec,
202*0b57cec5SDimitry Andric                                                     file_permissions);
203*0b57cec5SDimitry Andric   return Platform::GetFilePermissions(file_spec, file_permissions);
204*0b57cec5SDimitry Andric }
205*0b57cec5SDimitry Andric 
SetFilePermissions(const FileSpec & file_spec,uint32_t file_permissions)206*0b57cec5SDimitry Andric Status RemoteAwarePlatform::SetFilePermissions(const FileSpec &file_spec,
207*0b57cec5SDimitry Andric                                                uint32_t file_permissions) {
208*0b57cec5SDimitry Andric   if (m_remote_platform_sp)
209*0b57cec5SDimitry Andric     return m_remote_platform_sp->SetFilePermissions(file_spec,
210*0b57cec5SDimitry Andric                                                     file_permissions);
211*0b57cec5SDimitry Andric   return Platform::SetFilePermissions(file_spec, file_permissions);
212*0b57cec5SDimitry Andric }
213*0b57cec5SDimitry Andric 
OpenFile(const FileSpec & file_spec,File::OpenOptions flags,uint32_t mode,Status & error)214*0b57cec5SDimitry Andric lldb::user_id_t RemoteAwarePlatform::OpenFile(const FileSpec &file_spec,
215*0b57cec5SDimitry Andric                                               File::OpenOptions flags,
216*0b57cec5SDimitry Andric                                               uint32_t mode, Status &error) {
217*0b57cec5SDimitry Andric   if (m_remote_platform_sp)
218*0b57cec5SDimitry Andric     return m_remote_platform_sp->OpenFile(file_spec, flags, mode, error);
219*0b57cec5SDimitry Andric   return Platform::OpenFile(file_spec, flags, mode, error);
220*0b57cec5SDimitry Andric }
221*0b57cec5SDimitry Andric 
CloseFile(lldb::user_id_t fd,Status & error)222*0b57cec5SDimitry Andric bool RemoteAwarePlatform::CloseFile(lldb::user_id_t fd, Status &error) {
223*0b57cec5SDimitry Andric   if (m_remote_platform_sp)
224*0b57cec5SDimitry Andric     return m_remote_platform_sp->CloseFile(fd, error);
225*0b57cec5SDimitry Andric   return Platform::CloseFile(fd, error);
226*0b57cec5SDimitry Andric }
227*0b57cec5SDimitry Andric 
ReadFile(lldb::user_id_t fd,uint64_t offset,void * dst,uint64_t dst_len,Status & error)228*0b57cec5SDimitry Andric uint64_t RemoteAwarePlatform::ReadFile(lldb::user_id_t fd, uint64_t offset,
229*0b57cec5SDimitry Andric                                        void *dst, uint64_t dst_len,
230*0b57cec5SDimitry Andric                                        Status &error) {
231*0b57cec5SDimitry Andric   if (m_remote_platform_sp)
232*0b57cec5SDimitry Andric     return m_remote_platform_sp->ReadFile(fd, offset, dst, dst_len, error);
233*0b57cec5SDimitry Andric   return Platform::ReadFile(fd, offset, dst, dst_len, error);
234*0b57cec5SDimitry Andric }
235*0b57cec5SDimitry Andric 
WriteFile(lldb::user_id_t fd,uint64_t offset,const void * src,uint64_t src_len,Status & error)236*0b57cec5SDimitry Andric uint64_t RemoteAwarePlatform::WriteFile(lldb::user_id_t fd, uint64_t offset,
237*0b57cec5SDimitry Andric                                         const void *src, uint64_t src_len,
238*0b57cec5SDimitry Andric                                         Status &error) {
239*0b57cec5SDimitry Andric   if (m_remote_platform_sp)
240*0b57cec5SDimitry Andric     return m_remote_platform_sp->WriteFile(fd, offset, src, src_len, error);
241*0b57cec5SDimitry Andric   return Platform::WriteFile(fd, offset, src, src_len, error);
242*0b57cec5SDimitry Andric }
243*0b57cec5SDimitry Andric 
GetFileSize(const FileSpec & file_spec)244*0b57cec5SDimitry Andric lldb::user_id_t RemoteAwarePlatform::GetFileSize(const FileSpec &file_spec) {
245*0b57cec5SDimitry Andric   if (m_remote_platform_sp)
246*0b57cec5SDimitry Andric     return m_remote_platform_sp->GetFileSize(file_spec);
247*0b57cec5SDimitry Andric   return Platform::GetFileSize(file_spec);
248*0b57cec5SDimitry Andric }
249*0b57cec5SDimitry Andric 
CreateSymlink(const FileSpec & src,const FileSpec & dst)250*0b57cec5SDimitry Andric Status RemoteAwarePlatform::CreateSymlink(const FileSpec &src,
251*0b57cec5SDimitry Andric                                           const FileSpec &dst) {
252*0b57cec5SDimitry Andric   if (m_remote_platform_sp)
253*0b57cec5SDimitry Andric     return m_remote_platform_sp->CreateSymlink(src, dst);
254*0b57cec5SDimitry Andric   return Platform::CreateSymlink(src, dst);
255*0b57cec5SDimitry Andric }
256*0b57cec5SDimitry Andric 
GetFileExists(const FileSpec & file_spec)257*0b57cec5SDimitry Andric bool RemoteAwarePlatform::GetFileExists(const FileSpec &file_spec) {
258*0b57cec5SDimitry Andric   if (m_remote_platform_sp)
259*0b57cec5SDimitry Andric     return m_remote_platform_sp->GetFileExists(file_spec);
260*0b57cec5SDimitry Andric   return Platform::GetFileExists(file_spec);
261*0b57cec5SDimitry Andric }
262*0b57cec5SDimitry Andric 
Unlink(const FileSpec & file_spec)263*0b57cec5SDimitry Andric Status RemoteAwarePlatform::Unlink(const FileSpec &file_spec) {
264*0b57cec5SDimitry Andric   if (m_remote_platform_sp)
265*0b57cec5SDimitry Andric     return m_remote_platform_sp->Unlink(file_spec);
266*0b57cec5SDimitry Andric   return Platform::Unlink(file_spec);
267*0b57cec5SDimitry Andric }
268*0b57cec5SDimitry Andric 
CalculateMD5(const FileSpec & file_spec,uint64_t & low,uint64_t & high)269*0b57cec5SDimitry Andric bool RemoteAwarePlatform::CalculateMD5(const FileSpec &file_spec, uint64_t &low,
270*0b57cec5SDimitry Andric                                        uint64_t &high) {
271*0b57cec5SDimitry Andric   if (m_remote_platform_sp)
272*0b57cec5SDimitry Andric     return m_remote_platform_sp->CalculateMD5(file_spec, low, high);
273*0b57cec5SDimitry Andric   return Platform::CalculateMD5(file_spec, low, high);
274*0b57cec5SDimitry Andric }
275*0b57cec5SDimitry Andric 
GetRemoteWorkingDirectory()276*0b57cec5SDimitry Andric FileSpec RemoteAwarePlatform::GetRemoteWorkingDirectory() {
277*0b57cec5SDimitry Andric   if (IsRemote() && m_remote_platform_sp)
278*0b57cec5SDimitry Andric     return m_remote_platform_sp->GetRemoteWorkingDirectory();
279*0b57cec5SDimitry Andric   return Platform::GetRemoteWorkingDirectory();
280*0b57cec5SDimitry Andric }
281*0b57cec5SDimitry Andric 
SetRemoteWorkingDirectory(const FileSpec & working_dir)282*0b57cec5SDimitry Andric bool RemoteAwarePlatform::SetRemoteWorkingDirectory(
283*0b57cec5SDimitry Andric     const FileSpec &working_dir) {
284*0b57cec5SDimitry Andric   if (IsRemote() && m_remote_platform_sp)
285     return m_remote_platform_sp->SetRemoteWorkingDirectory(working_dir);
286   return Platform::SetRemoteWorkingDirectory(working_dir);
287 }
288 
GetFileWithUUID(const FileSpec & platform_file,const UUID * uuid_ptr,FileSpec & local_file)289 Status RemoteAwarePlatform::GetFileWithUUID(const FileSpec &platform_file,
290                                             const UUID *uuid_ptr,
291                                             FileSpec &local_file) {
292   if (IsRemote() && m_remote_platform_sp)
293     return m_remote_platform_sp->GetFileWithUUID(platform_file, uuid_ptr,
294                                                  local_file);
295 
296   // Default to the local case
297   local_file = platform_file;
298   return Status();
299 }
300 
GetRemoteOSVersion()301 bool RemoteAwarePlatform::GetRemoteOSVersion() {
302   if (m_remote_platform_sp) {
303     m_os_version = m_remote_platform_sp->GetOSVersion();
304     return !m_os_version.empty();
305   }
306   return false;
307 }
308 
GetRemoteOSBuildString()309 std::optional<std::string> RemoteAwarePlatform::GetRemoteOSBuildString() {
310   if (m_remote_platform_sp)
311     return m_remote_platform_sp->GetRemoteOSBuildString();
312   return std::nullopt;
313 }
314 
GetRemoteOSKernelDescription()315 std::optional<std::string> RemoteAwarePlatform::GetRemoteOSKernelDescription() {
316   if (m_remote_platform_sp)
317     return m_remote_platform_sp->GetRemoteOSKernelDescription();
318   return std::nullopt;
319 }
320 
GetRemoteSystemArchitecture()321 ArchSpec RemoteAwarePlatform::GetRemoteSystemArchitecture() {
322   if (m_remote_platform_sp)
323     return m_remote_platform_sp->GetRemoteSystemArchitecture();
324   return ArchSpec();
325 }
326 
GetHostname()327 const char *RemoteAwarePlatform::GetHostname() {
328   if (m_remote_platform_sp)
329     return m_remote_platform_sp->GetHostname();
330   return Platform::GetHostname();
331 }
332 
GetUserIDResolver()333 UserIDResolver &RemoteAwarePlatform::GetUserIDResolver() {
334   if (m_remote_platform_sp)
335     return m_remote_platform_sp->GetUserIDResolver();
336   return Platform::GetUserIDResolver();
337 }
338 
GetEnvironment()339 Environment RemoteAwarePlatform::GetEnvironment() {
340   if (m_remote_platform_sp)
341     return m_remote_platform_sp->GetEnvironment();
342   return Platform::GetEnvironment();
343 }
344 
IsConnected() const345 bool RemoteAwarePlatform::IsConnected() const {
346   if (m_remote_platform_sp)
347     return m_remote_platform_sp->IsConnected();
348   return Platform::IsConnected();
349 }
350 
GetProcessInfo(lldb::pid_t pid,ProcessInstanceInfo & process_info)351 bool RemoteAwarePlatform::GetProcessInfo(lldb::pid_t pid,
352                                          ProcessInstanceInfo &process_info) {
353   if (m_remote_platform_sp)
354     return m_remote_platform_sp->GetProcessInfo(pid, process_info);
355   return Platform::GetProcessInfo(pid, process_info);
356 }
357 
358 uint32_t
FindProcesses(const ProcessInstanceInfoMatch & match_info,ProcessInstanceInfoList & process_infos)359 RemoteAwarePlatform::FindProcesses(const ProcessInstanceInfoMatch &match_info,
360                                    ProcessInstanceInfoList &process_infos) {
361   if (m_remote_platform_sp)
362     return m_remote_platform_sp->FindProcesses(match_info, process_infos);
363   return Platform::FindProcesses(match_info, process_infos);
364 }
365 
ConnectProcess(llvm::StringRef connect_url,llvm::StringRef plugin_name,Debugger & debugger,Target * target,Status & error)366 lldb::ProcessSP RemoteAwarePlatform::ConnectProcess(llvm::StringRef connect_url,
367                                                     llvm::StringRef plugin_name,
368                                                     Debugger &debugger,
369                                                     Target *target,
370                                                     Status &error) {
371   if (m_remote_platform_sp)
372     return m_remote_platform_sp->ConnectProcess(connect_url, plugin_name,
373                                                 debugger, target, error);
374   return Platform::ConnectProcess(connect_url, plugin_name, debugger, target,
375                                   error);
376 }
377 
LaunchProcess(ProcessLaunchInfo & launch_info)378 Status RemoteAwarePlatform::LaunchProcess(ProcessLaunchInfo &launch_info) {
379   if (m_remote_platform_sp)
380     return m_remote_platform_sp->LaunchProcess(launch_info);
381   return Platform::LaunchProcess(launch_info);
382 }
383 
KillProcess(const lldb::pid_t pid)384 Status RemoteAwarePlatform::KillProcess(const lldb::pid_t pid) {
385   if (m_remote_platform_sp)
386     return m_remote_platform_sp->KillProcess(pid);
387   return Platform::KillProcess(pid);
388 }
389 
ConnectToWaitingProcesses(Debugger & debugger,Status & error)390 size_t RemoteAwarePlatform::ConnectToWaitingProcesses(Debugger &debugger,
391                                                 Status &error) {
392   if (m_remote_platform_sp)
393     return m_remote_platform_sp->ConnectToWaitingProcesses(debugger, error);
394   return Platform::ConnectToWaitingProcesses(debugger, error);
395 }
396