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( | 
