diff options
Diffstat (limited to 'lldb/source/Commands/CommandObjectPlatform.cpp')
| -rw-r--r-- | lldb/source/Commands/CommandObjectPlatform.cpp | 218 |
1 files changed, 185 insertions, 33 deletions
diff --git a/lldb/source/Commands/CommandObjectPlatform.cpp b/lldb/source/Commands/CommandObjectPlatform.cpp index bf23c4552aa8..10dd87824911 100644 --- a/lldb/source/Commands/CommandObjectPlatform.cpp +++ b/lldb/source/Commands/CommandObjectPlatform.cpp @@ -211,20 +211,18 @@ protected: ostrm.Printf("Available platforms:\n"); PlatformSP host_platform_sp(Platform::GetHostPlatform()); - ostrm.Printf("%s: %s\n", host_platform_sp->GetPluginName().GetCString(), + ostrm.Format("{0}: {1}\n", host_platform_sp->GetPluginName(), host_platform_sp->GetDescription()); uint32_t idx; for (idx = 0; true; ++idx) { - const char *plugin_name = + llvm::StringRef plugin_name = PluginManager::GetPlatformPluginNameAtIndex(idx); - if (plugin_name == nullptr) + if (plugin_name.empty()) break; - const char *plugin_desc = + llvm::StringRef plugin_desc = PluginManager::GetPlatformPluginDescriptionAtIndex(idx); - if (plugin_desc == nullptr) - break; - ostrm.Printf("%s: %s\n", plugin_name, plugin_desc); + ostrm.Format("{0}: {1}\n", plugin_name, plugin_desc); } if (idx == 0) { @@ -346,8 +344,8 @@ protected: if (error.Success()) { Stream &ostrm = result.GetOutputStream(); if (hostname.empty()) - ostrm.Printf("Disconnected from \"%s\"\n", - platform_sp->GetPluginName().GetCString()); + ostrm.Format("Disconnected from \"{0}\"\n", + platform_sp->GetPluginName()); else ostrm.Printf("Disconnected from \"%s\"\n", hostname.c_str()); result.SetStatus(eReturnStatusSuccessFinishResult); @@ -356,9 +354,8 @@ protected: } } else { // Not connected... - result.AppendErrorWithFormat( - "not connected to '%s'", - platform_sp->GetPluginName().GetCString()); + result.AppendErrorWithFormatv("not connected to '{0}'", + platform_sp->GetPluginName()); } } else { // Bad args @@ -498,8 +495,7 @@ public: lldb::eFilePermissionsWorldRead; lldb::user_id_t fd = platform_sp->OpenFile( FileSpec(cmd_line), - File::eOpenOptionRead | File::eOpenOptionWrite | - File::eOpenOptionAppend | File::eOpenOptionCanCreate, + File::eOpenOptionReadWrite | File::eOpenOptionCanCreate, perms, error); if (error.Success()) { result.AppendMessageWithFormat("File Descriptor = %" PRIu64 "\n", fd); @@ -589,11 +585,15 @@ public: } std::string buffer(m_options.m_count, 0); Status error; - uint32_t retcode = platform_sp->ReadFile( + uint64_t retcode = platform_sp->ReadFile( fd, m_options.m_offset, &buffer[0], m_options.m_count, error); - result.AppendMessageWithFormat("Return = %d\n", retcode); - result.AppendMessageWithFormat("Data = \"%s\"\n", buffer.c_str()); - result.SetStatus(eReturnStatusSuccessFinishResult); + if (retcode != UINT64_MAX) { + result.AppendMessageWithFormat("Return = %" PRIu64 "\n", retcode); + result.AppendMessageWithFormat("Data = \"%s\"\n", buffer.c_str()); + result.SetStatus(eReturnStatusSuccessFinishResult); + } else { + result.AppendError(error.AsCString()); + } } else { result.AppendError("no platform currently selected\n"); } @@ -678,11 +678,15 @@ public: cmd_line); return result.Succeeded(); } - uint32_t retcode = + uint64_t retcode = platform_sp->WriteFile(fd, m_options.m_offset, &m_options.m_data[0], m_options.m_data.size(), error); - result.AppendMessageWithFormat("Return = %d\n", retcode); - result.SetStatus(eReturnStatusSuccessFinishResult); + if (retcode != UINT64_MAX) { + result.AppendMessageWithFormat("Return = %" PRIu64 "\n", retcode); + result.SetStatus(eReturnStatusSuccessFinishResult); + } else { + result.AppendError(error.AsCString()); + } } else { result.AppendError("no platform currently selected\n"); } @@ -919,13 +923,159 @@ public: } }; +// "platform get-permissions remote-file-path" +class CommandObjectPlatformGetPermissions : public CommandObjectParsed { +public: + CommandObjectPlatformGetPermissions(CommandInterpreter &interpreter) + : CommandObjectParsed(interpreter, "platform get-permissions", + "Get the file permission bits from the remote end.", + "platform get-permissions <remote-file-spec>", 0) { + SetHelpLong( + R"(Examples: + +(lldb) platform get-permissions /the/remote/file/path + + Get the file permissions from the remote end with path /the/remote/file/path.)"); + + CommandArgumentEntry arg1; + CommandArgumentData file_arg_remote; + + // Define the first (and only) variant of this arg. + file_arg_remote.arg_type = eArgTypeFilename; + file_arg_remote.arg_repetition = eArgRepeatPlain; + // There is only one variant this argument could be; put it into the + // argument entry. + arg1.push_back(file_arg_remote); + + // Push the data for the first argument into the m_arguments vector. + m_arguments.push_back(arg1); + } + + ~CommandObjectPlatformGetPermissions() override = default; + + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { + if (request.GetCursorIndex() != 0) + return; + + CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), CommandCompletions::eRemoteDiskFileCompletion, + request, nullptr); + } + + bool DoExecute(Args &args, CommandReturnObject &result) override { + // If the number of arguments is incorrect, issue an error message. + if (args.GetArgumentCount() != 1) { + result.AppendError("required argument missing; specify the source file " + "path as the only argument"); + return false; + } + + PlatformSP platform_sp( + GetDebugger().GetPlatformList().GetSelectedPlatform()); + if (platform_sp) { + std::string remote_file_path(args.GetArgumentAtIndex(0)); + uint32_t permissions; + Status error = platform_sp->GetFilePermissions(FileSpec(remote_file_path), + permissions); + if (error.Success()) { + result.AppendMessageWithFormat( + "File permissions of %s (remote): 0o%04" PRIo32 "\n", + remote_file_path.c_str(), permissions); + result.SetStatus(eReturnStatusSuccessFinishResult); + } else + result.AppendError(error.AsCString()); + } else { + result.AppendError("no platform currently selected\n"); + } + return result.Succeeded(); + } +}; + +// "platform file-exists remote-file-path" +class CommandObjectPlatformFileExists : public CommandObjectParsed { +public: + CommandObjectPlatformFileExists(CommandInterpreter &interpreter) + : CommandObjectParsed(interpreter, "platform file-exists", + "Check if the file exists on the remote end.", + "platform file-exists <remote-file-spec>", 0) { + SetHelpLong( + R"(Examples: + +(lldb) platform file-exists /the/remote/file/path + + Check if /the/remote/file/path exists on the remote end.)"); + + CommandArgumentEntry arg1; + CommandArgumentData file_arg_remote; + + // Define the first (and only) variant of this arg. + file_arg_remote.arg_type = eArgTypeFilename; + file_arg_remote.arg_repetition = eArgRepeatPlain; + // There is only one variant this argument could be; put it into the + // argument entry. + arg1.push_back(file_arg_remote); + + // Push the data for the first argument into the m_arguments vector. + m_arguments.push_back(arg1); + } + + ~CommandObjectPlatformFileExists() override = default; + + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { + if (request.GetCursorIndex() != 0) + return; + + CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), CommandCompletions::eRemoteDiskFileCompletion, + request, nullptr); + } + + bool DoExecute(Args &args, CommandReturnObject &result) override { + // If the number of arguments is incorrect, issue an error message. + if (args.GetArgumentCount() != 1) { + result.AppendError("required argument missing; specify the source file " + "path as the only argument"); + return false; + } + + PlatformSP platform_sp( + GetDebugger().GetPlatformList().GetSelectedPlatform()); + if (platform_sp) { + std::string remote_file_path(args.GetArgumentAtIndex(0)); + bool exists = platform_sp->GetFileExists(FileSpec(remote_file_path)); + result.AppendMessageWithFormat( + "File %s (remote) %s\n", + remote_file_path.c_str(), exists ? "exists" : "does not exist"); + result.SetStatus(eReturnStatusSuccessFinishResult); + } else { + result.AppendError("no platform currently selected\n"); + } + return result.Succeeded(); + } +}; + // "platform put-file" class CommandObjectPlatformPutFile : public CommandObjectParsed { public: CommandObjectPlatformPutFile(CommandInterpreter &interpreter) : CommandObjectParsed( interpreter, "platform put-file", - "Transfer a file from this system to the remote end.", nullptr, 0) { + "Transfer a file from this system to the remote end.", + "platform put-file <source> [<destination>]", 0) { + SetHelpLong( + R"(Examples: + +(lldb) platform put-file /source/foo.txt /destination/bar.txt + +(lldb) platform put-file /source/foo.txt + + Relative source file paths are resolved against lldb's local working directory. + + Omitting the destination places the file in the platform working directory.)"); } ~CommandObjectPlatformPutFile() override = default; @@ -1029,7 +1179,7 @@ protected: target->GetRunArguments(m_options.launch_info.GetArguments()); ProcessSP process_sp(platform_sp->DebugProcess( - m_options.launch_info, debugger, target, error)); + m_options.launch_info, debugger, *target, error)); if (process_sp && process_sp->IsAlive()) { result.SetStatus(eReturnStatusSuccessFinishNoResult); return true; @@ -1136,15 +1286,14 @@ protected: if (matches == 0) { if (match_desc) - result.AppendErrorWithFormat( - "no processes were found that %s \"%s\" on the \"%s\" " + result.AppendErrorWithFormatv( + "no processes were found that {0} \"{1}\" on the \"{2}\" " "platform\n", - match_desc, match_name, - platform_sp->GetPluginName().GetCString()); + match_desc, match_name, platform_sp->GetPluginName()); else - result.AppendErrorWithFormat( - "no processes were found on the \"%s\" platform\n", - platform_sp->GetPluginName().GetCString()); + result.AppendErrorWithFormatv( + "no processes were found on the \"{0}\" platform\n", + platform_sp->GetPluginName()); } else { result.AppendMessageWithFormat( "%u matching process%s found on \"%s\"", matches, @@ -1390,9 +1539,8 @@ protected: } } else { // Not connected... - result.AppendErrorWithFormat( - "not connected to '%s'", - platform_sp->GetPluginName().GetCString()); + result.AppendErrorWithFormatv("not connected to '{0}'", + platform_sp->GetPluginName()); } } else { // No args @@ -1752,8 +1900,12 @@ CommandObjectPlatform::CommandObjectPlatform(CommandInterpreter &interpreter) CommandObjectSP(new CommandObjectPlatformMkDir(interpreter))); LoadSubCommand("file", CommandObjectSP(new CommandObjectPlatformFile(interpreter))); + LoadSubCommand("file-exists", + CommandObjectSP(new CommandObjectPlatformFileExists(interpreter))); LoadSubCommand("get-file", CommandObjectSP(new CommandObjectPlatformGetFile( interpreter))); + LoadSubCommand("get-permissions", + CommandObjectSP(new CommandObjectPlatformGetPermissions(interpreter))); LoadSubCommand("get-size", CommandObjectSP(new CommandObjectPlatformGetSize( interpreter))); LoadSubCommand("put-file", CommandObjectSP(new CommandObjectPlatformPutFile( |
