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  llvm::StringRef command, const FileSpec &working_dir, int *status_ptr,
175  int *signo_ptr, std::string *command_output,
176  const Timeout<std::micro> &timeout) {
177  return RunShellCommand(llvm::StringRef(), command, working_dir, status_ptr,
178  signo_ptr, command_output, timeout);
179 }
180 
182  llvm::StringRef shell, llvm::StringRef command, const FileSpec &working_dir,
183  int *status_ptr, int *signo_ptr, std::string *command_output,
184  const Timeout<std::micro> &timeout) {
185  if (IsHost())
186  return Host::RunShellCommand(shell, command, working_dir, status_ptr,
187  signo_ptr, command_output, timeout);
188  if (m_remote_platform_sp)
189  return m_remote_platform_sp->RunShellCommand(shell, command, working_dir,
190  status_ptr, signo_ptr,
191  command_output, timeout);
192  return Status("unable to run a remote command without a platform");
193 }
194 
196  uint32_t file_permissions) {
197  if (m_remote_platform_sp)
198  return m_remote_platform_sp->MakeDirectory(file_spec, file_permissions);
199  return Platform::MakeDirectory(file_spec, file_permissions);
200 }
201 
203  uint32_t &file_permissions) {
204  if (m_remote_platform_sp)
205  return m_remote_platform_sp->GetFilePermissions(file_spec,
206  file_permissions);
207  return Platform::GetFilePermissions(file_spec, file_permissions);
208 }
209 
211  uint32_t file_permissions) {
212  if (m_remote_platform_sp)
213  return m_remote_platform_sp->SetFilePermissions(file_spec,
214  file_permissions);
215  return Platform::SetFilePermissions(file_spec, file_permissions);
216 }
217 
219  File::OpenOptions flags,
220  uint32_t mode, Status &error) {
221  if (IsHost())
222  return FileCache::GetInstance().OpenFile(file_spec, flags, mode, error);
223  if (m_remote_platform_sp)
224  return m_remote_platform_sp->OpenFile(file_spec, flags, mode, error);
225  return Platform::OpenFile(file_spec, flags, mode, error);
226 }
227 
229  if (IsHost())
230  return FileCache::GetInstance().CloseFile(fd, error);
231  if (m_remote_platform_sp)
232  return m_remote_platform_sp->CloseFile(fd, error);
233  return Platform::CloseFile(fd, error);
234 }
235 
236 uint64_t RemoteAwarePlatform::ReadFile(lldb::user_id_t fd, uint64_t offset,
237  void *dst, uint64_t dst_len,
238  Status &error) {
239  if (IsHost())
240  return FileCache::GetInstance().ReadFile(fd, offset, dst, dst_len, error);
241  if (m_remote_platform_sp)
242  return m_remote_platform_sp->ReadFile(fd, offset, dst, dst_len, error);
243  return Platform::ReadFile(fd, offset, dst, dst_len, error);
244 }
245 
246 uint64_t RemoteAwarePlatform::WriteFile(lldb::user_id_t fd, uint64_t offset,
247  const void *src, uint64_t src_len,
248  Status &error) {
249  if (IsHost())
250  return FileCache::GetInstance().WriteFile(fd, offset, src, src_len, error);
251  if (m_remote_platform_sp)
252  return m_remote_platform_sp->WriteFile(fd, offset, src, src_len, error);
253  return Platform::WriteFile(fd, offset, src, src_len, error);
254 }
255 
257  if (IsHost()) {
258  uint64_t Size;
259  if (llvm::sys::fs::file_size(file_spec.GetPath(), Size))
260  return 0;
261  return Size;
262  }
263  if (m_remote_platform_sp)
264  return m_remote_platform_sp->GetFileSize(file_spec);
265  return Platform::GetFileSize(file_spec);
266 }
267 
269  const FileSpec &dst) {
270  if (IsHost())
271  return FileSystem::Instance().Symlink(src, dst);
272  if (m_remote_platform_sp)
273  return m_remote_platform_sp->CreateSymlink(src, dst);
274  return Platform::CreateSymlink(src, dst);
275 }
276 
278  if (IsHost())
279  return FileSystem::Instance().Exists(file_spec);
280  if (m_remote_platform_sp)
281  return m_remote_platform_sp->GetFileExists(file_spec);
282  return Platform::GetFileExists(file_spec);
283 }
284 
286  if (IsHost())
287  return llvm::sys::fs::remove(file_spec.GetPath());
288  if (m_remote_platform_sp)
289  return m_remote_platform_sp->Unlink(file_spec);
290  return Platform::Unlink(file_spec);
291 }
292 
293 bool RemoteAwarePlatform::CalculateMD5(const FileSpec &file_spec, uint64_t &low,
294  uint64_t &high) {
295  if (IsHost())
296  return Platform::CalculateMD5(file_spec, low, high);
297  if (m_remote_platform_sp)
298  return m_remote_platform_sp->CalculateMD5(file_spec, low, high);
299  return false;
300 }
301 
303  if (IsRemote() && m_remote_platform_sp)
304  return m_remote_platform_sp->GetRemoteWorkingDirectory();
306 }
307 
309  const FileSpec &working_dir) {
310  if (IsRemote() && m_remote_platform_sp)
311  return m_remote_platform_sp->SetRemoteWorkingDirectory(working_dir);
312  return Platform::SetRemoteWorkingDirectory(working_dir);
313 }
314 
316  const UUID *uuid_ptr,
317  FileSpec &local_file) {
318  if (IsRemote() && m_remote_platform_sp)
319  return m_remote_platform_sp->GetFileWithUUID(platform_file, uuid_ptr,
320  local_file);
321 
322  // Default to the local case
323  local_file = platform_file;
324  return Status();
325 }
326 
328  if (m_remote_platform_sp) {
329  m_os_version = m_remote_platform_sp->GetOSVersion();
330  return !m_os_version.empty();
331  }
332  return false;
333 }
334 
336  if (m_remote_platform_sp)
337  return m_remote_platform_sp->GetRemoteOSBuildString(s);
338  s.clear();
339  return false;
340 }
341 
343  if (m_remote_platform_sp)
344  return m_remote_platform_sp->GetRemoteOSKernelDescription(s);
345  s.clear();
346  return false;
347 }
348 
350  if (m_remote_platform_sp)
351  return m_remote_platform_sp->GetRemoteSystemArchitecture();
352  return ArchSpec();
353 }
354 
356  if (IsHost())
357  return Platform::GetHostname();
358  if (m_remote_platform_sp)
359  return m_remote_platform_sp->GetHostname();
360  return nullptr;
361 }
362 
364  if (IsHost())
365  return HostInfo::GetUserIDResolver();
366  if (m_remote_platform_sp)
367  return m_remote_platform_sp->GetUserIDResolver();
369 }
370 
372  if (IsRemote()) {
373  if (m_remote_platform_sp)
374  return m_remote_platform_sp->GetEnvironment();
375  return Environment();
376  }
377  return Host::GetEnvironment();
378 }
379 
381  if (IsHost())
382  return true;
383  else if (m_remote_platform_sp)
384  return m_remote_platform_sp->IsConnected();
385  return false;
386 }
387 
389  ProcessInstanceInfo &process_info) {
390  if (IsHost())
391  return Platform::GetProcessInfo(pid, process_info);
392  if (m_remote_platform_sp)
393  return m_remote_platform_sp->GetProcessInfo(pid, process_info);
394  return false;
395 }
396 
397 uint32_t
399  ProcessInstanceInfoList &process_infos) {
400  if (IsHost())
401  return Platform::FindProcesses(match_info, process_infos);
402  if (m_remote_platform_sp)
403  return m_remote_platform_sp->FindProcesses(match_info, process_infos);
404  return 0;
405 }
406 
407 lldb::ProcessSP RemoteAwarePlatform::ConnectProcess(llvm::StringRef connect_url,
408  llvm::StringRef plugin_name,
409  Debugger &debugger,
410  Target *target,
411  Status &error) {
412  if (m_remote_platform_sp)
413  return m_remote_platform_sp->ConnectProcess(connect_url, plugin_name,
414  debugger, target, error);
415  return Platform::ConnectProcess(connect_url, plugin_name, debugger, target,
416  error);
417 }
418 
420  Status error;
421 
422  if (IsHost()) {
423  error = Platform::LaunchProcess(launch_info);
424  } else {
425  if (m_remote_platform_sp)
426  error = m_remote_platform_sp->LaunchProcess(launch_info);
427  else
428  error.SetErrorString("the platform is not currently connected");
429  }
430  return error;
431 }
432 
434  if (IsHost())
435  return Platform::KillProcess(pid);
436  if (m_remote_platform_sp)
437  return m_remote_platform_sp->KillProcess(pid);
438  return Status("the platform is not currently connected");
439 }
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:63
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:1001
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:1288
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:1295
virtual FileSpec GetRemoteWorkingDirectory()
Definition: Platform.h:261
virtual Status KillProcess(const lldb::pid_t pid)
Kill process on a platform.
Definition: Platform.cpp:1065
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:536
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
const char * GetData() const
Definition: StreamString.h:43
bool IsValid() const
Tests if this ArchSpec is valid.
Definition: ArchSpec.h:332
Status RunShellCommand(llvm::StringRef command, const FileSpec &working_dir, int *status_ptr, int *signo_ptr, std::string *command_output, const Timeout< std::micro > &timeout) override
static FileSystem & Instance()
static Status GetSharedModule(const ModuleSpec &module_spec, lldb::ModuleSP &module_sp, const FileSpecList *module_search_paths_ptr, llvm::SmallVectorImpl< lldb::ModuleSP > *old_modules, bool *did_create_ptr, bool always_create=false)
Definition: ModuleList.cpp:750
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:513
bool GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &proc_info) override
virtual lldb::ProcessSP ConnectProcess(llvm::StringRef connect_url, llvm::StringRef plugin_name, Debugger &debugger, Target *target, Status &error)
Definition: Platform.cpp:1793
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
static llvm::raw_ostream & error(Stream &strm)
static Status RunShellCommand(llvm::StringRef command, const FileSpec &working_dir, int *status_ptr, int *signo_ptr, std::string *command_output, const Timeout< std::micro > &timeout, bool run_in_shell=true, bool hide_stderr=false)
Run a shell command.
bool GetRemoteOSBuildString(std::string &s) override
virtual lldb::user_id_t GetFileSize(const FileSpec &file_spec)
Definition: Platform.h:521
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:59
virtual bool SetRemoteWorkingDirectory(const FileSpec &working_dir)
Definition: Platform.cpp:824
virtual bool CloseFile(lldb::user_id_t fd, Status &error)
Definition: Platform.h:519
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:795
ArchSpec & GetArchitecture()
Definition: ModuleSpec.h:95
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.
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:766
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:779
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:1351
virtual uint64_t ReadFile(lldb::user_id_t fd, uint64_t offset, void *dst, uint64_t dst_len, Status &error)
Definition: Platform.h:528
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:1299
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:1011
virtual bool GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &proc_info)
Definition: Platform.cpp:992
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:811