Index: include/lldb/Target/RemoteAwarePlatform.h =================================================================== --- include/lldb/Target/RemoteAwarePlatform.h +++ include/lldb/Target/RemoteAwarePlatform.h @@ -21,6 +21,41 @@ bool GetModuleSpec(const FileSpec &module_file_spec, const ArchSpec &arch, ModuleSpec &module_spec) override; + + lldb::user_id_t OpenFile(const FileSpec &file_spec, uint32_t flags, + uint32_t mode, Status &error) override; + + bool CloseFile(lldb::user_id_t fd, Status &error) override; + + uint64_t ReadFile(lldb::user_id_t fd, uint64_t offset, void *dst, + uint64_t dst_len, Status &error) override; + + uint64_t WriteFile(lldb::user_id_t fd, uint64_t offset, const void *src, + uint64_t src_len, Status &error) override; + + lldb::user_id_t GetFileSize(const FileSpec &file_spec) override; + + Status CreateSymlink(const FileSpec &src, const FileSpec &dst) override; + + bool GetFileExists(const FileSpec &file_spec) override; + + Status Unlink(const FileSpec &file_spec) override; + + FileSpec GetRemoteWorkingDirectory() override; + + bool SetRemoteWorkingDirectory(const FileSpec &working_dir) override; + + Status MakeDirectory(const FileSpec &file_spec, uint32_t mode) override; + + Status GetFilePermissions(const FileSpec &file_spec, + uint32_t &file_permissions) override; + + Status SetFilePermissions(const FileSpec &file_spec, + uint32_t file_permissions) override; + + bool CalculateMD5(const FileSpec &file_spec, uint64_t &low, + uint64_t &high) override; + Status GetFileWithUUID(const FileSpec &platform_file, const UUID *uuid, FileSpec &local_file) override; @@ -29,6 +64,11 @@ bool GetRemoteOSKernelDescription(std::string &s) override; ArchSpec GetRemoteSystemArchitecture() override; + Status RunShellCommand(const char *command, const FileSpec &working_dir, + int *status_ptr, int *signo_ptr, + std::string *command_output, + const Timeout &timeout) override; + const char *GetHostname() override; const char *GetUserName(uint32_t uid) override; const char *GetGroupName(uint32_t gid) override; @@ -39,8 +79,16 @@ bool GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &proc_info) override; uint32_t FindProcesses(const ProcessInstanceInfoMatch &match_info, ProcessInstanceInfoList &process_infos) override; + + lldb::ProcessSP ConnectProcess(llvm::StringRef connect_url, + llvm::StringRef plugin_name, + Debugger &debugger, Target *target, + Status &error) override; + Status LaunchProcess(ProcessLaunchInfo &launch_info) override; + Status KillProcess(const lldb::pid_t pid) override; + protected: lldb::PlatformSP m_remote_platform_sp; }; Index: source/Plugins/Platform/POSIX/PlatformPOSIX.h =================================================================== --- source/Plugins/Platform/POSIX/PlatformPOSIX.h +++ source/Plugins/Platform/POSIX/PlatformPOSIX.h @@ -33,68 +33,16 @@ uint32_t uid = UINT32_MAX, uint32_t gid = UINT32_MAX) override; - lldb::user_id_t OpenFile(const lldb_private::FileSpec &file_spec, - uint32_t flags, uint32_t mode, - lldb_private::Status &error) override; - - bool CloseFile(lldb::user_id_t fd, lldb_private::Status &error) override; - - uint64_t ReadFile(lldb::user_id_t fd, uint64_t offset, void *dst, - uint64_t dst_len, lldb_private::Status &error) override; - - uint64_t WriteFile(lldb::user_id_t fd, uint64_t offset, const void *src, - uint64_t src_len, lldb_private::Status &error) override; - - lldb::user_id_t GetFileSize(const lldb_private::FileSpec &file_spec) override; - - lldb_private::Status - CreateSymlink(const lldb_private::FileSpec &src, - const lldb_private::FileSpec &dst) override; - lldb_private::Status GetFile(const lldb_private::FileSpec &source, const lldb_private::FileSpec &destination) override; - lldb_private::FileSpec GetRemoteWorkingDirectory() override; - - bool - SetRemoteWorkingDirectory(const lldb_private::FileSpec &working_dir) override; - const lldb::UnixSignalsSP &GetRemoteUnixSignals() override; - lldb_private::Status RunShellCommand( - const char *command, // Shouldn't be nullptr - const lldb_private::FileSpec &working_dir, // Pass empty FileSpec to use - // the current working - // directory - int *status_ptr, // Pass nullptr if you don't want the process exit status - int *signo_ptr, // Pass nullptr if you don't want the signal that caused - // the process to exit - std::string - *command_output, // Pass nullptr if you don't want the command output - const lldb_private::Timeout &timeout) override; - lldb_private::Status ResolveExecutable( const lldb_private::ModuleSpec &module_spec, lldb::ModuleSP &module_sp, const lldb_private::FileSpecList *module_search_paths_ptr) override; - lldb_private::Status MakeDirectory(const lldb_private::FileSpec &file_spec, - uint32_t mode) override; - - lldb_private::Status - GetFilePermissions(const lldb_private::FileSpec &file_spec, - uint32_t &file_permissions) override; - - lldb_private::Status - SetFilePermissions(const lldb_private::FileSpec &file_spec, - uint32_t file_permissions) override; - - bool GetFileExists(const lldb_private::FileSpec &file_spec) override; - - lldb_private::Status Unlink(const lldb_private::FileSpec &file_spec) override; - - lldb_private::Status KillProcess(const lldb::pid_t pid) override; - lldb::ProcessSP Attach(lldb_private::ProcessAttachInfo &attach_info, lldb_private::Debugger &debugger, lldb_private::Target *target, // Can be nullptr, if @@ -114,9 +62,6 @@ std::string GetPlatformSpecificConnectionInformation() override; - bool CalculateMD5(const lldb_private::FileSpec &file_spec, uint64_t &low, - uint64_t &high) override; - void CalculateTrapHandlerSymbolNames() override; lldb_private::Status ConnectRemote(lldb_private::Args &args) override; @@ -132,16 +77,11 @@ lldb_private::Status UnloadImage(lldb_private::Process *process, uint32_t image_token) override; - lldb::ProcessSP ConnectProcess(llvm::StringRef connect_url, - llvm::StringRef plugin_name, - lldb_private::Debugger &debugger, - lldb_private::Target *target, - lldb_private::Status &error) override; - size_t ConnectToWaitingProcesses(lldb_private::Debugger &debugger, lldb_private::Status &error) override; - lldb_private::ConstString GetFullNameForDylib(lldb_private::ConstString basename) override; + lldb_private::ConstString + GetFullNameForDylib(lldb_private::ConstString basename) override; protected: std::unique_ptr @@ -164,8 +104,8 @@ MakeLoadImageUtilityFunction(lldb_private::ExecutionContext &exe_ctx, lldb_private::Status &error); - virtual - llvm::StringRef GetLibdlFunctionDeclarations(lldb_private::Process *process); + virtual llvm::StringRef + GetLibdlFunctionDeclarations(lldb_private::Process *process); private: DISALLOW_COPY_AND_ASSIGN(PlatformPOSIX); Index: source/Plugins/Platform/POSIX/PlatformPOSIX.cpp =================================================================== --- source/Plugins/Platform/POSIX/PlatformPOSIX.cpp +++ source/Plugins/Platform/POSIX/PlatformPOSIX.cpp @@ -68,28 +68,6 @@ return m_options.at(&interpreter).get(); } -lldb_private::Status PlatformPOSIX::RunShellCommand( - const char *command, // Shouldn't be NULL - const FileSpec & - working_dir, // Pass empty FileSpec to use the current working directory - int *status_ptr, // Pass NULL if you don't want the process exit status - int *signo_ptr, // Pass NULL if you don't want the signal that caused the - // process to exit - std::string - *command_output, // Pass NULL if you don't want the command output - const Timeout &timeout) { - if (IsHost()) - return Host::RunShellCommand(command, working_dir, status_ptr, signo_ptr, - command_output, timeout); - else { - if (m_remote_platform_sp) - return m_remote_platform_sp->RunShellCommand( - command, working_dir, status_ptr, signo_ptr, command_output, timeout); - else - return Status("unable to run a remote command without a platform"); - } -} - Status PlatformPOSIX::ResolveExecutable(const ModuleSpec &module_spec, lldb::ModuleSP &exe_module_sp, @@ -156,11 +134,12 @@ if (error.Success()) { if (resolved_module_spec.GetArchitecture().IsValid()) { error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp, - module_search_paths_ptr, nullptr, nullptr); + module_search_paths_ptr, nullptr, + nullptr); if (error.Fail()) { // If we failed, it may be because the vendor and os aren't known. If - // that is the case, try setting them to the host architecture and give - // it another try. + // that is the case, try setting them to the host architecture and give + // it another try. llvm::Triple &module_triple = resolved_module_spec.GetArchitecture().GetTriple(); bool is_vendor_specified = @@ -176,8 +155,9 @@ if (!is_os_specified) module_triple.setOSName(host_triple.getOSName()); - error = ModuleList::GetSharedModule(resolved_module_spec, - exe_module_sp, module_search_paths_ptr, nullptr, nullptr); + error = ModuleList::GetSharedModule( + resolved_module_spec, exe_module_sp, module_search_paths_ptr, + nullptr, nullptr); } } @@ -198,7 +178,8 @@ idx, resolved_module_spec.GetArchitecture()); ++idx) { error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp, - module_search_paths_ptr, nullptr, nullptr); + module_search_paths_ptr, nullptr, + nullptr); // Did we find an executable using one of the if (error.Success()) { if (exe_module_sp && exe_module_sp->GetObjectFile()) @@ -232,73 +213,6 @@ return error; } -Status PlatformPOSIX::MakeDirectory(const FileSpec &file_spec, - uint32_t file_permissions) { - if (m_remote_platform_sp) - return m_remote_platform_sp->MakeDirectory(file_spec, file_permissions); - else - return Platform::MakeDirectory(file_spec, file_permissions); -} - -Status PlatformPOSIX::GetFilePermissions(const FileSpec &file_spec, - uint32_t &file_permissions) { - if (m_remote_platform_sp) - return m_remote_platform_sp->GetFilePermissions(file_spec, - file_permissions); - else - return Platform::GetFilePermissions(file_spec, file_permissions); -} - -Status PlatformPOSIX::SetFilePermissions(const FileSpec &file_spec, - uint32_t file_permissions) { - if (m_remote_platform_sp) - return m_remote_platform_sp->SetFilePermissions(file_spec, - file_permissions); - else - return Platform::SetFilePermissions(file_spec, file_permissions); -} - -lldb::user_id_t PlatformPOSIX::OpenFile(const FileSpec &file_spec, - uint32_t flags, uint32_t mode, - Status &error) { - if (IsHost()) - return FileCache::GetInstance().OpenFile(file_spec, flags, mode, error); - else if (m_remote_platform_sp) - return m_remote_platform_sp->OpenFile(file_spec, flags, mode, error); - else - return Platform::OpenFile(file_spec, flags, mode, error); -} - -bool PlatformPOSIX::CloseFile(lldb::user_id_t fd, Status &error) { - if (IsHost()) - return FileCache::GetInstance().CloseFile(fd, error); - else if (m_remote_platform_sp) - return m_remote_platform_sp->CloseFile(fd, error); - else - return Platform::CloseFile(fd, error); -} - -uint64_t PlatformPOSIX::ReadFile(lldb::user_id_t fd, uint64_t offset, void *dst, - uint64_t dst_len, Status &error) { - if (IsHost()) - return FileCache::GetInstance().ReadFile(fd, offset, dst, dst_len, error); - else if (m_remote_platform_sp) - return m_remote_platform_sp->ReadFile(fd, offset, dst, dst_len, error); - else - return Platform::ReadFile(fd, offset, dst, dst_len, error); -} - -uint64_t PlatformPOSIX::WriteFile(lldb::user_id_t fd, uint64_t offset, - const void *src, uint64_t src_len, - Status &error) { - if (IsHost()) - return FileCache::GetInstance().WriteFile(fd, offset, src, src_len, error); - else if (m_remote_platform_sp) - return m_remote_platform_sp->WriteFile(fd, offset, src, src_len, error); - else - return Platform::WriteFile(fd, offset, src, src_len, error); -} - static uint32_t chown_file(Platform *platform, const char *path, uint32_t uid = UINT32_MAX, uint32_t gid = UINT32_MAX) { @@ -387,45 +301,6 @@ return Platform::PutFile(source, destination, uid, gid); } -lldb::user_id_t PlatformPOSIX::GetFileSize(const FileSpec &file_spec) { - if (IsHost()) { - uint64_t Size; - if (llvm::sys::fs::file_size(file_spec.GetPath(), Size)) - return 0; - return Size; - } else if (m_remote_platform_sp) - return m_remote_platform_sp->GetFileSize(file_spec); - else - return Platform::GetFileSize(file_spec); -} - -Status PlatformPOSIX::CreateSymlink(const FileSpec &src, const FileSpec &dst) { - if (IsHost()) - return FileSystem::Instance().Symlink(src, dst); - else if (m_remote_platform_sp) - return m_remote_platform_sp->CreateSymlink(src, dst); - else - return Platform::CreateSymlink(src, dst); -} - -bool PlatformPOSIX::GetFileExists(const FileSpec &file_spec) { - if (IsHost()) - return FileSystem::Instance().Exists(file_spec); - else if (m_remote_platform_sp) - return m_remote_platform_sp->GetFileExists(file_spec); - else - return Platform::GetFileExists(file_spec); -} - -Status PlatformPOSIX::Unlink(const FileSpec &file_spec) { - if (IsHost()) - return llvm::sys::fs::remove(file_spec.GetPath()); - else if (m_remote_platform_sp) - return m_remote_platform_sp->Unlink(file_spec); - else - return Platform::Unlink(file_spec); -} - lldb_private::Status PlatformPOSIX::GetFile( const lldb_private::FileSpec &source, // remote file path const lldb_private::FileSpec &destination) // local file path @@ -496,8 +371,9 @@ permissions = lldb::eFilePermissionsFileDefault; user_id_t fd_dst = FileCache::GetInstance().OpenFile( - destination, File::eOpenOptionCanCreate | File::eOpenOptionWrite | - File::eOpenOptionTruncate, + destination, + File::eOpenOptionCanCreate | File::eOpenOptionWrite | + File::eOpenOptionTruncate, permissions, error); if (fd_dst == UINT64_MAX) { @@ -569,35 +445,12 @@ return ""; } -bool PlatformPOSIX::CalculateMD5(const FileSpec &file_spec, uint64_t &low, - uint64_t &high) { - if (IsHost()) - return Platform::CalculateMD5(file_spec, low, high); - if (m_remote_platform_sp) - return m_remote_platform_sp->CalculateMD5(file_spec, low, high); - return false; -} - const lldb::UnixSignalsSP &PlatformPOSIX::GetRemoteUnixSignals() { if (IsRemote() && m_remote_platform_sp) return m_remote_platform_sp->GetRemoteUnixSignals(); return Platform::GetRemoteUnixSignals(); } -FileSpec PlatformPOSIX::GetRemoteWorkingDirectory() { - if (IsRemote() && m_remote_platform_sp) - return m_remote_platform_sp->GetRemoteWorkingDirectory(); - else - return Platform::GetRemoteWorkingDirectory(); -} - -bool PlatformPOSIX::SetRemoteWorkingDirectory(const FileSpec &working_dir) { - if (IsRemote() && m_remote_platform_sp) - return m_remote_platform_sp->SetRemoteWorkingDirectory(working_dir); - else - return Platform::SetRemoteWorkingDirectory(working_dir); -} - Status PlatformPOSIX::ConnectRemote(Args &args) { Status error; if (IsHost()) { @@ -657,16 +510,6 @@ return error; } -lldb_private::Status PlatformPOSIX::KillProcess(const lldb::pid_t pid) { - if (IsHost()) - return Platform::KillProcess(pid); - - if (m_remote_platform_sp) - return m_remote_platform_sp->KillProcess(pid); - - return Status("the platform is not currently connected"); -} - lldb::ProcessSP PlatformPOSIX::Attach(ProcessAttachInfo &attach_info, Debugger &debugger, Target *target, Status &error) { @@ -854,20 +697,19 @@ expr.append(dlopen_wrapper_code); Status utility_error; DiagnosticManager diagnostics; - - std::unique_ptr dlopen_utility_func_up(process - ->GetTarget().GetUtilityFunctionForLanguage(expr.c_str(), - eLanguageTypeObjC, - dlopen_wrapper_name, - utility_error)); + + std::unique_ptr dlopen_utility_func_up( + process->GetTarget().GetUtilityFunctionForLanguage( + expr.c_str(), eLanguageTypeObjC, dlopen_wrapper_name, utility_error)); if (utility_error.Fail()) { error.SetErrorStringWithFormat("dlopen error: could not make utility" - "function: %s", utility_error.AsCString()); + "function: %s", + utility_error.AsCString()); return nullptr; } if (!dlopen_utility_func_up->Install(diagnostics, exe_ctx)) { error.SetErrorStringWithFormat("dlopen error: could not install utility" - "function: %s", + "function: %s", diagnostics.GetString().c_str()); return nullptr; } @@ -879,10 +721,10 @@ // Fetch the clang types we will need: ClangASTContext *ast = process->GetTarget().GetScratchClangASTContext(); - CompilerType clang_void_pointer_type - = ast->GetBasicType(eBasicTypeVoid).GetPointerType(); - CompilerType clang_char_pointer_type - = ast->GetBasicType(eBasicTypeChar).GetPointerType(); + CompilerType clang_void_pointer_type = + ast->GetBasicType(eBasicTypeVoid).GetPointerType(); + CompilerType clang_char_pointer_type = + ast->GetBasicType(eBasicTypeChar).GetPointerType(); // We are passing four arguments, the basename, the list of places to look, // a buffer big enough for all the path + name combos, and @@ -894,21 +736,22 @@ arguments.PushValue(value); arguments.PushValue(value); arguments.PushValue(value); - + do_dlopen_function = dlopen_utility_func_up->MakeFunctionCaller( clang_void_pointer_type, arguments, exe_ctx.GetThreadSP(), utility_error); if (utility_error.Fail()) { error.SetErrorStringWithFormat("dlopen error: could not make function" - "caller: %s", utility_error.AsCString()); + "caller: %s", + utility_error.AsCString()); return nullptr; } - + do_dlopen_function = dlopen_utility_func_up->GetFunctionCaller(); if (!do_dlopen_function) { error.SetErrorString("dlopen error: could not get function caller."); return nullptr; } - + // We made a good utility function, so cache it in the process: return dlopen_utility_func_up; } @@ -923,15 +766,15 @@ std::string path; path = remote_file.GetPath(); - + ThreadSP thread_sp = process->GetThreadList().GetExpressionExecutionThread(); if (!thread_sp) { error.SetErrorString("dlopen error: no thread available to call dlopen."); return LLDB_INVALID_IMAGE_TOKEN; } - + DiagnosticManager diagnostics; - + ExecutionContext exe_ctx; thread_sp->CalculateExecutionContext(exe_ctx); @@ -949,70 +792,69 @@ // If we couldn't make it, the error will be in error, so we can exit here. if (!dlopen_utility_func) return LLDB_INVALID_IMAGE_TOKEN; - + do_dlopen_function = dlopen_utility_func->GetFunctionCaller(); if (!do_dlopen_function) { error.SetErrorString("dlopen error: could not get function caller."); return LLDB_INVALID_IMAGE_TOKEN; } arguments = do_dlopen_function->GetArgumentValues(); - + // Now insert the path we are searching for and the result structure into the // target. - uint32_t permissions = ePermissionsReadable|ePermissionsWritable; + uint32_t permissions = ePermissionsReadable | ePermissionsWritable; size_t path_len = path.size() + 1; - lldb::addr_t path_addr = process->AllocateMemory(path_len, - permissions, - utility_error); + lldb::addr_t path_addr = + process->AllocateMemory(path_len, permissions, utility_error); if (path_addr == LLDB_INVALID_ADDRESS) { error.SetErrorStringWithFormat("dlopen error: could not allocate memory" - "for path: %s", utility_error.AsCString()); + "for path: %s", + utility_error.AsCString()); return LLDB_INVALID_IMAGE_TOKEN; } - + // Make sure we deallocate the input string memory: - CleanUp path_cleanup([process, path_addr] { - process->DeallocateMemory(path_addr); - }); - + CleanUp path_cleanup( + [process, path_addr] { process->DeallocateMemory(path_addr); }); + process->WriteMemory(path_addr, path.c_str(), path_len, utility_error); if (utility_error.Fail()) { error.SetErrorStringWithFormat("dlopen error: could not write path string:" - " %s", utility_error.AsCString()); + " %s", + utility_error.AsCString()); return LLDB_INVALID_IMAGE_TOKEN; } - + // Make space for our return structure. It is two pointers big: the token // and the error string. const uint32_t addr_size = process->GetAddressByteSize(); - lldb::addr_t return_addr = process->CallocateMemory(2*addr_size, - permissions, - utility_error); + lldb::addr_t return_addr = + process->CallocateMemory(2 * addr_size, permissions, utility_error); if (utility_error.Fail()) { error.SetErrorStringWithFormat("dlopen error: could not allocate memory" - "for path: %s", utility_error.AsCString()); + "for path: %s", + utility_error.AsCString()); return LLDB_INVALID_IMAGE_TOKEN; } - + // Make sure we deallocate the result structure memory - CleanUp return_cleanup([process, return_addr] { - process->DeallocateMemory(return_addr); - }); - + CleanUp return_cleanup( + [process, return_addr] { process->DeallocateMemory(return_addr); }); + // This will be the address of the storage for paths, if we are using them, // or nullptr to signal we aren't. lldb::addr_t path_array_addr = 0x0; llvm::Optional path_array_cleanup; // This is the address to a buffer large enough to hold the largest path - // conjoined with the library name we're passing in. This is a convenience + // conjoined with the library name we're passing in. This is a convenience // to avoid having to call malloc in the dlopen function. lldb::addr_t buffer_addr = 0x0; llvm::Optional buffer_cleanup; - + // Set the values into our args and write them to the target: if (paths != nullptr) { - // First insert the paths into the target. This is expected to be a + // First insert the paths into the target. This is expected to be a // continuous buffer with the strings laid out null terminated and // end to end with an empty string terminating the buffer. // We also compute the buffer's required size as we go. @@ -1030,75 +872,71 @@ buffer_size = path_size; } path_array.push_back('\0'); - - path_array_addr = process->AllocateMemory(path_array.size(), - permissions, - utility_error); + + path_array_addr = + process->AllocateMemory(path_array.size(), permissions, utility_error); if (path_array_addr == LLDB_INVALID_ADDRESS) { error.SetErrorStringWithFormat("dlopen error: could not allocate memory" - "for path array: %s", - utility_error.AsCString()); + "for path array: %s", + utility_error.AsCString()); return LLDB_INVALID_IMAGE_TOKEN; } - + // Make sure we deallocate the paths array. - path_array_cleanup.emplace([process, path_array_addr] { - process->DeallocateMemory(path_array_addr); + path_array_cleanup.emplace([process, path_array_addr] { + process->DeallocateMemory(path_array_addr); }); - process->WriteMemory(path_array_addr, path_array.data(), - path_array.size(), utility_error); + process->WriteMemory(path_array_addr, path_array.data(), path_array.size(), + utility_error); if (utility_error.Fail()) { error.SetErrorStringWithFormat("dlopen error: could not write path array:" - " %s", utility_error.AsCString()); + " %s", + utility_error.AsCString()); return LLDB_INVALID_IMAGE_TOKEN; } // Now make spaces in the target for the buffer. We need to add one for // the '/' that the utility function will insert and one for the '\0': buffer_size += path.size() + 2; - - buffer_addr = process->AllocateMemory(buffer_size, - permissions, - utility_error); + + buffer_addr = + process->AllocateMemory(buffer_size, permissions, utility_error); if (buffer_addr == LLDB_INVALID_ADDRESS) { error.SetErrorStringWithFormat("dlopen error: could not allocate memory" - "for buffer: %s", - utility_error.AsCString()); + "for buffer: %s", + utility_error.AsCString()); return LLDB_INVALID_IMAGE_TOKEN; } - + // Make sure we deallocate the buffer memory: - buffer_cleanup.emplace([process, buffer_addr] { - process->DeallocateMemory(buffer_addr); - }); + buffer_cleanup.emplace( + [process, buffer_addr] { process->DeallocateMemory(buffer_addr); }); } - + arguments.GetValueAtIndex(0)->GetScalar() = path_addr; arguments.GetValueAtIndex(1)->GetScalar() = path_array_addr; arguments.GetValueAtIndex(2)->GetScalar() = buffer_addr; arguments.GetValueAtIndex(3)->GetScalar() = return_addr; lldb::addr_t func_args_addr = LLDB_INVALID_ADDRESS; - + diagnostics.Clear(); - if (!do_dlopen_function->WriteFunctionArguments(exe_ctx, - func_args_addr, - arguments, - diagnostics)) { + if (!do_dlopen_function->WriteFunctionArguments(exe_ctx, func_args_addr, + arguments, diagnostics)) { error.SetErrorStringWithFormat("dlopen error: could not write function " - "arguments: %s", + "arguments: %s", diagnostics.GetString().c_str()); return LLDB_INVALID_IMAGE_TOKEN; } - + // Make sure we clean up the args structure. We can't reuse it because the // Platform lives longer than the process and the Platforms don't get a // signal to clean up cached data when a process goes away. CleanUp args_cleanup([do_dlopen_function, &exe_ctx, func_args_addr] { do_dlopen_function->DeallocateFunctionResults(exe_ctx, func_args_addr); }); - + // Now run the caller: EvaluateExpressionOptions options; options.SetExecutionPolicy(eExecutionPolicyAlways); @@ -1114,33 +952,33 @@ // Fetch the clang types we will need: ClangASTContext *ast = process->GetTarget().GetScratchClangASTContext(); - CompilerType clang_void_pointer_type - = ast->GetBasicType(eBasicTypeVoid).GetPointerType(); + CompilerType clang_void_pointer_type = + ast->GetBasicType(eBasicTypeVoid).GetPointerType(); return_value.SetCompilerType(clang_void_pointer_type); - + ExpressionResults results = do_dlopen_function->ExecuteFunction( exe_ctx, &func_args_addr, options, diagnostics, return_value); if (results != eExpressionCompleted) { error.SetErrorStringWithFormat("dlopen error: failed executing " - "dlopen wrapper function: %s", + "dlopen wrapper function: %s", diagnostics.GetString().c_str()); return LLDB_INVALID_IMAGE_TOKEN; } - + // Read the dlopen token from the return area: - lldb::addr_t token = process->ReadPointerFromMemory(return_addr, - utility_error); + lldb::addr_t token = + process->ReadPointerFromMemory(return_addr, utility_error); if (utility_error.Fail()) { error.SetErrorStringWithFormat("dlopen error: could not read the return " - "struct: %s", utility_error.AsCString()); + "struct: %s", + utility_error.AsCString()); return LLDB_INVALID_IMAGE_TOKEN; } - + // The dlopen succeeded! if (token != 0x0) { - if (loaded_image && buffer_addr != 0x0) - { + if (loaded_image && buffer_addr != 0x0) { // Capture the image which was loaded. We leave it in the buffer on // exit from the dlopen function, so we can just read it from there: std::string name_string; @@ -1150,20 +988,20 @@ } return process->AddImageToken(token); } - + // We got an error, lets read in the error string: std::string dlopen_error_str; - lldb::addr_t error_addr - = process->ReadPointerFromMemory(return_addr + addr_size, utility_error); + lldb::addr_t error_addr = + process->ReadPointerFromMemory(return_addr + addr_size, utility_error); if (utility_error.Fail()) { error.SetErrorStringWithFormat("dlopen error: could not read error string: " - "%s", utility_error.AsCString()); + "%s", + utility_error.AsCString()); return LLDB_INVALID_IMAGE_TOKEN; } - - size_t num_chars = process->ReadCStringFromMemory(error_addr + addr_size, - dlopen_error_str, - utility_error); + + size_t num_chars = process->ReadCStringFromMemory( + error_addr + addr_size, dlopen_error_str, utility_error); if (utility_error.Success() && num_chars > 0) error.SetErrorStringWithFormat("dlopen error: %s", dlopen_error_str.c_str()); @@ -1200,19 +1038,6 @@ return Status(); } -lldb::ProcessSP PlatformPOSIX::ConnectProcess(llvm::StringRef connect_url, - llvm::StringRef plugin_name, - lldb_private::Debugger &debugger, - lldb_private::Target *target, - lldb_private::Status &error) { - if (m_remote_platform_sp) - return m_remote_platform_sp->ConnectProcess(connect_url, plugin_name, - debugger, target, error); - - return Platform::ConnectProcess(connect_url, plugin_name, debugger, target, - error); -} - llvm::StringRef PlatformPOSIX::GetLibdlFunctionDeclarations(lldb_private::Process *process) { return R"( Index: source/Plugins/Platform/Windows/PlatformWindows.h =================================================================== --- source/Plugins/Platform/Windows/PlatformWindows.h +++ source/Plugins/Platform/Windows/PlatformWindows.h @@ -63,13 +63,6 @@ lldb_private::Target *target, lldb_private::Status &error) override; - lldb_private::Status - GetSharedModule(const lldb_private::ModuleSpec &module_spec, - lldb_private::Process *process, lldb::ModuleSP &module_sp, - const lldb_private::FileSpecList *module_search_paths_ptr, - lldb::ModuleSP *old_module_sp_ptr, - bool *did_create_ptr) override; - bool GetSupportedArchitectureAtIndex(uint32_t idx, lldb_private::ArchSpec &arch) override; Index: source/Plugins/Platform/Windows/PlatformWindows.cpp =================================================================== --- source/Plugins/Platform/Windows/PlatformWindows.cpp +++ source/Plugins/Platform/Windows/PlatformWindows.cpp @@ -197,8 +197,9 @@ } } else { if (m_remote_platform_sp) { - error = GetCachedExecutable(resolved_module_spec, exe_module_sp, nullptr, - *m_remote_platform_sp); + error = + GetCachedExecutable(resolved_module_spec, exe_module_sp, + module_search_paths_ptr, *m_remote_platform_sp); } else { // We may connect to a process and use the provided executable (Don't use // local $PATH). @@ -233,7 +234,8 @@ idx, resolved_module_spec.GetArchitecture()); ++idx) { error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp, - nullptr, nullptr, nullptr); + module_search_paths_ptr, nullptr, + nullptr); // Did we find an executable using one of the if (error.Success()) { if (exe_module_sp && exe_module_sp->GetObjectFile()) @@ -335,6 +337,14 @@ // plugin, and PlatformWindows::DebugProcess is just a pass-through to get to // the process plugin. + if (IsRemote()) { + if (m_remote_platform_sp) + return m_remote_platform_sp->DebugProcess(launch_info, debugger, target, + error); + else + error.SetErrorString("the platform is not currently connected"); + } + if (launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID) { // This is a process attach. Don't need to launch anything. ProcessAttachInfo attach_info(launch_info); @@ -392,34 +402,6 @@ return process_sp; } -Status PlatformWindows::GetSharedModule( - const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp, - const FileSpecList *module_search_paths_ptr, ModuleSP *old_module_sp_ptr, - bool *did_create_ptr) { - Status error; - module_sp.reset(); - - if (IsRemote()) { - // If we have a remote platform always, let it try and locate the shared - // module first. - if (m_remote_platform_sp) { - error = m_remote_platform_sp->GetSharedModule( - module_spec, process, module_sp, module_search_paths_ptr, - old_module_sp_ptr, did_create_ptr); - } - } - - if (!module_sp) { - // Fall back to the local platform and find the file locally - error = Platform::GetSharedModule(module_spec, process, module_sp, - module_search_paths_ptr, - old_module_sp_ptr, did_create_ptr); - } - if (module_sp) - module_sp->SetPlatformFileSpec(module_spec.GetFileSpec()); - return error; -} - bool PlatformWindows::GetSupportedArchitectureAtIndex(uint32_t idx, ArchSpec &arch) { static SupportedArchList architectures; @@ -435,7 +417,7 @@ #ifdef _WIN32 llvm::VersionTuple version = HostInfo::GetOSVersion(); - strm << "Host: Windows " << version.getAsString() << '\n'; + strm << " Host: Windows " << version.getAsString() << '\n'; #endif } Index: source/Target/RemoteAwarePlatform.cpp =================================================================== --- source/Target/RemoteAwarePlatform.cpp +++ source/Target/RemoteAwarePlatform.cpp @@ -7,6 +7,8 @@ //===----------------------------------------------------------------------===// #include "lldb/Target/RemoteAwarePlatform.h" +#include "lldb/Host/FileCache.h" +#include "lldb/Host/FileSystem.h" #include "lldb/Host/Host.h" using namespace lldb_private; @@ -21,6 +23,139 @@ return Platform::GetModuleSpec(module_file_spec, arch, module_spec); } +Status RemoteAwarePlatform::RunShellCommand( + const char *command, const FileSpec &working_dir, int *status_ptr, + int *signo_ptr, std::string *command_output, + const Timeout &timeout) { + if (IsHost()) + return Host::RunShellCommand(command, working_dir, status_ptr, signo_ptr, + command_output, timeout); + if (m_remote_platform_sp) + return m_remote_platform_sp->RunShellCommand( + command, working_dir, status_ptr, signo_ptr, command_output, timeout); + return Status("unable to run a remote command without a platform"); +} + +Status RemoteAwarePlatform::MakeDirectory(const FileSpec &file_spec, + uint32_t file_permissions) { + if (m_remote_platform_sp) + return m_remote_platform_sp->MakeDirectory(file_spec, file_permissions); + return Platform::MakeDirectory(file_spec, file_permissions); +} + +Status RemoteAwarePlatform::GetFilePermissions(const FileSpec &file_spec, + uint32_t &file_permissions) { + if (m_remote_platform_sp) + return m_remote_platform_sp->GetFilePermissions(file_spec, + file_permissions); + return Platform::GetFilePermissions(file_spec, file_permissions); +} + +Status RemoteAwarePlatform::SetFilePermissions(const FileSpec &file_spec, + uint32_t file_permissions) { + if (m_remote_platform_sp) + return m_remote_platform_sp->SetFilePermissions(file_spec, + file_permissions); + return Platform::SetFilePermissions(file_spec, file_permissions); +} + +lldb::user_id_t RemoteAwarePlatform::OpenFile(const FileSpec &file_spec, + uint32_t flags, uint32_t mode, + Status &error) { + if (IsHost()) + return FileCache::GetInstance().OpenFile(file_spec, flags, mode, error); + if (m_remote_platform_sp) + return m_remote_platform_sp->OpenFile(file_spec, flags, mode, error); + return Platform::OpenFile(file_spec, flags, mode, error); +} + +bool RemoteAwarePlatform::CloseFile(lldb::user_id_t fd, Status &error) { + if (IsHost()) + return FileCache::GetInstance().CloseFile(fd, error); + if (m_remote_platform_sp) + return m_remote_platform_sp->CloseFile(fd, error); + return Platform::CloseFile(fd, error); +} + +uint64_t RemoteAwarePlatform::ReadFile(lldb::user_id_t fd, uint64_t offset, + void *dst, uint64_t dst_len, + Status &error) { + if (IsHost()) + return FileCache::GetInstance().ReadFile(fd, offset, dst, dst_len, error); + if (m_remote_platform_sp) + return m_remote_platform_sp->ReadFile(fd, offset, dst, dst_len, error); + return Platform::ReadFile(fd, offset, dst, dst_len, error); +} + +uint64_t RemoteAwarePlatform::WriteFile(lldb::user_id_t fd, uint64_t offset, + const void *src, uint64_t src_len, + Status &error) { + if (IsHost()) + return FileCache::GetInstance().WriteFile(fd, offset, src, src_len, error); + if (m_remote_platform_sp) + return m_remote_platform_sp->WriteFile(fd, offset, src, src_len, error); + return Platform::WriteFile(fd, offset, src, src_len, error); +} + +lldb::user_id_t RemoteAwarePlatform::GetFileSize(const FileSpec &file_spec) { + if (IsHost()) { + uint64_t Size; + if (llvm::sys::fs::file_size(file_spec.GetPath(), Size)) + return 0; + return Size; + } + if (m_remote_platform_sp) + return m_remote_platform_sp->GetFileSize(file_spec); + return Platform::GetFileSize(file_spec); +} + +Status RemoteAwarePlatform::CreateSymlink(const FileSpec &src, + const FileSpec &dst) { + if (IsHost()) + return FileSystem::Instance().Symlink(src, dst); + if (m_remote_platform_sp) + return m_remote_platform_sp->CreateSymlink(src, dst); + return Platform::CreateSymlink(src, dst); +} + +bool RemoteAwarePlatform::GetFileExists(const FileSpec &file_spec) { + if (IsHost()) + return FileSystem::Instance().Exists(file_spec); + if (m_remote_platform_sp) + return m_remote_platform_sp->GetFileExists(file_spec); + return Platform::GetFileExists(file_spec); +} + +Status RemoteAwarePlatform::Unlink(const FileSpec &file_spec) { + if (IsHost()) + return llvm::sys::fs::remove(file_spec.GetPath()); + if (m_remote_platform_sp) + return m_remote_platform_sp->Unlink(file_spec); + return Platform::Unlink(file_spec); +} + +bool RemoteAwarePlatform::CalculateMD5(const FileSpec &file_spec, uint64_t &low, + uint64_t &high) { + if (IsHost()) + return Platform::CalculateMD5(file_spec, low, high); + if (m_remote_platform_sp) + return m_remote_platform_sp->CalculateMD5(file_spec, low, high); + return false; +} + +FileSpec RemoteAwarePlatform::GetRemoteWorkingDirectory() { + if (IsRemote() && m_remote_platform_sp) + return m_remote_platform_sp->GetRemoteWorkingDirectory(); + return Platform::GetRemoteWorkingDirectory(); +} + +bool RemoteAwarePlatform::SetRemoteWorkingDirectory( + const FileSpec &working_dir) { + if (IsRemote() && m_remote_platform_sp) + return m_remote_platform_sp->SetRemoteWorkingDirectory(working_dir); + return Platform::SetRemoteWorkingDirectory(working_dir); +} + Status RemoteAwarePlatform::GetFileWithUUID(const FileSpec &platform_file, const UUID *uuid_ptr, FileSpec &local_file) { @@ -64,7 +199,6 @@ const char *RemoteAwarePlatform::GetHostname() { if (IsHost()) return Platform::GetHostname(); - if (m_remote_platform_sp) return m_remote_platform_sp->GetHostname(); return nullptr; @@ -127,6 +261,18 @@ return 0; } +lldb::ProcessSP RemoteAwarePlatform::ConnectProcess(llvm::StringRef connect_url, + llvm::StringRef plugin_name, + Debugger &debugger, + Target *target, + Status &error) { + if (m_remote_platform_sp) + return m_remote_platform_sp->ConnectProcess(connect_url, plugin_name, + debugger, target, error); + return Platform::ConnectProcess(connect_url, plugin_name, debugger, target, + error); +} + Status RemoteAwarePlatform::LaunchProcess(ProcessLaunchInfo &launch_info) { Status error; @@ -140,3 +286,11 @@ } return error; } + +Status RemoteAwarePlatform::KillProcess(const lldb::pid_t pid) { + if (IsHost()) + return Platform::KillProcess(pid); + if (m_remote_platform_sp) + return m_remote_platform_sp->KillProcess(pid); + return Status("the platform is not currently connected"); +}