LLDB  mainline
PlatformPOSIX.cpp
Go to the documentation of this file.
1 //===-- PlatformPOSIX.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 "PlatformPOSIX.h"
10 
11 #include "lldb/Core/Debugger.h"
12 #include "lldb/Core/Module.h"
13 #include "lldb/Core/ModuleSpec.h"
14 #include "lldb/Core/ValueObject.h"
19 #include "lldb/Host/File.h"
20 #include "lldb/Host/FileCache.h"
21 #include "lldb/Host/FileSystem.h"
22 #include "lldb/Host/Host.h"
23 #include "lldb/Host/HostInfo.h"
28 #include "lldb/Target/Process.h"
29 #include "lldb/Target/Thread.h"
30 #include "lldb/Utility/CleanUp.h"
32 #include "lldb/Utility/FileSpec.h"
33 #include "lldb/Utility/Log.h"
35 
36 using namespace lldb;
37 using namespace lldb_private;
38 
39 /// Default Constructor
41  : RemoteAwarePlatform(is_host), // This is the local host platform
42  m_option_group_platform_rsync(new OptionGroupPlatformRSync()),
43  m_option_group_platform_ssh(new OptionGroupPlatformSSH()),
44  m_option_group_platform_caching(new OptionGroupPlatformCaching()) {}
45 
46 /// Destructor.
47 ///
48 /// The destructor is virtual since this class is designed to be
49 /// inherited from by the plug-in instance.
51 
53  lldb_private::CommandInterpreter &interpreter) {
54  auto iter = m_options.find(&interpreter), end = m_options.end();
55  if (iter == end) {
56  std::unique_ptr<lldb_private::OptionGroupOptions> options(
57  new OptionGroupOptions());
58  options->Append(m_option_group_platform_rsync.get());
59  options->Append(m_option_group_platform_ssh.get());
60  options->Append(m_option_group_platform_caching.get());
61  m_options[&interpreter] = std::move(options);
62  }
63 
64  return m_options.at(&interpreter).get();
65 }
66 
67 Status
69  lldb::ModuleSP &exe_module_sp,
70  const FileSpecList *module_search_paths_ptr) {
71  Status error;
72  // Nothing special to do here, just use the actual file and architecture
73 
74  char exe_path[PATH_MAX];
75  ModuleSpec resolved_module_spec(module_spec);
76 
77  if (IsHost()) {
78  // If we have "ls" as the exe_file, resolve the executable location based
79  // on the current path variables
80  if (!FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec())) {
81  resolved_module_spec.GetFileSpec().GetPath(exe_path, sizeof(exe_path));
82  resolved_module_spec.GetFileSpec().SetFile(exe_path,
83  FileSpec::Style::native);
84  FileSystem::Instance().Resolve(resolved_module_spec.GetFileSpec());
85  }
86 
87  if (!FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec()))
88  FileSystem::Instance().ResolveExecutableLocation(
89  resolved_module_spec.GetFileSpec());
90 
91  // Resolve any executable within a bundle on MacOSX
92  Host::ResolveExecutableInBundle(resolved_module_spec.GetFileSpec());
93 
94  if (FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec()))
95  error.Clear();
96  else {
97  const uint32_t permissions = FileSystem::Instance().GetPermissions(
98  resolved_module_spec.GetFileSpec());
99  if (permissions && (permissions & eFilePermissionsEveryoneR) == 0)
101  "executable '%s' is not readable",
102  resolved_module_spec.GetFileSpec().GetPath().c_str());
103  else
105  "unable to find executable for '%s'",
106  resolved_module_spec.GetFileSpec().GetPath().c_str());
107  }
108  } else {
109  if (m_remote_platform_sp) {
110  error =
111  GetCachedExecutable(resolved_module_spec, exe_module_sp,
112  module_search_paths_ptr, *m_remote_platform_sp);
113  } else {
114  // We may connect to a process and use the provided executable (Don't use
115  // local $PATH).
116 
117  // Resolve any executable within a bundle on MacOSX
118  Host::ResolveExecutableInBundle(resolved_module_spec.GetFileSpec());
119 
120  if (FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec()))
121  error.Clear();
122  else
123  error.SetErrorStringWithFormat("the platform is not currently "
124  "connected, and '%s' doesn't exist in "
125  "the system root.",
126  exe_path);
127  }
128  }
129 
130  if (error.Success()) {
131  if (resolved_module_spec.GetArchitecture().IsValid()) {
132  error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
133  module_search_paths_ptr, nullptr, nullptr);
134  if (error.Fail()) {
135  // If we failed, it may be because the vendor and os aren't known. If
136  // that is the case, try setting them to the host architecture and give
137  // it another try.
138  llvm::Triple &module_triple =
139  resolved_module_spec.GetArchitecture().GetTriple();
140  bool is_vendor_specified =
141  (module_triple.getVendor() != llvm::Triple::UnknownVendor);
142  bool is_os_specified =
143  (module_triple.getOS() != llvm::Triple::UnknownOS);
144  if (!is_vendor_specified || !is_os_specified) {
145  const llvm::Triple &host_triple =
146  HostInfo::GetArchitecture(HostInfo::eArchKindDefault).GetTriple();
147 
148  if (!is_vendor_specified)
149  module_triple.setVendorName(host_triple.getVendorName());
150  if (!is_os_specified)
151  module_triple.setOSName(host_triple.getOSName());
152 
153  error = ModuleList::GetSharedModule(resolved_module_spec,
154  exe_module_sp, module_search_paths_ptr, nullptr, nullptr);
155  }
156  }
157 
158  // TODO find out why exe_module_sp might be NULL
159  if (error.Fail() || !exe_module_sp || !exe_module_sp->GetObjectFile()) {
160  exe_module_sp.reset();
162  "'%s' doesn't contain the architecture %s",
163  resolved_module_spec.GetFileSpec().GetPath().c_str(),
164  resolved_module_spec.GetArchitecture().GetArchitectureName());
165  }
166  } else {
167  // No valid architecture was specified, ask the platform for the
168  // architectures that we should be using (in the correct order) and see
169  // if we can find a match that way
170  StreamString arch_names;
172  idx, resolved_module_spec.GetArchitecture());
173  ++idx) {
174  error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
175  module_search_paths_ptr, nullptr, nullptr);
176  // Did we find an executable using one of the
177  if (error.Success()) {
178  if (exe_module_sp && exe_module_sp->GetObjectFile())
179  break;
180  else
181  error.SetErrorToGenericError();
182  }
183 
184  if (idx > 0)
185  arch_names.PutCString(", ");
186  arch_names.PutCString(
187  resolved_module_spec.GetArchitecture().GetArchitectureName());
188  }
189 
190  if (error.Fail() || !exe_module_sp) {
191  if (FileSystem::Instance().Readable(
192  resolved_module_spec.GetFileSpec())) {
194  "'%s' doesn't contain any '%s' platform architectures: %s",
195  resolved_module_spec.GetFileSpec().GetPath().c_str(),
196  GetPluginName().GetCString(), arch_names.GetData());
197  } else {
199  "'%s' is not readable",
200  resolved_module_spec.GetFileSpec().GetPath().c_str());
201  }
202  }
203  }
204  }
205 
206  return error;
207 }
208 
209 static uint32_t chown_file(Platform *platform, const char *path,
210  uint32_t uid = UINT32_MAX,
211  uint32_t gid = UINT32_MAX) {
212  if (!platform || !path || *path == 0)
213  return UINT32_MAX;
214 
215  if (uid == UINT32_MAX && gid == UINT32_MAX)
216  return 0; // pretend I did chown correctly - actually I just didn't care
217 
218  StreamString command;
219  command.PutCString("chown ");
220  if (uid != UINT32_MAX)
221  command.Printf("%d", uid);
222  if (gid != UINT32_MAX)
223  command.Printf(":%d", gid);
224  command.Printf("%s", path);
225  int status;
226  platform->RunShellCommand(command.GetData(), NULL, &status, NULL, NULL,
227  std::chrono::seconds(10));
228  return status;
229 }
230 
233  const lldb_private::FileSpec &destination, uint32_t uid,
234  uint32_t gid) {
236 
237  if (IsHost()) {
238  if (FileSpec::Equal(source, destination, true))
239  return Status();
240  // cp src dst
241  // chown uid:gid dst
242  std::string src_path(source.GetPath());
243  if (src_path.empty())
244  return Status("unable to get file path for source");
245  std::string dst_path(destination.GetPath());
246  if (dst_path.empty())
247  return Status("unable to get file path for destination");
248  StreamString command;
249  command.Printf("cp %s %s", src_path.c_str(), dst_path.c_str());
250  int status;
251  RunShellCommand(command.GetData(), NULL, &status, NULL, NULL,
252  std::chrono::seconds(10));
253  if (status != 0)
254  return Status("unable to perform copy");
255  if (uid == UINT32_MAX && gid == UINT32_MAX)
256  return Status();
257  if (chown_file(this, dst_path.c_str(), uid, gid) != 0)
258  return Status("unable to perform chown");
259  return Status();
260  } else if (m_remote_platform_sp) {
261  if (GetSupportsRSync()) {
262  std::string src_path(source.GetPath());
263  if (src_path.empty())
264  return Status("unable to get file path for source");
265  std::string dst_path(destination.GetPath());
266  if (dst_path.empty())
267  return Status("unable to get file path for destination");
268  StreamString command;
269  if (GetIgnoresRemoteHostname()) {
270  if (!GetRSyncPrefix())
271  command.Printf("rsync %s %s %s", GetRSyncOpts(), src_path.c_str(),
272  dst_path.c_str());
273  else
274  command.Printf("rsync %s %s %s%s", GetRSyncOpts(), src_path.c_str(),
275  GetRSyncPrefix(), dst_path.c_str());
276  } else
277  command.Printf("rsync %s %s %s:%s", GetRSyncOpts(), src_path.c_str(),
278  GetHostname(), dst_path.c_str());
279  if (log)
280  log->Printf("[PutFile] Running command: %s\n", command.GetData());
281  int retcode;
282  Host::RunShellCommand(command.GetData(), NULL, &retcode, NULL, NULL,
283  std::chrono::minutes(1));
284  if (retcode == 0) {
285  // Don't chown a local file for a remote system
286  // if (chown_file(this,dst_path.c_str(),uid,gid) != 0)
287  // return Status("unable to perform chown");
288  return Status();
289  }
290  // if we are still here rsync has failed - let's try the slow way before
291  // giving up
292  }
293  }
294  return Platform::PutFile(source, destination, uid, gid);
295 }
296 
298  const lldb_private::FileSpec &source, // remote file path
299  const lldb_private::FileSpec &destination) // local file path
300 {
302 
303  // Check the args, first.
304  std::string src_path(source.GetPath());
305  if (src_path.empty())
306  return Status("unable to get file path for source");
307  std::string dst_path(destination.GetPath());
308  if (dst_path.empty())
309  return Status("unable to get file path for destination");
310  if (IsHost()) {
311  if (FileSpec::Equal(source, destination, true))
312  return Status("local scenario->source and destination are the same file "
313  "path: no operation performed");
314  // cp src dst
315  StreamString cp_command;
316  cp_command.Printf("cp %s %s", src_path.c_str(), dst_path.c_str());
317  int status;
318  RunShellCommand(cp_command.GetData(), NULL, &status, NULL, NULL,
319  std::chrono::seconds(10));
320  if (status != 0)
321  return Status("unable to perform copy");
322  return Status();
323  } else if (m_remote_platform_sp) {
324  if (GetSupportsRSync()) {
325  StreamString command;
326  if (GetIgnoresRemoteHostname()) {
327  if (!GetRSyncPrefix())
328  command.Printf("rsync %s %s %s", GetRSyncOpts(), src_path.c_str(),
329  dst_path.c_str());
330  else
331  command.Printf("rsync %s %s%s %s", GetRSyncOpts(), GetRSyncPrefix(),
332  src_path.c_str(), dst_path.c_str());
333  } else
334  command.Printf("rsync %s %s:%s %s", GetRSyncOpts(),
335  m_remote_platform_sp->GetHostname(), src_path.c_str(),
336  dst_path.c_str());
337  if (log)
338  log->Printf("[GetFile] Running command: %s\n", command.GetData());
339  int retcode;
340  Host::RunShellCommand(command.GetData(), NULL, &retcode, NULL, NULL,
341  std::chrono::minutes(1));
342  if (retcode == 0)
343  return Status();
344  // If we are here, rsync has failed - let's try the slow way before
345  // giving up
346  }
347  // open src and dst
348  // read/write, read/write, read/write, ...
349  // close src
350  // close dst
351  if (log)
352  log->Printf("[GetFile] Using block by block transfer....\n");
353  Status error;
354  user_id_t fd_src = OpenFile(source, File::eOpenOptionRead,
355  lldb::eFilePermissionsFileDefault, error);
356 
357  if (fd_src == UINT64_MAX)
358  return Status("unable to open source file");
359 
360  uint32_t permissions = 0;
361  error = GetFilePermissions(source, permissions);
362 
363  if (permissions == 0)
364  permissions = lldb::eFilePermissionsFileDefault;
365 
366  user_id_t fd_dst = FileCache::GetInstance().OpenFile(
367  destination, File::eOpenOptionCanCreate | File::eOpenOptionWrite |
368  File::eOpenOptionTruncate,
369  permissions, error);
370 
371  if (fd_dst == UINT64_MAX) {
372  if (error.Success())
373  error.SetErrorString("unable to open destination file");
374  }
375 
376  if (error.Success()) {
377  lldb::DataBufferSP buffer_sp(new DataBufferHeap(1024, 0));
378  uint64_t offset = 0;
379  error.Clear();
380  while (error.Success()) {
381  const uint64_t n_read = ReadFile(fd_src, offset, buffer_sp->GetBytes(),
382  buffer_sp->GetByteSize(), error);
383  if (error.Fail())
384  break;
385  if (n_read == 0)
386  break;
387  if (FileCache::GetInstance().WriteFile(fd_dst, offset,
388  buffer_sp->GetBytes(), n_read,
389  error) != n_read) {
390  if (!error.Fail())
391  error.SetErrorString("unable to write to destination file");
392  break;
393  }
394  offset += n_read;
395  }
396  }
397  // Ignore the close error of src.
398  if (fd_src != UINT64_MAX)
399  CloseFile(fd_src, error);
400  // And close the dst file descriptot.
401  if (fd_dst != UINT64_MAX &&
402  !FileCache::GetInstance().CloseFile(fd_dst, error)) {
403  if (!error.Fail())
404  error.SetErrorString("unable to close destination file");
405  }
406  return error;
407  }
408  return Platform::GetFile(source, destination);
409 }
410 
412  StreamString stream;
413  if (GetSupportsRSync()) {
414  stream.PutCString("rsync");
415  if ((GetRSyncOpts() && *GetRSyncOpts()) ||
417  stream.Printf(", options: ");
418  if (GetRSyncOpts() && *GetRSyncOpts())
419  stream.Printf("'%s' ", GetRSyncOpts());
420  stream.Printf(", prefix: ");
421  if (GetRSyncPrefix() && *GetRSyncPrefix())
422  stream.Printf("'%s' ", GetRSyncPrefix());
424  stream.Printf("ignore remote-hostname ");
425  }
426  }
427  if (GetSupportsSSH()) {
428  stream.PutCString("ssh");
429  if (GetSSHOpts() && *GetSSHOpts())
430  stream.Printf(", options: '%s' ", GetSSHOpts());
431  }
433  stream.Printf("cache dir: %s", GetLocalCacheDirectory());
434  if (stream.GetSize())
435  return stream.GetString();
436  else
437  return "";
438 }
439 
440 const lldb::UnixSignalsSP &PlatformPOSIX::GetRemoteUnixSignals() {
442  return m_remote_platform_sp->GetRemoteUnixSignals();
443  return Platform::GetRemoteUnixSignals();
444 }
445 
447  Status error;
448  if (IsHost()) {
450  "can't connect to the host platform '%s', always connected",
451  GetPluginName().GetCString());
452  } else {
455  Platform::Create(ConstString("remote-gdb-server"), error);
456 
457  if (m_remote_platform_sp && error.Success())
458  error = m_remote_platform_sp->ConnectRemote(args);
459  else
460  error.SetErrorString("failed to create a 'remote-gdb-server' platform");
461 
462  if (error.Fail())
463  m_remote_platform_sp.reset();
464  }
465 
466  if (error.Success() && m_remote_platform_sp) {
467  if (m_option_group_platform_rsync.get() &&
470  if (m_option_group_platform_rsync->m_rsync) {
471  SetSupportsRSync(true);
472  SetRSyncOpts(m_option_group_platform_rsync->m_rsync_opts.c_str());
473  SetRSyncPrefix(m_option_group_platform_rsync->m_rsync_prefix.c_str());
475  m_option_group_platform_rsync->m_ignores_remote_hostname);
476  }
477  if (m_option_group_platform_ssh->m_ssh) {
478  SetSupportsSSH(true);
479  SetSSHOpts(m_option_group_platform_ssh->m_ssh_opts.c_str());
480  }
482  m_option_group_platform_caching->m_cache_dir.c_str());
483  }
484  }
485 
486  return error;
487 }
488 
490  Status error;
491 
492  if (IsHost()) {
494  "can't disconnect from the host platform '%s', always connected",
495  GetPluginName().GetCString());
496  } else {
498  error = m_remote_platform_sp->DisconnectRemote();
499  else
500  error.SetErrorString("the platform is not currently connected");
501  }
502  return error;
503 }
504 
505 lldb::ProcessSP PlatformPOSIX::Attach(ProcessAttachInfo &attach_info,
506  Debugger &debugger, Target *target,
507  Status &error) {
508  lldb::ProcessSP process_sp;
510 
511  if (IsHost()) {
512  if (target == NULL) {
513  TargetSP new_target_sp;
514 
515  error = debugger.GetTargetList().CreateTarget(
516  debugger, "", "", eLoadDependentsNo, NULL, new_target_sp);
517  target = new_target_sp.get();
518  if (log)
519  log->Printf("PlatformPOSIX::%s created new target", __FUNCTION__);
520  } else {
521  error.Clear();
522  if (log)
523  log->Printf("PlatformPOSIX::%s target already existed, setting target",
524  __FUNCTION__);
525  }
526 
527  if (target && error.Success()) {
528  debugger.GetTargetList().SetSelectedTarget(target);
529  if (log) {
530  ModuleSP exe_module_sp = target->GetExecutableModule();
531  log->Printf("PlatformPOSIX::%s set selected target to %p %s",
532  __FUNCTION__, (void *)target,
533  exe_module_sp
534  ? exe_module_sp->GetFileSpec().GetPath().c_str()
535  : "<null>");
536  }
537 
538  process_sp =
539  target->CreateProcess(attach_info.GetListenerForProcess(debugger),
540  attach_info.GetProcessPluginName(), NULL);
541 
542  if (process_sp) {
543  ListenerSP listener_sp = attach_info.GetHijackListener();
544  if (listener_sp == nullptr) {
545  listener_sp =
546  Listener::MakeListener("lldb.PlatformPOSIX.attach.hijack");
547  attach_info.SetHijackListener(listener_sp);
548  }
549  process_sp->HijackProcessEvents(listener_sp);
550  error = process_sp->Attach(attach_info);
551  }
552  }
553  } else {
555  process_sp =
556  m_remote_platform_sp->Attach(attach_info, debugger, target, error);
557  else
558  error.SetErrorString("the platform is not currently connected");
559  }
560  return process_sp;
561 }
562 
563 lldb::ProcessSP
565  Target *target, // Can be NULL, if NULL create a new
566  // target, else use existing one
567  Status &error) {
568  ProcessSP process_sp;
569 
570  if (IsHost()) {
571  // We are going to hand this process off to debugserver which will be in
572  // charge of setting the exit status. However, we still need to reap it
573  // from lldb. So, make sure we use a exit callback which does not set exit
574  // status.
575  const bool monitor_signals = false;
576  launch_info.SetMonitorProcessCallback(
577  &ProcessLaunchInfo::NoOpMonitorCallback, monitor_signals);
578  process_sp = Platform::DebugProcess(launch_info, debugger, target, error);
579  } else {
581  process_sp = m_remote_platform_sp->DebugProcess(launch_info, debugger,
582  target, error);
583  else
584  error.SetErrorString("the platform is not currently connected");
585  }
586  return process_sp;
587 }
588 
590  m_trap_handlers.push_back(ConstString("_sigtramp"));
591 }
592 
594  lldb_private::Process *process, const char *expr_cstr,
595  llvm::StringRef expr_prefix, lldb::ValueObjectSP &result_valobj_sp) {
596  DynamicLoader *loader = process->GetDynamicLoader();
597  if (loader) {
598  Status error = loader->CanLoadImage();
599  if (error.Fail())
600  return error;
601  }
602 
603  ThreadSP thread_sp(process->GetThreadList().GetExpressionExecutionThread());
604  if (!thread_sp)
605  return Status("Selected thread isn't valid");
606 
607  StackFrameSP frame_sp(thread_sp->GetStackFrameAtIndex(0));
608  if (!frame_sp)
609  return Status("Frame 0 isn't valid");
610 
611  ExecutionContext exe_ctx;
612  frame_sp->CalculateExecutionContext(exe_ctx);
613  EvaluateExpressionOptions expr_options;
614  expr_options.SetUnwindOnError(true);
615  expr_options.SetIgnoreBreakpoints(true);
618  expr_options.SetTrapExceptions(false); // dlopen can't throw exceptions, so
619  // don't do the work to trap them.
620  expr_options.SetTimeout(process->GetUtilityExpressionTimeout());
621 
622  Status expr_error;
623  ExpressionResults result =
624  UserExpression::Evaluate(exe_ctx, expr_options, expr_cstr, expr_prefix,
625  result_valobj_sp, expr_error);
626  if (result != eExpressionCompleted)
627  return expr_error;
628 
629  if (result_valobj_sp->GetError().Fail())
630  return result_valobj_sp->GetError();
631  return Status();
632 }
633 
634 std::unique_ptr<UtilityFunction>
636  Status &error) {
637  // Remember to prepend this with the prefix from
638  // GetLibdlFunctionDeclarations. The returned values are all in
639  // __lldb_dlopen_result for consistency. The wrapper returns a void * but
640  // doesn't use it because UtilityFunctions don't work with void returns at
641  // present.
642  static const char *dlopen_wrapper_code = R"(
643  struct __lldb_dlopen_result {
644  void *image_ptr;
645  const char *error_str;
646  };
647 
648  extern void *memcpy(void *, const void *, size_t size);
649  extern size_t strlen(const char *);
650 
651 
652  void * __lldb_dlopen_wrapper (const char *name,
653  const char *path_strings,
654  char *buffer,
655  __lldb_dlopen_result *result_ptr)
656  {
657  // This is the case where the name is the full path:
658  if (!path_strings) {
659  result_ptr->image_ptr = dlopen(name, 2);
660  if (result_ptr->image_ptr)
661  result_ptr->error_str = nullptr;
662  return nullptr;
663  }
664 
665  // This is the case where we have a list of paths:
666  size_t name_len = strlen(name);
667  while (path_strings && path_strings[0] != '\0') {
668  size_t path_len = strlen(path_strings);
669  memcpy((void *) buffer, (void *) path_strings, path_len);
670  buffer[path_len] = '/';
671  char *target_ptr = buffer+path_len+1;
672  memcpy((void *) target_ptr, (void *) name, name_len + 1);
673  result_ptr->image_ptr = dlopen(buffer, 2);
674  if (result_ptr->image_ptr) {
675  result_ptr->error_str = nullptr;
676  break;
677  }
678  result_ptr->error_str = dlerror();
679  path_strings = path_strings + path_len + 1;
680  }
681  return nullptr;
682  }
683  )";
684 
685  static const char *dlopen_wrapper_name = "__lldb_dlopen_wrapper";
686  Process *process = exe_ctx.GetProcessSP().get();
687  // Insert the dlopen shim defines into our generic expression:
688  std::string expr(GetLibdlFunctionDeclarations(process));
689  expr.append(dlopen_wrapper_code);
690  Status utility_error;
691  DiagnosticManager diagnostics;
692 
693  std::unique_ptr<UtilityFunction> dlopen_utility_func_up(process
694  ->GetTarget().GetUtilityFunctionForLanguage(expr.c_str(),
696  dlopen_wrapper_name,
697  utility_error));
698  if (utility_error.Fail()) {
699  error.SetErrorStringWithFormat("dlopen error: could not make utility"
700  "function: %s", utility_error.AsCString());
701  return nullptr;
702  }
703  if (!dlopen_utility_func_up->Install(diagnostics, exe_ctx)) {
704  error.SetErrorStringWithFormat("dlopen error: could not install utility"
705  "function: %s",
706  diagnostics.GetString().c_str());
707  return nullptr;
708  }
709 
710  Value value;
711  ValueList arguments;
712  FunctionCaller *do_dlopen_function = nullptr;
713 
714  // Fetch the clang types we will need:
716 
717  CompilerType clang_void_pointer_type
719  CompilerType clang_char_pointer_type
721 
722  // We are passing four arguments, the basename, the list of places to look,
723  // a buffer big enough for all the path + name combos, and
724  // a pointer to the storage we've made for the result:
725  value.SetValueType(Value::eValueTypeScalar);
726  value.SetCompilerType(clang_void_pointer_type);
727  arguments.PushValue(value);
728  value.SetCompilerType(clang_char_pointer_type);
729  arguments.PushValue(value);
730  arguments.PushValue(value);
731  arguments.PushValue(value);
732 
733  do_dlopen_function = dlopen_utility_func_up->MakeFunctionCaller(
734  clang_void_pointer_type, arguments, exe_ctx.GetThreadSP(), utility_error);
735  if (utility_error.Fail()) {
736  error.SetErrorStringWithFormat("dlopen error: could not make function"
737  "caller: %s", utility_error.AsCString());
738  return nullptr;
739  }
740 
741  do_dlopen_function = dlopen_utility_func_up->GetFunctionCaller();
742  if (!do_dlopen_function) {
743  error.SetErrorString("dlopen error: could not get function caller.");
744  return nullptr;
745  }
746 
747  // We made a good utility function, so cache it in the process:
748  return dlopen_utility_func_up;
749 }
750 
752  const lldb_private::FileSpec &remote_file,
753  const std::vector<std::string> *paths,
754  lldb_private::Status &error,
755  lldb_private::FileSpec *loaded_image) {
756  if (loaded_image)
757  loaded_image->Clear();
758 
759  std::string path;
760  path = remote_file.GetPath();
761 
762  ThreadSP thread_sp = process->GetThreadList().GetExpressionExecutionThread();
763  if (!thread_sp) {
764  error.SetErrorString("dlopen error: no thread available to call dlopen.");
766  }
767 
768  DiagnosticManager diagnostics;
769 
770  ExecutionContext exe_ctx;
771  thread_sp->CalculateExecutionContext(exe_ctx);
772 
773  Status utility_error;
774  UtilityFunction *dlopen_utility_func;
775  ValueList arguments;
776  FunctionCaller *do_dlopen_function = nullptr;
777 
778  // The UtilityFunction is held in the Process. Platforms don't track the
779  // lifespan of the Targets that use them, we can't put this in the Platform.
780  dlopen_utility_func = process->GetLoadImageUtilityFunction(
781  this, [&]() -> std::unique_ptr<UtilityFunction> {
782  return MakeLoadImageUtilityFunction(exe_ctx, error);
783  });
784  // If we couldn't make it, the error will be in error, so we can exit here.
785  if (!dlopen_utility_func)
787 
788  do_dlopen_function = dlopen_utility_func->GetFunctionCaller();
789  if (!do_dlopen_function) {
790  error.SetErrorString("dlopen error: could not get function caller.");
792  }
793  arguments = do_dlopen_function->GetArgumentValues();
794 
795  // Now insert the path we are searching for and the result structure into the
796  // target.
797  uint32_t permissions = ePermissionsReadable|ePermissionsWritable;
798  size_t path_len = path.size() + 1;
799  lldb::addr_t path_addr = process->AllocateMemory(path_len,
800  permissions,
801  utility_error);
802  if (path_addr == LLDB_INVALID_ADDRESS) {
803  error.SetErrorStringWithFormat("dlopen error: could not allocate memory"
804  "for path: %s", utility_error.AsCString());
806  }
807 
808  // Make sure we deallocate the input string memory:
809  CleanUp path_cleanup([process, path_addr] {
810  process->DeallocateMemory(path_addr);
811  });
812 
813  process->WriteMemory(path_addr, path.c_str(), path_len, utility_error);
814  if (utility_error.Fail()) {
815  error.SetErrorStringWithFormat("dlopen error: could not write path string:"
816  " %s", utility_error.AsCString());
818  }
819 
820  // Make space for our return structure. It is two pointers big: the token
821  // and the error string.
822  const uint32_t addr_size = process->GetAddressByteSize();
823  lldb::addr_t return_addr = process->CallocateMemory(2*addr_size,
824  permissions,
825  utility_error);
826  if (utility_error.Fail()) {
827  error.SetErrorStringWithFormat("dlopen error: could not allocate memory"
828  "for path: %s", utility_error.AsCString());
830  }
831 
832  // Make sure we deallocate the result structure memory
833  CleanUp return_cleanup([process, return_addr] {
834  process->DeallocateMemory(return_addr);
835  });
836 
837  // This will be the address of the storage for paths, if we are using them,
838  // or nullptr to signal we aren't.
839  lldb::addr_t path_array_addr = 0x0;
840  llvm::Optional<CleanUp> path_array_cleanup;
841 
842  // This is the address to a buffer large enough to hold the largest path
843  // conjoined with the library name we're passing in. This is a convenience
844  // to avoid having to call malloc in the dlopen function.
845  lldb::addr_t buffer_addr = 0x0;
846  llvm::Optional<CleanUp> buffer_cleanup;
847 
848  // Set the values into our args and write them to the target:
849  if (paths != nullptr) {
850  // First insert the paths into the target. This is expected to be a
851  // continuous buffer with the strings laid out null terminated and
852  // end to end with an empty string terminating the buffer.
853  // We also compute the buffer's required size as we go.
854  size_t buffer_size = 0;
855  std::string path_array;
856  for (auto path : *paths) {
857  // Don't insert empty paths, they will make us abort the path
858  // search prematurely.
859  if (path.empty())
860  continue;
861  size_t path_size = path.size();
862  path_array.append(path);
863  path_array.push_back('\0');
864  if (path_size > buffer_size)
865  buffer_size = path_size;
866  }
867  path_array.push_back('\0');
868 
869  path_array_addr = process->AllocateMemory(path_array.size(),
870  permissions,
871  utility_error);
872  if (path_array_addr == LLDB_INVALID_ADDRESS) {
873  error.SetErrorStringWithFormat("dlopen error: could not allocate memory"
874  "for path array: %s",
875  utility_error.AsCString());
877  }
878 
879  // Make sure we deallocate the paths array.
880  path_array_cleanup.emplace([process, path_array_addr] {
881  process->DeallocateMemory(path_array_addr);
882  });
883 
884  process->WriteMemory(path_array_addr, path_array.data(),
885  path_array.size(), utility_error);
886 
887  if (utility_error.Fail()) {
888  error.SetErrorStringWithFormat("dlopen error: could not write path array:"
889  " %s", utility_error.AsCString());
891  }
892  // Now make spaces in the target for the buffer. We need to add one for
893  // the '/' that the utility function will insert and one for the '\0':
894  buffer_size += path.size() + 2;
895 
896  buffer_addr = process->AllocateMemory(buffer_size,
897  permissions,
898  utility_error);
899  if (buffer_addr == LLDB_INVALID_ADDRESS) {
900  error.SetErrorStringWithFormat("dlopen error: could not allocate memory"
901  "for buffer: %s",
902  utility_error.AsCString());
904  }
905 
906  // Make sure we deallocate the buffer memory:
907  buffer_cleanup.emplace([process, buffer_addr] {
908  process->DeallocateMemory(buffer_addr);
909  });
910  }
911 
912  arguments.GetValueAtIndex(0)->GetScalar() = path_addr;
913  arguments.GetValueAtIndex(1)->GetScalar() = path_array_addr;
914  arguments.GetValueAtIndex(2)->GetScalar() = buffer_addr;
915  arguments.GetValueAtIndex(3)->GetScalar() = return_addr;
916 
917  lldb::addr_t func_args_addr = LLDB_INVALID_ADDRESS;
918 
919  diagnostics.Clear();
920  if (!do_dlopen_function->WriteFunctionArguments(exe_ctx,
921  func_args_addr,
922  arguments,
923  diagnostics)) {
924  error.SetErrorStringWithFormat("dlopen error: could not write function "
925  "arguments: %s",
926  diagnostics.GetString().c_str());
928  }
929 
930  // Make sure we clean up the args structure. We can't reuse it because the
931  // Platform lives longer than the process and the Platforms don't get a
932  // signal to clean up cached data when a process goes away.
933  CleanUp args_cleanup([do_dlopen_function, &exe_ctx, func_args_addr] {
934  do_dlopen_function->DeallocateFunctionResults(exe_ctx, func_args_addr);
935  });
936 
937  // Now run the caller:
940  options.SetLanguage(eLanguageTypeC_plus_plus);
941  options.SetIgnoreBreakpoints(true);
942  options.SetUnwindOnError(true);
943  options.SetTrapExceptions(false); // dlopen can't throw exceptions, so
944  // don't do the work to trap them.
945  options.SetTimeout(process->GetUtilityExpressionTimeout());
946  options.SetIsForUtilityExpr(true);
947 
948  Value return_value;
949  // Fetch the clang types we will need:
951 
952  CompilerType clang_void_pointer_type
954 
955  return_value.SetCompilerType(clang_void_pointer_type);
956 
957  ExpressionResults results = do_dlopen_function->ExecuteFunction(
958  exe_ctx, &func_args_addr, options, diagnostics, return_value);
959  if (results != eExpressionCompleted) {
960  error.SetErrorStringWithFormat("dlopen error: failed executing "
961  "dlopen wrapper function: %s",
962  diagnostics.GetString().c_str());
964  }
965 
966  // Read the dlopen token from the return area:
967  lldb::addr_t token = process->ReadPointerFromMemory(return_addr,
968  utility_error);
969  if (utility_error.Fail()) {
970  error.SetErrorStringWithFormat("dlopen error: could not read the return "
971  "struct: %s", utility_error.AsCString());
973  }
974 
975  // The dlopen succeeded!
976  if (token != 0x0) {
977  if (loaded_image && buffer_addr != 0x0)
978  {
979  // Capture the image which was loaded. We leave it in the buffer on
980  // exit from the dlopen function, so we can just read it from there:
981  std::string name_string;
982  process->ReadCStringFromMemory(buffer_addr, name_string, utility_error);
983  if (utility_error.Success())
984  loaded_image->SetFile(name_string, llvm::sys::path::Style::posix);
985  }
986  return process->AddImageToken(token);
987  }
988 
989  // We got an error, lets read in the error string:
990  std::string dlopen_error_str;
991  lldb::addr_t error_addr
992  = process->ReadPointerFromMemory(return_addr + addr_size, utility_error);
993  if (utility_error.Fail()) {
994  error.SetErrorStringWithFormat("dlopen error: could not read error string: "
995  "%s", utility_error.AsCString());
997  }
998 
999  size_t num_chars = process->ReadCStringFromMemory(error_addr + addr_size,
1000  dlopen_error_str,
1001  utility_error);
1002  if (utility_error.Success() && num_chars > 0)
1003  error.SetErrorStringWithFormat("dlopen error: %s",
1004  dlopen_error_str.c_str());
1005  else
1006  error.SetErrorStringWithFormat("dlopen failed for unknown reasons.");
1007 
1008  return LLDB_INVALID_IMAGE_TOKEN;
1009 }
1010 
1012  uint32_t image_token) {
1013  const addr_t image_addr = process->GetImagePtrFromToken(image_token);
1014  if (image_addr == LLDB_INVALID_ADDRESS)
1015  return Status("Invalid image token");
1016 
1017  StreamString expr;
1018  expr.Printf("dlclose((void *)0x%" PRIx64 ")", image_addr);
1019  llvm::StringRef prefix = GetLibdlFunctionDeclarations(process);
1020  lldb::ValueObjectSP result_valobj_sp;
1021  Status error = EvaluateLibdlExpression(process, expr.GetData(), prefix,
1022  result_valobj_sp);
1023  if (error.Fail())
1024  return error;
1025 
1026  if (result_valobj_sp->GetError().Fail())
1027  return result_valobj_sp->GetError();
1028 
1029  Scalar scalar;
1030  if (result_valobj_sp->ResolveValue(scalar)) {
1031  if (scalar.UInt(1))
1032  return Status("expression failed: \"%s\"", expr.GetData());
1033  process->ResetImageToken(image_token);
1034  }
1035  return Status();
1036 }
1037 
1038 llvm::StringRef
1040  return R"(
1041  extern "C" void* dlopen(const char*, int);
1042  extern "C" void* dlsym(void*, const char*);
1043  extern "C" int dlclose(void*);
1044  extern "C" char* dlerror(void);
1045  )";
1046 }
1047 
1049  Status &error) {
1051  return m_remote_platform_sp->ConnectToWaitingProcesses(debugger, error);
1052  return Platform::ConnectToWaitingProcesses(debugger, error);
1053 }
1054 
1056  if (basename.IsEmpty())
1057  return basename;
1058 
1059  StreamString stream;
1060  stream.Printf("lib%s.so", basename.GetCString());
1061  return ConstString(stream.GetString());
1062 }
lldb::ExpressionResults ExecuteFunction(ExecutionContext &exe_ctx, lldb::addr_t *args_addr_ptr, const EvaluateExpressionOptions &options, DiagnosticManager &diagnostic_manager, Value &results)
Run the function this FunctionCaller was created with.
void SetIgnoreBreakpoints(bool ignore=false)
Definition: Target.h:289
A class to manage flag bits.
Definition: Debugger.h:82
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
Definition: Stream.cpp:61
const lldb::ThreadSP & GetThreadSP() const
Get accessor to get the thread shared pointer.
virtual void SetSSHOpts(const char *opts)
Definition: Platform.h:613
A command line argument class.
Definition: Args.h:32
void SetExecutionPolicy(ExecutionPolicy policy=eExecutionPolicyAlways)
Definition: Target.h:260
virtual const char * GetLocalCacheDirectory()
Definition: Platform.cpp:1361
Enumerations for broadcasting.
Definition: SBLaunchInfo.h:14
void DeallocateFunctionResults(ExecutionContext &exe_ctx, lldb::addr_t args_addr)
Deallocate the arguments structure.
lldb::ProcessSP DebugProcess(lldb_private::ProcessLaunchInfo &launch_info, lldb_private::Debugger &debugger, lldb_private::Target *target, lldb_private::Status &error) override
Subclasses do not need to implement this function as it uses the Platform::LaunchProcess() followed b...
lldb::ProcessSP Attach(lldb_private::ProcessAttachInfo &attach_info, lldb_private::Debugger &debugger, lldb_private::Target *target, lldb_private::Status &error) override
Attach to an existing process using a process ID.
virtual void SetLocalCacheDirectory(const char *local)
Definition: Platform.cpp:1357
virtual const char * GetRSyncPrefix()
Definition: Platform.h:601
FunctionCaller * GetFunctionCaller()
uint32_t DoLoadImage(lldb_private::Process *process, const lldb_private::FileSpec &remote_file, const std::vector< std::string > *paths, lldb_private::Status &error, lldb_private::FileSpec *loaded_image) override
void SetUnwindOnError(bool unwind=false)
Definition: Target.h:285
const lldb::ProcessSP & CreateProcess(lldb::ListenerSP listener_sp, llvm::StringRef plugin_name, const FileSpec *crash_file)
Definition: Target.cpp:195
bool IsHost() const
Definition: Platform.h:450
A file utility class.
Definition: FileSpec.h:55
ThreadList & GetThreadList()
Definition: Process.h:2045
size_t ReadCStringFromMemory(lldb::addr_t vm_addr, char *cstr, size_t cstr_max_len, Status &error)
Read a NULL terminated C string from memory.
Definition: Process.cpp:2080
#define LIBLLDB_LOG_PLATFORM
Definition: Logging.h:39
Value * GetValueAtIndex(size_t idx)
Definition: Value.cpp:701
void SetValueType(ValueType value_type)
Definition: Value.h:154
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
void Clear()
Clears the object state.
Definition: FileSpec.cpp:285
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:329
lldb_private::Status GetFile(const lldb_private::FileSpec &source, const lldb_private::FileSpec &destination) override
Status CreateTarget(Debugger &debugger, llvm::StringRef user_exe_path, llvm::StringRef triple_str, LoadDependentFiles get_dependent_modules, const OptionGroupPlatform *platform_options, lldb::TargetSP &target_sp)
Create a new Target.
A subclass of DataBuffer that stores a data buffer on the heap.
const char * GetProcessPluginName() const
Definition: Process.h:140
llvm::Triple & GetTriple()
Architecture triple accessor.
Definition: ArchSpec.h:431
std::map< lldb_private::CommandInterpreter *, std::unique_ptr< lldb_private::OptionGroupOptions > > m_options
Definition: PlatformPOSIX.h:93
Status GetCachedExecutable(ModuleSpec &module_spec, lldb::ModuleSP &module_sp, const FileSpecList *module_search_paths_ptr, Platform &remote_platform)
Definition: Platform.cpp:1515
lldb_private::Status DisconnectRemote() override
virtual void SetSupportsSSH(bool flag)
Definition: Platform.h:609
virtual void SetRSyncPrefix(const char *prefix)
Definition: Platform.h:603
bool WriteFunctionArguments(ExecutionContext &exe_ctx, lldb::addr_t &args_addr_ref, DiagnosticManager &diagnostic_manager)
Insert the default function argument struct.
const char * GetArchitectureName() const
Returns a static string representing the current architecture.
Definition: ArchSpec.cpp:591
lldb::addr_t AllocateMemory(size_t size, uint32_t permissions, Status &error)
The public interface to allocating memory in the process.
Definition: Process.cpp:2344
#define UINT32_MAX
Definition: lldb-defines.h:31
std::unique_ptr< lldb_private::OptionGroupPlatformCaching > m_option_group_platform_caching
Definition: PlatformPOSIX.h:89
#define LLDB_INVALID_ADDRESS
Invalid value definitions.
Definition: lldb-defines.h:85
void SetTimeout(const Timeout< std::micro > &timeout)
Definition: Target.h:306
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
lldb_private::ConstString GetFullNameForDylib(lldb_private::ConstString basename) override
void SetErrorToGenericError()
Set the current error to a generic error.
Definition: Status.cpp:231
bool IsRemote() const
Definition: Platform.h:454
lldb::ListenerSP GetListenerForProcess(Debugger &debugger)
Definition: Process.cpp:2786
virtual llvm::StringRef GetLibdlFunctionDeclarations(lldb_private::Process *process)
Status DeallocateMemory(lldb::addr_t ptr)
The public interface to deallocating memory in the process.
Definition: Process.cpp:2415
void Clear()
Clear the object state.
Definition: Status.cpp:167
virtual const char * GetSSHOpts()
Definition: Platform.h:611
Encapsulates a function that can be called.
uint32_t GetAddressByteSize() const
Definition: Process.cpp:3370
llvm::StringRef GetString() const
PlatformPOSIX(bool is_host)
Default Constructor.
std::string GetString(char separator='\n')
void SetErrorString(llvm::StringRef err_str)
Set the current error string to err_str.
Definition: Status.cpp:241
A plug-in interface definition class for debugging a process.
Definition: Process.h:353
lldb::ModuleSP GetExecutableModule()
Gets the module for the main executable.
Definition: Target.cpp:1380
size_t WriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size, Status &error)
Write memory to a process.
Definition: Process.cpp:2208
virtual void SetIgnoresRemoteHostname(bool flag)
Definition: Platform.h:617
A plug-in interface definition class for debug platform that includes many platform abilities such as...
Definition: Platform.h:67
virtual lldb_private::Status RunShellCommand(const char *command, const FileSpec &working_dir, int *status_ptr, int *signo_ptr, std::string *command_output, const Timeout< std::micro > &timeout)
Definition: Platform.cpp:1329
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition: Stream.cpp:106
size_t ConnectToWaitingProcesses(lldb_private::Debugger &debugger, lldb_private::Status &error) override
Connect to all processes waiting for a debugger to attach.
bool Success() const
Test for success condition.
Definition: Status.cpp:287
TargetList & GetTargetList()
Get accessor for the target list.
Definition: Debugger.h:180
const lldb::ProcessSP & GetProcessSP() const
Get accessor to get the process shared pointer.
size_t AddImageToken(lldb::addr_t image_ptr)
Definition: Process.cpp:5784
ValueList GetArgumentValues() const
void SetHijackListener(const lldb::ListenerSP &listener_sp)
Definition: Process.h:167
virtual bool GetSupportsRSync()
Definition: Platform.h:593
lldb_private::Status UnloadImage(lldb_private::Process *process, uint32_t image_token) override
unsigned int UInt(unsigned int fail_value=0) const
Definition: Scalar.cpp:1452
CompilerType GetPointerType() const
FileSpec & GetFileSpec()
Definition: ModuleSpec.h:75
const lldb::UnixSignalsSP & GetRemoteUnixSignals() override
virtual DynamicLoader * GetDynamicLoader()
Get the dynamic loader plug-in for this process.
Definition: Process.cpp:2687
virtual bool GetIgnoresRemoteHostname()
Definition: Platform.h:615
UtilityFunction * GetLoadImageUtilityFunction(Platform *platform, llvm::function_ref< std::unique_ptr< UtilityFunction >()> factory)
Get the cached UtilityFunction that assists in loading binary images into the process.
Definition: Process.cpp:6001
lldb_private::Status ResolveExecutable(const lldb_private::ModuleSpec &module_spec, lldb::ModuleSP &module_sp, const lldb_private::FileSpecList *module_search_paths_ptr) override
A plug-in interface definition class for dynamic loaders.
Definition: DynamicLoader.h:64
ClangASTContext * GetScratchClangASTContext(bool create_on_demand=true)
Definition: Target.cpp:2299
#define LLDB_INVALID_IMAGE_TOKEN
Definition: lldb-defines.h:88
std::chrono::seconds GetUtilityExpressionTimeout() const
Definition: Process.cpp:287
void SetLanguage(lldb::LanguageType language)
Definition: Target.h:266
lldb::addr_t ReadPointerFromMemory(lldb::addr_t vm_addr, Status &error)
Definition: Process.cpp:2172
ArchSpec & GetArchitecture()
Definition: ModuleSpec.h:111
lldb::addr_t CallocateMemory(size_t size, uint32_t permissions, Status &error)
The public interface to allocating memory in the process, this also clears the allocated memory...
Definition: Process.cpp:2367
lldb_private::Status ConnectRemote(lldb_private::Args &args) override
Target & GetTarget()
Get the target object pointer for this module.
Definition: Process.h:1194
std::unique_ptr< lldb_private::OptionGroupPlatformRSync > m_option_group_platform_rsync
Definition: PlatformPOSIX.h:85
Run a cleanup function on scope exit unless it&#39;s explicitly disabled.
Definition: CleanUp.h:18
static uint32_t chown_file(Platform *platform, const char *path, uint32_t uid=UINT32_MAX, uint32_t gid=UINT32_MAX)
uint64_t addr_t
Definition: lldb-types.h:83
A uniqued constant string class.
Definition: ConstString.h:38
bool Fail() const
Test for error condition.
Definition: Status.cpp:181
const char * GetCString() const
Get the string value as a C string.
Definition: ConstString.h:247
lldb_private::OptionGroupOptions * GetConnectionOptions(lldb_private::CommandInterpreter &interpreter) override
lldb_private::Status EvaluateLibdlExpression(lldb_private::Process *process, const char *expr_cstr, llvm::StringRef expr_prefix, lldb::ValueObjectSP &result_valobj_sp)
virtual Status CanLoadImage()=0
Ask if it is ok to try and load or unload an shared library (image).
Log * GetLogIfAnyCategoriesSet(uint32_t mask)
Definition: Logging.cpp:61
virtual const char * GetRSyncOpts()
Definition: Platform.h:597
char * basename(char *path)
Definition: SBAddress.h:15
lldb_private::Status PutFile(const lldb_private::FileSpec &source, const lldb_private::FileSpec &destination, uint32_t uid=UINT32_MAX, uint32_t gid=UINT32_MAX) override
uint32_t SetSelectedTarget(Target *target)
Definition: TargetList.cpp:601
virtual void SetSupportsRSync(bool flag)
Definition: Platform.h:595
#define PATH_MAX
~PlatformPOSIX() override
Destructor.
virtual bool GetSupportsSSH()
Definition: Platform.h:607
std::unique_ptr< lldb_private::OptionGroupPlatformSSH > m_option_group_platform_ssh
Definition: PlatformPOSIX.h:87
A base class for platforms which automatically want to be able to forward operations to a remote plat...
int SetErrorStringWithFormat(const char *format,...) __attribute__((format(printf
Set the current error string to a formatted error string.
Definition: Status.cpp:255
void SetCompilerType(const CompilerType &compiler_type)
Definition: Value.cpp:268
void SetFile(llvm::StringRef path, Style style)
Change the file specified with a new path.
Definition: FileSpec.cpp:198
virtual bool GetSupportedArchitectureAtIndex(uint32_t idx, ArchSpec &arch)=0
Get the platform&#39;s supported architectures in the order in which they should be searched.
lldb::addr_t GetImagePtrFromToken(size_t token) const
Definition: Process.cpp:5789
void CalculateTrapHandlerSymbolNames() override
Ask the Platform subclass to fill in the list of trap handler names.
virtual ConstString GetPluginName()=0
lldb::user_id_t OpenFile(const FileSpec &file_spec, uint32_t flags, uint32_t mode, Status &error) override
const Scalar & GetScalar() const
Definition: Value.h:178
const char * AsCString(const char *default_error_str="unknown error") const
Get the error string associated with the current error.
Definition: Status.cpp:130
Status GetFilePermissions(const FileSpec &file_spec, uint32_t &file_permissions) override
"lldb/Expression/UtilityFunction.h" Encapsulates a bit of source code that provides a function that i...
ValueType GetError() const
Access the error value.
Definition: Status.cpp:174
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
Definition: FileSpec.cpp:376
virtual void SetRSyncOpts(const char *opts)
Definition: Platform.h:599
#define UINT64_MAX
Definition: lldb-defines.h:35
void SetMonitorProcessCallback(const Host::MonitorChildProcessCallback &callback, bool monitor_signals)
void Printf(const char *format,...) __attribute__((format(printf
Definition: Log.cpp:113
std::vector< ConstString > m_trap_handlers
Definition: Platform.h:872
bool IsEmpty() const
Test for empty string.
Definition: ConstString.h:340
std::string GetPlatformSpecificConnectionInformation() override
CompilerType GetBasicType(lldb::BasicType type)
lldb::ListenerSP GetHijackListener() const
Definition: Process.h:165
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
void ResetImageToken(size_t token)
Definition: Process.cpp:5795
lldb::ThreadSP GetExpressionExecutionThread()
Definition: ThreadList.cpp:59
An error handling class.
Definition: Status.h:44
void PushValue(const Value &value)
Definition: Value.cpp:697
std::unique_ptr< lldb_private::UtilityFunction > MakeLoadImageUtilityFunction(lldb_private::ExecutionContext &exe_ctx, lldb_private::Status &error)