35#include "llvm/ADT/ScopeExit.h"
58 std::unique_ptr<lldb_private::OptionGroupOptions> options(
63 m_options[&interpreter] = std::move(options);
72 if (!platform || !path || *path == 0)
83 command.
Printf(
":%d", gid);
84 command.
Printf(
"%s", path);
87 nullptr, std::chrono::seconds(10));
98 if (source == destination)
102 std::string src_path(source.
GetPath());
103 if (src_path.empty())
104 return Status(
"unable to get file path for source");
105 std::string dst_path(destination.
GetPath());
106 if (dst_path.empty())
107 return Status(
"unable to get file path for destination");
109 command.
Printf(
"cp %s %s", src_path.c_str(), dst_path.c_str());
112 std::chrono::seconds(10));
114 return Status(
"unable to perform copy");
117 if (
chown_file(
this, dst_path.c_str(), uid, gid) != 0)
118 return Status(
"unable to perform chown");
122 std::string src_path(source.
GetPath());
123 if (src_path.empty())
124 return Status(
"unable to get file path for source");
125 std::string dst_path(destination.
GetPath());
126 if (dst_path.empty())
127 return Status(
"unable to get file path for destination");
142 nullptr, std::chrono::minutes(1));
163 std::string src_path(source.
GetPath());
164 if (src_path.empty())
165 return Status(
"unable to get file path for source");
166 std::string dst_path(destination.
GetPath());
167 if (dst_path.empty())
168 return Status(
"unable to get file path for destination");
170 if (source == destination)
171 return Status(
"local scenario->source and destination are the same file "
172 "path: no operation performed");
175 cp_command.
Printf(
"cp %s %s", src_path.c_str(), dst_path.c_str());
178 std::chrono::seconds(10));
180 return Status(
"unable to perform copy");
191 src_path.c_str(), dst_path.c_str());
199 nullptr, std::chrono::minutes(1));
209 LLDB_LOGF(log,
"[GetFile] Using block by block transfer....\n");
212 lldb::eFilePermissionsFileDefault,
error);
215 return Status(
"unable to open source file");
217 uint32_t permissions = 0;
220 if (permissions == 0)
221 permissions = lldb::eFilePermissionsFileDefault;
230 error.SetErrorString(
"unable to open destination file");
233 if (
error.Success()) {
237 while (
error.Success()) {
238 const uint64_t n_read =
ReadFile(fd_src, offset, buffer_sp->GetBytes(),
239 buffer_sp->GetByteSize(),
error);
245 buffer_sp->GetBytes(), n_read,
248 error.SetErrorString(
"unable to write to destination file");
261 error.SetErrorString(
"unable to close destination file");
274 stream.
Printf(
", options: ");
277 stream.
Printf(
", prefix: ");
281 stream.
Printf(
"ignore remote-hostname ");
306 error.SetErrorStringWithFormatv(
307 "can't connect to the host platform '{0}', always connected",
318 error.SetErrorString(
"failed to create a 'remote-gdb-server' platform");
351 error.SetErrorStringWithFormatv(
352 "can't disconnect from the host platform '{0}', always connected",
358 error.SetErrorString(
"the platform is not currently connected");
370 if (target ==
nullptr) {
375 target = new_target_sp.get();
376 LLDB_LOGF(log,
"PlatformPOSIX::%s created new target", __FUNCTION__);
379 LLDB_LOGF(log,
"PlatformPOSIX::%s target already existed, setting target",
383 if (target &&
error.Success()) {
386 LLDB_LOGF(log,
"PlatformPOSIX::%s set selected target to %p %s",
387 __FUNCTION__, (
void *)target,
388 exe_module_sp ? exe_module_sp->GetFileSpec().GetPath().c_str()
394 "gdb-remote",
nullptr,
true);
398 if (listener_sp ==
nullptr) {
403 process_sp->HijackProcessEvents(listener_sp);
405 error = process_sp->Attach(attach_info);
413 error.SetErrorString(
"the platform is not currently connected");
422 LLDB_LOG(log,
"target {0}", &target);
431 error.SetErrorString(
"the platform is not currently connected");
449 LLDB_LOG(log,
"having target create process with gdb-remote plugin");
454 error.SetErrorString(
"CreateProcess() failed for gdb-remote process");
459 LLDB_LOG(log,
"successfully created process");
466 LLDB_LOG(log,
"launching process with the following file actions:");
471 file_action->
Dump(stream);
478 error = process_sp->Launch(launch_info);
479 if (
error.Success()) {
484 process_sp->SetSTDIOFileDescriptor(pty_fd);
485 LLDB_LOG(log,
"hooked up STDIO pty to process");
487 LLDB_LOG(log,
"not using process STDIO pty");
513 return Status(
"Selected thread isn't valid");
515 StackFrameSP frame_sp(thread_sp->GetStackFrameAtIndex(0));
517 return Status(
"Frame 0 isn't valid");
520 frame_sp->CalculateExecutionContext(exe_ctx);
533 result_valobj_sp, expr_error);
537 if (result_valobj_sp->GetError().Fail())
538 return result_valobj_sp->
GetError();
542std::unique_ptr<UtilityFunction>
560 static const char *dlopen_wrapper_code = R
"(
561 const int RTLD_LAZY = 1;
563 struct __lldb_dlopen_result {
565 const char *error_str;
568 extern "C" void *memcpy(void *, const void *, size_t size);
569 extern "C" size_t strlen(const char *);
572 void * __lldb_dlopen_wrapper (const char *name,
573 const char *path_strings,
575 __lldb_dlopen_result *result_ptr)
577 // This is the case where the name is the full path:
579 result_ptr->image_ptr = dlopen(name, RTLD_LAZY);
580 if (result_ptr->image_ptr)
581 result_ptr->error_str = nullptr;
583 result_ptr->error_str = dlerror();
587 // This is the case where we have a list of paths:
588 size_t name_len = strlen(name);
589 while (path_strings && path_strings[0] != '\0') {
590 size_t path_len = strlen(path_strings);
591 memcpy((void *) buffer, (void *) path_strings, path_len);
592 buffer[path_len] = '/';
593 char *target_ptr = buffer+path_len+1;
594 memcpy((void *) target_ptr, (void *) name, name_len + 1);
595 result_ptr->image_ptr = dlopen(buffer, RTLD_LAZY);
596 if (result_ptr->image_ptr) {
597 result_ptr->error_str = nullptr;
600 result_ptr->error_str = dlerror();
601 path_strings = path_strings + path_len + 1;
607 static const char *dlopen_wrapper_name =
"__lldb_dlopen_wrapper";
611 expr.append(dlopen_wrapper_code);
617 if (!utility_fn_or_error) {
618 std::string error_str = llvm::toString(utility_fn_or_error.takeError());
619 error.SetErrorStringWithFormat(
620 "dlopen error: could not create utility function: %s",
624 std::unique_ptr<UtilityFunction> dlopen_utility_func_up =
625 std::move(*utility_fn_or_error);
653 do_dlopen_function = dlopen_utility_func_up->MakeFunctionCaller(
654 clang_void_pointer_type, arguments, exe_ctx.
GetThreadSP(), utility_error);
655 if (utility_error.
Fail()) {
656 error.SetErrorStringWithFormat(
657 "dlopen error: could not make function caller: %s",
662 do_dlopen_function = dlopen_utility_func_up->GetFunctionCaller();
663 if (!do_dlopen_function) {
664 error.SetErrorString(
"dlopen error: could not get function caller.");
669 return dlopen_utility_func_up;
674 const std::vector<std::string> *paths,
678 loaded_image->
Clear();
681 path = remote_file.
GetPath(
false);
685 error.SetErrorString(
"dlopen error: no thread available to call dlopen.");
692 thread_sp->CalculateExecutionContext(exe_ctx);
702 this, [&]() -> std::unique_ptr<UtilityFunction> {
706 if (!dlopen_utility_func)
710 if (!do_dlopen_function) {
711 error.SetErrorString(
"dlopen error: could not get function caller.");
718 uint32_t permissions = ePermissionsReadable|ePermissionsWritable;
719 size_t path_len = path.size() + 1;
724 error.SetErrorStringWithFormat(
725 "dlopen error: could not allocate memory for path: %s",
731 auto path_cleanup = llvm::make_scope_exit([process, path_addr] {
736 process->
WriteMemory(path_addr, path.c_str(), path_len, utility_error);
737 if (utility_error.
Fail()) {
738 error.SetErrorStringWithFormat(
739 "dlopen error: could not write path string: %s",
750 if (utility_error.
Fail()) {
751 error.SetErrorStringWithFormat(
752 "dlopen error: could not allocate memory for path: %s",
758 auto return_cleanup = llvm::make_scope_exit([process, return_addr] {
766 std::optional<llvm::detail::scope_exit<std::function<void()>>>
773 std::optional<llvm::detail::scope_exit<std::function<void()>>> buffer_cleanup;
776 if (paths !=
nullptr) {
781 size_t buffer_size = 0;
782 std::string path_array;
783 for (
auto path : *paths) {
788 size_t path_size = path.size();
789 path_array.append(path);
790 path_array.push_back(
'\0');
791 if (path_size > buffer_size)
792 buffer_size = path_size;
794 path_array.push_back(
'\0');
800 error.SetErrorStringWithFormat(
801 "dlopen error: could not allocate memory for path array: %s",
807 path_array_cleanup.emplace([process, path_array_addr]() {
812 process->
WriteMemory(path_array_addr, path_array.data(),
813 path_array.size(), utility_error);
815 if (utility_error.
Fail()) {
816 error.SetErrorStringWithFormat(
817 "dlopen error: could not write path array: %s",
823 buffer_size += path.size() + 2;
829 error.SetErrorStringWithFormat(
830 "dlopen error: could not allocate memory for buffer: %s",
836 buffer_cleanup.emplace([process, buffer_addr]() {
854 error.SetErrorStringWithFormat(
855 "dlopen error: could not write function arguments: %s",
864 llvm::make_scope_exit([do_dlopen_function, &exe_ctx, func_args_addr] {
872 options.SetIgnoreBreakpoints(
true);
873 options.SetUnwindOnError(
true);
874 options.SetTrapExceptions(
false);
877 options.SetIsForUtilityExpr(
true);
883 if (!scratch_ts_sp) {
884 error.SetErrorString(
"dlopen error: Unable to get TypeSystemClang");
894 exe_ctx, &func_args_addr, options, diagnostics, return_value);
896 error.SetErrorStringWithFormat(
897 "dlopen error: failed executing dlopen wrapper function: %s",
905 if (utility_error.
Fail()) {
906 error.SetErrorStringWithFormat(
907 "dlopen error: could not read the return struct: %s",
914 if (loaded_image && buffer_addr != 0x0)
918 std::string name_string;
921 loaded_image->
SetFile(name_string, llvm::sys::path::Style::posix);
927 std::string dlopen_error_str;
930 if (utility_error.
Fail()) {
931 error.SetErrorStringWithFormat(
932 "dlopen error: could not read error string: %s",
940 if (utility_error.
Success() && num_chars > 0)
941 error.SetErrorStringWithFormat(
"dlopen error: %s",
942 dlopen_error_str.c_str());
944 error.SetErrorStringWithFormat(
"dlopen failed for unknown reasons.");
950 uint32_t image_token) {
953 return Status(
"Invalid image token");
956 expr.
Printf(
"dlclose((void *)0x%" PRIx64
")", image_addr);
964 if (result_valobj_sp->GetError().Fail())
965 return result_valobj_sp->GetError();
968 if (result_valobj_sp->ResolveValue(scalar)) {
979 extern "C" void* dlopen(const char*, int);
980 extern "C" void* dlsym(void*, const char*);
981 extern "C" int dlclose(void*);
982 extern "C" char* dlerror(void);
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
#define LLDB_LOGF(log,...)
A command line argument class.
Generic representation of a type in a programming language.
CompilerType GetPointerType() const
Return a new CompilerType that is a pointer to this type.
A uniqued constant string class.
bool IsEmpty() const
Test for empty string.
const char * GetCString() const
Get the string value as a C string.
A subclass of DataBuffer that stores a data buffer on the heap.
A class to manage flag bits.
TargetList & GetTargetList()
Get accessor for the target list.
std::string GetString(char separator='\n')
A plug-in interface definition class for dynamic loaders.
virtual Status CanLoadImage()=0
Ask if it is ok to try and load or unload an shared library (image).
void SetUnwindOnError(bool unwind=false)
void SetExecutionPolicy(ExecutionPolicy policy=eExecutionPolicyAlways)
void SetLanguage(lldb::LanguageType language_type)
void SetTrapExceptions(bool b)
void SetTimeout(const Timeout< std::micro > &timeout)
void SetIgnoreBreakpoints(bool ignore=false)
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
const lldb::ProcessSP & GetProcessSP() const
Get accessor to get the process shared pointer.
const lldb::ThreadSP & GetThreadSP() const
Get accessor to get the thread shared pointer.
void Dump(Stream &stream) const
lldb::user_id_t OpenFile(const FileSpec &file_spec, File::OpenOptions flags, uint32_t mode, Status &error)
static FileCache & GetInstance()
void SetFile(llvm::StringRef path, Style style)
Change the file specified with a new path.
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
void Clear()
Clears the object state.
ValueType Set(ValueType mask)
Set one or more flags by logical OR'ing mask with the current flags.
Encapsulates a function that can be called.
ValueList GetArgumentValues() const
void DeallocateFunctionResults(ExecutionContext &exe_ctx, lldb::addr_t args_addr)
Deallocate the arguments structure.
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.
bool WriteFunctionArguments(ExecutionContext &exe_ctx, lldb::addr_t &args_addr_ref, DiagnosticManager &diagnostic_manager)
Insert the default function argument struct.
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.
static lldb::ListenerSP MakeListener(const char *name)
virtual llvm::StringRef GetPluginName()=0
lldb::ListenerSP GetListenerForProcess(Debugger &debugger)
void SetHijackListener(const lldb::ListenerSP &listener_sp)
lldb::ListenerSP GetHijackListener() const
lldb::ListenerSP GetListener() const
lldb::ListenerSP GetShadowListener() const
PseudoTerminal & GetPTY()
const FileAction * GetFileActionAtIndex(size_t idx) const
void SetLaunchInSeparateProcessGroup(bool separate)
std::chrono::seconds GetUtilityExpressionTimeout() const
A plug-in interface definition class for debugging a process.
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.
void ResetImageToken(size_t token)
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.
ThreadList & GetThreadList()
lldb::addr_t AllocateMemory(size_t size, uint32_t permissions, Status &error)
The public interface to allocating memory in the process.
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.
size_t AddImageToken(lldb::addr_t image_ptr)
lldb::addr_t ReadPointerFromMemory(lldb::addr_t vm_addr, Status &error)
Status DeallocateMemory(lldb::addr_t ptr)
The public interface to deallocating memory in the process.
lldb::addr_t GetImagePtrFromToken(size_t token) const
uint32_t GetAddressByteSize() const
size_t WriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size, Status &error)
Write memory to a process.
virtual DynamicLoader * GetDynamicLoader()
Get the dynamic loader plug-in for this process.
Target & GetTarget()
Get the target object pointer for this module.
int ReleasePrimaryFileDescriptor()
Release the primary file descriptor.
@ invalid_fd
Invalid file descriptor value.
unsigned int UInt(unsigned int fail_value=0) const
static lldb::TypeSystemClangSP GetForTarget(Target &target, std::optional< IsolatedASTKind > ast_kind=DefaultAST, bool create_on_demand=true)
Returns the scratch TypeSystemClang for the given target.
ValueType GetError() const
Access the error value.
bool Fail() const
Test for error condition.
const char * AsCString(const char *default_error_str="unknown error") const
Get the error string associated with the current error.
bool Success() const
Test for success condition.
const char * GetData() const
llvm::StringRef GetString() const
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
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.
lldb::ModuleSP GetExecutableModule()
Gets the module for the main executable.
const lldb::ProcessSP & CreateProcess(lldb::ListenerSP listener_sp, llvm::StringRef plugin_name, const FileSpec *crash_file, bool can_connect)
llvm::Expected< std::unique_ptr< UtilityFunction > > CreateUtilityFunction(std::string expression, std::string name, lldb::LanguageType language, ExecutionContext &exe_ctx)
Creates and installs a UtilityFunction for the given language.
lldb::ThreadSP GetExpressionExecutionThread()
static lldb::ExpressionResults Evaluate(ExecutionContext &exe_ctx, const EvaluateExpressionOptions &options, llvm::StringRef expr_cstr, llvm::StringRef expr_prefix, lldb::ValueObjectSP &result_valobj_sp, Status &error, std::string *fixed_expression=nullptr, ValueObject *ctx_obj=nullptr)
Evaluate one expression in the scratch context of the target passed in the exe_ctx and return its res...
"lldb/Expression/UtilityFunction.h" Encapsulates a bit of source code that provides a function that i...
FunctionCaller * GetFunctionCaller()
void PushValue(const Value &value)
Value * GetValueAtIndex(size_t idx)
const Scalar & GetScalar() const
void SetCompilerType(const CompilerType &compiler_type)
void SetValueType(ValueType value_type)
#define LLDB_INVALID_IMAGE_TOKEN
#define LLDB_INVALID_ADDRESS
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
std::shared_ptr< lldb_private::StackFrame > StackFrameSP
std::shared_ptr< lldb_private::Thread > ThreadSP
std::shared_ptr< lldb_private::ValueObject > ValueObjectSP
std::shared_ptr< lldb_private::UnixSignals > UnixSignalsSP
@ eLanguageTypeC_plus_plus
ISO C++:1998.
ExpressionResults
The results of expression evaluation.
std::shared_ptr< lldb_private::Process > ProcessSP
std::shared_ptr< lldb_private::Listener > ListenerSP
std::shared_ptr< lldb_private::TypeSystemClang > TypeSystemClangSP
std::shared_ptr< lldb_private::WritableDataBuffer > WritableDataBufferSP
std::shared_ptr< lldb_private::Target > TargetSP
std::shared_ptr< lldb_private::Module > ModuleSP