LLDB  mainline
RemoteAwarePlatform.cpp
Go to the documentation of this file.
1 //===-- RemoteAwarePlatform.cpp -------------------------------------------===//
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 
10 #include "lldb/Core/Module.h"
11 #include "lldb/Core/ModuleList.h"
12 #include "lldb/Core/ModuleSpec.h"
13 #include "lldb/Host/FileCache.h"
14 #include "lldb/Host/FileSystem.h"
15 #include "lldb/Host/Host.h"
16 #include "lldb/Host/HostInfo.h"
18 
19 using namespace lldb_private;
20 using namespace lldb;
21 
22 bool RemoteAwarePlatform::GetModuleSpec(const FileSpec &module_file_spec,
23  const ArchSpec &arch,
24  ModuleSpec &module_spec) {
25  if (m_remote_platform_sp)
26  return m_remote_platform_sp->GetModuleSpec(module_file_spec, arch,
27  module_spec);
28 
29  return false;
30 }
31 
33  const ModuleSpec &module_spec, ModuleSP &exe_module_sp,
34  const FileSpecList *module_search_paths_ptr) {
35  Status error;
36  // Nothing special to do here, just use the actual file and architecture
37 
38  char exe_path[PATH_MAX];
39  ModuleSpec resolved_module_spec(module_spec);
40 
41  if (IsHost()) {
42  // If we have "ls" as the exe_file, resolve the executable location based
43  // on the current path variables
44  if (!FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec())) {
45  resolved_module_spec.GetFileSpec().GetPath(exe_path, sizeof(exe_path));
46  resolved_module_spec.GetFileSpec().SetFile(exe_path,
47  FileSpec::Style::native);
48  FileSystem::Instance().Resolve(resolved_module_spec.GetFileSpec());
49  }
50 
51  if (!FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec()))
53  resolved_module_spec.GetFileSpec());
54 
55  // Resolve any executable within a bundle on MacOSX
56  Host::ResolveExecutableInBundle(resolved_module_spec.GetFileSpec());
57 
58  if (FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec()))
59  error.Clear();
60  else {
61  const uint32_t permissions = FileSystem::Instance().GetPermissions(
62  resolved_module_spec.GetFileSpec());
63  if (permissions && (permissions & eFilePermissionsEveryoneR) == 0)
65  "executable '%s' is not readable",
66  resolved_module_spec.GetFileSpec().GetPath().c_str());
67  else
69  "unable to find executable for '%s'",
70  resolved_module_spec.GetFileSpec().GetPath().c_str());
71  }
72  } else {
73  if (m_remote_platform_sp) {
74  return GetCachedExecutable(resolved_module_spec, exe_module_sp,
75  module_search_paths_ptr,
76  *m_remote_platform_sp);
77  }
78 
79  // We may connect to a process and use the provided executable (Don't use
80  // local $PATH).
81 
82  // Resolve any executable within a bundle on MacOSX
83  Host::ResolveExecutableInBundle(resolved_module_spec.GetFileSpec());
84 
85  if (FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec()))
86  error.Clear();
87  else
88  error.SetErrorStringWithFormat("the platform is not currently "
89  "connected, and '%s' doesn't exist in "
90  "the system root.",
91  exe_path);
92  }
93 
94  if (error.Success()) {
95  if (resolved_module_spec.GetArchitecture().IsValid()) {
96  error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
97  module_search_paths_ptr, nullptr, nullptr);
98  if (error.Fail()) {
99  // If we failed, it may be because the vendor and os aren't known. If
100  // that is the case, try setting them to the host architecture and give
101  // it another try.
102  llvm::Triple &module_triple =
103  resolved_module_spec.GetArchitecture().GetTriple();
104  bool is_vendor_specified =
105  (module_triple.getVendor() != llvm::Triple::UnknownVendor);
106  bool is_os_specified =
107  (module_triple.getOS() != llvm::Triple::UnknownOS);
108  if (!is_vendor_specified || !is_os_specified) {
109  const llvm::Triple &host_triple =
110  HostInfo::GetArchitecture(HostInfo::eArchKindDefault).GetTriple();
111 
112  if (!is_vendor_specified)
113  module_triple.setVendorName(host_triple.getVendorName());
114  if (!is_os_specified)
115  module_triple.setOSName(host_triple.getOSName());
116 
117  error = ModuleList::GetSharedModule(resolved_module_spec,
118  exe_module_sp, module_search_paths_ptr, nullptr, nullptr);
119  }
120  }
121 
122  // TODO find out why exe_module_sp might be NULL
123  if (error.Fail() || !exe_module_sp || !exe_module_sp->GetObjectFile()) {
124  exe_module_sp.reset();
126  "'%s' doesn't contain the architecture %s",
127  resolved_module_spec.GetFileSpec().GetPath().c_str(),
128  resolved_module_spec.GetArchitecture().GetArchitectureName());
129  }
130  } else {
131  // No valid architecture was specified, ask the platform for the
132  // architectures that we should be using (in the correct order) and see
133  // if we can find a match that way
134  StreamString arch_names;
135  for (uint32_t idx = 0; GetSupportedArchitectureAtIndex(
136  idx, resolved_module_spec.GetArchitecture());
137  ++idx) {
138  error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
139  module_search_paths_ptr, nullptr, nullptr);
140  // Did we find an executable using one of the
141  if (error.Success()) {
142  if (exe_module_sp && exe_module_sp->GetObjectFile())
143  break;
144  else
145  error.SetErrorToGenericError();
146  }
147 
148  if (idx > 0)
149  arch_names.PutCString(", ");
150  arch_names.PutCString(
151  resolved_module_spec.GetArchitecture().GetArchitectureName());
152  }
153 
154  if (error.Fail() || !exe_module_sp) {
156  resolved_module_spec.GetFileSpec())) {
158  "'%s' doesn't contain any '%s' platform architectures: %s",
159  resolved_module_spec.GetFileSpec().GetPath().c_str(),
160  GetPluginName().GetCString(), arch_names.GetData());
161  } else {
163  "'%s' is not readable",
164  resolved_module_spec.GetFileSpec().GetPath().c_str());
165  }
166  }
167  }
168  }
169 
170  return error;
171 }
172 
174  const char *command, const FileSpec &working_dir, int *status_ptr,
175  int *signo_ptr, std::string *command_output,
176  const Timeout<std::micro> &timeout) {
177  if (IsHost())
178  return Host::RunShellCommand(command, working_dir, status_ptr, signo_ptr,
179  command_output, timeout);
180  if (m_remote_platform_sp)
181  return m_remote_platform_sp->RunShellCommand(
182  command, working_dir, status_ptr, signo_ptr, command_output, timeout);
183  return Status("unable to run a remote command without a platform");
184 }
185 
187  uint32_t file_permissions) {
188  if (m_remote_platform_sp)
189  return m_remote_platform_sp->MakeDirectory(file_spec, file_permissions);
190  return Platform::MakeDirectory(file_spec, file_permissions);
191 }
192 
194  uint32_t &file_permissions) {
195  if (m_remote_platform_sp)
196  return m_remote_platform_sp->GetFilePermissions(file_spec,
197  file_permissions);
198  return Platform::GetFilePermissions(file_spec, file_permissions);
199 }
200 
202  uint32_t file_permissions) {
203  if (m_remote_platform_sp)
204  return m_remote_platform_sp->SetFilePermissions(file_spec,
205  file_permissions);
206  return Platform::SetFilePermissions(file_spec, file_permissions);
207 }
208 
210  File::OpenOptions flags,
211  uint32_t mode, Status &error) {
212  if (IsHost())
213  return FileCache::GetInstance().OpenFile(file_spec, flags, mode, error);
214  if (m_remote_platform_sp)
215  return m_remote_platform_sp->OpenFile(file_spec, flags, mode, error);
216  return Platform::OpenFile(file_spec, flags, mode, error);
217 }
218 
220  if (IsHost())
221  return FileCache::GetInstance().CloseFile(fd, error);
222  if (m_remote_platform_sp)
223  return m_remote_platform_sp->CloseFile(fd, error);
224  return Platform::CloseFile(fd, error);
225 }
226 
227 uint64_t RemoteAwarePlatform::ReadFile(lldb::user_id_t fd, uint64_t offset,
228  void *dst, uint64_t dst_len,
229  Status &error) {
230  if (IsHost())
231  return FileCache::GetInstance().ReadFile(fd, offset, dst, dst_len, error);
232  if (m_remote_platform_sp)
233  return m_remote_platform_sp->ReadFile(fd, offset, dst, dst_len, error);
234  return Platform::ReadFile(fd, offset, dst, dst_len, error);
235 }
236 
237 uint64_t RemoteAwarePlatform::WriteFile(lldb::user_id_t fd, uint64_t offset,
238  const void *src, uint64_t src_len,
239  Status &error) {
240  if (IsHost())
241  return FileCache::GetInstance().WriteFile(fd, offset, src, src_len, error);
242  if (m_remote_platform_sp)
243  return m_remote_platform_sp->WriteFile(fd, offset, src, src_len, error);
244  return Platform::WriteFile(fd, offset, src, src_len, error);
245 }
246 
248  if (IsHost()) {
249  uint64_t Size;
250  if (llvm::sys::fs::file_size(file_spec.GetPath(), Size))
251  return 0;
252  return Size;
253  }
254  if (m_remote_platform_sp)
255  return m_remote_platform_sp->GetFileSize(file_spec);
256  return Platform::GetFileSize(file_spec);
257 }
258 
260  const FileSpec &dst) {
261  if (IsHost())
262  return FileSystem::Instance().Symlink(src, dst);
263  if (m_remote_platform_sp)
264  return m_remote_platform_sp->CreateSymlink(src, dst);
265  return Platform::CreateSymlink(src, dst);
266 }
267 
269  if (IsHost())
270  return FileSystem::Instance().Exists(file_spec);
271  if (m_remote_platform_sp)
272  return m_remote_platform_sp->GetFileExists(file_spec);
273  return Platform::GetFileExists(file_spec);
274 }
275 
277  if (IsHost())
278  return llvm::sys::fs::remove(file_spec.GetPath());
279  if (m_remote_platform_sp)
280  return m_remote_platform_sp->Unlink(file_spec);
281  return Platform::Unlink(file_spec);
282 }
283 
284 bool RemoteAwarePlatform::CalculateMD5(const FileSpec &file_spec, uint64_t &low,
285  uint64_t &high) {
286  if (IsHost())
287  return Platform::CalculateMD5(file_spec, low, high);
288  if (m_remote_platform_sp)
289  return m_remote_platform_sp->CalculateMD5(file_spec, low, high);
290  return false;
291 }
292 
294  if (IsRemote() && m_remote_platform_sp)
295  return m_remote_platform_sp->GetRemoteWorkingDirectory();
297 }
298 
300  const FileSpec &working_dir) {
301  if (IsRemote() && m_remote_platform_sp)
302  return m_remote_platform_sp->SetRemoteWorkingDirectory(working_dir);
303  return Platform::SetRemoteWorkingDirectory(working_dir);
304 }
305 
307  const UUID *uuid_ptr,
308  FileSpec &local_file) {
309  if (IsRemote() && m_remote_platform_sp)
310  return m_remote_platform_sp->GetFileWithUUID(platform_file, uuid_ptr,
311  local_file);
312 
313  // Default to the local case
314  local_file = platform_file;
315  return Status();
316 }
317 
319  if (m_remote_platform_sp) {
320  m_os_version = m_remote_platform_sp->GetOSVersion();
321  return !m_os_version.empty();
322  }
323  return false;
324 }
325 
327  if (m_remote_platform_sp)
328  return m_remote_platform_sp->GetRemoteOSBuildString(s);
329  s.clear();
330  return false;
331 }
332 
334  if (m_remote_platform_sp)
335  return m_remote_platform_sp->GetRemoteOSKernelDescription(s);
336  s.clear();
337  return false;
338 }
339 
341  if (m_remote_platform_sp)
342  return m_remote_platform_sp->GetRemoteSystemArchitecture();
343  return ArchSpec();
344 }
345 
347  if (IsHost())
348  return Platform::GetHostname();
349  if (m_remote_platform_sp)
350  return m_remote_platform_sp->GetHostname();
351  return nullptr;
352 }
353 
355  if (IsHost())
356  return HostInfo::GetUserIDResolver();
357  if (m_remote_platform_sp)
358  return m_remote_platform_sp->GetUserIDResolver();
360 }
361 
363  if (IsRemote()) {
364  if (m_remote_platform_sp)
365  return m_remote_platform_sp->GetEnvironment();
366  return Environment();
367  }
368  return Host::GetEnvironment();
369 }
370 
372  if (IsHost())
373  return true;
374  else if (m_remote_platform_sp)
375  return m_remote_platform_sp->IsConnected();
376  return false;
377 }
378 
380  ProcessInstanceInfo &process_info) {
381  if (IsHost())
382  return Platform::GetProcessInfo(pid, process_info);
383  if (m_remote_platform_sp)
384  return m_remote_platform_sp->GetProcessInfo(pid, process_info);
385  return false;
386 }
387 
388 uint32_t
390  ProcessInstanceInfoList &process_infos) {
391  if (IsHost())
392  return Platform::FindProcesses(match_info, process_infos);
393  if (m_remote_platform_sp)
394  return m_remote_platform_sp->FindProcesses(match_info, process_infos);
395  return 0;
396 }
397 
398 lldb::ProcessSP RemoteAwarePlatform::ConnectProcess(llvm::StringRef connect_url,
399  llvm::StringRef plugin_name,
400  Debugger &debugger,
401  Target *target,
402  Status &error) {
403  if (m_remote_platform_sp)
404  return m_remote_platform_sp->ConnectProcess(connect_url, plugin_name,
405  debugger, target, error);
406  return Platform::ConnectProcess(connect_url, plugin_name, debugger, target,
407  error);
408 }
409 
411  Status error;
412 
413  if (IsHost()) {
414  error = Platform::LaunchProcess(launch_info);
415  } else {
416  if (m_remote_platform_sp)
417  error = m_remote_platform_sp->LaunchProcess(launch_info);
418  else
419  error.SetErrorString("the platform is not currently connected");
420  }
421  return error;
422 }
423 
425  if (IsHost())
426  return Platform::KillProcess(pid);
427  if (m_remote_platform_sp)
428  return m_remote_platform_sp->KillProcess(pid);
429  return Status("the platform is not currently connected");
430 }
static Status GetSharedModule(const ModuleSpec &module_spec, lldb::ModuleSP &module_sp, const FileSpecList *module_search_paths_ptr, lldb::ModuleSP *old_module_sp_ptr, bool *did_create_ptr, bool always_create=false)
Definition: ModuleList.cpp:734
A class to manage flag bits.
Definition: Debugger.h:70
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
Definition: Stream.cpp:62
uint64_t WriteFile(lldb::user_id_t fd, uint64_t offset, const void *src, uint64_t src_len, Status &error)
Definition: FileCache.cpp:63
bool ResolveExecutableLocation(FileSpec &file_spec)
Call into the Host to see if it can help find the file.
static bool ResolveExecutableInBundle(FileSpec &file)
When executable files may live within a directory, where the directory represents an executable bundl...
lldb::user_id_t OpenFile(const FileSpec &file_spec, File::OpenOptions flags, uint32_t mode, Status &error)
Definition: FileCache.cpp:26
A class that represents a running process on the host machine.
uint64_t WriteFile(lldb::user_id_t fd, uint64_t offset, const void *src, uint64_t src_len, Status &error) override
virtual uint32_t FindProcesses(const ProcessInstanceInfoMatch &match_info, ProcessInstanceInfoList &proc_infos)
Attach to an existing process by process name.
Definition: Platform.cpp:1005
std::vector< ProcessInstanceInfo > ProcessInstanceInfoList
Definition: Host.h:30
Status CreateSymlink(const FileSpec &src, const FileSpec &dst) override
bool GetRemoteOSKernelDescription(std::string &s) override
lldb::user_id_t GetFileSize(const FileSpec &file_spec) override
Status LaunchProcess(ProcessLaunchInfo &launch_info) override
Launch a new process on a platform, not necessarily for debugging, it could be just for running the p...
virtual Status CreateSymlink(const FileSpec &src, const FileSpec &dst)
Definition: Platform.cpp:1294
uint32_t FindProcesses(const ProcessInstanceInfoMatch &match_info, ProcessInstanceInfoList &process_infos) override
Attach to an existing process by process name.
virtual bool GetFileExists(const lldb_private::FileSpec &file_spec)
Definition: Platform.cpp:1301
virtual FileSpec GetRemoteWorkingDirectory()
Definition: Platform.h:261
virtual Status KillProcess(const lldb::pid_t pid)
Kill process on a platform.
Definition: Platform.cpp:1071
A file utility class.
Definition: FileSpec.h:56
An architecture specification class.
Definition: ArchSpec.h:33
virtual uint64_t WriteFile(lldb::user_id_t fd, uint64_t offset, const void *src, uint64_t src_len, Status &error)
Definition: Platform.h:530
uint64_t ReadFile(lldb::user_id_t fd, uint64_t offset, void *dst, uint64_t dst_len, Status &error)
Definition: FileCache.cpp:90
Status MakeDirectory(const FileSpec &file_spec, uint32_t mode) override
Status ResolveExecutable(const ModuleSpec &module_spec, lldb::ModuleSP &module_sp, const FileSpecList *module_search_paths_ptr) override
Find a platform plugin for a given process.
bool CloseFile(lldb::user_id_t fd, Status &error) override
virtual lldb::ProcessSP ConnectProcess(llvm::StringRef connect_url, llvm::StringRef plugin_name, lldb_private::Debugger &debugger, lldb_private::Target *target, lldb_private::Status &error)
Definition: Platform.cpp:1775
const char * GetData() const
Definition: StreamString.h:43
bool IsValid() const
Tests if this ArchSpec is valid.
Definition: ArchSpec.h:332
static FileSystem & Instance()
llvm::Triple & GetTriple()
Architecture triple accessor.
Definition: ArchSpec.h:434
bool CalculateMD5(const FileSpec &file_spec, uint64_t &low, uint64_t &high) override
virtual lldb::user_id_t OpenFile(const FileSpec &file_spec, File::OpenOptions flags, uint32_t mode, Status &error)
Definition: Platform.h:510
bool GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &proc_info) override
const char * GetArchitectureName() const
Returns a static string representing the current architecture.
Definition: ArchSpec.cpp:585
Status Unlink(const FileSpec &file_spec) override
uint64_t user_id_t
Definition: lldb-types.h:84
uint64_t ReadFile(lldb::user_id_t fd, uint64_t offset, void *dst, uint64_t dst_len, Status &error) override
void SetErrorToGenericError()
Set the current error to a generic error.
Definition: Status.cpp:232
bool GetRemoteOSBuildString(std::string &s) override
virtual lldb::user_id_t GetFileSize(const FileSpec &file_spec)
Definition: Platform.h:518
static UserIDResolver & GetNoopResolver()
Returns a resolver which returns a failure value for each query.
void Clear()
Clear the object state.
Definition: Status.cpp:168
static Environment GetEnvironment()
lldb::ProcessSP ConnectProcess(llvm::StringRef connect_url, llvm::StringRef plugin_name, Debugger &debugger, Target *target, Status &error) override
void SetErrorString(llvm::StringRef err_str)
Set the current error string to err_str.
Definition: Status.cpp:242
bool SetRemoteWorkingDirectory(const FileSpec &working_dir) override
lldb_private::Environment GetEnvironment() override
bool Success() const
Test for success condition.
Definition: Status.cpp:288
bool GetFileExists(const FileSpec &file_spec) override
void Resolve(llvm::SmallVectorImpl< char > &path)
Resolve path to make it canonical.
FileSpec & GetFileSpec()
Definition: ModuleSpec.h:75
virtual bool SetRemoteWorkingDirectory(const FileSpec &working_dir)
Definition: Platform.cpp:828
virtual bool CloseFile(lldb::user_id_t fd, Status &error)
Definition: Platform.h:516
uint32_t GetPermissions(const FileSpec &file_spec) const
Return the current permissions of the given file.
Status Symlink(const FileSpec &src, const FileSpec &dst)
Status GetFileWithUUID(const FileSpec &platform_file, const UUID *uuid, FileSpec &local_file) override
Locate a file for a platform.
virtual Status SetFilePermissions(const FileSpec &file_spec, uint32_t file_permissions)
Definition: Platform.cpp:799
ArchSpec & GetArchitecture()
Definition: ModuleSpec.h:111
An abstract interface for things that know how to map numeric user/group IDs into names...
Status KillProcess(const lldb::pid_t pid) override
Kill process on a platform.
static Status RunShellCommand(const char *command, const FileSpec &working_dir, int *status_ptr, int *signo_ptr, std::string *command_output, const Timeout< std::micro > &timeout, bool run_in_default_shell=true, bool hide_stderr=false)
Run a shell command.
bool Readable(const FileSpec &file_spec) const
Returns whether the given file is readable.
UserIDResolver & GetUserIDResolver() override
bool Fail() const
Test for error condition.
Definition: Status.cpp:182
virtual Status MakeDirectory(const FileSpec &file_spec, uint32_t permissions)
Definition: Platform.cpp:770
bool GetModuleSpec(const FileSpec &module_file_spec, const ArchSpec &arch, ModuleSpec &module_spec) override
static FileCache & GetInstance()
Definition: FileCache.cpp:19
Definition: SBAddress.h:15
bool Exists(const FileSpec &file_spec) const
Returns whether the given file exists.
uint64_t pid_t
Definition: lldb-types.h:85
#define PATH_MAX
virtual Status GetFilePermissions(const FileSpec &file_spec, uint32_t &file_permissions)
Definition: Platform.cpp:783
int SetErrorStringWithFormat(const char *format,...) __attribute__((format(printf
Set the current error string to a formatted error string.
Definition: Status.cpp:256
void SetFile(llvm::StringRef path, Style style)
Change the file specified with a new path.
Definition: FileSpec.cpp:174
virtual bool CalculateMD5(const FileSpec &file_spec, uint64_t &low, uint64_t &high)
Definition: Platform.cpp:1341
virtual uint64_t ReadFile(lldb::user_id_t fd, uint64_t offset, void *dst, uint64_t dst_len, Status &error)
Definition: Platform.h:522
Status GetFilePermissions(const FileSpec &file_spec, uint32_t &file_permissions) override
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
Definition: FileSpec.cpp:348
virtual Status Unlink(const FileSpec &file_spec)
Definition: Platform.cpp:1305
lldb::user_id_t OpenFile(const FileSpec &file_spec, File::OpenOptions flags, uint32_t mode, Status &error) override
virtual Status LaunchProcess(ProcessLaunchInfo &launch_info)
Launch a new process on a platform, not necessarily for debugging, it could be just for running the p...
Definition: Platform.cpp:1015
Status RunShellCommand(const char *command, const FileSpec &working_dir, int *status_ptr, int *signo_ptr, std::string *command_output, const Timeout< std::micro > &timeout) override
virtual bool GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &proc_info)
Definition: Platform.cpp:996
bool CloseFile(lldb::user_id_t fd, Status &error)
Definition: FileCache.cpp:43
An error handling class.
Definition: Status.h:44
Status SetFilePermissions(const FileSpec &file_spec, uint32_t file_permissions) override
virtual const char * GetHostname()
Definition: Platform.cpp:815