15ffd83dbSDimitry Andric //===-- CommandObjectPlatform.cpp -----------------------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #include "CommandObjectPlatform.h"
10af732203SDimitry Andric #include "CommandOptionsProcessLaunch.h"
110b57cec5SDimitry Andric #include "lldb/Core/Debugger.h"
120b57cec5SDimitry Andric #include "lldb/Core/Module.h"
130b57cec5SDimitry Andric #include "lldb/Core/PluginManager.h"
140b57cec5SDimitry Andric #include "lldb/Host/OptionParser.h"
150b57cec5SDimitry Andric #include "lldb/Interpreter/CommandInterpreter.h"
160b57cec5SDimitry Andric #include "lldb/Interpreter/CommandOptionValidators.h"
170b57cec5SDimitry Andric #include "lldb/Interpreter/CommandReturnObject.h"
180b57cec5SDimitry Andric #include "lldb/Interpreter/OptionGroupFile.h"
190b57cec5SDimitry Andric #include "lldb/Interpreter/OptionGroupPlatform.h"
200b57cec5SDimitry Andric #include "lldb/Target/ExecutionContext.h"
210b57cec5SDimitry Andric #include "lldb/Target/Platform.h"
220b57cec5SDimitry Andric #include "lldb/Target/Process.h"
230b57cec5SDimitry Andric #include "lldb/Utility/Args.h"
240b57cec5SDimitry Andric 
250b57cec5SDimitry Andric #include "llvm/ADT/SmallString.h"
260b57cec5SDimitry Andric 
270b57cec5SDimitry Andric using namespace lldb;
280b57cec5SDimitry Andric using namespace lldb_private;
290b57cec5SDimitry Andric 
300b57cec5SDimitry Andric static mode_t ParsePermissionString(const char *) = delete;
310b57cec5SDimitry Andric 
ParsePermissionString(llvm::StringRef permissions)320b57cec5SDimitry Andric static mode_t ParsePermissionString(llvm::StringRef permissions) {
330b57cec5SDimitry Andric   if (permissions.size() != 9)
340b57cec5SDimitry Andric     return (mode_t)(-1);
350b57cec5SDimitry Andric   bool user_r, user_w, user_x, group_r, group_w, group_x, world_r, world_w,
360b57cec5SDimitry Andric       world_x;
370b57cec5SDimitry Andric 
380b57cec5SDimitry Andric   user_r = (permissions[0] == 'r');
390b57cec5SDimitry Andric   user_w = (permissions[1] == 'w');
400b57cec5SDimitry Andric   user_x = (permissions[2] == 'x');
410b57cec5SDimitry Andric 
420b57cec5SDimitry Andric   group_r = (permissions[3] == 'r');
430b57cec5SDimitry Andric   group_w = (permissions[4] == 'w');
440b57cec5SDimitry Andric   group_x = (permissions[5] == 'x');
450b57cec5SDimitry Andric 
460b57cec5SDimitry Andric   world_r = (permissions[6] == 'r');
470b57cec5SDimitry Andric   world_w = (permissions[7] == 'w');
480b57cec5SDimitry Andric   world_x = (permissions[8] == 'x');
490b57cec5SDimitry Andric 
500b57cec5SDimitry Andric   mode_t user, group, world;
510b57cec5SDimitry Andric   user = (user_r ? 4 : 0) | (user_w ? 2 : 0) | (user_x ? 1 : 0);
520b57cec5SDimitry Andric   group = (group_r ? 4 : 0) | (group_w ? 2 : 0) | (group_x ? 1 : 0);
530b57cec5SDimitry Andric   world = (world_r ? 4 : 0) | (world_w ? 2 : 0) | (world_x ? 1 : 0);
540b57cec5SDimitry Andric 
550b57cec5SDimitry Andric   return user | group | world;
560b57cec5SDimitry Andric }
570b57cec5SDimitry Andric 
589dba64beSDimitry Andric #define LLDB_OPTIONS_permissions
599dba64beSDimitry Andric #include "CommandOptions.inc"
600b57cec5SDimitry Andric 
610b57cec5SDimitry Andric class OptionPermissions : public OptionGroup {
620b57cec5SDimitry Andric public:
63*5f7ddb14SDimitry Andric   OptionPermissions() = default;
640b57cec5SDimitry Andric 
650b57cec5SDimitry Andric   ~OptionPermissions() override = default;
660b57cec5SDimitry Andric 
670b57cec5SDimitry Andric   lldb_private::Status
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)680b57cec5SDimitry Andric   SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
690b57cec5SDimitry Andric                  ExecutionContext *execution_context) override {
700b57cec5SDimitry Andric     Status error;
710b57cec5SDimitry Andric     char short_option = (char)GetDefinitions()[option_idx].short_option;
720b57cec5SDimitry Andric     switch (short_option) {
730b57cec5SDimitry Andric     case 'v': {
740b57cec5SDimitry Andric       if (option_arg.getAsInteger(8, m_permissions)) {
750b57cec5SDimitry Andric         m_permissions = 0777;
760b57cec5SDimitry Andric         error.SetErrorStringWithFormat("invalid value for permissions: %s",
770b57cec5SDimitry Andric                                        option_arg.str().c_str());
780b57cec5SDimitry Andric       }
790b57cec5SDimitry Andric 
800b57cec5SDimitry Andric     } break;
810b57cec5SDimitry Andric     case 's': {
820b57cec5SDimitry Andric       mode_t perms = ParsePermissionString(option_arg);
830b57cec5SDimitry Andric       if (perms == (mode_t)-1)
840b57cec5SDimitry Andric         error.SetErrorStringWithFormat("invalid value for permissions: %s",
850b57cec5SDimitry Andric                                        option_arg.str().c_str());
860b57cec5SDimitry Andric       else
870b57cec5SDimitry Andric         m_permissions = perms;
880b57cec5SDimitry Andric     } break;
890b57cec5SDimitry Andric     case 'r':
900b57cec5SDimitry Andric       m_permissions |= lldb::eFilePermissionsUserRead;
910b57cec5SDimitry Andric       break;
920b57cec5SDimitry Andric     case 'w':
930b57cec5SDimitry Andric       m_permissions |= lldb::eFilePermissionsUserWrite;
940b57cec5SDimitry Andric       break;
950b57cec5SDimitry Andric     case 'x':
960b57cec5SDimitry Andric       m_permissions |= lldb::eFilePermissionsUserExecute;
970b57cec5SDimitry Andric       break;
980b57cec5SDimitry Andric     case 'R':
990b57cec5SDimitry Andric       m_permissions |= lldb::eFilePermissionsGroupRead;
1000b57cec5SDimitry Andric       break;
1010b57cec5SDimitry Andric     case 'W':
1020b57cec5SDimitry Andric       m_permissions |= lldb::eFilePermissionsGroupWrite;
1030b57cec5SDimitry Andric       break;
1040b57cec5SDimitry Andric     case 'X':
1050b57cec5SDimitry Andric       m_permissions |= lldb::eFilePermissionsGroupExecute;
1060b57cec5SDimitry Andric       break;
1070b57cec5SDimitry Andric     case 'd':
1080b57cec5SDimitry Andric       m_permissions |= lldb::eFilePermissionsWorldRead;
1090b57cec5SDimitry Andric       break;
1100b57cec5SDimitry Andric     case 't':
1110b57cec5SDimitry Andric       m_permissions |= lldb::eFilePermissionsWorldWrite;
1120b57cec5SDimitry Andric       break;
1130b57cec5SDimitry Andric     case 'e':
1140b57cec5SDimitry Andric       m_permissions |= lldb::eFilePermissionsWorldExecute;
1150b57cec5SDimitry Andric       break;
1160b57cec5SDimitry Andric     default:
1179dba64beSDimitry Andric       llvm_unreachable("Unimplemented option");
1180b57cec5SDimitry Andric     }
1190b57cec5SDimitry Andric 
1200b57cec5SDimitry Andric     return error;
1210b57cec5SDimitry Andric   }
1220b57cec5SDimitry Andric 
OptionParsingStarting(ExecutionContext * execution_context)1230b57cec5SDimitry Andric   void OptionParsingStarting(ExecutionContext *execution_context) override {
1240b57cec5SDimitry Andric     m_permissions = 0;
1250b57cec5SDimitry Andric   }
1260b57cec5SDimitry Andric 
GetDefinitions()1270b57cec5SDimitry Andric   llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1280b57cec5SDimitry Andric     return llvm::makeArrayRef(g_permissions_options);
1290b57cec5SDimitry Andric   }
1300b57cec5SDimitry Andric 
1310b57cec5SDimitry Andric   // Instance variables to hold the values for command options.
1320b57cec5SDimitry Andric 
1330b57cec5SDimitry Andric   uint32_t m_permissions;
1340b57cec5SDimitry Andric 
1350b57cec5SDimitry Andric private:
1365ffd83dbSDimitry Andric   OptionPermissions(const OptionPermissions &) = delete;
1375ffd83dbSDimitry Andric   const OptionPermissions &operator=(const OptionPermissions &) = delete;
1380b57cec5SDimitry Andric };
1390b57cec5SDimitry Andric 
1400b57cec5SDimitry Andric // "platform select <platform-name>"
1410b57cec5SDimitry Andric class CommandObjectPlatformSelect : public CommandObjectParsed {
1420b57cec5SDimitry Andric public:
CommandObjectPlatformSelect(CommandInterpreter & interpreter)1430b57cec5SDimitry Andric   CommandObjectPlatformSelect(CommandInterpreter &interpreter)
1440b57cec5SDimitry Andric       : CommandObjectParsed(interpreter, "platform select",
1450b57cec5SDimitry Andric                             "Create a platform if needed and select it as the "
1460b57cec5SDimitry Andric                             "current platform.",
1470b57cec5SDimitry Andric                             "platform select <platform-name>", 0),
1480b57cec5SDimitry Andric         m_option_group(),
1490b57cec5SDimitry Andric         m_platform_options(
1500b57cec5SDimitry Andric             false) // Don't include the "--platform" option by passing false
1510b57cec5SDimitry Andric   {
1520b57cec5SDimitry Andric     m_option_group.Append(&m_platform_options, LLDB_OPT_SET_ALL, 1);
1530b57cec5SDimitry Andric     m_option_group.Finalize();
1540b57cec5SDimitry Andric   }
1550b57cec5SDimitry Andric 
1560b57cec5SDimitry Andric   ~CommandObjectPlatformSelect() override = default;
1570b57cec5SDimitry Andric 
HandleCompletion(CompletionRequest & request)1589dba64beSDimitry Andric   void HandleCompletion(CompletionRequest &request) override {
1590b57cec5SDimitry Andric     CommandCompletions::PlatformPluginNames(GetCommandInterpreter(), request,
1600b57cec5SDimitry Andric                                             nullptr);
1610b57cec5SDimitry Andric   }
1620b57cec5SDimitry Andric 
GetOptions()1630b57cec5SDimitry Andric   Options *GetOptions() override { return &m_option_group; }
1640b57cec5SDimitry Andric 
1650b57cec5SDimitry Andric protected:
DoExecute(Args & args,CommandReturnObject & result)1660b57cec5SDimitry Andric   bool DoExecute(Args &args, CommandReturnObject &result) override {
1670b57cec5SDimitry Andric     if (args.GetArgumentCount() == 1) {
1680b57cec5SDimitry Andric       const char *platform_name = args.GetArgumentAtIndex(0);
1690b57cec5SDimitry Andric       if (platform_name && platform_name[0]) {
1700b57cec5SDimitry Andric         const bool select = true;
1710b57cec5SDimitry Andric         m_platform_options.SetPlatformName(platform_name);
1720b57cec5SDimitry Andric         Status error;
1730b57cec5SDimitry Andric         ArchSpec platform_arch;
1740b57cec5SDimitry Andric         PlatformSP platform_sp(m_platform_options.CreatePlatformWithOptions(
1750b57cec5SDimitry Andric             m_interpreter, ArchSpec(), select, error, platform_arch));
1760b57cec5SDimitry Andric         if (platform_sp) {
1770b57cec5SDimitry Andric           GetDebugger().GetPlatformList().SetSelectedPlatform(platform_sp);
1780b57cec5SDimitry Andric 
1790b57cec5SDimitry Andric           platform_sp->GetStatus(result.GetOutputStream());
1800b57cec5SDimitry Andric           result.SetStatus(eReturnStatusSuccessFinishResult);
1810b57cec5SDimitry Andric         } else {
1820b57cec5SDimitry Andric           result.AppendError(error.AsCString());
1830b57cec5SDimitry Andric         }
1840b57cec5SDimitry Andric       } else {
1850b57cec5SDimitry Andric         result.AppendError("invalid platform name");
1860b57cec5SDimitry Andric       }
1870b57cec5SDimitry Andric     } else {
1880b57cec5SDimitry Andric       result.AppendError(
1890b57cec5SDimitry Andric           "platform create takes a platform name as an argument\n");
1900b57cec5SDimitry Andric     }
1910b57cec5SDimitry Andric     return result.Succeeded();
1920b57cec5SDimitry Andric   }
1930b57cec5SDimitry Andric 
1940b57cec5SDimitry Andric   OptionGroupOptions m_option_group;
1950b57cec5SDimitry Andric   OptionGroupPlatform m_platform_options;
1960b57cec5SDimitry Andric };
1970b57cec5SDimitry Andric 
1980b57cec5SDimitry Andric // "platform list"
1990b57cec5SDimitry Andric class CommandObjectPlatformList : public CommandObjectParsed {
2000b57cec5SDimitry Andric public:
CommandObjectPlatformList(CommandInterpreter & interpreter)2010b57cec5SDimitry Andric   CommandObjectPlatformList(CommandInterpreter &interpreter)
2020b57cec5SDimitry Andric       : CommandObjectParsed(interpreter, "platform list",
2030b57cec5SDimitry Andric                             "List all platforms that are available.", nullptr,
2040b57cec5SDimitry Andric                             0) {}
2050b57cec5SDimitry Andric 
2060b57cec5SDimitry Andric   ~CommandObjectPlatformList() override = default;
2070b57cec5SDimitry Andric 
2080b57cec5SDimitry Andric protected:
DoExecute(Args & args,CommandReturnObject & result)2090b57cec5SDimitry Andric   bool DoExecute(Args &args, CommandReturnObject &result) override {
2100b57cec5SDimitry Andric     Stream &ostrm = result.GetOutputStream();
2110b57cec5SDimitry Andric     ostrm.Printf("Available platforms:\n");
2120b57cec5SDimitry Andric 
2130b57cec5SDimitry Andric     PlatformSP host_platform_sp(Platform::GetHostPlatform());
2140b57cec5SDimitry Andric     ostrm.Printf("%s: %s\n", host_platform_sp->GetPluginName().GetCString(),
2150b57cec5SDimitry Andric                  host_platform_sp->GetDescription());
2160b57cec5SDimitry Andric 
2170b57cec5SDimitry Andric     uint32_t idx;
2180b57cec5SDimitry Andric     for (idx = 0; true; ++idx) {
2190b57cec5SDimitry Andric       const char *plugin_name =
2200b57cec5SDimitry Andric           PluginManager::GetPlatformPluginNameAtIndex(idx);
2210b57cec5SDimitry Andric       if (plugin_name == nullptr)
2220b57cec5SDimitry Andric         break;
2230b57cec5SDimitry Andric       const char *plugin_desc =
2240b57cec5SDimitry Andric           PluginManager::GetPlatformPluginDescriptionAtIndex(idx);
2250b57cec5SDimitry Andric       if (plugin_desc == nullptr)
2260b57cec5SDimitry Andric         break;
2270b57cec5SDimitry Andric       ostrm.Printf("%s: %s\n", plugin_name, plugin_desc);
2280b57cec5SDimitry Andric     }
2290b57cec5SDimitry Andric 
2300b57cec5SDimitry Andric     if (idx == 0) {
2310b57cec5SDimitry Andric       result.AppendError("no platforms are available\n");
2320b57cec5SDimitry Andric     } else
2330b57cec5SDimitry Andric       result.SetStatus(eReturnStatusSuccessFinishResult);
2340b57cec5SDimitry Andric     return result.Succeeded();
2350b57cec5SDimitry Andric   }
2360b57cec5SDimitry Andric };
2370b57cec5SDimitry Andric 
2380b57cec5SDimitry Andric // "platform status"
2390b57cec5SDimitry Andric class CommandObjectPlatformStatus : public CommandObjectParsed {
2400b57cec5SDimitry Andric public:
CommandObjectPlatformStatus(CommandInterpreter & interpreter)2410b57cec5SDimitry Andric   CommandObjectPlatformStatus(CommandInterpreter &interpreter)
2420b57cec5SDimitry Andric       : CommandObjectParsed(interpreter, "platform status",
2430b57cec5SDimitry Andric                             "Display status for the current platform.", nullptr,
2440b57cec5SDimitry Andric                             0) {}
2450b57cec5SDimitry Andric 
2460b57cec5SDimitry Andric   ~CommandObjectPlatformStatus() override = default;
2470b57cec5SDimitry Andric 
2480b57cec5SDimitry Andric protected:
DoExecute(Args & args,CommandReturnObject & result)2490b57cec5SDimitry Andric   bool DoExecute(Args &args, CommandReturnObject &result) override {
2500b57cec5SDimitry Andric     Stream &ostrm = result.GetOutputStream();
2510b57cec5SDimitry Andric 
2520b57cec5SDimitry Andric     Target *target = GetDebugger().GetSelectedTarget().get();
2530b57cec5SDimitry Andric     PlatformSP platform_sp;
2540b57cec5SDimitry Andric     if (target) {
2550b57cec5SDimitry Andric       platform_sp = target->GetPlatform();
2560b57cec5SDimitry Andric     }
2570b57cec5SDimitry Andric     if (!platform_sp) {
2580b57cec5SDimitry Andric       platform_sp = GetDebugger().GetPlatformList().GetSelectedPlatform();
2590b57cec5SDimitry Andric     }
2600b57cec5SDimitry Andric     if (platform_sp) {
2610b57cec5SDimitry Andric       platform_sp->GetStatus(ostrm);
2620b57cec5SDimitry Andric       result.SetStatus(eReturnStatusSuccessFinishResult);
2630b57cec5SDimitry Andric     } else {
2640b57cec5SDimitry Andric       result.AppendError("no platform is currently selected\n");
2650b57cec5SDimitry Andric     }
2660b57cec5SDimitry Andric     return result.Succeeded();
2670b57cec5SDimitry Andric   }
2680b57cec5SDimitry Andric };
2690b57cec5SDimitry Andric 
2700b57cec5SDimitry Andric // "platform connect <connect-url>"
2710b57cec5SDimitry Andric class CommandObjectPlatformConnect : public CommandObjectParsed {
2720b57cec5SDimitry Andric public:
CommandObjectPlatformConnect(CommandInterpreter & interpreter)2730b57cec5SDimitry Andric   CommandObjectPlatformConnect(CommandInterpreter &interpreter)
2740b57cec5SDimitry Andric       : CommandObjectParsed(
2750b57cec5SDimitry Andric             interpreter, "platform connect",
2760b57cec5SDimitry Andric             "Select the current platform by providing a connection URL.",
2770b57cec5SDimitry Andric             "platform connect <connect-url>", 0) {}
2780b57cec5SDimitry Andric 
2790b57cec5SDimitry Andric   ~CommandObjectPlatformConnect() override = default;
2800b57cec5SDimitry Andric 
2810b57cec5SDimitry Andric protected:
DoExecute(Args & args,CommandReturnObject & result)2820b57cec5SDimitry Andric   bool DoExecute(Args &args, CommandReturnObject &result) override {
2830b57cec5SDimitry Andric     Stream &ostrm = result.GetOutputStream();
2840b57cec5SDimitry Andric 
2850b57cec5SDimitry Andric     PlatformSP platform_sp(
2860b57cec5SDimitry Andric         GetDebugger().GetPlatformList().GetSelectedPlatform());
2870b57cec5SDimitry Andric     if (platform_sp) {
2880b57cec5SDimitry Andric       Status error(platform_sp->ConnectRemote(args));
2890b57cec5SDimitry Andric       if (error.Success()) {
2900b57cec5SDimitry Andric         platform_sp->GetStatus(ostrm);
2910b57cec5SDimitry Andric         result.SetStatus(eReturnStatusSuccessFinishResult);
2920b57cec5SDimitry Andric 
2930b57cec5SDimitry Andric         platform_sp->ConnectToWaitingProcesses(GetDebugger(), error);
2940b57cec5SDimitry Andric         if (error.Fail()) {
2950b57cec5SDimitry Andric           result.AppendError(error.AsCString());
2960b57cec5SDimitry Andric         }
2970b57cec5SDimitry Andric       } else {
2980b57cec5SDimitry Andric         result.AppendErrorWithFormat("%s\n", error.AsCString());
2990b57cec5SDimitry Andric       }
3000b57cec5SDimitry Andric     } else {
3010b57cec5SDimitry Andric       result.AppendError("no platform is currently selected\n");
3020b57cec5SDimitry Andric     }
3030b57cec5SDimitry Andric     return result.Succeeded();
3040b57cec5SDimitry Andric   }
3050b57cec5SDimitry Andric 
GetOptions()3060b57cec5SDimitry Andric   Options *GetOptions() override {
3070b57cec5SDimitry Andric     PlatformSP platform_sp(
3080b57cec5SDimitry Andric         GetDebugger().GetPlatformList().GetSelectedPlatform());
3090b57cec5SDimitry Andric     OptionGroupOptions *m_platform_options = nullptr;
3100b57cec5SDimitry Andric     if (platform_sp) {
3110b57cec5SDimitry Andric       m_platform_options = platform_sp->GetConnectionOptions(m_interpreter);
3120b57cec5SDimitry Andric       if (m_platform_options != nullptr && !m_platform_options->m_did_finalize)
3130b57cec5SDimitry Andric         m_platform_options->Finalize();
3140b57cec5SDimitry Andric     }
3150b57cec5SDimitry Andric     return m_platform_options;
3160b57cec5SDimitry Andric   }
3170b57cec5SDimitry Andric };
3180b57cec5SDimitry Andric 
3190b57cec5SDimitry Andric // "platform disconnect"
3200b57cec5SDimitry Andric class CommandObjectPlatformDisconnect : public CommandObjectParsed {
3210b57cec5SDimitry Andric public:
CommandObjectPlatformDisconnect(CommandInterpreter & interpreter)3220b57cec5SDimitry Andric   CommandObjectPlatformDisconnect(CommandInterpreter &interpreter)
3230b57cec5SDimitry Andric       : CommandObjectParsed(interpreter, "platform disconnect",
3240b57cec5SDimitry Andric                             "Disconnect from the current platform.",
3250b57cec5SDimitry Andric                             "platform disconnect", 0) {}
3260b57cec5SDimitry Andric 
3270b57cec5SDimitry Andric   ~CommandObjectPlatformDisconnect() override = default;
3280b57cec5SDimitry Andric 
3290b57cec5SDimitry Andric protected:
DoExecute(Args & args,CommandReturnObject & result)3300b57cec5SDimitry Andric   bool DoExecute(Args &args, CommandReturnObject &result) override {
3310b57cec5SDimitry Andric     PlatformSP platform_sp(
3320b57cec5SDimitry Andric         GetDebugger().GetPlatformList().GetSelectedPlatform());
3330b57cec5SDimitry Andric     if (platform_sp) {
3340b57cec5SDimitry Andric       if (args.GetArgumentCount() == 0) {
3350b57cec5SDimitry Andric         Status error;
3360b57cec5SDimitry Andric 
3370b57cec5SDimitry Andric         if (platform_sp->IsConnected()) {
3380b57cec5SDimitry Andric           // Cache the instance name if there is one since we are about to
3390b57cec5SDimitry Andric           // disconnect and the name might go with it.
3400b57cec5SDimitry Andric           const char *hostname_cstr = platform_sp->GetHostname();
3410b57cec5SDimitry Andric           std::string hostname;
3420b57cec5SDimitry Andric           if (hostname_cstr)
3430b57cec5SDimitry Andric             hostname.assign(hostname_cstr);
3440b57cec5SDimitry Andric 
3450b57cec5SDimitry Andric           error = platform_sp->DisconnectRemote();
3460b57cec5SDimitry Andric           if (error.Success()) {
3470b57cec5SDimitry Andric             Stream &ostrm = result.GetOutputStream();
3480b57cec5SDimitry Andric             if (hostname.empty())
3490b57cec5SDimitry Andric               ostrm.Printf("Disconnected from \"%s\"\n",
3500b57cec5SDimitry Andric                            platform_sp->GetPluginName().GetCString());
3510b57cec5SDimitry Andric             else
3520b57cec5SDimitry Andric               ostrm.Printf("Disconnected from \"%s\"\n", hostname.c_str());
3530b57cec5SDimitry Andric             result.SetStatus(eReturnStatusSuccessFinishResult);
3540b57cec5SDimitry Andric           } else {
3550b57cec5SDimitry Andric             result.AppendErrorWithFormat("%s", error.AsCString());
3560b57cec5SDimitry Andric           }
3570b57cec5SDimitry Andric         } else {
3580b57cec5SDimitry Andric           // Not connected...
3590b57cec5SDimitry Andric           result.AppendErrorWithFormat(
3600b57cec5SDimitry Andric               "not connected to '%s'",
3610b57cec5SDimitry Andric               platform_sp->GetPluginName().GetCString());
3620b57cec5SDimitry Andric         }
3630b57cec5SDimitry Andric       } else {
3640b57cec5SDimitry Andric         // Bad args
3650b57cec5SDimitry Andric         result.AppendError(
3660b57cec5SDimitry Andric             "\"platform disconnect\" doesn't take any arguments");
3670b57cec5SDimitry Andric       }
3680b57cec5SDimitry Andric     } else {
3690b57cec5SDimitry Andric       result.AppendError("no platform is currently selected");
3700b57cec5SDimitry Andric     }
3710b57cec5SDimitry Andric     return result.Succeeded();
3720b57cec5SDimitry Andric   }
3730b57cec5SDimitry Andric };
3740b57cec5SDimitry Andric 
3750b57cec5SDimitry Andric // "platform settings"
3760b57cec5SDimitry Andric class CommandObjectPlatformSettings : public CommandObjectParsed {
3770b57cec5SDimitry Andric public:
CommandObjectPlatformSettings(CommandInterpreter & interpreter)3780b57cec5SDimitry Andric   CommandObjectPlatformSettings(CommandInterpreter &interpreter)
3790b57cec5SDimitry Andric       : CommandObjectParsed(interpreter, "platform settings",
3800b57cec5SDimitry Andric                             "Set settings for the current target's platform, "
3810b57cec5SDimitry Andric                             "or for a platform by name.",
3820b57cec5SDimitry Andric                             "platform settings", 0),
3830b57cec5SDimitry Andric         m_options(),
384af732203SDimitry Andric         m_option_working_dir(LLDB_OPT_SET_1, false, "working-dir", 'w',
385af732203SDimitry Andric                              CommandCompletions::eRemoteDiskDirectoryCompletion,
3860b57cec5SDimitry Andric                              eArgTypePath,
3870b57cec5SDimitry Andric                              "The working directory for the platform.") {
3880b57cec5SDimitry Andric     m_options.Append(&m_option_working_dir, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
3890b57cec5SDimitry Andric   }
3900b57cec5SDimitry Andric 
3910b57cec5SDimitry Andric   ~CommandObjectPlatformSettings() override = default;
3920b57cec5SDimitry Andric 
3930b57cec5SDimitry Andric protected:
DoExecute(Args & args,CommandReturnObject & result)3940b57cec5SDimitry Andric   bool DoExecute(Args &args, CommandReturnObject &result) override {
3950b57cec5SDimitry Andric     PlatformSP platform_sp(
3960b57cec5SDimitry Andric         GetDebugger().GetPlatformList().GetSelectedPlatform());
3970b57cec5SDimitry Andric     if (platform_sp) {
3980b57cec5SDimitry Andric       if (m_option_working_dir.GetOptionValue().OptionWasSet())
3990b57cec5SDimitry Andric         platform_sp->SetWorkingDirectory(
4000b57cec5SDimitry Andric             m_option_working_dir.GetOptionValue().GetCurrentValue());
4010b57cec5SDimitry Andric     } else {
4020b57cec5SDimitry Andric       result.AppendError("no platform is currently selected");
4030b57cec5SDimitry Andric     }
4040b57cec5SDimitry Andric     return result.Succeeded();
4050b57cec5SDimitry Andric   }
4060b57cec5SDimitry Andric 
GetOptions()4070b57cec5SDimitry Andric   Options *GetOptions() override {
4080b57cec5SDimitry Andric     if (!m_options.DidFinalize())
4090b57cec5SDimitry Andric       m_options.Finalize();
4100b57cec5SDimitry Andric     return &m_options;
4110b57cec5SDimitry Andric   }
4120b57cec5SDimitry Andric 
4130b57cec5SDimitry Andric   OptionGroupOptions m_options;
4140b57cec5SDimitry Andric   OptionGroupFile m_option_working_dir;
4150b57cec5SDimitry Andric };
4160b57cec5SDimitry Andric 
4170b57cec5SDimitry Andric // "platform mkdir"
4180b57cec5SDimitry Andric class CommandObjectPlatformMkDir : public CommandObjectParsed {
4190b57cec5SDimitry Andric public:
CommandObjectPlatformMkDir(CommandInterpreter & interpreter)4200b57cec5SDimitry Andric   CommandObjectPlatformMkDir(CommandInterpreter &interpreter)
4210b57cec5SDimitry Andric       : CommandObjectParsed(interpreter, "platform mkdir",
4220b57cec5SDimitry Andric                             "Make a new directory on the remote end.", nullptr,
4230b57cec5SDimitry Andric                             0),
4240b57cec5SDimitry Andric         m_options() {}
4250b57cec5SDimitry Andric 
4260b57cec5SDimitry Andric   ~CommandObjectPlatformMkDir() override = default;
4270b57cec5SDimitry Andric 
DoExecute(Args & args,CommandReturnObject & result)4280b57cec5SDimitry Andric   bool DoExecute(Args &args, CommandReturnObject &result) override {
4290b57cec5SDimitry Andric     PlatformSP platform_sp(
4300b57cec5SDimitry Andric         GetDebugger().GetPlatformList().GetSelectedPlatform());
4310b57cec5SDimitry Andric     if (platform_sp) {
4320b57cec5SDimitry Andric       std::string cmd_line;
4330b57cec5SDimitry Andric       args.GetCommandString(cmd_line);
4340b57cec5SDimitry Andric       uint32_t mode;
4350b57cec5SDimitry Andric       const OptionPermissions *options_permissions =
4360b57cec5SDimitry Andric           (const OptionPermissions *)m_options.GetGroupWithOption('r');
4370b57cec5SDimitry Andric       if (options_permissions)
4380b57cec5SDimitry Andric         mode = options_permissions->m_permissions;
4390b57cec5SDimitry Andric       else
4400b57cec5SDimitry Andric         mode = lldb::eFilePermissionsUserRWX | lldb::eFilePermissionsGroupRWX |
4410b57cec5SDimitry Andric                lldb::eFilePermissionsWorldRX;
4420b57cec5SDimitry Andric       Status error = platform_sp->MakeDirectory(FileSpec(cmd_line), mode);
4430b57cec5SDimitry Andric       if (error.Success()) {
4440b57cec5SDimitry Andric         result.SetStatus(eReturnStatusSuccessFinishResult);
4450b57cec5SDimitry Andric       } else {
4460b57cec5SDimitry Andric         result.AppendError(error.AsCString());
4470b57cec5SDimitry Andric       }
4480b57cec5SDimitry Andric     } else {
4490b57cec5SDimitry Andric       result.AppendError("no platform currently selected\n");
4500b57cec5SDimitry Andric     }
4510b57cec5SDimitry Andric     return result.Succeeded();
4520b57cec5SDimitry Andric   }
4530b57cec5SDimitry Andric 
GetOptions()4540b57cec5SDimitry Andric   Options *GetOptions() override {
4550b57cec5SDimitry Andric     if (!m_options.DidFinalize()) {
4560b57cec5SDimitry Andric       m_options.Append(new OptionPermissions());
4570b57cec5SDimitry Andric       m_options.Finalize();
4580b57cec5SDimitry Andric     }
4590b57cec5SDimitry Andric     return &m_options;
4600b57cec5SDimitry Andric   }
4610b57cec5SDimitry Andric 
4620b57cec5SDimitry Andric   OptionGroupOptions m_options;
4630b57cec5SDimitry Andric };
4640b57cec5SDimitry Andric 
4650b57cec5SDimitry Andric // "platform fopen"
4660b57cec5SDimitry Andric class CommandObjectPlatformFOpen : public CommandObjectParsed {
4670b57cec5SDimitry Andric public:
CommandObjectPlatformFOpen(CommandInterpreter & interpreter)4680b57cec5SDimitry Andric   CommandObjectPlatformFOpen(CommandInterpreter &interpreter)
4690b57cec5SDimitry Andric       : CommandObjectParsed(interpreter, "platform file open",
4700b57cec5SDimitry Andric                             "Open a file on the remote end.", nullptr, 0),
4710b57cec5SDimitry Andric         m_options() {}
4720b57cec5SDimitry Andric 
4730b57cec5SDimitry Andric   ~CommandObjectPlatformFOpen() override = default;
4740b57cec5SDimitry Andric 
475af732203SDimitry Andric   void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)476af732203SDimitry Andric   HandleArgumentCompletion(CompletionRequest &request,
477af732203SDimitry Andric                            OptionElementVector &opt_element_vector) override {
478af732203SDimitry Andric     if (request.GetCursorIndex() == 0)
479af732203SDimitry Andric       CommandCompletions::InvokeCommonCompletionCallbacks(
480af732203SDimitry Andric           GetCommandInterpreter(),
481af732203SDimitry Andric           CommandCompletions::eRemoteDiskFileCompletion, request, nullptr);
482af732203SDimitry Andric   }
483af732203SDimitry Andric 
DoExecute(Args & args,CommandReturnObject & result)4840b57cec5SDimitry Andric   bool DoExecute(Args &args, CommandReturnObject &result) override {
4850b57cec5SDimitry Andric     PlatformSP platform_sp(
4860b57cec5SDimitry Andric         GetDebugger().GetPlatformList().GetSelectedPlatform());
4870b57cec5SDimitry Andric     if (platform_sp) {
4880b57cec5SDimitry Andric       Status error;
4890b57cec5SDimitry Andric       std::string cmd_line;
4900b57cec5SDimitry Andric       args.GetCommandString(cmd_line);
4910b57cec5SDimitry Andric       mode_t perms;
4920b57cec5SDimitry Andric       const OptionPermissions *options_permissions =
4930b57cec5SDimitry Andric           (const OptionPermissions *)m_options.GetGroupWithOption('r');
4940b57cec5SDimitry Andric       if (options_permissions)
4950b57cec5SDimitry Andric         perms = options_permissions->m_permissions;
4960b57cec5SDimitry Andric       else
4970b57cec5SDimitry Andric         perms = lldb::eFilePermissionsUserRW | lldb::eFilePermissionsGroupRW |
4980b57cec5SDimitry Andric                 lldb::eFilePermissionsWorldRead;
4990b57cec5SDimitry Andric       lldb::user_id_t fd = platform_sp->OpenFile(
5000b57cec5SDimitry Andric           FileSpec(cmd_line),
5010b57cec5SDimitry Andric           File::eOpenOptionRead | File::eOpenOptionWrite |
5020b57cec5SDimitry Andric               File::eOpenOptionAppend | File::eOpenOptionCanCreate,
5030b57cec5SDimitry Andric           perms, error);
5040b57cec5SDimitry Andric       if (error.Success()) {
5050b57cec5SDimitry Andric         result.AppendMessageWithFormat("File Descriptor = %" PRIu64 "\n", fd);
5060b57cec5SDimitry Andric         result.SetStatus(eReturnStatusSuccessFinishResult);
5070b57cec5SDimitry Andric       } else {
5080b57cec5SDimitry Andric         result.AppendError(error.AsCString());
5090b57cec5SDimitry Andric       }
5100b57cec5SDimitry Andric     } else {
5110b57cec5SDimitry Andric       result.AppendError("no platform currently selected\n");
5120b57cec5SDimitry Andric     }
5130b57cec5SDimitry Andric     return result.Succeeded();
5140b57cec5SDimitry Andric   }
5150b57cec5SDimitry Andric 
GetOptions()5160b57cec5SDimitry Andric   Options *GetOptions() override {
5170b57cec5SDimitry Andric     if (!m_options.DidFinalize()) {
5180b57cec5SDimitry Andric       m_options.Append(new OptionPermissions());
5190b57cec5SDimitry Andric       m_options.Finalize();
5200b57cec5SDimitry Andric     }
5210b57cec5SDimitry Andric     return &m_options;
5220b57cec5SDimitry Andric   }
5230b57cec5SDimitry Andric 
5240b57cec5SDimitry Andric   OptionGroupOptions m_options;
5250b57cec5SDimitry Andric };
5260b57cec5SDimitry Andric 
5270b57cec5SDimitry Andric // "platform fclose"
5280b57cec5SDimitry Andric class CommandObjectPlatformFClose : public CommandObjectParsed {
5290b57cec5SDimitry Andric public:
CommandObjectPlatformFClose(CommandInterpreter & interpreter)5300b57cec5SDimitry Andric   CommandObjectPlatformFClose(CommandInterpreter &interpreter)
5310b57cec5SDimitry Andric       : CommandObjectParsed(interpreter, "platform file close",
5320b57cec5SDimitry Andric                             "Close a file on the remote end.", nullptr, 0) {}
5330b57cec5SDimitry Andric 
5340b57cec5SDimitry Andric   ~CommandObjectPlatformFClose() override = default;
5350b57cec5SDimitry Andric 
DoExecute(Args & args,CommandReturnObject & result)5360b57cec5SDimitry Andric   bool DoExecute(Args &args, CommandReturnObject &result) override {
5370b57cec5SDimitry Andric     PlatformSP platform_sp(
5380b57cec5SDimitry Andric         GetDebugger().GetPlatformList().GetSelectedPlatform());
5390b57cec5SDimitry Andric     if (platform_sp) {
5400b57cec5SDimitry Andric       std::string cmd_line;
5410b57cec5SDimitry Andric       args.GetCommandString(cmd_line);
5425ffd83dbSDimitry Andric       lldb::user_id_t fd;
5435ffd83dbSDimitry Andric       if (!llvm::to_integer(cmd_line, fd)) {
5445ffd83dbSDimitry Andric         result.AppendErrorWithFormatv("'{0}' is not a valid file descriptor.\n",
5455ffd83dbSDimitry Andric                                       cmd_line);
5465ffd83dbSDimitry Andric         return result.Succeeded();
5475ffd83dbSDimitry Andric       }
5480b57cec5SDimitry Andric       Status error;
5490b57cec5SDimitry Andric       bool success = platform_sp->CloseFile(fd, error);
5500b57cec5SDimitry Andric       if (success) {
5510b57cec5SDimitry Andric         result.AppendMessageWithFormat("file %" PRIu64 " closed.\n", fd);
5520b57cec5SDimitry Andric         result.SetStatus(eReturnStatusSuccessFinishResult);
5530b57cec5SDimitry Andric       } else {
5540b57cec5SDimitry Andric         result.AppendError(error.AsCString());
5550b57cec5SDimitry Andric       }
5560b57cec5SDimitry Andric     } else {
5570b57cec5SDimitry Andric       result.AppendError("no platform currently selected\n");
5580b57cec5SDimitry Andric     }
5590b57cec5SDimitry Andric     return result.Succeeded();
5600b57cec5SDimitry Andric   }
5610b57cec5SDimitry Andric };
5620b57cec5SDimitry Andric 
5630b57cec5SDimitry Andric // "platform fread"
5640b57cec5SDimitry Andric 
5659dba64beSDimitry Andric #define LLDB_OPTIONS_platform_fread
5669dba64beSDimitry Andric #include "CommandOptions.inc"
5670b57cec5SDimitry Andric 
5680b57cec5SDimitry Andric class CommandObjectPlatformFRead : public CommandObjectParsed {
5690b57cec5SDimitry Andric public:
CommandObjectPlatformFRead(CommandInterpreter & interpreter)5700b57cec5SDimitry Andric   CommandObjectPlatformFRead(CommandInterpreter &interpreter)
5710b57cec5SDimitry Andric       : CommandObjectParsed(interpreter, "platform file read",
5720b57cec5SDimitry Andric                             "Read data from a file on the remote end.", nullptr,
5730b57cec5SDimitry Andric                             0),
5740b57cec5SDimitry Andric         m_options() {}
5750b57cec5SDimitry Andric 
5760b57cec5SDimitry Andric   ~CommandObjectPlatformFRead() override = default;
5770b57cec5SDimitry Andric 
DoExecute(Args & args,CommandReturnObject & result)5780b57cec5SDimitry Andric   bool DoExecute(Args &args, CommandReturnObject &result) override {
5790b57cec5SDimitry Andric     PlatformSP platform_sp(
5800b57cec5SDimitry Andric         GetDebugger().GetPlatformList().GetSelectedPlatform());
5810b57cec5SDimitry Andric     if (platform_sp) {
5820b57cec5SDimitry Andric       std::string cmd_line;
5830b57cec5SDimitry Andric       args.GetCommandString(cmd_line);
5845ffd83dbSDimitry Andric       lldb::user_id_t fd;
5855ffd83dbSDimitry Andric       if (!llvm::to_integer(cmd_line, fd)) {
5865ffd83dbSDimitry Andric         result.AppendErrorWithFormatv("'{0}' is not a valid file descriptor.\n",
5875ffd83dbSDimitry Andric                                       cmd_line);
5885ffd83dbSDimitry Andric         return result.Succeeded();
5895ffd83dbSDimitry Andric       }
5900b57cec5SDimitry Andric       std::string buffer(m_options.m_count, 0);
5910b57cec5SDimitry Andric       Status error;
5920b57cec5SDimitry Andric       uint32_t retcode = platform_sp->ReadFile(
5930b57cec5SDimitry Andric           fd, m_options.m_offset, &buffer[0], m_options.m_count, error);
5940b57cec5SDimitry Andric       result.AppendMessageWithFormat("Return = %d\n", retcode);
5950b57cec5SDimitry Andric       result.AppendMessageWithFormat("Data = \"%s\"\n", buffer.c_str());
5960b57cec5SDimitry Andric       result.SetStatus(eReturnStatusSuccessFinishResult);
5970b57cec5SDimitry Andric     } else {
5980b57cec5SDimitry Andric       result.AppendError("no platform currently selected\n");
5990b57cec5SDimitry Andric     }
6000b57cec5SDimitry Andric     return result.Succeeded();
6010b57cec5SDimitry Andric   }
6020b57cec5SDimitry Andric 
GetOptions()6030b57cec5SDimitry Andric   Options *GetOptions() override { return &m_options; }
6040b57cec5SDimitry Andric 
6050b57cec5SDimitry Andric protected:
6060b57cec5SDimitry Andric   class CommandOptions : public Options {
6070b57cec5SDimitry Andric   public:
CommandOptions()6080b57cec5SDimitry Andric     CommandOptions() : Options() {}
6090b57cec5SDimitry Andric 
6100b57cec5SDimitry Andric     ~CommandOptions() override = default;
6110b57cec5SDimitry Andric 
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)6120b57cec5SDimitry Andric     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
6130b57cec5SDimitry Andric                           ExecutionContext *execution_context) override {
6140b57cec5SDimitry Andric       Status error;
6150b57cec5SDimitry Andric       char short_option = (char)m_getopt_table[option_idx].val;
6160b57cec5SDimitry Andric 
6170b57cec5SDimitry Andric       switch (short_option) {
6180b57cec5SDimitry Andric       case 'o':
6190b57cec5SDimitry Andric         if (option_arg.getAsInteger(0, m_offset))
6200b57cec5SDimitry Andric           error.SetErrorStringWithFormat("invalid offset: '%s'",
6210b57cec5SDimitry Andric                                          option_arg.str().c_str());
6220b57cec5SDimitry Andric         break;
6230b57cec5SDimitry Andric       case 'c':
6240b57cec5SDimitry Andric         if (option_arg.getAsInteger(0, m_count))
6250b57cec5SDimitry Andric           error.SetErrorStringWithFormat("invalid offset: '%s'",
6260b57cec5SDimitry Andric                                          option_arg.str().c_str());
6270b57cec5SDimitry Andric         break;
6280b57cec5SDimitry Andric       default:
6299dba64beSDimitry Andric         llvm_unreachable("Unimplemented option");
6300b57cec5SDimitry Andric       }
6310b57cec5SDimitry Andric 
6320b57cec5SDimitry Andric       return error;
6330b57cec5SDimitry Andric     }
6340b57cec5SDimitry Andric 
OptionParsingStarting(ExecutionContext * execution_context)6350b57cec5SDimitry Andric     void OptionParsingStarting(ExecutionContext *execution_context) override {
6360b57cec5SDimitry Andric       m_offset = 0;
6370b57cec5SDimitry Andric       m_count = 1;
6380b57cec5SDimitry Andric     }
6390b57cec5SDimitry Andric 
GetDefinitions()6400b57cec5SDimitry Andric     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
6410b57cec5SDimitry Andric       return llvm::makeArrayRef(g_platform_fread_options);
6420b57cec5SDimitry Andric     }
6430b57cec5SDimitry Andric 
6440b57cec5SDimitry Andric     // Instance variables to hold the values for command options.
6450b57cec5SDimitry Andric 
6460b57cec5SDimitry Andric     uint32_t m_offset;
6470b57cec5SDimitry Andric     uint32_t m_count;
6480b57cec5SDimitry Andric   };
6490b57cec5SDimitry Andric 
6500b57cec5SDimitry Andric   CommandOptions m_options;
6510b57cec5SDimitry Andric };
6520b57cec5SDimitry Andric 
6530b57cec5SDimitry Andric // "platform fwrite"
6540b57cec5SDimitry Andric 
6559dba64beSDimitry Andric #define LLDB_OPTIONS_platform_fwrite
6569dba64beSDimitry Andric #include "CommandOptions.inc"
6570b57cec5SDimitry Andric 
6580b57cec5SDimitry Andric class CommandObjectPlatformFWrite : public CommandObjectParsed {
6590b57cec5SDimitry Andric public:
CommandObjectPlatformFWrite(CommandInterpreter & interpreter)6600b57cec5SDimitry Andric   CommandObjectPlatformFWrite(CommandInterpreter &interpreter)
6610b57cec5SDimitry Andric       : CommandObjectParsed(interpreter, "platform file write",
6620b57cec5SDimitry Andric                             "Write data to a file on the remote end.", nullptr,
6630b57cec5SDimitry Andric                             0),
6640b57cec5SDimitry Andric         m_options() {}
6650b57cec5SDimitry Andric 
6660b57cec5SDimitry Andric   ~CommandObjectPlatformFWrite() override = default;
6670b57cec5SDimitry Andric 
DoExecute(Args & args,CommandReturnObject & result)6680b57cec5SDimitry Andric   bool DoExecute(Args &args, CommandReturnObject &result) override {
6690b57cec5SDimitry Andric     PlatformSP platform_sp(
6700b57cec5SDimitry Andric         GetDebugger().GetPlatformList().GetSelectedPlatform());
6710b57cec5SDimitry Andric     if (platform_sp) {
6720b57cec5SDimitry Andric       std::string cmd_line;
6730b57cec5SDimitry Andric       args.GetCommandString(cmd_line);
6740b57cec5SDimitry Andric       Status error;
6755ffd83dbSDimitry Andric       lldb::user_id_t fd;
6765ffd83dbSDimitry Andric       if (!llvm::to_integer(cmd_line, fd)) {
6775ffd83dbSDimitry Andric         result.AppendErrorWithFormatv("'{0}' is not a valid file descriptor.",
6785ffd83dbSDimitry Andric                                       cmd_line);
6795ffd83dbSDimitry Andric         return result.Succeeded();
6805ffd83dbSDimitry Andric       }
6810b57cec5SDimitry Andric       uint32_t retcode =
6820b57cec5SDimitry Andric           platform_sp->WriteFile(fd, m_options.m_offset, &m_options.m_data[0],
6830b57cec5SDimitry Andric                                  m_options.m_data.size(), error);
6840b57cec5SDimitry Andric       result.AppendMessageWithFormat("Return = %d\n", retcode);
6850b57cec5SDimitry Andric       result.SetStatus(eReturnStatusSuccessFinishResult);
6860b57cec5SDimitry Andric     } else {
6870b57cec5SDimitry Andric       result.AppendError("no platform currently selected\n");
6880b57cec5SDimitry Andric     }
6890b57cec5SDimitry Andric     return result.Succeeded();
6900b57cec5SDimitry Andric   }
6910b57cec5SDimitry Andric 
GetOptions()6920b57cec5SDimitry Andric   Options *GetOptions() override { return &m_options; }
6930b57cec5SDimitry Andric 
6940b57cec5SDimitry Andric protected:
6950b57cec5SDimitry Andric   class CommandOptions : public Options {
6960b57cec5SDimitry Andric   public:
CommandOptions()6970b57cec5SDimitry Andric     CommandOptions() : Options() {}
6980b57cec5SDimitry Andric 
6990b57cec5SDimitry Andric     ~CommandOptions() override = default;
7000b57cec5SDimitry Andric 
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)7010b57cec5SDimitry Andric     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
7020b57cec5SDimitry Andric                           ExecutionContext *execution_context) override {
7030b57cec5SDimitry Andric       Status error;
7040b57cec5SDimitry Andric       char short_option = (char)m_getopt_table[option_idx].val;
7050b57cec5SDimitry Andric 
7060b57cec5SDimitry Andric       switch (short_option) {
7070b57cec5SDimitry Andric       case 'o':
7080b57cec5SDimitry Andric         if (option_arg.getAsInteger(0, m_offset))
7090b57cec5SDimitry Andric           error.SetErrorStringWithFormat("invalid offset: '%s'",
7100b57cec5SDimitry Andric                                          option_arg.str().c_str());
7110b57cec5SDimitry Andric         break;
7120b57cec5SDimitry Andric       case 'd':
7135ffd83dbSDimitry Andric         m_data.assign(std::string(option_arg));
7140b57cec5SDimitry Andric         break;
7150b57cec5SDimitry Andric       default:
7169dba64beSDimitry Andric         llvm_unreachable("Unimplemented option");
7170b57cec5SDimitry Andric       }
7180b57cec5SDimitry Andric 
7190b57cec5SDimitry Andric       return error;
7200b57cec5SDimitry Andric     }
7210b57cec5SDimitry Andric 
OptionParsingStarting(ExecutionContext * execution_context)7220b57cec5SDimitry Andric     void OptionParsingStarting(ExecutionContext *execution_context) override {
7230b57cec5SDimitry Andric       m_offset = 0;
7240b57cec5SDimitry Andric       m_data.clear();
7250b57cec5SDimitry Andric     }
7260b57cec5SDimitry Andric 
GetDefinitions()7270b57cec5SDimitry Andric     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
7280b57cec5SDimitry Andric       return llvm::makeArrayRef(g_platform_fwrite_options);
7290b57cec5SDimitry Andric     }
7300b57cec5SDimitry Andric 
7310b57cec5SDimitry Andric     // Instance variables to hold the values for command options.
7320b57cec5SDimitry Andric 
7330b57cec5SDimitry Andric     uint32_t m_offset;
7340b57cec5SDimitry Andric     std::string m_data;
7350b57cec5SDimitry Andric   };
7360b57cec5SDimitry Andric 
7370b57cec5SDimitry Andric   CommandOptions m_options;
7380b57cec5SDimitry Andric };
7390b57cec5SDimitry Andric 
7400b57cec5SDimitry Andric class CommandObjectPlatformFile : public CommandObjectMultiword {
7410b57cec5SDimitry Andric public:
7420b57cec5SDimitry Andric   // Constructors and Destructors
CommandObjectPlatformFile(CommandInterpreter & interpreter)7430b57cec5SDimitry Andric   CommandObjectPlatformFile(CommandInterpreter &interpreter)
7440b57cec5SDimitry Andric       : CommandObjectMultiword(
7450b57cec5SDimitry Andric             interpreter, "platform file",
7460b57cec5SDimitry Andric             "Commands to access files on the current platform.",
7470b57cec5SDimitry Andric             "platform file [open|close|read|write] ...") {
7480b57cec5SDimitry Andric     LoadSubCommand(
7490b57cec5SDimitry Andric         "open", CommandObjectSP(new CommandObjectPlatformFOpen(interpreter)));
7500b57cec5SDimitry Andric     LoadSubCommand(
7510b57cec5SDimitry Andric         "close", CommandObjectSP(new CommandObjectPlatformFClose(interpreter)));
7520b57cec5SDimitry Andric     LoadSubCommand(
7530b57cec5SDimitry Andric         "read", CommandObjectSP(new CommandObjectPlatformFRead(interpreter)));
7540b57cec5SDimitry Andric     LoadSubCommand(
7550b57cec5SDimitry Andric         "write", CommandObjectSP(new CommandObjectPlatformFWrite(interpreter)));
7560b57cec5SDimitry Andric   }
7570b57cec5SDimitry Andric 
7580b57cec5SDimitry Andric   ~CommandObjectPlatformFile() override = default;
7590b57cec5SDimitry Andric 
7600b57cec5SDimitry Andric private:
7610b57cec5SDimitry Andric   // For CommandObjectPlatform only
7625ffd83dbSDimitry Andric   CommandObjectPlatformFile(const CommandObjectPlatformFile &) = delete;
7635ffd83dbSDimitry Andric   const CommandObjectPlatformFile &
7645ffd83dbSDimitry Andric   operator=(const CommandObjectPlatformFile &) = delete;
7650b57cec5SDimitry Andric };
7660b57cec5SDimitry Andric 
7670b57cec5SDimitry Andric // "platform get-file remote-file-path host-file-path"
7680b57cec5SDimitry Andric class CommandObjectPlatformGetFile : public CommandObjectParsed {
7690b57cec5SDimitry Andric public:
CommandObjectPlatformGetFile(CommandInterpreter & interpreter)7700b57cec5SDimitry Andric   CommandObjectPlatformGetFile(CommandInterpreter &interpreter)
7710b57cec5SDimitry Andric       : CommandObjectParsed(
7720b57cec5SDimitry Andric             interpreter, "platform get-file",
7730b57cec5SDimitry Andric             "Transfer a file from the remote end to the local host.",
7740b57cec5SDimitry Andric             "platform get-file <remote-file-spec> <local-file-spec>", 0) {
7750b57cec5SDimitry Andric     SetHelpLong(
7760b57cec5SDimitry Andric         R"(Examples:
7770b57cec5SDimitry Andric 
7780b57cec5SDimitry Andric (lldb) platform get-file /the/remote/file/path /the/local/file/path
7790b57cec5SDimitry Andric 
7800b57cec5SDimitry Andric     Transfer a file from the remote end with file path /the/remote/file/path to the local host.)");
7810b57cec5SDimitry Andric 
7820b57cec5SDimitry Andric     CommandArgumentEntry arg1, arg2;
7830b57cec5SDimitry Andric     CommandArgumentData file_arg_remote, file_arg_host;
7840b57cec5SDimitry Andric 
7850b57cec5SDimitry Andric     // Define the first (and only) variant of this arg.
7860b57cec5SDimitry Andric     file_arg_remote.arg_type = eArgTypeFilename;
7870b57cec5SDimitry Andric     file_arg_remote.arg_repetition = eArgRepeatPlain;
7880b57cec5SDimitry Andric     // There is only one variant this argument could be; put it into the
7890b57cec5SDimitry Andric     // argument entry.
7900b57cec5SDimitry Andric     arg1.push_back(file_arg_remote);
7910b57cec5SDimitry Andric 
7920b57cec5SDimitry Andric     // Define the second (and only) variant of this arg.
7930b57cec5SDimitry Andric     file_arg_host.arg_type = eArgTypeFilename;
7940b57cec5SDimitry Andric     file_arg_host.arg_repetition = eArgRepeatPlain;
7950b57cec5SDimitry Andric     // There is only one variant this argument could be; put it into the
7960b57cec5SDimitry Andric     // argument entry.
7970b57cec5SDimitry Andric     arg2.push_back(file_arg_host);
7980b57cec5SDimitry Andric 
7990b57cec5SDimitry Andric     // Push the data for the first and the second arguments into the
8000b57cec5SDimitry Andric     // m_arguments vector.
8010b57cec5SDimitry Andric     m_arguments.push_back(arg1);
8020b57cec5SDimitry Andric     m_arguments.push_back(arg2);
8030b57cec5SDimitry Andric   }
8040b57cec5SDimitry Andric 
8050b57cec5SDimitry Andric   ~CommandObjectPlatformGetFile() override = default;
8060b57cec5SDimitry Andric 
807af732203SDimitry Andric   void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)808af732203SDimitry Andric   HandleArgumentCompletion(CompletionRequest &request,
809af732203SDimitry Andric                            OptionElementVector &opt_element_vector) override {
810af732203SDimitry Andric     if (request.GetCursorIndex() == 0)
811af732203SDimitry Andric       CommandCompletions::InvokeCommonCompletionCallbacks(
812af732203SDimitry Andric           GetCommandInterpreter(),
813af732203SDimitry Andric           CommandCompletions::eRemoteDiskFileCompletion, request, nullptr);
814af732203SDimitry Andric     else if (request.GetCursorIndex() == 1)
815af732203SDimitry Andric       CommandCompletions::InvokeCommonCompletionCallbacks(
816af732203SDimitry Andric           GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
817af732203SDimitry Andric           request, nullptr);
818af732203SDimitry Andric   }
819af732203SDimitry Andric 
DoExecute(Args & args,CommandReturnObject & result)8200b57cec5SDimitry Andric   bool DoExecute(Args &args, CommandReturnObject &result) override {
8210b57cec5SDimitry Andric     // If the number of arguments is incorrect, issue an error message.
8220b57cec5SDimitry Andric     if (args.GetArgumentCount() != 2) {
823*5f7ddb14SDimitry Andric       result.AppendError("required arguments missing; specify both the "
824*5f7ddb14SDimitry Andric                          "source and destination file paths");
8250b57cec5SDimitry Andric       return false;
8260b57cec5SDimitry Andric     }
8270b57cec5SDimitry Andric 
8280b57cec5SDimitry Andric     PlatformSP platform_sp(
8290b57cec5SDimitry Andric         GetDebugger().GetPlatformList().GetSelectedPlatform());
8300b57cec5SDimitry Andric     if (platform_sp) {
8310b57cec5SDimitry Andric       const char *remote_file_path = args.GetArgumentAtIndex(0);
8320b57cec5SDimitry Andric       const char *local_file_path = args.GetArgumentAtIndex(1);
8330b57cec5SDimitry Andric       Status error = platform_sp->GetFile(FileSpec(remote_file_path),
8340b57cec5SDimitry Andric                                           FileSpec(local_file_path));
8350b57cec5SDimitry Andric       if (error.Success()) {
8360b57cec5SDimitry Andric         result.AppendMessageWithFormat(
8370b57cec5SDimitry Andric             "successfully get-file from %s (remote) to %s (host)\n",
8380b57cec5SDimitry Andric             remote_file_path, local_file_path);
8390b57cec5SDimitry Andric         result.SetStatus(eReturnStatusSuccessFinishResult);
8400b57cec5SDimitry Andric       } else {
8410b57cec5SDimitry Andric         result.AppendMessageWithFormat("get-file failed: %s\n",
8420b57cec5SDimitry Andric                                        error.AsCString());
8430b57cec5SDimitry Andric       }
8440b57cec5SDimitry Andric     } else {
8450b57cec5SDimitry Andric       result.AppendError("no platform currently selected\n");
8460b57cec5SDimitry Andric     }
8470b57cec5SDimitry Andric     return result.Succeeded();
8480b57cec5SDimitry Andric   }
8490b57cec5SDimitry Andric };
8500b57cec5SDimitry Andric 
8510b57cec5SDimitry Andric // "platform get-size remote-file-path"
8520b57cec5SDimitry Andric class CommandObjectPlatformGetSize : public CommandObjectParsed {
8530b57cec5SDimitry Andric public:
CommandObjectPlatformGetSize(CommandInterpreter & interpreter)8540b57cec5SDimitry Andric   CommandObjectPlatformGetSize(CommandInterpreter &interpreter)
8550b57cec5SDimitry Andric       : CommandObjectParsed(interpreter, "platform get-size",
8560b57cec5SDimitry Andric                             "Get the file size from the remote end.",
8570b57cec5SDimitry Andric                             "platform get-size <remote-file-spec>", 0) {
8580b57cec5SDimitry Andric     SetHelpLong(
8590b57cec5SDimitry Andric         R"(Examples:
8600b57cec5SDimitry Andric 
8610b57cec5SDimitry Andric (lldb) platform get-size /the/remote/file/path
8620b57cec5SDimitry Andric 
8630b57cec5SDimitry Andric     Get the file size from the remote end with path /the/remote/file/path.)");
8640b57cec5SDimitry Andric 
8650b57cec5SDimitry Andric     CommandArgumentEntry arg1;
8660b57cec5SDimitry Andric     CommandArgumentData file_arg_remote;
8670b57cec5SDimitry Andric 
8680b57cec5SDimitry Andric     // Define the first (and only) variant of this arg.
8690b57cec5SDimitry Andric     file_arg_remote.arg_type = eArgTypeFilename;
8700b57cec5SDimitry Andric     file_arg_remote.arg_repetition = eArgRepeatPlain;
8710b57cec5SDimitry Andric     // There is only one variant this argument could be; put it into the
8720b57cec5SDimitry Andric     // argument entry.
8730b57cec5SDimitry Andric     arg1.push_back(file_arg_remote);
8740b57cec5SDimitry Andric 
8750b57cec5SDimitry Andric     // Push the data for the first argument into the m_arguments vector.
8760b57cec5SDimitry Andric     m_arguments.push_back(arg1);
8770b57cec5SDimitry Andric   }
8780b57cec5SDimitry Andric 
8790b57cec5SDimitry Andric   ~CommandObjectPlatformGetSize() override = default;
8800b57cec5SDimitry Andric 
881af732203SDimitry Andric   void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)882af732203SDimitry Andric   HandleArgumentCompletion(CompletionRequest &request,
883af732203SDimitry Andric                            OptionElementVector &opt_element_vector) override {
884af732203SDimitry Andric     if (request.GetCursorIndex() != 0)
885af732203SDimitry Andric       return;
886af732203SDimitry Andric 
887af732203SDimitry Andric     CommandCompletions::InvokeCommonCompletionCallbacks(
888af732203SDimitry Andric         GetCommandInterpreter(), CommandCompletions::eRemoteDiskFileCompletion,
889af732203SDimitry Andric         request, nullptr);
890af732203SDimitry Andric   }
891af732203SDimitry Andric 
DoExecute(Args & args,CommandReturnObject & result)8920b57cec5SDimitry Andric   bool DoExecute(Args &args, CommandReturnObject &result) override {
8930b57cec5SDimitry Andric     // If the number of arguments is incorrect, issue an error message.
8940b57cec5SDimitry Andric     if (args.GetArgumentCount() != 1) {
895*5f7ddb14SDimitry Andric       result.AppendError("required argument missing; specify the source file "
896*5f7ddb14SDimitry Andric                          "path as the only argument");
8970b57cec5SDimitry Andric       return false;
8980b57cec5SDimitry Andric     }
8990b57cec5SDimitry Andric 
9000b57cec5SDimitry Andric     PlatformSP platform_sp(
9010b57cec5SDimitry Andric         GetDebugger().GetPlatformList().GetSelectedPlatform());
9020b57cec5SDimitry Andric     if (platform_sp) {
9030b57cec5SDimitry Andric       std::string remote_file_path(args.GetArgumentAtIndex(0));
9040b57cec5SDimitry Andric       user_id_t size = platform_sp->GetFileSize(FileSpec(remote_file_path));
9050b57cec5SDimitry Andric       if (size != UINT64_MAX) {
9060b57cec5SDimitry Andric         result.AppendMessageWithFormat("File size of %s (remote): %" PRIu64
9070b57cec5SDimitry Andric                                        "\n",
9080b57cec5SDimitry Andric                                        remote_file_path.c_str(), size);
9090b57cec5SDimitry Andric         result.SetStatus(eReturnStatusSuccessFinishResult);
9100b57cec5SDimitry Andric       } else {
9110b57cec5SDimitry Andric         result.AppendMessageWithFormat(
9120b57cec5SDimitry Andric             "Error getting file size of %s (remote)\n",
9130b57cec5SDimitry Andric             remote_file_path.c_str());
9140b57cec5SDimitry Andric       }
9150b57cec5SDimitry Andric     } else {
9160b57cec5SDimitry Andric       result.AppendError("no platform currently selected\n");
9170b57cec5SDimitry Andric     }
9180b57cec5SDimitry Andric     return result.Succeeded();
9190b57cec5SDimitry Andric   }
9200b57cec5SDimitry Andric };
9210b57cec5SDimitry Andric 
9220b57cec5SDimitry Andric // "platform put-file"
9230b57cec5SDimitry Andric class CommandObjectPlatformPutFile : public CommandObjectParsed {
9240b57cec5SDimitry Andric public:
CommandObjectPlatformPutFile(CommandInterpreter & interpreter)9250b57cec5SDimitry Andric   CommandObjectPlatformPutFile(CommandInterpreter &interpreter)
9260b57cec5SDimitry Andric       : CommandObjectParsed(
9270b57cec5SDimitry Andric             interpreter, "platform put-file",
9280b57cec5SDimitry Andric             "Transfer a file from this system to the remote end.", nullptr, 0) {
9290b57cec5SDimitry Andric   }
9300b57cec5SDimitry Andric 
9310b57cec5SDimitry Andric   ~CommandObjectPlatformPutFile() override = default;
9320b57cec5SDimitry Andric 
933af732203SDimitry Andric   void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)934af732203SDimitry Andric   HandleArgumentCompletion(CompletionRequest &request,
935af732203SDimitry Andric                            OptionElementVector &opt_element_vector) override {
936af732203SDimitry Andric     if (request.GetCursorIndex() == 0)
937af732203SDimitry Andric       CommandCompletions::InvokeCommonCompletionCallbacks(
938af732203SDimitry Andric           GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
939af732203SDimitry Andric           request, nullptr);
940af732203SDimitry Andric     else if (request.GetCursorIndex() == 1)
941af732203SDimitry Andric       CommandCompletions::InvokeCommonCompletionCallbacks(
942af732203SDimitry Andric           GetCommandInterpreter(),
943af732203SDimitry Andric           CommandCompletions::eRemoteDiskFileCompletion, request, nullptr);
944af732203SDimitry Andric   }
945af732203SDimitry Andric 
DoExecute(Args & args,CommandReturnObject & result)9460b57cec5SDimitry Andric   bool DoExecute(Args &args, CommandReturnObject &result) override {
9470b57cec5SDimitry Andric     const char *src = args.GetArgumentAtIndex(0);
9480b57cec5SDimitry Andric     const char *dst = args.GetArgumentAtIndex(1);
9490b57cec5SDimitry Andric 
9500b57cec5SDimitry Andric     FileSpec src_fs(src);
9510b57cec5SDimitry Andric     FileSystem::Instance().Resolve(src_fs);
9520b57cec5SDimitry Andric     FileSpec dst_fs(dst ? dst : src_fs.GetFilename().GetCString());
9530b57cec5SDimitry Andric 
9540b57cec5SDimitry Andric     PlatformSP platform_sp(
9550b57cec5SDimitry Andric         GetDebugger().GetPlatformList().GetSelectedPlatform());
9560b57cec5SDimitry Andric     if (platform_sp) {
9570b57cec5SDimitry Andric       Status error(platform_sp->PutFile(src_fs, dst_fs));
9580b57cec5SDimitry Andric       if (error.Success()) {
9590b57cec5SDimitry Andric         result.SetStatus(eReturnStatusSuccessFinishNoResult);
9600b57cec5SDimitry Andric       } else {
9610b57cec5SDimitry Andric         result.AppendError(error.AsCString());
9620b57cec5SDimitry Andric       }
9630b57cec5SDimitry Andric     } else {
9640b57cec5SDimitry Andric       result.AppendError("no platform currently selected\n");
9650b57cec5SDimitry Andric     }
9660b57cec5SDimitry Andric     return result.Succeeded();
9670b57cec5SDimitry Andric   }
9680b57cec5SDimitry Andric };
9690b57cec5SDimitry Andric 
9700b57cec5SDimitry Andric // "platform process launch"
9710b57cec5SDimitry Andric class CommandObjectPlatformProcessLaunch : public CommandObjectParsed {
9720b57cec5SDimitry Andric public:
CommandObjectPlatformProcessLaunch(CommandInterpreter & interpreter)9730b57cec5SDimitry Andric   CommandObjectPlatformProcessLaunch(CommandInterpreter &interpreter)
9740b57cec5SDimitry Andric       : CommandObjectParsed(interpreter, "platform process launch",
9750b57cec5SDimitry Andric                             "Launch a new process on a remote platform.",
9760b57cec5SDimitry Andric                             "platform process launch program",
9770b57cec5SDimitry Andric                             eCommandRequiresTarget | eCommandTryTargetAPILock),
978*5f7ddb14SDimitry Andric         m_options(), m_all_options() {
979*5f7ddb14SDimitry Andric     m_all_options.Append(&m_options);
980*5f7ddb14SDimitry Andric     m_all_options.Finalize();
981*5f7ddb14SDimitry Andric   }
9820b57cec5SDimitry Andric 
9830b57cec5SDimitry Andric   ~CommandObjectPlatformProcessLaunch() override = default;
9840b57cec5SDimitry Andric 
GetOptions()985*5f7ddb14SDimitry Andric   Options *GetOptions() override { return &m_all_options; }
9860b57cec5SDimitry Andric 
9870b57cec5SDimitry Andric protected:
DoExecute(Args & args,CommandReturnObject & result)9880b57cec5SDimitry Andric   bool DoExecute(Args &args, CommandReturnObject &result) override {
9890b57cec5SDimitry Andric     Target *target = GetDebugger().GetSelectedTarget().get();
9900b57cec5SDimitry Andric     PlatformSP platform_sp;
9910b57cec5SDimitry Andric     if (target) {
9920b57cec5SDimitry Andric       platform_sp = target->GetPlatform();
9930b57cec5SDimitry Andric     }
9940b57cec5SDimitry Andric     if (!platform_sp) {
9950b57cec5SDimitry Andric       platform_sp = GetDebugger().GetPlatformList().GetSelectedPlatform();
9960b57cec5SDimitry Andric     }
9970b57cec5SDimitry Andric 
9980b57cec5SDimitry Andric     if (platform_sp) {
9990b57cec5SDimitry Andric       Status error;
10000b57cec5SDimitry Andric       const size_t argc = args.GetArgumentCount();
10010b57cec5SDimitry Andric       Target *target = m_exe_ctx.GetTargetPtr();
10020b57cec5SDimitry Andric       Module *exe_module = target->GetExecutableModulePointer();
10030b57cec5SDimitry Andric       if (exe_module) {
10040b57cec5SDimitry Andric         m_options.launch_info.GetExecutableFile() = exe_module->GetFileSpec();
10050b57cec5SDimitry Andric         llvm::SmallString<128> exe_path;
10060b57cec5SDimitry Andric         m_options.launch_info.GetExecutableFile().GetPath(exe_path);
10070b57cec5SDimitry Andric         if (!exe_path.empty())
10080b57cec5SDimitry Andric           m_options.launch_info.GetArguments().AppendArgument(exe_path);
10090b57cec5SDimitry Andric         m_options.launch_info.GetArchitecture() = exe_module->GetArchitecture();
10100b57cec5SDimitry Andric       }
10110b57cec5SDimitry Andric 
10120b57cec5SDimitry Andric       if (argc > 0) {
10130b57cec5SDimitry Andric         if (m_options.launch_info.GetExecutableFile()) {
10140b57cec5SDimitry Andric           // We already have an executable file, so we will use this and all
10150b57cec5SDimitry Andric           // arguments to this function are extra arguments
10160b57cec5SDimitry Andric           m_options.launch_info.GetArguments().AppendArguments(args);
10170b57cec5SDimitry Andric         } else {
10180b57cec5SDimitry Andric           // We don't have any file yet, so the first argument is our
10190b57cec5SDimitry Andric           // executable, and the rest are program arguments
10200b57cec5SDimitry Andric           const bool first_arg_is_executable = true;
10210b57cec5SDimitry Andric           m_options.launch_info.SetArguments(args, first_arg_is_executable);
10220b57cec5SDimitry Andric         }
10230b57cec5SDimitry Andric       }
10240b57cec5SDimitry Andric 
10250b57cec5SDimitry Andric       if (m_options.launch_info.GetExecutableFile()) {
10260b57cec5SDimitry Andric         Debugger &debugger = GetDebugger();
10270b57cec5SDimitry Andric 
10280b57cec5SDimitry Andric         if (argc == 0)
10290b57cec5SDimitry Andric           target->GetRunArguments(m_options.launch_info.GetArguments());
10300b57cec5SDimitry Andric 
10310b57cec5SDimitry Andric         ProcessSP process_sp(platform_sp->DebugProcess(
10320b57cec5SDimitry Andric             m_options.launch_info, debugger, target, error));
10330b57cec5SDimitry Andric         if (process_sp && process_sp->IsAlive()) {
10340b57cec5SDimitry Andric           result.SetStatus(eReturnStatusSuccessFinishNoResult);
10350b57cec5SDimitry Andric           return true;
10360b57cec5SDimitry Andric         }
10370b57cec5SDimitry Andric 
10380b57cec5SDimitry Andric         if (error.Success())
10390b57cec5SDimitry Andric           result.AppendError("process launch failed");
10400b57cec5SDimitry Andric         else
10410b57cec5SDimitry Andric           result.AppendError(error.AsCString());
10420b57cec5SDimitry Andric       } else {
10430b57cec5SDimitry Andric         result.AppendError("'platform process launch' uses the current target "
10440b57cec5SDimitry Andric                            "file and arguments, or the executable and its "
10450b57cec5SDimitry Andric                            "arguments can be specified in this command");
10460b57cec5SDimitry Andric         return false;
10470b57cec5SDimitry Andric       }
10480b57cec5SDimitry Andric     } else {
10490b57cec5SDimitry Andric       result.AppendError("no platform is selected\n");
10500b57cec5SDimitry Andric     }
10510b57cec5SDimitry Andric     return result.Succeeded();
10520b57cec5SDimitry Andric   }
10530b57cec5SDimitry Andric 
1054af732203SDimitry Andric   CommandOptionsProcessLaunch m_options;
1055*5f7ddb14SDimitry Andric   OptionGroupOptions m_all_options;
10560b57cec5SDimitry Andric };
10570b57cec5SDimitry Andric 
10580b57cec5SDimitry Andric // "platform process list"
10590b57cec5SDimitry Andric 
10609dba64beSDimitry Andric static PosixPlatformCommandOptionValidator posix_validator;
10619dba64beSDimitry Andric #define LLDB_OPTIONS_platform_process_list
10629dba64beSDimitry Andric #include "CommandOptions.inc"
10630b57cec5SDimitry Andric 
10640b57cec5SDimitry Andric class CommandObjectPlatformProcessList : public CommandObjectParsed {
10650b57cec5SDimitry Andric public:
CommandObjectPlatformProcessList(CommandInterpreter & interpreter)10660b57cec5SDimitry Andric   CommandObjectPlatformProcessList(CommandInterpreter &interpreter)
10670b57cec5SDimitry Andric       : CommandObjectParsed(interpreter, "platform process list",
10680b57cec5SDimitry Andric                             "List processes on a remote platform by name, pid, "
10690b57cec5SDimitry Andric                             "or many other matching attributes.",
10700b57cec5SDimitry Andric                             "platform process list", 0),
10710b57cec5SDimitry Andric         m_options() {}
10720b57cec5SDimitry Andric 
10730b57cec5SDimitry Andric   ~CommandObjectPlatformProcessList() override = default;
10740b57cec5SDimitry Andric 
GetOptions()10750b57cec5SDimitry Andric   Options *GetOptions() override { return &m_options; }
10760b57cec5SDimitry Andric 
10770b57cec5SDimitry Andric protected:
DoExecute(Args & args,CommandReturnObject & result)10780b57cec5SDimitry Andric   bool DoExecute(Args &args, CommandReturnObject &result) override {
10790b57cec5SDimitry Andric     Target *target = GetDebugger().GetSelectedTarget().get();
10800b57cec5SDimitry Andric     PlatformSP platform_sp;
10810b57cec5SDimitry Andric     if (target) {
10820b57cec5SDimitry Andric       platform_sp = target->GetPlatform();
10830b57cec5SDimitry Andric     }
10840b57cec5SDimitry Andric     if (!platform_sp) {
10850b57cec5SDimitry Andric       platform_sp = GetDebugger().GetPlatformList().GetSelectedPlatform();
10860b57cec5SDimitry Andric     }
10870b57cec5SDimitry Andric 
10880b57cec5SDimitry Andric     if (platform_sp) {
10890b57cec5SDimitry Andric       Status error;
10900b57cec5SDimitry Andric       if (args.GetArgumentCount() == 0) {
10910b57cec5SDimitry Andric         if (platform_sp) {
10920b57cec5SDimitry Andric           Stream &ostrm = result.GetOutputStream();
10930b57cec5SDimitry Andric 
10940b57cec5SDimitry Andric           lldb::pid_t pid =
10950b57cec5SDimitry Andric               m_options.match_info.GetProcessInfo().GetProcessID();
10960b57cec5SDimitry Andric           if (pid != LLDB_INVALID_PROCESS_ID) {
10970b57cec5SDimitry Andric             ProcessInstanceInfo proc_info;
10980b57cec5SDimitry Andric             if (platform_sp->GetProcessInfo(pid, proc_info)) {
10990b57cec5SDimitry Andric               ProcessInstanceInfo::DumpTableHeader(ostrm, m_options.show_args,
11000b57cec5SDimitry Andric                                                    m_options.verbose);
11010b57cec5SDimitry Andric               proc_info.DumpAsTableRow(ostrm, platform_sp->GetUserIDResolver(),
11020b57cec5SDimitry Andric                                        m_options.show_args, m_options.verbose);
11030b57cec5SDimitry Andric               result.SetStatus(eReturnStatusSuccessFinishResult);
11040b57cec5SDimitry Andric             } else {
11050b57cec5SDimitry Andric               result.AppendErrorWithFormat(
11060b57cec5SDimitry Andric                   "no process found with pid = %" PRIu64 "\n", pid);
11070b57cec5SDimitry Andric             }
11080b57cec5SDimitry Andric           } else {
11090b57cec5SDimitry Andric             ProcessInstanceInfoList proc_infos;
11100b57cec5SDimitry Andric             const uint32_t matches =
11110b57cec5SDimitry Andric                 platform_sp->FindProcesses(m_options.match_info, proc_infos);
11120b57cec5SDimitry Andric             const char *match_desc = nullptr;
11130b57cec5SDimitry Andric             const char *match_name =
11140b57cec5SDimitry Andric                 m_options.match_info.GetProcessInfo().GetName();
11150b57cec5SDimitry Andric             if (match_name && match_name[0]) {
11160b57cec5SDimitry Andric               switch (m_options.match_info.GetNameMatchType()) {
11170b57cec5SDimitry Andric               case NameMatch::Ignore:
11180b57cec5SDimitry Andric                 break;
11190b57cec5SDimitry Andric               case NameMatch::Equals:
11200b57cec5SDimitry Andric                 match_desc = "matched";
11210b57cec5SDimitry Andric                 break;
11220b57cec5SDimitry Andric               case NameMatch::Contains:
11230b57cec5SDimitry Andric                 match_desc = "contained";
11240b57cec5SDimitry Andric                 break;
11250b57cec5SDimitry Andric               case NameMatch::StartsWith:
11260b57cec5SDimitry Andric                 match_desc = "started with";
11270b57cec5SDimitry Andric                 break;
11280b57cec5SDimitry Andric               case NameMatch::EndsWith:
11290b57cec5SDimitry Andric                 match_desc = "ended with";
11300b57cec5SDimitry Andric                 break;
11310b57cec5SDimitry Andric               case NameMatch::RegularExpression:
11320b57cec5SDimitry Andric                 match_desc = "matched the regular expression";
11330b57cec5SDimitry Andric                 break;
11340b57cec5SDimitry Andric               }
11350b57cec5SDimitry Andric             }
11360b57cec5SDimitry Andric 
11370b57cec5SDimitry Andric             if (matches == 0) {
11380b57cec5SDimitry Andric               if (match_desc)
11390b57cec5SDimitry Andric                 result.AppendErrorWithFormat(
11400b57cec5SDimitry Andric                     "no processes were found that %s \"%s\" on the \"%s\" "
11410b57cec5SDimitry Andric                     "platform\n",
11420b57cec5SDimitry Andric                     match_desc, match_name,
11430b57cec5SDimitry Andric                     platform_sp->GetPluginName().GetCString());
11440b57cec5SDimitry Andric               else
11450b57cec5SDimitry Andric                 result.AppendErrorWithFormat(
11460b57cec5SDimitry Andric                     "no processes were found on the \"%s\" platform\n",
11470b57cec5SDimitry Andric                     platform_sp->GetPluginName().GetCString());
11480b57cec5SDimitry Andric             } else {
11490b57cec5SDimitry Andric               result.AppendMessageWithFormat(
11500b57cec5SDimitry Andric                   "%u matching process%s found on \"%s\"", matches,
11510b57cec5SDimitry Andric                   matches > 1 ? "es were" : " was",
11520b57cec5SDimitry Andric                   platform_sp->GetName().GetCString());
11530b57cec5SDimitry Andric               if (match_desc)
11540b57cec5SDimitry Andric                 result.AppendMessageWithFormat(" whose name %s \"%s\"",
11550b57cec5SDimitry Andric                                                match_desc, match_name);
11560b57cec5SDimitry Andric               result.AppendMessageWithFormat("\n");
11570b57cec5SDimitry Andric               ProcessInstanceInfo::DumpTableHeader(ostrm, m_options.show_args,
11580b57cec5SDimitry Andric                                                    m_options.verbose);
11590b57cec5SDimitry Andric               for (uint32_t i = 0; i < matches; ++i) {
11605ffd83dbSDimitry Andric                 proc_infos[i].DumpAsTableRow(
11610b57cec5SDimitry Andric                     ostrm, platform_sp->GetUserIDResolver(),
11620b57cec5SDimitry Andric                     m_options.show_args, m_options.verbose);
11630b57cec5SDimitry Andric               }
11640b57cec5SDimitry Andric             }
11650b57cec5SDimitry Andric           }
11660b57cec5SDimitry Andric         }
11670b57cec5SDimitry Andric       } else {
11680b57cec5SDimitry Andric         result.AppendError("invalid args: process list takes only options\n");
11690b57cec5SDimitry Andric       }
11700b57cec5SDimitry Andric     } else {
11710b57cec5SDimitry Andric       result.AppendError("no platform is selected\n");
11720b57cec5SDimitry Andric     }
11730b57cec5SDimitry Andric     return result.Succeeded();
11740b57cec5SDimitry Andric   }
11750b57cec5SDimitry Andric 
11760b57cec5SDimitry Andric   class CommandOptions : public Options {
11770b57cec5SDimitry Andric   public:
CommandOptions()1178*5f7ddb14SDimitry Andric     CommandOptions() : Options(), match_info() {}
11790b57cec5SDimitry Andric 
11800b57cec5SDimitry Andric     ~CommandOptions() override = default;
11810b57cec5SDimitry Andric 
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)11820b57cec5SDimitry Andric     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
11830b57cec5SDimitry Andric                           ExecutionContext *execution_context) override {
11840b57cec5SDimitry Andric       Status error;
11850b57cec5SDimitry Andric       const int short_option = m_getopt_table[option_idx].val;
11860b57cec5SDimitry Andric       bool success = false;
11870b57cec5SDimitry Andric 
11880b57cec5SDimitry Andric       uint32_t id = LLDB_INVALID_PROCESS_ID;
11890b57cec5SDimitry Andric       success = !option_arg.getAsInteger(0, id);
11900b57cec5SDimitry Andric       switch (short_option) {
11910b57cec5SDimitry Andric       case 'p': {
11920b57cec5SDimitry Andric         match_info.GetProcessInfo().SetProcessID(id);
11930b57cec5SDimitry Andric         if (!success)
11940b57cec5SDimitry Andric           error.SetErrorStringWithFormat("invalid process ID string: '%s'",
11950b57cec5SDimitry Andric                                          option_arg.str().c_str());
11960b57cec5SDimitry Andric         break;
11970b57cec5SDimitry Andric       }
11980b57cec5SDimitry Andric       case 'P':
11990b57cec5SDimitry Andric         match_info.GetProcessInfo().SetParentProcessID(id);
12000b57cec5SDimitry Andric         if (!success)
12010b57cec5SDimitry Andric           error.SetErrorStringWithFormat(
12020b57cec5SDimitry Andric               "invalid parent process ID string: '%s'",
12030b57cec5SDimitry Andric               option_arg.str().c_str());
12040b57cec5SDimitry Andric         break;
12050b57cec5SDimitry Andric 
12060b57cec5SDimitry Andric       case 'u':
12070b57cec5SDimitry Andric         match_info.GetProcessInfo().SetUserID(success ? id : UINT32_MAX);
12080b57cec5SDimitry Andric         if (!success)
12090b57cec5SDimitry Andric           error.SetErrorStringWithFormat("invalid user ID string: '%s'",
12100b57cec5SDimitry Andric                                          option_arg.str().c_str());
12110b57cec5SDimitry Andric         break;
12120b57cec5SDimitry Andric 
12130b57cec5SDimitry Andric       case 'U':
12140b57cec5SDimitry Andric         match_info.GetProcessInfo().SetEffectiveUserID(success ? id
12150b57cec5SDimitry Andric                                                                : UINT32_MAX);
12160b57cec5SDimitry Andric         if (!success)
12170b57cec5SDimitry Andric           error.SetErrorStringWithFormat(
12180b57cec5SDimitry Andric               "invalid effective user ID string: '%s'",
12190b57cec5SDimitry Andric               option_arg.str().c_str());
12200b57cec5SDimitry Andric         break;
12210b57cec5SDimitry Andric 
12220b57cec5SDimitry Andric       case 'g':
12230b57cec5SDimitry Andric         match_info.GetProcessInfo().SetGroupID(success ? id : UINT32_MAX);
12240b57cec5SDimitry Andric         if (!success)
12250b57cec5SDimitry Andric           error.SetErrorStringWithFormat("invalid group ID string: '%s'",
12260b57cec5SDimitry Andric                                          option_arg.str().c_str());
12270b57cec5SDimitry Andric         break;
12280b57cec5SDimitry Andric 
12290b57cec5SDimitry Andric       case 'G':
12300b57cec5SDimitry Andric         match_info.GetProcessInfo().SetEffectiveGroupID(success ? id
12310b57cec5SDimitry Andric                                                                 : UINT32_MAX);
12320b57cec5SDimitry Andric         if (!success)
12330b57cec5SDimitry Andric           error.SetErrorStringWithFormat(
12340b57cec5SDimitry Andric               "invalid effective group ID string: '%s'",
12350b57cec5SDimitry Andric               option_arg.str().c_str());
12360b57cec5SDimitry Andric         break;
12370b57cec5SDimitry Andric 
12380b57cec5SDimitry Andric       case 'a': {
12390b57cec5SDimitry Andric         TargetSP target_sp =
12400b57cec5SDimitry Andric             execution_context ? execution_context->GetTargetSP() : TargetSP();
12410b57cec5SDimitry Andric         DebuggerSP debugger_sp =
12420b57cec5SDimitry Andric             target_sp ? target_sp->GetDebugger().shared_from_this()
12430b57cec5SDimitry Andric                       : DebuggerSP();
12440b57cec5SDimitry Andric         PlatformSP platform_sp =
12450b57cec5SDimitry Andric             debugger_sp ? debugger_sp->GetPlatformList().GetSelectedPlatform()
12460b57cec5SDimitry Andric                         : PlatformSP();
12470b57cec5SDimitry Andric         match_info.GetProcessInfo().GetArchitecture() =
12480b57cec5SDimitry Andric             Platform::GetAugmentedArchSpec(platform_sp.get(), option_arg);
12490b57cec5SDimitry Andric       } break;
12500b57cec5SDimitry Andric 
12510b57cec5SDimitry Andric       case 'n':
12520b57cec5SDimitry Andric         match_info.GetProcessInfo().GetExecutableFile().SetFile(
12530b57cec5SDimitry Andric             option_arg, FileSpec::Style::native);
12540b57cec5SDimitry Andric         match_info.SetNameMatchType(NameMatch::Equals);
12550b57cec5SDimitry Andric         break;
12560b57cec5SDimitry Andric 
12570b57cec5SDimitry Andric       case 'e':
12580b57cec5SDimitry Andric         match_info.GetProcessInfo().GetExecutableFile().SetFile(
12590b57cec5SDimitry Andric             option_arg, FileSpec::Style::native);
12600b57cec5SDimitry Andric         match_info.SetNameMatchType(NameMatch::EndsWith);
12610b57cec5SDimitry Andric         break;
12620b57cec5SDimitry Andric 
12630b57cec5SDimitry Andric       case 's':
12640b57cec5SDimitry Andric         match_info.GetProcessInfo().GetExecutableFile().SetFile(
12650b57cec5SDimitry Andric             option_arg, FileSpec::Style::native);
12660b57cec5SDimitry Andric         match_info.SetNameMatchType(NameMatch::StartsWith);
12670b57cec5SDimitry Andric         break;
12680b57cec5SDimitry Andric 
12690b57cec5SDimitry Andric       case 'c':
12700b57cec5SDimitry Andric         match_info.GetProcessInfo().GetExecutableFile().SetFile(
12710b57cec5SDimitry Andric             option_arg, FileSpec::Style::native);
12720b57cec5SDimitry Andric         match_info.SetNameMatchType(NameMatch::Contains);
12730b57cec5SDimitry Andric         break;
12740b57cec5SDimitry Andric 
12750b57cec5SDimitry Andric       case 'r':
12760b57cec5SDimitry Andric         match_info.GetProcessInfo().GetExecutableFile().SetFile(
12770b57cec5SDimitry Andric             option_arg, FileSpec::Style::native);
12780b57cec5SDimitry Andric         match_info.SetNameMatchType(NameMatch::RegularExpression);
12790b57cec5SDimitry Andric         break;
12800b57cec5SDimitry Andric 
12810b57cec5SDimitry Andric       case 'A':
12820b57cec5SDimitry Andric         show_args = true;
12830b57cec5SDimitry Andric         break;
12840b57cec5SDimitry Andric 
12850b57cec5SDimitry Andric       case 'v':
12860b57cec5SDimitry Andric         verbose = true;
12870b57cec5SDimitry Andric         break;
12880b57cec5SDimitry Andric 
12899dba64beSDimitry Andric       case 'x':
12909dba64beSDimitry Andric         match_info.SetMatchAllUsers(true);
12910b57cec5SDimitry Andric         break;
12929dba64beSDimitry Andric 
12939dba64beSDimitry Andric       default:
12949dba64beSDimitry Andric         llvm_unreachable("Unimplemented option");
12950b57cec5SDimitry Andric       }
12960b57cec5SDimitry Andric 
12970b57cec5SDimitry Andric       return error;
12980b57cec5SDimitry Andric     }
12990b57cec5SDimitry Andric 
OptionParsingStarting(ExecutionContext * execution_context)13000b57cec5SDimitry Andric     void OptionParsingStarting(ExecutionContext *execution_context) override {
13010b57cec5SDimitry Andric       match_info.Clear();
13020b57cec5SDimitry Andric       show_args = false;
13030b57cec5SDimitry Andric       verbose = false;
13040b57cec5SDimitry Andric     }
13050b57cec5SDimitry Andric 
GetDefinitions()13060b57cec5SDimitry Andric     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
13070b57cec5SDimitry Andric       return llvm::makeArrayRef(g_platform_process_list_options);
13080b57cec5SDimitry Andric     }
13090b57cec5SDimitry Andric 
13100b57cec5SDimitry Andric     // Instance variables to hold the values for command options.
13110b57cec5SDimitry Andric 
13120b57cec5SDimitry Andric     ProcessInstanceInfoMatch match_info;
1313*5f7ddb14SDimitry Andric     bool show_args = false;
1314*5f7ddb14SDimitry Andric     bool verbose = false;
13150b57cec5SDimitry Andric   };
13160b57cec5SDimitry Andric 
13170b57cec5SDimitry Andric   CommandOptions m_options;
13180b57cec5SDimitry Andric };
13190b57cec5SDimitry Andric 
13200b57cec5SDimitry Andric // "platform process info"
13210b57cec5SDimitry Andric class CommandObjectPlatformProcessInfo : public CommandObjectParsed {
13220b57cec5SDimitry Andric public:
CommandObjectPlatformProcessInfo(CommandInterpreter & interpreter)13230b57cec5SDimitry Andric   CommandObjectPlatformProcessInfo(CommandInterpreter &interpreter)
13240b57cec5SDimitry Andric       : CommandObjectParsed(
13250b57cec5SDimitry Andric             interpreter, "platform process info",
13260b57cec5SDimitry Andric             "Get detailed information for one or more process by process ID.",
13270b57cec5SDimitry Andric             "platform process info <pid> [<pid> <pid> ...]", 0) {
13280b57cec5SDimitry Andric     CommandArgumentEntry arg;
13290b57cec5SDimitry Andric     CommandArgumentData pid_args;
13300b57cec5SDimitry Andric 
13310b57cec5SDimitry Andric     // Define the first (and only) variant of this arg.
13320b57cec5SDimitry Andric     pid_args.arg_type = eArgTypePid;
13330b57cec5SDimitry Andric     pid_args.arg_repetition = eArgRepeatStar;
13340b57cec5SDimitry Andric 
13350b57cec5SDimitry Andric     // There is only one variant this argument could be; put it into the
13360b57cec5SDimitry Andric     // argument entry.
13370b57cec5SDimitry Andric     arg.push_back(pid_args);
13380b57cec5SDimitry Andric 
13390b57cec5SDimitry Andric     // Push the data for the first argument into the m_arguments vector.
13400b57cec5SDimitry Andric     m_arguments.push_back(arg);
13410b57cec5SDimitry Andric   }
13420b57cec5SDimitry Andric 
13430b57cec5SDimitry Andric   ~CommandObjectPlatformProcessInfo() override = default;
13440b57cec5SDimitry Andric 
1345af732203SDimitry Andric   void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)1346af732203SDimitry Andric   HandleArgumentCompletion(CompletionRequest &request,
1347af732203SDimitry Andric                            OptionElementVector &opt_element_vector) override {
1348af732203SDimitry Andric     CommandCompletions::InvokeCommonCompletionCallbacks(
1349af732203SDimitry Andric         GetCommandInterpreter(), CommandCompletions::eProcessIDCompletion,
1350af732203SDimitry Andric         request, nullptr);
1351af732203SDimitry Andric   }
1352af732203SDimitry Andric 
13530b57cec5SDimitry Andric protected:
DoExecute(Args & args,CommandReturnObject & result)13540b57cec5SDimitry Andric   bool DoExecute(Args &args, CommandReturnObject &result) override {
13550b57cec5SDimitry Andric     Target *target = GetDebugger().GetSelectedTarget().get();
13560b57cec5SDimitry Andric     PlatformSP platform_sp;
13570b57cec5SDimitry Andric     if (target) {
13580b57cec5SDimitry Andric       platform_sp = target->GetPlatform();
13590b57cec5SDimitry Andric     }
13600b57cec5SDimitry Andric     if (!platform_sp) {
13610b57cec5SDimitry Andric       platform_sp = GetDebugger().GetPlatformList().GetSelectedPlatform();
13620b57cec5SDimitry Andric     }
13630b57cec5SDimitry Andric 
13640b57cec5SDimitry Andric     if (platform_sp) {
13650b57cec5SDimitry Andric       const size_t argc = args.GetArgumentCount();
13660b57cec5SDimitry Andric       if (argc > 0) {
13670b57cec5SDimitry Andric         Status error;
13680b57cec5SDimitry Andric 
13690b57cec5SDimitry Andric         if (platform_sp->IsConnected()) {
13700b57cec5SDimitry Andric           Stream &ostrm = result.GetOutputStream();
13710b57cec5SDimitry Andric           for (auto &entry : args.entries()) {
13720b57cec5SDimitry Andric             lldb::pid_t pid;
13739dba64beSDimitry Andric             if (entry.ref().getAsInteger(0, pid)) {
13740b57cec5SDimitry Andric               result.AppendErrorWithFormat("invalid process ID argument '%s'",
13759dba64beSDimitry Andric                                            entry.ref().str().c_str());
13760b57cec5SDimitry Andric               break;
13770b57cec5SDimitry Andric             } else {
13780b57cec5SDimitry Andric               ProcessInstanceInfo proc_info;
13790b57cec5SDimitry Andric               if (platform_sp->GetProcessInfo(pid, proc_info)) {
13800b57cec5SDimitry Andric                 ostrm.Printf("Process information for process %" PRIu64 ":\n",
13810b57cec5SDimitry Andric                              pid);
13820b57cec5SDimitry Andric                 proc_info.Dump(ostrm, platform_sp->GetUserIDResolver());
13830b57cec5SDimitry Andric               } else {
13840b57cec5SDimitry Andric                 ostrm.Printf("error: no process information is available for "
13850b57cec5SDimitry Andric                              "process %" PRIu64 "\n",
13860b57cec5SDimitry Andric                              pid);
13870b57cec5SDimitry Andric               }
13880b57cec5SDimitry Andric               ostrm.EOL();
13890b57cec5SDimitry Andric             }
13900b57cec5SDimitry Andric           }
13910b57cec5SDimitry Andric         } else {
13920b57cec5SDimitry Andric           // Not connected...
13930b57cec5SDimitry Andric           result.AppendErrorWithFormat(
13940b57cec5SDimitry Andric               "not connected to '%s'",
13950b57cec5SDimitry Andric               platform_sp->GetPluginName().GetCString());
13960b57cec5SDimitry Andric         }
13970b57cec5SDimitry Andric       } else {
13980b57cec5SDimitry Andric         // No args
13990b57cec5SDimitry Andric         result.AppendError("one or more process id(s) must be specified");
14000b57cec5SDimitry Andric       }
14010b57cec5SDimitry Andric     } else {
14020b57cec5SDimitry Andric       result.AppendError("no platform is currently selected");
14030b57cec5SDimitry Andric     }
14040b57cec5SDimitry Andric     return result.Succeeded();
14050b57cec5SDimitry Andric   }
14060b57cec5SDimitry Andric };
14070b57cec5SDimitry Andric 
14089dba64beSDimitry Andric #define LLDB_OPTIONS_platform_process_attach
14099dba64beSDimitry Andric #include "CommandOptions.inc"
14100b57cec5SDimitry Andric 
14110b57cec5SDimitry Andric class CommandObjectPlatformProcessAttach : public CommandObjectParsed {
14120b57cec5SDimitry Andric public:
14130b57cec5SDimitry Andric   class CommandOptions : public Options {
14140b57cec5SDimitry Andric   public:
CommandOptions()14150b57cec5SDimitry Andric     CommandOptions() : Options() {
14160b57cec5SDimitry Andric       // Keep default values of all options in one place: OptionParsingStarting
14170b57cec5SDimitry Andric       // ()
14180b57cec5SDimitry Andric       OptionParsingStarting(nullptr);
14190b57cec5SDimitry Andric     }
14200b57cec5SDimitry Andric 
14210b57cec5SDimitry Andric     ~CommandOptions() override = default;
14220b57cec5SDimitry Andric 
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)14230b57cec5SDimitry Andric     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
14240b57cec5SDimitry Andric                           ExecutionContext *execution_context) override {
14250b57cec5SDimitry Andric       Status error;
14260b57cec5SDimitry Andric       char short_option = (char)m_getopt_table[option_idx].val;
14270b57cec5SDimitry Andric       switch (short_option) {
14280b57cec5SDimitry Andric       case 'p': {
14290b57cec5SDimitry Andric         lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
14300b57cec5SDimitry Andric         if (option_arg.getAsInteger(0, pid)) {
14310b57cec5SDimitry Andric           error.SetErrorStringWithFormat("invalid process ID '%s'",
14320b57cec5SDimitry Andric                                          option_arg.str().c_str());
14330b57cec5SDimitry Andric         } else {
14340b57cec5SDimitry Andric           attach_info.SetProcessID(pid);
14350b57cec5SDimitry Andric         }
14360b57cec5SDimitry Andric       } break;
14370b57cec5SDimitry Andric 
14380b57cec5SDimitry Andric       case 'P':
14390b57cec5SDimitry Andric         attach_info.SetProcessPluginName(option_arg);
14400b57cec5SDimitry Andric         break;
14410b57cec5SDimitry Andric 
14420b57cec5SDimitry Andric       case 'n':
14430b57cec5SDimitry Andric         attach_info.GetExecutableFile().SetFile(option_arg,
14440b57cec5SDimitry Andric                                                 FileSpec::Style::native);
14450b57cec5SDimitry Andric         break;
14460b57cec5SDimitry Andric 
14470b57cec5SDimitry Andric       case 'w':
14480b57cec5SDimitry Andric         attach_info.SetWaitForLaunch(true);
14490b57cec5SDimitry Andric         break;
14500b57cec5SDimitry Andric 
14510b57cec5SDimitry Andric       default:
14529dba64beSDimitry Andric         llvm_unreachable("Unimplemented option");
14530b57cec5SDimitry Andric       }
14540b57cec5SDimitry Andric       return error;
14550b57cec5SDimitry Andric     }
14560b57cec5SDimitry Andric 
OptionParsingStarting(ExecutionContext * execution_context)14570b57cec5SDimitry Andric     void OptionParsingStarting(ExecutionContext *execution_context) override {
14580b57cec5SDimitry Andric       attach_info.Clear();
14590b57cec5SDimitry Andric     }
14600b57cec5SDimitry Andric 
GetDefinitions()14610b57cec5SDimitry Andric     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
14620b57cec5SDimitry Andric       return llvm::makeArrayRef(g_platform_process_attach_options);
14630b57cec5SDimitry Andric     }
14640b57cec5SDimitry Andric 
14650b57cec5SDimitry Andric     // Options table: Required for subclasses of Options.
14660b57cec5SDimitry Andric 
14670b57cec5SDimitry Andric     static OptionDefinition g_option_table[];
14680b57cec5SDimitry Andric 
14690b57cec5SDimitry Andric     // Instance variables to hold the values for command options.
14700b57cec5SDimitry Andric 
14710b57cec5SDimitry Andric     ProcessAttachInfo attach_info;
14720b57cec5SDimitry Andric   };
14730b57cec5SDimitry Andric 
CommandObjectPlatformProcessAttach(CommandInterpreter & interpreter)14740b57cec5SDimitry Andric   CommandObjectPlatformProcessAttach(CommandInterpreter &interpreter)
14750b57cec5SDimitry Andric       : CommandObjectParsed(interpreter, "platform process attach",
14760b57cec5SDimitry Andric                             "Attach to a process.",
14770b57cec5SDimitry Andric                             "platform process attach <cmd-options>"),
14780b57cec5SDimitry Andric         m_options() {}
14790b57cec5SDimitry Andric 
14800b57cec5SDimitry Andric   ~CommandObjectPlatformProcessAttach() override = default;
14810b57cec5SDimitry Andric 
DoExecute(Args & command,CommandReturnObject & result)14820b57cec5SDimitry Andric   bool DoExecute(Args &command, CommandReturnObject &result) override {
14830b57cec5SDimitry Andric     PlatformSP platform_sp(
14840b57cec5SDimitry Andric         GetDebugger().GetPlatformList().GetSelectedPlatform());
14850b57cec5SDimitry Andric     if (platform_sp) {
14860b57cec5SDimitry Andric       Status err;
14870b57cec5SDimitry Andric       ProcessSP remote_process_sp = platform_sp->Attach(
14880b57cec5SDimitry Andric           m_options.attach_info, GetDebugger(), nullptr, err);
14890b57cec5SDimitry Andric       if (err.Fail()) {
14900b57cec5SDimitry Andric         result.AppendError(err.AsCString());
14910b57cec5SDimitry Andric       } else if (!remote_process_sp) {
14920b57cec5SDimitry Andric         result.AppendError("could not attach: unknown reason");
14930b57cec5SDimitry Andric       } else
14940b57cec5SDimitry Andric         result.SetStatus(eReturnStatusSuccessFinishResult);
14950b57cec5SDimitry Andric     } else {
14960b57cec5SDimitry Andric       result.AppendError("no platform is currently selected");
14970b57cec5SDimitry Andric     }
14980b57cec5SDimitry Andric     return result.Succeeded();
14990b57cec5SDimitry Andric   }
15000b57cec5SDimitry Andric 
GetOptions()15010b57cec5SDimitry Andric   Options *GetOptions() override { return &m_options; }
15020b57cec5SDimitry Andric 
15030b57cec5SDimitry Andric protected:
15040b57cec5SDimitry Andric   CommandOptions m_options;
15050b57cec5SDimitry Andric };
15060b57cec5SDimitry Andric 
15070b57cec5SDimitry Andric class CommandObjectPlatformProcess : public CommandObjectMultiword {
15080b57cec5SDimitry Andric public:
15090b57cec5SDimitry Andric   // Constructors and Destructors
CommandObjectPlatformProcess(CommandInterpreter & interpreter)15100b57cec5SDimitry Andric   CommandObjectPlatformProcess(CommandInterpreter &interpreter)
15110b57cec5SDimitry Andric       : CommandObjectMultiword(interpreter, "platform process",
15120b57cec5SDimitry Andric                                "Commands to query, launch and attach to "
15130b57cec5SDimitry Andric                                "processes on the current platform.",
15140b57cec5SDimitry Andric                                "platform process [attach|launch|list] ...") {
15150b57cec5SDimitry Andric     LoadSubCommand(
15160b57cec5SDimitry Andric         "attach",
15170b57cec5SDimitry Andric         CommandObjectSP(new CommandObjectPlatformProcessAttach(interpreter)));
15180b57cec5SDimitry Andric     LoadSubCommand(
15190b57cec5SDimitry Andric         "launch",
15200b57cec5SDimitry Andric         CommandObjectSP(new CommandObjectPlatformProcessLaunch(interpreter)));
15210b57cec5SDimitry Andric     LoadSubCommand("info", CommandObjectSP(new CommandObjectPlatformProcessInfo(
15220b57cec5SDimitry Andric                                interpreter)));
15230b57cec5SDimitry Andric     LoadSubCommand("list", CommandObjectSP(new CommandObjectPlatformProcessList(
15240b57cec5SDimitry Andric                                interpreter)));
15250b57cec5SDimitry Andric   }
15260b57cec5SDimitry Andric 
15270b57cec5SDimitry Andric   ~CommandObjectPlatformProcess() override = default;
15280b57cec5SDimitry Andric 
15290b57cec5SDimitry Andric private:
15300b57cec5SDimitry Andric   // For CommandObjectPlatform only
15315ffd83dbSDimitry Andric   CommandObjectPlatformProcess(const CommandObjectPlatformProcess &) = delete;
15325ffd83dbSDimitry Andric   const CommandObjectPlatformProcess &
15335ffd83dbSDimitry Andric   operator=(const CommandObjectPlatformProcess &) = delete;
15340b57cec5SDimitry Andric };
15350b57cec5SDimitry Andric 
15360b57cec5SDimitry Andric // "platform shell"
15379dba64beSDimitry Andric #define LLDB_OPTIONS_platform_shell
15389dba64beSDimitry Andric #include "CommandOptions.inc"
15390b57cec5SDimitry Andric 
15400b57cec5SDimitry Andric class CommandObjectPlatformShell : public CommandObjectRaw {
15410b57cec5SDimitry Andric public:
15420b57cec5SDimitry Andric   class CommandOptions : public Options {
15430b57cec5SDimitry Andric   public:
CommandOptions()15440b57cec5SDimitry Andric     CommandOptions() : Options() {}
15450b57cec5SDimitry Andric 
15460b57cec5SDimitry Andric     ~CommandOptions() override = default;
15470b57cec5SDimitry Andric 
GetDefinitions()15480b57cec5SDimitry Andric     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
15490b57cec5SDimitry Andric       return llvm::makeArrayRef(g_platform_shell_options);
15500b57cec5SDimitry Andric     }
15510b57cec5SDimitry Andric 
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)15520b57cec5SDimitry Andric     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
15530b57cec5SDimitry Andric                           ExecutionContext *execution_context) override {
15540b57cec5SDimitry Andric       Status error;
15550b57cec5SDimitry Andric 
15560b57cec5SDimitry Andric       const char short_option = (char)GetDefinitions()[option_idx].short_option;
15570b57cec5SDimitry Andric 
15580b57cec5SDimitry Andric       switch (short_option) {
15595ffd83dbSDimitry Andric       case 'h':
15605ffd83dbSDimitry Andric         m_use_host_platform = true;
15615ffd83dbSDimitry Andric         break;
15620b57cec5SDimitry Andric       case 't':
15630b57cec5SDimitry Andric         uint32_t timeout_sec;
15640b57cec5SDimitry Andric         if (option_arg.getAsInteger(10, timeout_sec))
15650b57cec5SDimitry Andric           error.SetErrorStringWithFormat(
15660b57cec5SDimitry Andric               "could not convert \"%s\" to a numeric value.",
15670b57cec5SDimitry Andric               option_arg.str().c_str());
15680b57cec5SDimitry Andric         else
15695ffd83dbSDimitry Andric           m_timeout = std::chrono::seconds(timeout_sec);
15700b57cec5SDimitry Andric         break;
1571af732203SDimitry Andric       case 's': {
1572af732203SDimitry Andric         if (option_arg.empty()) {
1573af732203SDimitry Andric           error.SetErrorStringWithFormat(
1574af732203SDimitry Andric               "missing shell interpreter path for option -i|--interpreter.");
1575af732203SDimitry Andric           return error;
1576af732203SDimitry Andric         }
1577af732203SDimitry Andric 
1578af732203SDimitry Andric         m_shell_interpreter = option_arg.str();
1579af732203SDimitry Andric         break;
1580af732203SDimitry Andric       }
15810b57cec5SDimitry Andric       default:
15829dba64beSDimitry Andric         llvm_unreachable("Unimplemented option");
15830b57cec5SDimitry Andric       }
15840b57cec5SDimitry Andric 
15850b57cec5SDimitry Andric       return error;
15860b57cec5SDimitry Andric     }
15870b57cec5SDimitry Andric 
OptionParsingStarting(ExecutionContext * execution_context)15885ffd83dbSDimitry Andric     void OptionParsingStarting(ExecutionContext *execution_context) override {
15895ffd83dbSDimitry Andric       m_timeout.reset();
15905ffd83dbSDimitry Andric       m_use_host_platform = false;
1591af732203SDimitry Andric       m_shell_interpreter.clear();
15925ffd83dbSDimitry Andric     }
15930b57cec5SDimitry Andric 
15945ffd83dbSDimitry Andric     Timeout<std::micro> m_timeout = std::chrono::seconds(10);
15955ffd83dbSDimitry Andric     bool m_use_host_platform;
1596af732203SDimitry Andric     std::string m_shell_interpreter;
15970b57cec5SDimitry Andric   };
15980b57cec5SDimitry Andric 
CommandObjectPlatformShell(CommandInterpreter & interpreter)15990b57cec5SDimitry Andric   CommandObjectPlatformShell(CommandInterpreter &interpreter)
16000b57cec5SDimitry Andric       : CommandObjectRaw(interpreter, "platform shell",
16010b57cec5SDimitry Andric                          "Run a shell command on the current platform.",
16020b57cec5SDimitry Andric                          "platform shell <shell-command>", 0),
16030b57cec5SDimitry Andric         m_options() {}
16040b57cec5SDimitry Andric 
16050b57cec5SDimitry Andric   ~CommandObjectPlatformShell() override = default;
16060b57cec5SDimitry Andric 
GetOptions()16070b57cec5SDimitry Andric   Options *GetOptions() override { return &m_options; }
16080b57cec5SDimitry Andric 
DoExecute(llvm::StringRef raw_command_line,CommandReturnObject & result)16090b57cec5SDimitry Andric   bool DoExecute(llvm::StringRef raw_command_line,
16100b57cec5SDimitry Andric                  CommandReturnObject &result) override {
16110b57cec5SDimitry Andric     ExecutionContext exe_ctx = GetCommandInterpreter().GetExecutionContext();
16120b57cec5SDimitry Andric     m_options.NotifyOptionParsingStarting(&exe_ctx);
16130b57cec5SDimitry Andric 
16140b57cec5SDimitry Andric     // Print out an usage syntax on an empty command line.
16150b57cec5SDimitry Andric     if (raw_command_line.empty()) {
16160b57cec5SDimitry Andric       result.GetOutputStream().Printf("%s\n", this->GetSyntax().str().c_str());
16170b57cec5SDimitry Andric       return true;
16180b57cec5SDimitry Andric     }
16190b57cec5SDimitry Andric 
16205ffd83dbSDimitry Andric     const bool is_alias = !raw_command_line.contains("platform");
16210b57cec5SDimitry Andric     OptionsWithRaw args(raw_command_line);
16220b57cec5SDimitry Andric 
16230b57cec5SDimitry Andric     if (args.HasArgs())
16240b57cec5SDimitry Andric       if (!ParseOptions(args.GetArgs(), result))
16250b57cec5SDimitry Andric         return false;
16260b57cec5SDimitry Andric 
16275ffd83dbSDimitry Andric     if (args.GetRawPart().empty()) {
16285ffd83dbSDimitry Andric       result.GetOutputStream().Printf("%s <shell-command>\n",
16295ffd83dbSDimitry Andric                                       is_alias ? "shell" : "platform shell");
16305ffd83dbSDimitry Andric       return false;
16315ffd83dbSDimitry Andric     }
16325ffd83dbSDimitry Andric 
1633af732203SDimitry Andric     llvm::StringRef cmd = args.GetRawPart();
1634af732203SDimitry Andric 
16350b57cec5SDimitry Andric     PlatformSP platform_sp(
16365ffd83dbSDimitry Andric         m_options.m_use_host_platform
16375ffd83dbSDimitry Andric             ? Platform::GetHostPlatform()
16385ffd83dbSDimitry Andric             : GetDebugger().GetPlatformList().GetSelectedPlatform());
16390b57cec5SDimitry Andric     Status error;
16400b57cec5SDimitry Andric     if (platform_sp) {
16410b57cec5SDimitry Andric       FileSpec working_dir{};
16420b57cec5SDimitry Andric       std::string output;
16430b57cec5SDimitry Andric       int status = -1;
16440b57cec5SDimitry Andric       int signo = -1;
1645af732203SDimitry Andric       error = (platform_sp->RunShellCommand(m_options.m_shell_interpreter, cmd,
1646af732203SDimitry Andric                                             working_dir, &status, &signo,
16475ffd83dbSDimitry Andric                                             &output, m_options.m_timeout));
16480b57cec5SDimitry Andric       if (!output.empty())
16490b57cec5SDimitry Andric         result.GetOutputStream().PutCString(output);
16500b57cec5SDimitry Andric       if (status > 0) {
16510b57cec5SDimitry Andric         if (signo > 0) {
16520b57cec5SDimitry Andric           const char *signo_cstr = Host::GetSignalAsCString(signo);
16530b57cec5SDimitry Andric           if (signo_cstr)
16540b57cec5SDimitry Andric             result.GetOutputStream().Printf(
16550b57cec5SDimitry Andric                 "error: command returned with status %i and signal %s\n",
16560b57cec5SDimitry Andric                 status, signo_cstr);
16570b57cec5SDimitry Andric           else
16580b57cec5SDimitry Andric             result.GetOutputStream().Printf(
16590b57cec5SDimitry Andric                 "error: command returned with status %i and signal %i\n",
16600b57cec5SDimitry Andric                 status, signo);
16610b57cec5SDimitry Andric         } else
16620b57cec5SDimitry Andric           result.GetOutputStream().Printf(
16630b57cec5SDimitry Andric               "error: command returned with status %i\n", status);
16640b57cec5SDimitry Andric       }
16650b57cec5SDimitry Andric     } else {
16660b57cec5SDimitry Andric       result.GetOutputStream().Printf(
16670b57cec5SDimitry Andric           "error: cannot run remote shell commands without a platform\n");
16680b57cec5SDimitry Andric       error.SetErrorString(
16690b57cec5SDimitry Andric           "error: cannot run remote shell commands without a platform");
16700b57cec5SDimitry Andric     }
16710b57cec5SDimitry Andric 
16720b57cec5SDimitry Andric     if (error.Fail()) {
16730b57cec5SDimitry Andric       result.AppendError(error.AsCString());
16740b57cec5SDimitry Andric     } else {
16750b57cec5SDimitry Andric       result.SetStatus(eReturnStatusSuccessFinishResult);
16760b57cec5SDimitry Andric     }
16770b57cec5SDimitry Andric     return true;
16780b57cec5SDimitry Andric   }
16790b57cec5SDimitry Andric 
16800b57cec5SDimitry Andric   CommandOptions m_options;
16810b57cec5SDimitry Andric };
16820b57cec5SDimitry Andric 
16830b57cec5SDimitry Andric // "platform install" - install a target to a remote end
16840b57cec5SDimitry Andric class CommandObjectPlatformInstall : public CommandObjectParsed {
16850b57cec5SDimitry Andric public:
CommandObjectPlatformInstall(CommandInterpreter & interpreter)16860b57cec5SDimitry Andric   CommandObjectPlatformInstall(CommandInterpreter &interpreter)
16870b57cec5SDimitry Andric       : CommandObjectParsed(
16880b57cec5SDimitry Andric             interpreter, "platform target-install",
16890b57cec5SDimitry Andric             "Install a target (bundle or executable file) to the remote end.",
16900b57cec5SDimitry Andric             "platform target-install <local-thing> <remote-sandbox>", 0) {}
16910b57cec5SDimitry Andric 
16920b57cec5SDimitry Andric   ~CommandObjectPlatformInstall() override = default;
16930b57cec5SDimitry Andric 
1694af732203SDimitry Andric   void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)1695af732203SDimitry Andric   HandleArgumentCompletion(CompletionRequest &request,
1696af732203SDimitry Andric                            OptionElementVector &opt_element_vector) override {
1697af732203SDimitry Andric     if (request.GetCursorIndex())
1698af732203SDimitry Andric       return;
1699af732203SDimitry Andric     CommandCompletions::InvokeCommonCompletionCallbacks(
1700af732203SDimitry Andric         GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
1701af732203SDimitry Andric         request, nullptr);
1702af732203SDimitry Andric   }
1703af732203SDimitry Andric 
DoExecute(Args & args,CommandReturnObject & result)17040b57cec5SDimitry Andric   bool DoExecute(Args &args, CommandReturnObject &result) override {
17050b57cec5SDimitry Andric     if (args.GetArgumentCount() != 2) {
17060b57cec5SDimitry Andric       result.AppendError("platform target-install takes two arguments");
17070b57cec5SDimitry Andric       return false;
17080b57cec5SDimitry Andric     }
17090b57cec5SDimitry Andric     // TODO: move the bulk of this code over to the platform itself
17100b57cec5SDimitry Andric     FileSpec src(args.GetArgumentAtIndex(0));
17110b57cec5SDimitry Andric     FileSystem::Instance().Resolve(src);
17120b57cec5SDimitry Andric     FileSpec dst(args.GetArgumentAtIndex(1));
17130b57cec5SDimitry Andric     if (!FileSystem::Instance().Exists(src)) {
17140b57cec5SDimitry Andric       result.AppendError("source location does not exist or is not accessible");
17150b57cec5SDimitry Andric       return false;
17160b57cec5SDimitry Andric     }
17170b57cec5SDimitry Andric     PlatformSP platform_sp(
17180b57cec5SDimitry Andric         GetDebugger().GetPlatformList().GetSelectedPlatform());
17190b57cec5SDimitry Andric     if (!platform_sp) {
17200b57cec5SDimitry Andric       result.AppendError("no platform currently selected");
17210b57cec5SDimitry Andric       return false;
17220b57cec5SDimitry Andric     }
17230b57cec5SDimitry Andric 
17240b57cec5SDimitry Andric     Status error = platform_sp->Install(src, dst);
17250b57cec5SDimitry Andric     if (error.Success()) {
17260b57cec5SDimitry Andric       result.SetStatus(eReturnStatusSuccessFinishNoResult);
17270b57cec5SDimitry Andric     } else {
17280b57cec5SDimitry Andric       result.AppendErrorWithFormat("install failed: %s", error.AsCString());
17290b57cec5SDimitry Andric     }
17300b57cec5SDimitry Andric     return result.Succeeded();
17310b57cec5SDimitry Andric   }
17320b57cec5SDimitry Andric };
17330b57cec5SDimitry Andric 
CommandObjectPlatform(CommandInterpreter & interpreter)17340b57cec5SDimitry Andric CommandObjectPlatform::CommandObjectPlatform(CommandInterpreter &interpreter)
17350b57cec5SDimitry Andric     : CommandObjectMultiword(
17360b57cec5SDimitry Andric           interpreter, "platform", "Commands to manage and create platforms.",
17370b57cec5SDimitry Andric           "platform [connect|disconnect|info|list|status|select] ...") {
17380b57cec5SDimitry Andric   LoadSubCommand("select",
17390b57cec5SDimitry Andric                  CommandObjectSP(new CommandObjectPlatformSelect(interpreter)));
17400b57cec5SDimitry Andric   LoadSubCommand("list",
17410b57cec5SDimitry Andric                  CommandObjectSP(new CommandObjectPlatformList(interpreter)));
17420b57cec5SDimitry Andric   LoadSubCommand("status",
17430b57cec5SDimitry Andric                  CommandObjectSP(new CommandObjectPlatformStatus(interpreter)));
17440b57cec5SDimitry Andric   LoadSubCommand("connect", CommandObjectSP(
17450b57cec5SDimitry Andric                                 new CommandObjectPlatformConnect(interpreter)));
17460b57cec5SDimitry Andric   LoadSubCommand(
17470b57cec5SDimitry Andric       "disconnect",
17480b57cec5SDimitry Andric       CommandObjectSP(new CommandObjectPlatformDisconnect(interpreter)));
17490b57cec5SDimitry Andric   LoadSubCommand("settings", CommandObjectSP(new CommandObjectPlatformSettings(
17500b57cec5SDimitry Andric                                  interpreter)));
17510b57cec5SDimitry Andric   LoadSubCommand("mkdir",
17520b57cec5SDimitry Andric                  CommandObjectSP(new CommandObjectPlatformMkDir(interpreter)));
17530b57cec5SDimitry Andric   LoadSubCommand("file",
17540b57cec5SDimitry Andric                  CommandObjectSP(new CommandObjectPlatformFile(interpreter)));
17550b57cec5SDimitry Andric   LoadSubCommand("get-file", CommandObjectSP(new CommandObjectPlatformGetFile(
17560b57cec5SDimitry Andric                                  interpreter)));
17570b57cec5SDimitry Andric   LoadSubCommand("get-size", CommandObjectSP(new CommandObjectPlatformGetSize(
17580b57cec5SDimitry Andric                                  interpreter)));
17590b57cec5SDimitry Andric   LoadSubCommand("put-file", CommandObjectSP(new CommandObjectPlatformPutFile(
17600b57cec5SDimitry Andric                                  interpreter)));
17610b57cec5SDimitry Andric   LoadSubCommand("process", CommandObjectSP(
17620b57cec5SDimitry Andric                                 new CommandObjectPlatformProcess(interpreter)));
17630b57cec5SDimitry Andric   LoadSubCommand("shell",
17640b57cec5SDimitry Andric                  CommandObjectSP(new CommandObjectPlatformShell(interpreter)));
17650b57cec5SDimitry Andric   LoadSubCommand(
17660b57cec5SDimitry Andric       "target-install",
17670b57cec5SDimitry Andric       CommandObjectSP(new CommandObjectPlatformInstall(interpreter)));
17680b57cec5SDimitry Andric }
17690b57cec5SDimitry Andric 
17700b57cec5SDimitry Andric CommandObjectPlatform::~CommandObjectPlatform() = default;
1771