1cfca06d7SDimitry Andric //===-- CommandObjectPlatform.cpp -----------------------------------------===//
2f034231aSEd Maste //
35f29bb8aSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45f29bb8aSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
55f29bb8aSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6f034231aSEd Maste //
7f034231aSEd Maste //===----------------------------------------------------------------------===//
8f034231aSEd Maste
9f3fbd1c0SDimitry Andric #include "CommandObjectPlatform.h"
107fa27ce4SDimitry Andric #include "CommandOptionsProcessAttach.h"
11b60736ecSDimitry Andric #include "CommandOptionsProcessLaunch.h"
12f034231aSEd Maste #include "lldb/Core/Debugger.h"
13f034231aSEd Maste #include "lldb/Core/Module.h"
14f034231aSEd Maste #include "lldb/Core/PluginManager.h"
1574a628f7SDimitry Andric #include "lldb/Host/OptionParser.h"
16f034231aSEd Maste #include "lldb/Interpreter/CommandInterpreter.h"
174b4fe385SDimitry Andric #include "lldb/Interpreter/CommandOptionArgumentTable.h"
180cac4ca3SEd Maste #include "lldb/Interpreter/CommandOptionValidators.h"
19f034231aSEd Maste #include "lldb/Interpreter/CommandReturnObject.h"
2086758c71SEd Maste #include "lldb/Interpreter/OptionGroupFile.h"
21f034231aSEd Maste #include "lldb/Interpreter/OptionGroupPlatform.h"
227fa27ce4SDimitry Andric #include "lldb/Interpreter/OptionGroupPythonClassWithDict.h"
23f034231aSEd Maste #include "lldb/Target/ExecutionContext.h"
24f034231aSEd Maste #include "lldb/Target/Platform.h"
25f034231aSEd Maste #include "lldb/Target/Process.h"
26f73363f1SDimitry Andric #include "lldb/Utility/Args.h"
277fa27ce4SDimitry Andric #include "lldb/Utility/ScriptedMetadata.h"
287fa27ce4SDimitry Andric #include "lldb/Utility/State.h"
29f034231aSEd Maste
3014f1b3e8SDimitry Andric #include "llvm/ADT/SmallString.h"
3114f1b3e8SDimitry Andric
32f034231aSEd Maste using namespace lldb;
33f034231aSEd Maste using namespace lldb_private;
34f034231aSEd Maste
3514f1b3e8SDimitry Andric static mode_t ParsePermissionString(const char *) = delete;
3614f1b3e8SDimitry Andric
ParsePermissionString(llvm::StringRef permissions)3714f1b3e8SDimitry Andric static mode_t ParsePermissionString(llvm::StringRef permissions) {
3814f1b3e8SDimitry Andric if (permissions.size() != 9)
39f21a844fSEd Maste return (mode_t)(-1);
4014f1b3e8SDimitry Andric bool user_r, user_w, user_x, group_r, group_w, group_x, world_r, world_w,
4114f1b3e8SDimitry Andric world_x;
42f21a844fSEd Maste
43f21a844fSEd Maste user_r = (permissions[0] == 'r');
44f21a844fSEd Maste user_w = (permissions[1] == 'w');
45f21a844fSEd Maste user_x = (permissions[2] == 'x');
46f21a844fSEd Maste
47f21a844fSEd Maste group_r = (permissions[3] == 'r');
48f21a844fSEd Maste group_w = (permissions[4] == 'w');
49f21a844fSEd Maste group_x = (permissions[5] == 'x');
50f21a844fSEd Maste
51f21a844fSEd Maste world_r = (permissions[6] == 'r');
52f21a844fSEd Maste world_w = (permissions[7] == 'w');
53f21a844fSEd Maste world_x = (permissions[8] == 'x');
54f21a844fSEd Maste
55f21a844fSEd Maste mode_t user, group, world;
56f21a844fSEd Maste user = (user_r ? 4 : 0) | (user_w ? 2 : 0) | (user_x ? 1 : 0);
57f21a844fSEd Maste group = (group_r ? 4 : 0) | (group_w ? 2 : 0) | (group_x ? 1 : 0);
58f21a844fSEd Maste world = (world_r ? 4 : 0) | (world_w ? 2 : 0) | (world_x ? 1 : 0);
59f21a844fSEd Maste
60f21a844fSEd Maste return user | group | world;
61f21a844fSEd Maste }
62f21a844fSEd Maste
63ead24645SDimitry Andric #define LLDB_OPTIONS_permissions
64ead24645SDimitry Andric #include "CommandOptions.inc"
65f21a844fSEd Maste
6614f1b3e8SDimitry Andric class OptionPermissions : public OptionGroup {
67f21a844fSEd Maste public:
68344a3780SDimitry Andric OptionPermissions() = default;
69f21a844fSEd Maste
70f3fbd1c0SDimitry Andric ~OptionPermissions() override = default;
71f21a844fSEd Maste
72b76161e4SDimitry Andric lldb_private::Status
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)7314f1b3e8SDimitry Andric SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
7414f1b3e8SDimitry Andric ExecutionContext *execution_context) override {
75b76161e4SDimitry Andric Status error;
76f21a844fSEd Maste char short_option = (char)GetDefinitions()[option_idx].short_option;
7714f1b3e8SDimitry Andric switch (short_option) {
7814f1b3e8SDimitry Andric case 'v': {
7914f1b3e8SDimitry Andric if (option_arg.getAsInteger(8, m_permissions)) {
8014f1b3e8SDimitry Andric m_permissions = 0777;
8114f1b3e8SDimitry Andric error.SetErrorStringWithFormat("invalid value for permissions: %s",
8214f1b3e8SDimitry Andric option_arg.str().c_str());
83f21a844fSEd Maste }
8414f1b3e8SDimitry Andric
8514f1b3e8SDimitry Andric } break;
8614f1b3e8SDimitry Andric case 's': {
87f21a844fSEd Maste mode_t perms = ParsePermissionString(option_arg);
88f21a844fSEd Maste if (perms == (mode_t)-1)
8914f1b3e8SDimitry Andric error.SetErrorStringWithFormat("invalid value for permissions: %s",
9014f1b3e8SDimitry Andric option_arg.str().c_str());
91f21a844fSEd Maste else
92f21a844fSEd Maste m_permissions = perms;
9314f1b3e8SDimitry Andric } break;
94f21a844fSEd Maste case 'r':
9586758c71SEd Maste m_permissions |= lldb::eFilePermissionsUserRead;
96f21a844fSEd Maste break;
97f21a844fSEd Maste case 'w':
9886758c71SEd Maste m_permissions |= lldb::eFilePermissionsUserWrite;
99f21a844fSEd Maste break;
100f21a844fSEd Maste case 'x':
10186758c71SEd Maste m_permissions |= lldb::eFilePermissionsUserExecute;
102f21a844fSEd Maste break;
103f21a844fSEd Maste case 'R':
10486758c71SEd Maste m_permissions |= lldb::eFilePermissionsGroupRead;
105f21a844fSEd Maste break;
106f21a844fSEd Maste case 'W':
10786758c71SEd Maste m_permissions |= lldb::eFilePermissionsGroupWrite;
108f21a844fSEd Maste break;
109f21a844fSEd Maste case 'X':
11086758c71SEd Maste m_permissions |= lldb::eFilePermissionsGroupExecute;
111f21a844fSEd Maste break;
112f21a844fSEd Maste case 'd':
11386758c71SEd Maste m_permissions |= lldb::eFilePermissionsWorldRead;
114f21a844fSEd Maste break;
115f21a844fSEd Maste case 't':
11686758c71SEd Maste m_permissions |= lldb::eFilePermissionsWorldWrite;
117f21a844fSEd Maste break;
118f21a844fSEd Maste case 'e':
11986758c71SEd Maste m_permissions |= lldb::eFilePermissionsWorldExecute;
120f21a844fSEd Maste break;
121f21a844fSEd Maste default:
122ead24645SDimitry Andric llvm_unreachable("Unimplemented option");
123f21a844fSEd Maste }
124f21a844fSEd Maste
125f21a844fSEd Maste return error;
126f21a844fSEd Maste }
127f21a844fSEd Maste
OptionParsingStarting(ExecutionContext * execution_context)12814f1b3e8SDimitry Andric void OptionParsingStarting(ExecutionContext *execution_context) override {
129f21a844fSEd Maste m_permissions = 0;
130f21a844fSEd Maste }
131f21a844fSEd Maste
GetDefinitions()13214f1b3e8SDimitry Andric llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
133e3b55780SDimitry Andric return llvm::ArrayRef(g_permissions_options);
134f21a844fSEd Maste }
135f21a844fSEd Maste
136f21a844fSEd Maste // Instance variables to hold the values for command options.
137f21a844fSEd Maste
138f21a844fSEd Maste uint32_t m_permissions;
139f3fbd1c0SDimitry Andric
140f21a844fSEd Maste private:
141cfca06d7SDimitry Andric OptionPermissions(const OptionPermissions &) = delete;
142cfca06d7SDimitry Andric const OptionPermissions &operator=(const OptionPermissions &) = delete;
143f21a844fSEd Maste };
144f034231aSEd Maste
145f034231aSEd Maste // "platform select <platform-name>"
14614f1b3e8SDimitry Andric class CommandObjectPlatformSelect : public CommandObjectParsed {
147f034231aSEd Maste public:
CommandObjectPlatformSelect(CommandInterpreter & interpreter)14814f1b3e8SDimitry Andric CommandObjectPlatformSelect(CommandInterpreter &interpreter)
14914f1b3e8SDimitry Andric : CommandObjectParsed(interpreter, "platform select",
15014f1b3e8SDimitry Andric "Create a platform if needed and select it as the "
15114f1b3e8SDimitry Andric "current platform.",
15214f1b3e8SDimitry Andric "platform select <platform-name>", 0),
15314f1b3e8SDimitry Andric m_platform_options(
15414f1b3e8SDimitry Andric false) // Don't include the "--platform" option by passing false
155f034231aSEd Maste {
156f034231aSEd Maste m_option_group.Append(&m_platform_options, LLDB_OPT_SET_ALL, 1);
157f034231aSEd Maste m_option_group.Finalize();
158ac9a064cSDimitry Andric AddSimpleArgumentList(eArgTypePlatform);
159f034231aSEd Maste }
160f034231aSEd Maste
161f3fbd1c0SDimitry Andric ~CommandObjectPlatformSelect() override = default;
162f034231aSEd Maste
HandleCompletion(CompletionRequest & request)163ead24645SDimitry Andric void HandleCompletion(CompletionRequest &request) override {
1647fa27ce4SDimitry Andric lldb_private::CommandCompletions::PlatformPluginNames(
1657fa27ce4SDimitry Andric GetCommandInterpreter(), request, nullptr);
166f034231aSEd Maste }
167f034231aSEd Maste
GetOptions()16814f1b3e8SDimitry Andric Options *GetOptions() override { return &m_option_group; }
169f034231aSEd Maste
170f034231aSEd Maste protected:
DoExecute(Args & args,CommandReturnObject & result)171b1c73532SDimitry Andric void DoExecute(Args &args, CommandReturnObject &result) override {
17214f1b3e8SDimitry Andric if (args.GetArgumentCount() == 1) {
173f034231aSEd Maste const char *platform_name = args.GetArgumentAtIndex(0);
17414f1b3e8SDimitry Andric if (platform_name && platform_name[0]) {
175f034231aSEd Maste const bool select = true;
176f034231aSEd Maste m_platform_options.SetPlatformName(platform_name);
177b76161e4SDimitry Andric Status error;
178f034231aSEd Maste ArchSpec platform_arch;
17914f1b3e8SDimitry Andric PlatformSP platform_sp(m_platform_options.CreatePlatformWithOptions(
18014f1b3e8SDimitry Andric m_interpreter, ArchSpec(), select, error, platform_arch));
18114f1b3e8SDimitry Andric if (platform_sp) {
1825f29bb8aSDimitry Andric GetDebugger().GetPlatformList().SetSelectedPlatform(platform_sp);
18312bd4897SEd Maste
184f034231aSEd Maste platform_sp->GetStatus(result.GetOutputStream());
185f034231aSEd Maste result.SetStatus(eReturnStatusSuccessFinishResult);
18614f1b3e8SDimitry Andric } else {
187f034231aSEd Maste result.AppendError(error.AsCString());
188f034231aSEd Maste }
18914f1b3e8SDimitry Andric } else {
190f034231aSEd Maste result.AppendError("invalid platform name");
191f034231aSEd Maste }
19214f1b3e8SDimitry Andric } else {
19314f1b3e8SDimitry Andric result.AppendError(
19414f1b3e8SDimitry Andric "platform create takes a platform name as an argument\n");
195f034231aSEd Maste }
196f034231aSEd Maste }
197f034231aSEd Maste
198f034231aSEd Maste OptionGroupOptions m_option_group;
199f034231aSEd Maste OptionGroupPlatform m_platform_options;
200f034231aSEd Maste };
201f034231aSEd Maste
202f034231aSEd Maste // "platform list"
20314f1b3e8SDimitry Andric class CommandObjectPlatformList : public CommandObjectParsed {
204f034231aSEd Maste public:
CommandObjectPlatformList(CommandInterpreter & interpreter)20514f1b3e8SDimitry Andric CommandObjectPlatformList(CommandInterpreter &interpreter)
20614f1b3e8SDimitry Andric : CommandObjectParsed(interpreter, "platform list",
20714f1b3e8SDimitry Andric "List all platforms that are available.", nullptr,
20814f1b3e8SDimitry Andric 0) {}
209f034231aSEd Maste
210f3fbd1c0SDimitry Andric ~CommandObjectPlatformList() override = default;
211f034231aSEd Maste
212f034231aSEd Maste protected:
DoExecute(Args & args,CommandReturnObject & result)213b1c73532SDimitry Andric void DoExecute(Args &args, CommandReturnObject &result) override {
214f034231aSEd Maste Stream &ostrm = result.GetOutputStream();
215f034231aSEd Maste ostrm.Printf("Available platforms:\n");
216f034231aSEd Maste
217205afe67SEd Maste PlatformSP host_platform_sp(Platform::GetHostPlatform());
218c0981da4SDimitry Andric ostrm.Format("{0}: {1}\n", host_platform_sp->GetPluginName(),
219f034231aSEd Maste host_platform_sp->GetDescription());
220f034231aSEd Maste
221f034231aSEd Maste uint32_t idx;
2225f29bb8aSDimitry Andric for (idx = 0; true; ++idx) {
223c0981da4SDimitry Andric llvm::StringRef plugin_name =
22414f1b3e8SDimitry Andric PluginManager::GetPlatformPluginNameAtIndex(idx);
225c0981da4SDimitry Andric if (plugin_name.empty())
226f034231aSEd Maste break;
227c0981da4SDimitry Andric llvm::StringRef plugin_desc =
22814f1b3e8SDimitry Andric PluginManager::GetPlatformPluginDescriptionAtIndex(idx);
229c0981da4SDimitry Andric ostrm.Format("{0}: {1}\n", plugin_name, plugin_desc);
230f034231aSEd Maste }
231f034231aSEd Maste
23214f1b3e8SDimitry Andric if (idx == 0) {
233f034231aSEd Maste result.AppendError("no platforms are available\n");
23414f1b3e8SDimitry Andric } else
235f034231aSEd Maste result.SetStatus(eReturnStatusSuccessFinishResult);
236f034231aSEd Maste }
237f034231aSEd Maste };
238f034231aSEd Maste
239f034231aSEd Maste // "platform status"
24014f1b3e8SDimitry Andric class CommandObjectPlatformStatus : public CommandObjectParsed {
241f034231aSEd Maste public:
CommandObjectPlatformStatus(CommandInterpreter & interpreter)242f3fbd1c0SDimitry Andric CommandObjectPlatformStatus(CommandInterpreter &interpreter)
24314f1b3e8SDimitry Andric : CommandObjectParsed(interpreter, "platform status",
24414f1b3e8SDimitry Andric "Display status for the current platform.", nullptr,
24514f1b3e8SDimitry Andric 0) {}
246f034231aSEd Maste
247f3fbd1c0SDimitry Andric ~CommandObjectPlatformStatus() override = default;
248f034231aSEd Maste
249f034231aSEd Maste protected:
DoExecute(Args & args,CommandReturnObject & result)250b1c73532SDimitry Andric void DoExecute(Args &args, CommandReturnObject &result) override {
251f034231aSEd Maste Stream &ostrm = result.GetOutputStream();
252f034231aSEd Maste
2535f29bb8aSDimitry Andric Target *target = GetDebugger().GetSelectedTarget().get();
254f034231aSEd Maste PlatformSP platform_sp;
25514f1b3e8SDimitry Andric if (target) {
256f034231aSEd Maste platform_sp = target->GetPlatform();
257f034231aSEd Maste }
25814f1b3e8SDimitry Andric if (!platform_sp) {
2595f29bb8aSDimitry Andric platform_sp = GetDebugger().GetPlatformList().GetSelectedPlatform();
260f034231aSEd Maste }
26114f1b3e8SDimitry Andric if (platform_sp) {
262f034231aSEd Maste platform_sp->GetStatus(ostrm);
263f034231aSEd Maste result.SetStatus(eReturnStatusSuccessFinishResult);
26414f1b3e8SDimitry Andric } else {
265ef5d0b5eSDimitry Andric result.AppendError("no platform is currently selected\n");
266f034231aSEd Maste }
267f034231aSEd Maste }
268f034231aSEd Maste };
269f034231aSEd Maste
270f034231aSEd Maste // "platform connect <connect-url>"
27114f1b3e8SDimitry Andric class CommandObjectPlatformConnect : public CommandObjectParsed {
272f034231aSEd Maste public:
CommandObjectPlatformConnect(CommandInterpreter & interpreter)273f3fbd1c0SDimitry Andric CommandObjectPlatformConnect(CommandInterpreter &interpreter)
27414f1b3e8SDimitry Andric : CommandObjectParsed(
27514f1b3e8SDimitry Andric interpreter, "platform connect",
276f3fbd1c0SDimitry Andric "Select the current platform by providing a connection URL.",
277145449b1SDimitry Andric "platform connect <connect-url>", 0) {
278ac9a064cSDimitry Andric AddSimpleArgumentList(eArgTypeConnectURL);
279145449b1SDimitry Andric }
280f034231aSEd Maste
281f3fbd1c0SDimitry Andric ~CommandObjectPlatformConnect() override = default;
282f034231aSEd Maste
283f034231aSEd Maste protected:
DoExecute(Args & args,CommandReturnObject & result)284b1c73532SDimitry Andric void DoExecute(Args &args, CommandReturnObject &result) override {
285f034231aSEd Maste Stream &ostrm = result.GetOutputStream();
286f034231aSEd Maste
28714f1b3e8SDimitry Andric PlatformSP platform_sp(
2885f29bb8aSDimitry Andric GetDebugger().GetPlatformList().GetSelectedPlatform());
28914f1b3e8SDimitry Andric if (platform_sp) {
290b76161e4SDimitry Andric Status error(platform_sp->ConnectRemote(args));
29114f1b3e8SDimitry Andric if (error.Success()) {
292f034231aSEd Maste platform_sp->GetStatus(ostrm);
293f034231aSEd Maste result.SetStatus(eReturnStatusSuccessFinishResult);
294e81d9d49SDimitry Andric
2955f29bb8aSDimitry Andric platform_sp->ConnectToWaitingProcesses(GetDebugger(), error);
29614f1b3e8SDimitry Andric if (error.Fail()) {
297e81d9d49SDimitry Andric result.AppendError(error.AsCString());
298e81d9d49SDimitry Andric }
29914f1b3e8SDimitry Andric } else {
300f034231aSEd Maste result.AppendErrorWithFormat("%s\n", error.AsCString());
301f034231aSEd Maste }
30214f1b3e8SDimitry Andric } else {
303f21a844fSEd Maste result.AppendError("no platform is currently selected\n");
304f034231aSEd Maste }
305f034231aSEd Maste }
306f21a844fSEd Maste
GetOptions()30714f1b3e8SDimitry Andric Options *GetOptions() override {
30814f1b3e8SDimitry Andric PlatformSP platform_sp(
3095f29bb8aSDimitry Andric GetDebugger().GetPlatformList().GetSelectedPlatform());
310f3fbd1c0SDimitry Andric OptionGroupOptions *m_platform_options = nullptr;
31114f1b3e8SDimitry Andric if (platform_sp) {
312f21a844fSEd Maste m_platform_options = platform_sp->GetConnectionOptions(m_interpreter);
313f3fbd1c0SDimitry Andric if (m_platform_options != nullptr && !m_platform_options->m_did_finalize)
314f21a844fSEd Maste m_platform_options->Finalize();
315f21a844fSEd Maste }
316f21a844fSEd Maste return m_platform_options;
317f21a844fSEd Maste }
318f034231aSEd Maste };
319f034231aSEd Maste
320f034231aSEd Maste // "platform disconnect"
32114f1b3e8SDimitry Andric class CommandObjectPlatformDisconnect : public CommandObjectParsed {
322f034231aSEd Maste public:
CommandObjectPlatformDisconnect(CommandInterpreter & interpreter)323f3fbd1c0SDimitry Andric CommandObjectPlatformDisconnect(CommandInterpreter &interpreter)
32414f1b3e8SDimitry Andric : CommandObjectParsed(interpreter, "platform disconnect",
32514f1b3e8SDimitry Andric "Disconnect from the current platform.",
32614f1b3e8SDimitry Andric "platform disconnect", 0) {}
327f034231aSEd Maste
328f3fbd1c0SDimitry Andric ~CommandObjectPlatformDisconnect() override = default;
329f034231aSEd Maste
330f034231aSEd Maste protected:
DoExecute(Args & args,CommandReturnObject & result)331b1c73532SDimitry Andric void DoExecute(Args &args, CommandReturnObject &result) override {
33214f1b3e8SDimitry Andric PlatformSP platform_sp(
3335f29bb8aSDimitry Andric GetDebugger().GetPlatformList().GetSelectedPlatform());
33414f1b3e8SDimitry Andric if (platform_sp) {
33514f1b3e8SDimitry Andric if (args.GetArgumentCount() == 0) {
336b76161e4SDimitry Andric Status error;
337f034231aSEd Maste
33814f1b3e8SDimitry Andric if (platform_sp->IsConnected()) {
339f73363f1SDimitry Andric // Cache the instance name if there is one since we are about to
340f73363f1SDimitry Andric // disconnect and the name might go with it.
341f034231aSEd Maste const char *hostname_cstr = platform_sp->GetHostname();
342f034231aSEd Maste std::string hostname;
343f034231aSEd Maste if (hostname_cstr)
344f034231aSEd Maste hostname.assign(hostname_cstr);
345f034231aSEd Maste
346f034231aSEd Maste error = platform_sp->DisconnectRemote();
34714f1b3e8SDimitry Andric if (error.Success()) {
348f034231aSEd Maste Stream &ostrm = result.GetOutputStream();
349f034231aSEd Maste if (hostname.empty())
350c0981da4SDimitry Andric ostrm.Format("Disconnected from \"{0}\"\n",
351c0981da4SDimitry Andric platform_sp->GetPluginName());
352f034231aSEd Maste else
353f034231aSEd Maste ostrm.Printf("Disconnected from \"%s\"\n", hostname.c_str());
354f034231aSEd Maste result.SetStatus(eReturnStatusSuccessFinishResult);
35514f1b3e8SDimitry Andric } else {
356f034231aSEd Maste result.AppendErrorWithFormat("%s", error.AsCString());
357f034231aSEd Maste }
35814f1b3e8SDimitry Andric } else {
359f034231aSEd Maste // Not connected...
360c0981da4SDimitry Andric result.AppendErrorWithFormatv("not connected to '{0}'",
361c0981da4SDimitry Andric platform_sp->GetPluginName());
362f034231aSEd Maste }
36314f1b3e8SDimitry Andric } else {
364f034231aSEd Maste // Bad args
36514f1b3e8SDimitry Andric result.AppendError(
36614f1b3e8SDimitry Andric "\"platform disconnect\" doesn't take any arguments");
367f034231aSEd Maste }
36814f1b3e8SDimitry Andric } else {
369f034231aSEd Maste result.AppendError("no platform is currently selected");
370f034231aSEd Maste }
371f034231aSEd Maste }
372f034231aSEd Maste };
373f21a844fSEd Maste
37486758c71SEd Maste // "platform settings"
37514f1b3e8SDimitry Andric class CommandObjectPlatformSettings : public CommandObjectParsed {
37686758c71SEd Maste public:
CommandObjectPlatformSettings(CommandInterpreter & interpreter)37714f1b3e8SDimitry Andric CommandObjectPlatformSettings(CommandInterpreter &interpreter)
37814f1b3e8SDimitry Andric : CommandObjectParsed(interpreter, "platform settings",
379e3b55780SDimitry Andric "Set settings for the current target's platform.",
38014f1b3e8SDimitry Andric "platform settings", 0),
381b60736ecSDimitry Andric m_option_working_dir(LLDB_OPT_SET_1, false, "working-dir", 'w',
3827fa27ce4SDimitry Andric lldb::eRemoteDiskDirectoryCompletion, eArgTypePath,
38314f1b3e8SDimitry Andric "The working directory for the platform.") {
38486758c71SEd Maste m_options.Append(&m_option_working_dir, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
38586758c71SEd Maste }
38686758c71SEd Maste
387f3fbd1c0SDimitry Andric ~CommandObjectPlatformSettings() override = default;
38886758c71SEd Maste
38986758c71SEd Maste protected:
DoExecute(Args & args,CommandReturnObject & result)390b1c73532SDimitry Andric void DoExecute(Args &args, CommandReturnObject &result) override {
39114f1b3e8SDimitry Andric PlatformSP platform_sp(
3925f29bb8aSDimitry Andric GetDebugger().GetPlatformList().GetSelectedPlatform());
39314f1b3e8SDimitry Andric if (platform_sp) {
39486758c71SEd Maste if (m_option_working_dir.GetOptionValue().OptionWasSet())
39514f1b3e8SDimitry Andric platform_sp->SetWorkingDirectory(
39614f1b3e8SDimitry Andric m_option_working_dir.GetOptionValue().GetCurrentValue());
39714f1b3e8SDimitry Andric } else {
39886758c71SEd Maste result.AppendError("no platform is currently selected");
39986758c71SEd Maste }
40086758c71SEd Maste }
40186758c71SEd Maste
GetOptions()40214f1b3e8SDimitry Andric Options *GetOptions() override {
403f3fbd1c0SDimitry Andric if (!m_options.DidFinalize())
40486758c71SEd Maste m_options.Finalize();
40586758c71SEd Maste return &m_options;
40686758c71SEd Maste }
40786758c71SEd Maste
40886758c71SEd Maste OptionGroupOptions m_options;
40986758c71SEd Maste OptionGroupFile m_option_working_dir;
41086758c71SEd Maste };
41186758c71SEd Maste
412f21a844fSEd Maste // "platform mkdir"
41314f1b3e8SDimitry Andric class CommandObjectPlatformMkDir : public CommandObjectParsed {
414f21a844fSEd Maste public:
CommandObjectPlatformMkDir(CommandInterpreter & interpreter)41514f1b3e8SDimitry Andric CommandObjectPlatformMkDir(CommandInterpreter &interpreter)
41614f1b3e8SDimitry Andric : CommandObjectParsed(interpreter, "platform mkdir",
41714f1b3e8SDimitry Andric "Make a new directory on the remote end.", nullptr,
418145449b1SDimitry Andric 0) {
419ac9a064cSDimitry Andric AddSimpleArgumentList(eArgTypeRemotePath);
420145449b1SDimitry Andric }
421f21a844fSEd Maste
422f3fbd1c0SDimitry Andric ~CommandObjectPlatformMkDir() override = default;
423f21a844fSEd Maste
DoExecute(Args & args,CommandReturnObject & result)424b1c73532SDimitry Andric void DoExecute(Args &args, CommandReturnObject &result) override {
42514f1b3e8SDimitry Andric PlatformSP platform_sp(
4265f29bb8aSDimitry Andric GetDebugger().GetPlatformList().GetSelectedPlatform());
42714f1b3e8SDimitry Andric if (platform_sp) {
428f21a844fSEd Maste std::string cmd_line;
429f21a844fSEd Maste args.GetCommandString(cmd_line);
43086758c71SEd Maste uint32_t mode;
43114f1b3e8SDimitry Andric const OptionPermissions *options_permissions =
43214f1b3e8SDimitry Andric (const OptionPermissions *)m_options.GetGroupWithOption('r');
433f21a844fSEd Maste if (options_permissions)
43486758c71SEd Maste mode = options_permissions->m_permissions;
435f21a844fSEd Maste else
43614f1b3e8SDimitry Andric mode = lldb::eFilePermissionsUserRWX | lldb::eFilePermissionsGroupRWX |
43714f1b3e8SDimitry Andric lldb::eFilePermissionsWorldRX;
43894994d37SDimitry Andric Status error = platform_sp->MakeDirectory(FileSpec(cmd_line), mode);
43914f1b3e8SDimitry Andric if (error.Success()) {
440f21a844fSEd Maste result.SetStatus(eReturnStatusSuccessFinishResult);
44114f1b3e8SDimitry Andric } else {
44286758c71SEd Maste result.AppendError(error.AsCString());
44386758c71SEd Maste }
44414f1b3e8SDimitry Andric } else {
445f21a844fSEd Maste result.AppendError("no platform currently selected\n");
446f21a844fSEd Maste }
447f21a844fSEd Maste }
448f21a844fSEd Maste
GetOptions()44914f1b3e8SDimitry Andric Options *GetOptions() override {
45014f1b3e8SDimitry Andric if (!m_options.DidFinalize()) {
451e3b55780SDimitry Andric m_options.Append(&m_option_permissions);
452f21a844fSEd Maste m_options.Finalize();
453f21a844fSEd Maste }
454f21a844fSEd Maste return &m_options;
455f21a844fSEd Maste }
456f21a844fSEd Maste
457e3b55780SDimitry Andric OptionPermissions m_option_permissions;
458f3fbd1c0SDimitry Andric OptionGroupOptions m_options;
459f21a844fSEd Maste };
460f21a844fSEd Maste
461f21a844fSEd Maste // "platform fopen"
46214f1b3e8SDimitry Andric class CommandObjectPlatformFOpen : public CommandObjectParsed {
463f21a844fSEd Maste public:
CommandObjectPlatformFOpen(CommandInterpreter & interpreter)46414f1b3e8SDimitry Andric CommandObjectPlatformFOpen(CommandInterpreter &interpreter)
46514f1b3e8SDimitry Andric : CommandObjectParsed(interpreter, "platform file open",
466145449b1SDimitry Andric "Open a file on the remote end.", nullptr, 0) {
467ac9a064cSDimitry Andric AddSimpleArgumentList(eArgTypeRemotePath);
468145449b1SDimitry Andric }
469f21a844fSEd Maste
470f3fbd1c0SDimitry Andric ~CommandObjectPlatformFOpen() override = default;
471f21a844fSEd Maste
DoExecute(Args & args,CommandReturnObject & result)472b1c73532SDimitry Andric void DoExecute(Args &args, CommandReturnObject &result) override {
47314f1b3e8SDimitry Andric PlatformSP platform_sp(
4745f29bb8aSDimitry Andric GetDebugger().GetPlatformList().GetSelectedPlatform());
47514f1b3e8SDimitry Andric if (platform_sp) {
476b76161e4SDimitry Andric Status error;
477f21a844fSEd Maste std::string cmd_line;
478f21a844fSEd Maste args.GetCommandString(cmd_line);
479f21a844fSEd Maste mode_t perms;
48014f1b3e8SDimitry Andric const OptionPermissions *options_permissions =
48114f1b3e8SDimitry Andric (const OptionPermissions *)m_options.GetGroupWithOption('r');
482f21a844fSEd Maste if (options_permissions)
483f21a844fSEd Maste perms = options_permissions->m_permissions;
484f21a844fSEd Maste else
48514f1b3e8SDimitry Andric perms = lldb::eFilePermissionsUserRW | lldb::eFilePermissionsGroupRW |
48614f1b3e8SDimitry Andric lldb::eFilePermissionsWorldRead;
48714f1b3e8SDimitry Andric lldb::user_id_t fd = platform_sp->OpenFile(
48894994d37SDimitry Andric FileSpec(cmd_line),
489c0981da4SDimitry Andric File::eOpenOptionReadWrite | File::eOpenOptionCanCreate,
49014f1b3e8SDimitry Andric perms, error);
49114f1b3e8SDimitry Andric if (error.Success()) {
492f21a844fSEd Maste result.AppendMessageWithFormat("File Descriptor = %" PRIu64 "\n", fd);
493f21a844fSEd Maste result.SetStatus(eReturnStatusSuccessFinishResult);
49414f1b3e8SDimitry Andric } else {
495f21a844fSEd Maste result.AppendError(error.AsCString());
496f21a844fSEd Maste }
49714f1b3e8SDimitry Andric } else {
498f21a844fSEd Maste result.AppendError("no platform currently selected\n");
499f21a844fSEd Maste }
500f21a844fSEd Maste }
501f3fbd1c0SDimitry Andric
GetOptions()50214f1b3e8SDimitry Andric Options *GetOptions() override {
50314f1b3e8SDimitry Andric if (!m_options.DidFinalize()) {
504e3b55780SDimitry Andric m_options.Append(&m_option_permissions);
505f21a844fSEd Maste m_options.Finalize();
506f21a844fSEd Maste }
507f21a844fSEd Maste return &m_options;
508f21a844fSEd Maste }
509f3fbd1c0SDimitry Andric
510e3b55780SDimitry Andric OptionPermissions m_option_permissions;
511f21a844fSEd Maste OptionGroupOptions m_options;
512f21a844fSEd Maste };
513f21a844fSEd Maste
514f21a844fSEd Maste // "platform fclose"
51514f1b3e8SDimitry Andric class CommandObjectPlatformFClose : public CommandObjectParsed {
516f21a844fSEd Maste public:
CommandObjectPlatformFClose(CommandInterpreter & interpreter)51714f1b3e8SDimitry Andric CommandObjectPlatformFClose(CommandInterpreter &interpreter)
51814f1b3e8SDimitry Andric : CommandObjectParsed(interpreter, "platform file close",
519145449b1SDimitry Andric "Close a file on the remote end.", nullptr, 0) {
520ac9a064cSDimitry Andric AddSimpleArgumentList(eArgTypeUnsignedInteger);
521145449b1SDimitry Andric }
522f21a844fSEd Maste
523f3fbd1c0SDimitry Andric ~CommandObjectPlatformFClose() override = default;
524f21a844fSEd Maste
DoExecute(Args & args,CommandReturnObject & result)525b1c73532SDimitry Andric void DoExecute(Args &args, CommandReturnObject &result) override {
52614f1b3e8SDimitry Andric PlatformSP platform_sp(
5275f29bb8aSDimitry Andric GetDebugger().GetPlatformList().GetSelectedPlatform());
52814f1b3e8SDimitry Andric if (platform_sp) {
529f21a844fSEd Maste std::string cmd_line;
530f21a844fSEd Maste args.GetCommandString(cmd_line);
531cfca06d7SDimitry Andric lldb::user_id_t fd;
532cfca06d7SDimitry Andric if (!llvm::to_integer(cmd_line, fd)) {
533cfca06d7SDimitry Andric result.AppendErrorWithFormatv("'{0}' is not a valid file descriptor.\n",
534cfca06d7SDimitry Andric cmd_line);
535b1c73532SDimitry Andric return;
536cfca06d7SDimitry Andric }
537b76161e4SDimitry Andric Status error;
538f21a844fSEd Maste bool success = platform_sp->CloseFile(fd, error);
53914f1b3e8SDimitry Andric if (success) {
540f21a844fSEd Maste result.AppendMessageWithFormat("file %" PRIu64 " closed.\n", fd);
541f21a844fSEd Maste result.SetStatus(eReturnStatusSuccessFinishResult);
54214f1b3e8SDimitry Andric } else {
543f21a844fSEd Maste result.AppendError(error.AsCString());
544f21a844fSEd Maste }
54514f1b3e8SDimitry Andric } else {
546f21a844fSEd Maste result.AppendError("no platform currently selected\n");
547f21a844fSEd Maste }
548f21a844fSEd Maste }
549f21a844fSEd Maste };
550f21a844fSEd Maste
551f21a844fSEd Maste // "platform fread"
55214f1b3e8SDimitry Andric
553ead24645SDimitry Andric #define LLDB_OPTIONS_platform_fread
554ead24645SDimitry Andric #include "CommandOptions.inc"
55514f1b3e8SDimitry Andric
55614f1b3e8SDimitry Andric class CommandObjectPlatformFRead : public CommandObjectParsed {
557f21a844fSEd Maste public:
CommandObjectPlatformFRead(CommandInterpreter & interpreter)55814f1b3e8SDimitry Andric CommandObjectPlatformFRead(CommandInterpreter &interpreter)
55914f1b3e8SDimitry Andric : CommandObjectParsed(interpreter, "platform file read",
56014f1b3e8SDimitry Andric "Read data from a file on the remote end.", nullptr,
561145449b1SDimitry Andric 0) {
562ac9a064cSDimitry Andric AddSimpleArgumentList(eArgTypeUnsignedInteger);
563145449b1SDimitry Andric }
564f21a844fSEd Maste
565f3fbd1c0SDimitry Andric ~CommandObjectPlatformFRead() override = default;
566f21a844fSEd Maste
DoExecute(Args & args,CommandReturnObject & result)567b1c73532SDimitry Andric void DoExecute(Args &args, CommandReturnObject &result) override {
56814f1b3e8SDimitry Andric PlatformSP platform_sp(
5695f29bb8aSDimitry Andric GetDebugger().GetPlatformList().GetSelectedPlatform());
57014f1b3e8SDimitry Andric if (platform_sp) {
571f21a844fSEd Maste std::string cmd_line;
572f21a844fSEd Maste args.GetCommandString(cmd_line);
573cfca06d7SDimitry Andric lldb::user_id_t fd;
574cfca06d7SDimitry Andric if (!llvm::to_integer(cmd_line, fd)) {
575cfca06d7SDimitry Andric result.AppendErrorWithFormatv("'{0}' is not a valid file descriptor.\n",
576cfca06d7SDimitry Andric cmd_line);
577b1c73532SDimitry Andric return;
578cfca06d7SDimitry Andric }
579f21a844fSEd Maste std::string buffer(m_options.m_count, 0);
580b76161e4SDimitry Andric Status error;
581c0981da4SDimitry Andric uint64_t retcode = platform_sp->ReadFile(
58214f1b3e8SDimitry Andric fd, m_options.m_offset, &buffer[0], m_options.m_count, error);
583c0981da4SDimitry Andric if (retcode != UINT64_MAX) {
584c0981da4SDimitry Andric result.AppendMessageWithFormat("Return = %" PRIu64 "\n", retcode);
585f21a844fSEd Maste result.AppendMessageWithFormat("Data = \"%s\"\n", buffer.c_str());
586f21a844fSEd Maste result.SetStatus(eReturnStatusSuccessFinishResult);
58714f1b3e8SDimitry Andric } else {
588c0981da4SDimitry Andric result.AppendError(error.AsCString());
589c0981da4SDimitry Andric }
590c0981da4SDimitry Andric } else {
591f21a844fSEd Maste result.AppendError("no platform currently selected\n");
592f21a844fSEd Maste }
593f21a844fSEd Maste }
594f3fbd1c0SDimitry Andric
GetOptions()59514f1b3e8SDimitry Andric Options *GetOptions() override { return &m_options; }
596f21a844fSEd Maste
597f21a844fSEd Maste protected:
59814f1b3e8SDimitry Andric class CommandOptions : public Options {
599f21a844fSEd Maste public:
600145449b1SDimitry Andric CommandOptions() = default;
601f21a844fSEd Maste
602f3fbd1c0SDimitry Andric ~CommandOptions() override = default;
603f21a844fSEd Maste
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)604b76161e4SDimitry Andric Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
60514f1b3e8SDimitry Andric ExecutionContext *execution_context) override {
606b76161e4SDimitry Andric Status error;
607f21a844fSEd Maste char short_option = (char)m_getopt_table[option_idx].val;
608f21a844fSEd Maste
60914f1b3e8SDimitry Andric switch (short_option) {
610f21a844fSEd Maste case 'o':
61114f1b3e8SDimitry Andric if (option_arg.getAsInteger(0, m_offset))
61214f1b3e8SDimitry Andric error.SetErrorStringWithFormat("invalid offset: '%s'",
61314f1b3e8SDimitry Andric option_arg.str().c_str());
614f21a844fSEd Maste break;
615f21a844fSEd Maste case 'c':
61614f1b3e8SDimitry Andric if (option_arg.getAsInteger(0, m_count))
61714f1b3e8SDimitry Andric error.SetErrorStringWithFormat("invalid offset: '%s'",
61814f1b3e8SDimitry Andric option_arg.str().c_str());
619f21a844fSEd Maste break;
620f21a844fSEd Maste default:
621ead24645SDimitry Andric llvm_unreachable("Unimplemented option");
622f21a844fSEd Maste }
623f21a844fSEd Maste
624f21a844fSEd Maste return error;
625f21a844fSEd Maste }
626f21a844fSEd Maste
OptionParsingStarting(ExecutionContext * execution_context)62714f1b3e8SDimitry Andric void OptionParsingStarting(ExecutionContext *execution_context) override {
628f21a844fSEd Maste m_offset = 0;
629f21a844fSEd Maste m_count = 1;
630f21a844fSEd Maste }
631f21a844fSEd Maste
GetDefinitions()63214f1b3e8SDimitry Andric llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
633e3b55780SDimitry Andric return llvm::ArrayRef(g_platform_fread_options);
634f21a844fSEd Maste }
635f21a844fSEd Maste
636f21a844fSEd Maste // Instance variables to hold the values for command options.
637f21a844fSEd Maste
638f21a844fSEd Maste uint32_t m_offset;
639f21a844fSEd Maste uint32_t m_count;
640f21a844fSEd Maste };
641f3fbd1c0SDimitry Andric
642f21a844fSEd Maste CommandOptions m_options;
643f21a844fSEd Maste };
644f3fbd1c0SDimitry Andric
645f21a844fSEd Maste // "platform fwrite"
64614f1b3e8SDimitry Andric
647ead24645SDimitry Andric #define LLDB_OPTIONS_platform_fwrite
648ead24645SDimitry Andric #include "CommandOptions.inc"
64914f1b3e8SDimitry Andric
65014f1b3e8SDimitry Andric class CommandObjectPlatformFWrite : public CommandObjectParsed {
651f21a844fSEd Maste public:
CommandObjectPlatformFWrite(CommandInterpreter & interpreter)65214f1b3e8SDimitry Andric CommandObjectPlatformFWrite(CommandInterpreter &interpreter)
65314f1b3e8SDimitry Andric : CommandObjectParsed(interpreter, "platform file write",
65414f1b3e8SDimitry Andric "Write data to a file on the remote end.", nullptr,
655145449b1SDimitry Andric 0) {
656ac9a064cSDimitry Andric AddSimpleArgumentList(eArgTypeUnsignedInteger);
657145449b1SDimitry Andric }
658f21a844fSEd Maste
659f3fbd1c0SDimitry Andric ~CommandObjectPlatformFWrite() override = default;
660f21a844fSEd Maste
DoExecute(Args & args,CommandReturnObject & result)661b1c73532SDimitry Andric void DoExecute(Args &args, CommandReturnObject &result) override {
66214f1b3e8SDimitry Andric PlatformSP platform_sp(
6635f29bb8aSDimitry Andric GetDebugger().GetPlatformList().GetSelectedPlatform());
66414f1b3e8SDimitry Andric if (platform_sp) {
665f21a844fSEd Maste std::string cmd_line;
666f21a844fSEd Maste args.GetCommandString(cmd_line);
667b76161e4SDimitry Andric Status error;
668cfca06d7SDimitry Andric lldb::user_id_t fd;
669cfca06d7SDimitry Andric if (!llvm::to_integer(cmd_line, fd)) {
670cfca06d7SDimitry Andric result.AppendErrorWithFormatv("'{0}' is not a valid file descriptor.",
671cfca06d7SDimitry Andric cmd_line);
672b1c73532SDimitry Andric return;
673cfca06d7SDimitry Andric }
674c0981da4SDimitry Andric uint64_t retcode =
67514f1b3e8SDimitry Andric platform_sp->WriteFile(fd, m_options.m_offset, &m_options.m_data[0],
67614f1b3e8SDimitry Andric m_options.m_data.size(), error);
677c0981da4SDimitry Andric if (retcode != UINT64_MAX) {
678c0981da4SDimitry Andric result.AppendMessageWithFormat("Return = %" PRIu64 "\n", retcode);
679f21a844fSEd Maste result.SetStatus(eReturnStatusSuccessFinishResult);
68014f1b3e8SDimitry Andric } else {
681c0981da4SDimitry Andric result.AppendError(error.AsCString());
682c0981da4SDimitry Andric }
683c0981da4SDimitry Andric } else {
684f21a844fSEd Maste result.AppendError("no platform currently selected\n");
685f21a844fSEd Maste }
686f21a844fSEd Maste }
687f3fbd1c0SDimitry Andric
GetOptions()68814f1b3e8SDimitry Andric Options *GetOptions() override { return &m_options; }
689f21a844fSEd Maste
690f21a844fSEd Maste protected:
69114f1b3e8SDimitry Andric class CommandOptions : public Options {
692f21a844fSEd Maste public:
693145449b1SDimitry Andric CommandOptions() = default;
694f21a844fSEd Maste
695f3fbd1c0SDimitry Andric ~CommandOptions() override = default;
696f21a844fSEd Maste
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)697b76161e4SDimitry Andric Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
69814f1b3e8SDimitry Andric ExecutionContext *execution_context) override {
699b76161e4SDimitry Andric Status error;
700f21a844fSEd Maste char short_option = (char)m_getopt_table[option_idx].val;
701f21a844fSEd Maste
70214f1b3e8SDimitry Andric switch (short_option) {
703f21a844fSEd Maste case 'o':
70414f1b3e8SDimitry Andric if (option_arg.getAsInteger(0, m_offset))
70514f1b3e8SDimitry Andric error.SetErrorStringWithFormat("invalid offset: '%s'",
70614f1b3e8SDimitry Andric option_arg.str().c_str());
707f21a844fSEd Maste break;
708f21a844fSEd Maste case 'd':
709cfca06d7SDimitry Andric m_data.assign(std::string(option_arg));
710f21a844fSEd Maste break;
711f21a844fSEd Maste default:
712ead24645SDimitry Andric llvm_unreachable("Unimplemented option");
713f21a844fSEd Maste }
714f21a844fSEd Maste
715f21a844fSEd Maste return error;
716f21a844fSEd Maste }
717f21a844fSEd Maste
OptionParsingStarting(ExecutionContext * execution_context)71814f1b3e8SDimitry Andric void OptionParsingStarting(ExecutionContext *execution_context) override {
719f21a844fSEd Maste m_offset = 0;
720f21a844fSEd Maste m_data.clear();
721f21a844fSEd Maste }
722f21a844fSEd Maste
GetDefinitions()72314f1b3e8SDimitry Andric llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
724e3b55780SDimitry Andric return llvm::ArrayRef(g_platform_fwrite_options);
725f21a844fSEd Maste }
726f21a844fSEd Maste
727f21a844fSEd Maste // Instance variables to hold the values for command options.
728f21a844fSEd Maste
729f21a844fSEd Maste uint32_t m_offset;
730f21a844fSEd Maste std::string m_data;
731f21a844fSEd Maste };
732f3fbd1c0SDimitry Andric
733f21a844fSEd Maste CommandOptions m_options;
734f21a844fSEd Maste };
735f3fbd1c0SDimitry Andric
73614f1b3e8SDimitry Andric class CommandObjectPlatformFile : public CommandObjectMultiword {
737f21a844fSEd Maste public:
738f21a844fSEd Maste // Constructors and Destructors
CommandObjectPlatformFile(CommandInterpreter & interpreter)739f3fbd1c0SDimitry Andric CommandObjectPlatformFile(CommandInterpreter &interpreter)
74014f1b3e8SDimitry Andric : CommandObjectMultiword(
74114f1b3e8SDimitry Andric interpreter, "platform file",
74214f1b3e8SDimitry Andric "Commands to access files on the current platform.",
74314f1b3e8SDimitry Andric "platform file [open|close|read|write] ...") {
74414f1b3e8SDimitry Andric LoadSubCommand(
74514f1b3e8SDimitry Andric "open", CommandObjectSP(new CommandObjectPlatformFOpen(interpreter)));
74614f1b3e8SDimitry Andric LoadSubCommand(
74714f1b3e8SDimitry Andric "close", CommandObjectSP(new CommandObjectPlatformFClose(interpreter)));
74814f1b3e8SDimitry Andric LoadSubCommand(
74914f1b3e8SDimitry Andric "read", CommandObjectSP(new CommandObjectPlatformFRead(interpreter)));
75014f1b3e8SDimitry Andric LoadSubCommand(
75114f1b3e8SDimitry Andric "write", CommandObjectSP(new CommandObjectPlatformFWrite(interpreter)));
752f21a844fSEd Maste }
753f21a844fSEd Maste
754f3fbd1c0SDimitry Andric ~CommandObjectPlatformFile() override = default;
755f21a844fSEd Maste
756f21a844fSEd Maste private:
757f21a844fSEd Maste // For CommandObjectPlatform only
758cfca06d7SDimitry Andric CommandObjectPlatformFile(const CommandObjectPlatformFile &) = delete;
759cfca06d7SDimitry Andric const CommandObjectPlatformFile &
760cfca06d7SDimitry Andric operator=(const CommandObjectPlatformFile &) = delete;
761f21a844fSEd Maste };
762f21a844fSEd Maste
763f21a844fSEd Maste // "platform get-file remote-file-path host-file-path"
76414f1b3e8SDimitry Andric class CommandObjectPlatformGetFile : public CommandObjectParsed {
765f21a844fSEd Maste public:
CommandObjectPlatformGetFile(CommandInterpreter & interpreter)76614f1b3e8SDimitry Andric CommandObjectPlatformGetFile(CommandInterpreter &interpreter)
76714f1b3e8SDimitry Andric : CommandObjectParsed(
76814f1b3e8SDimitry Andric interpreter, "platform get-file",
769f21a844fSEd Maste "Transfer a file from the remote end to the local host.",
77014f1b3e8SDimitry Andric "platform get-file <remote-file-spec> <local-file-spec>", 0) {
771f21a844fSEd Maste SetHelpLong(
772027f1c96SDimitry Andric R"(Examples:
773027f1c96SDimitry Andric
774027f1c96SDimitry Andric (lldb) platform get-file /the/remote/file/path /the/local/file/path
775027f1c96SDimitry Andric
77614f1b3e8SDimitry Andric Transfer a file from the remote end with file path /the/remote/file/path to the local host.)");
777f21a844fSEd Maste
778f21a844fSEd Maste CommandArgumentEntry arg1, arg2;
779f21a844fSEd Maste CommandArgumentData file_arg_remote, file_arg_host;
780f21a844fSEd Maste
781f21a844fSEd Maste // Define the first (and only) variant of this arg.
782ac9a064cSDimitry Andric file_arg_remote.arg_type = eArgTypeRemoteFilename;
783f21a844fSEd Maste file_arg_remote.arg_repetition = eArgRepeatPlain;
78414f1b3e8SDimitry Andric // There is only one variant this argument could be; put it into the
78514f1b3e8SDimitry Andric // argument entry.
786f21a844fSEd Maste arg1.push_back(file_arg_remote);
787f21a844fSEd Maste
788f21a844fSEd Maste // Define the second (and only) variant of this arg.
789f21a844fSEd Maste file_arg_host.arg_type = eArgTypeFilename;
790f21a844fSEd Maste file_arg_host.arg_repetition = eArgRepeatPlain;
79114f1b3e8SDimitry Andric // There is only one variant this argument could be; put it into the
79214f1b3e8SDimitry Andric // argument entry.
793f21a844fSEd Maste arg2.push_back(file_arg_host);
794f21a844fSEd Maste
795f73363f1SDimitry Andric // Push the data for the first and the second arguments into the
796f73363f1SDimitry Andric // m_arguments vector.
797f21a844fSEd Maste m_arguments.push_back(arg1);
798f21a844fSEd Maste m_arguments.push_back(arg2);
799f21a844fSEd Maste }
800f21a844fSEd Maste
801f3fbd1c0SDimitry Andric ~CommandObjectPlatformGetFile() override = default;
802f21a844fSEd Maste
803b60736ecSDimitry Andric void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)804b60736ecSDimitry Andric HandleArgumentCompletion(CompletionRequest &request,
805b60736ecSDimitry Andric OptionElementVector &opt_element_vector) override {
806b60736ecSDimitry Andric if (request.GetCursorIndex() == 0)
8077fa27ce4SDimitry Andric lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
8087fa27ce4SDimitry Andric GetCommandInterpreter(), lldb::eRemoteDiskFileCompletion, request,
8097fa27ce4SDimitry Andric nullptr);
810b60736ecSDimitry Andric else if (request.GetCursorIndex() == 1)
8117fa27ce4SDimitry Andric lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
8127fa27ce4SDimitry Andric GetCommandInterpreter(), lldb::eDiskFileCompletion, request, nullptr);
813b60736ecSDimitry Andric }
814b60736ecSDimitry Andric
DoExecute(Args & args,CommandReturnObject & result)815b1c73532SDimitry Andric void DoExecute(Args &args, CommandReturnObject &result) override {
816f21a844fSEd Maste // If the number of arguments is incorrect, issue an error message.
81714f1b3e8SDimitry Andric if (args.GetArgumentCount() != 2) {
818344a3780SDimitry Andric result.AppendError("required arguments missing; specify both the "
819344a3780SDimitry Andric "source and destination file paths");
820b1c73532SDimitry Andric return;
821f21a844fSEd Maste }
822f21a844fSEd Maste
82314f1b3e8SDimitry Andric PlatformSP platform_sp(
8245f29bb8aSDimitry Andric GetDebugger().GetPlatformList().GetSelectedPlatform());
82514f1b3e8SDimitry Andric if (platform_sp) {
826f21a844fSEd Maste const char *remote_file_path = args.GetArgumentAtIndex(0);
827f21a844fSEd Maste const char *local_file_path = args.GetArgumentAtIndex(1);
82894994d37SDimitry Andric Status error = platform_sp->GetFile(FileSpec(remote_file_path),
82994994d37SDimitry Andric FileSpec(local_file_path));
83014f1b3e8SDimitry Andric if (error.Success()) {
83114f1b3e8SDimitry Andric result.AppendMessageWithFormat(
83214f1b3e8SDimitry Andric "successfully get-file from %s (remote) to %s (host)\n",
833f21a844fSEd Maste remote_file_path, local_file_path);
834f21a844fSEd Maste result.SetStatus(eReturnStatusSuccessFinishResult);
83514f1b3e8SDimitry Andric } else {
83614f1b3e8SDimitry Andric result.AppendMessageWithFormat("get-file failed: %s\n",
83714f1b3e8SDimitry Andric error.AsCString());
838f21a844fSEd Maste }
83914f1b3e8SDimitry Andric } else {
840f21a844fSEd Maste result.AppendError("no platform currently selected\n");
841f21a844fSEd Maste }
842f21a844fSEd Maste }
843f21a844fSEd Maste };
844f21a844fSEd Maste
845f21a844fSEd Maste // "platform get-size remote-file-path"
84614f1b3e8SDimitry Andric class CommandObjectPlatformGetSize : public CommandObjectParsed {
847f21a844fSEd Maste public:
CommandObjectPlatformGetSize(CommandInterpreter & interpreter)84814f1b3e8SDimitry Andric CommandObjectPlatformGetSize(CommandInterpreter &interpreter)
84914f1b3e8SDimitry Andric : CommandObjectParsed(interpreter, "platform get-size",
850f21a844fSEd Maste "Get the file size from the remote end.",
85114f1b3e8SDimitry Andric "platform get-size <remote-file-spec>", 0) {
852f21a844fSEd Maste SetHelpLong(
853027f1c96SDimitry Andric R"(Examples:
854027f1c96SDimitry Andric
855027f1c96SDimitry Andric (lldb) platform get-size /the/remote/file/path
856027f1c96SDimitry Andric
85714f1b3e8SDimitry Andric Get the file size from the remote end with path /the/remote/file/path.)");
858f21a844fSEd Maste
859ac9a064cSDimitry Andric AddSimpleArgumentList(eArgTypeRemoteFilename);
860f21a844fSEd Maste }
861f21a844fSEd Maste
862f3fbd1c0SDimitry Andric ~CommandObjectPlatformGetSize() override = default;
863f21a844fSEd Maste
DoExecute(Args & args,CommandReturnObject & result)864b1c73532SDimitry Andric void DoExecute(Args &args, CommandReturnObject &result) override {
865f21a844fSEd Maste // If the number of arguments is incorrect, issue an error message.
86614f1b3e8SDimitry Andric if (args.GetArgumentCount() != 1) {
867344a3780SDimitry Andric result.AppendError("required argument missing; specify the source file "
868344a3780SDimitry Andric "path as the only argument");
869b1c73532SDimitry Andric return;
870f21a844fSEd Maste }
871f21a844fSEd Maste
87214f1b3e8SDimitry Andric PlatformSP platform_sp(
8735f29bb8aSDimitry Andric GetDebugger().GetPlatformList().GetSelectedPlatform());
87414f1b3e8SDimitry Andric if (platform_sp) {
875f21a844fSEd Maste std::string remote_file_path(args.GetArgumentAtIndex(0));
87694994d37SDimitry Andric user_id_t size = platform_sp->GetFileSize(FileSpec(remote_file_path));
87714f1b3e8SDimitry Andric if (size != UINT64_MAX) {
87814f1b3e8SDimitry Andric result.AppendMessageWithFormat("File size of %s (remote): %" PRIu64
87914f1b3e8SDimitry Andric "\n",
88014f1b3e8SDimitry Andric remote_file_path.c_str(), size);
881f21a844fSEd Maste result.SetStatus(eReturnStatusSuccessFinishResult);
88214f1b3e8SDimitry Andric } else {
88314f1b3e8SDimitry Andric result.AppendMessageWithFormat(
88414f1b3e8SDimitry Andric "Error getting file size of %s (remote)\n",
88514f1b3e8SDimitry Andric remote_file_path.c_str());
886f21a844fSEd Maste }
88714f1b3e8SDimitry Andric } else {
888f21a844fSEd Maste result.AppendError("no platform currently selected\n");
889f21a844fSEd Maste }
890f21a844fSEd Maste }
891f21a844fSEd Maste };
892f21a844fSEd Maste
893c0981da4SDimitry Andric // "platform get-permissions remote-file-path"
894c0981da4SDimitry Andric class CommandObjectPlatformGetPermissions : public CommandObjectParsed {
895c0981da4SDimitry Andric public:
CommandObjectPlatformGetPermissions(CommandInterpreter & interpreter)896c0981da4SDimitry Andric CommandObjectPlatformGetPermissions(CommandInterpreter &interpreter)
897c0981da4SDimitry Andric : CommandObjectParsed(interpreter, "platform get-permissions",
898c0981da4SDimitry Andric "Get the file permission bits from the remote end.",
899c0981da4SDimitry Andric "platform get-permissions <remote-file-spec>", 0) {
900c0981da4SDimitry Andric SetHelpLong(
901c0981da4SDimitry Andric R"(Examples:
902c0981da4SDimitry Andric
903c0981da4SDimitry Andric (lldb) platform get-permissions /the/remote/file/path
904c0981da4SDimitry Andric
905c0981da4SDimitry Andric Get the file permissions from the remote end with path /the/remote/file/path.)");
906c0981da4SDimitry Andric
907ac9a064cSDimitry Andric AddSimpleArgumentList(eArgTypeRemoteFilename);
908c0981da4SDimitry Andric }
909c0981da4SDimitry Andric
910c0981da4SDimitry Andric ~CommandObjectPlatformGetPermissions() override = default;
911c0981da4SDimitry Andric
DoExecute(Args & args,CommandReturnObject & result)912b1c73532SDimitry Andric void DoExecute(Args &args, CommandReturnObject &result) override {
913c0981da4SDimitry Andric // If the number of arguments is incorrect, issue an error message.
914c0981da4SDimitry Andric if (args.GetArgumentCount() != 1) {
915c0981da4SDimitry Andric result.AppendError("required argument missing; specify the source file "
916c0981da4SDimitry Andric "path as the only argument");
917b1c73532SDimitry Andric return;
918c0981da4SDimitry Andric }
919c0981da4SDimitry Andric
920c0981da4SDimitry Andric PlatformSP platform_sp(
921c0981da4SDimitry Andric GetDebugger().GetPlatformList().GetSelectedPlatform());
922c0981da4SDimitry Andric if (platform_sp) {
923c0981da4SDimitry Andric std::string remote_file_path(args.GetArgumentAtIndex(0));
924c0981da4SDimitry Andric uint32_t permissions;
925c0981da4SDimitry Andric Status error = platform_sp->GetFilePermissions(FileSpec(remote_file_path),
926c0981da4SDimitry Andric permissions);
927c0981da4SDimitry Andric if (error.Success()) {
928c0981da4SDimitry Andric result.AppendMessageWithFormat(
929c0981da4SDimitry Andric "File permissions of %s (remote): 0o%04" PRIo32 "\n",
930c0981da4SDimitry Andric remote_file_path.c_str(), permissions);
931c0981da4SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishResult);
932c0981da4SDimitry Andric } else
933c0981da4SDimitry Andric result.AppendError(error.AsCString());
934c0981da4SDimitry Andric } else {
935c0981da4SDimitry Andric result.AppendError("no platform currently selected\n");
936c0981da4SDimitry Andric }
937c0981da4SDimitry Andric }
938c0981da4SDimitry Andric };
939c0981da4SDimitry Andric
940c0981da4SDimitry Andric // "platform file-exists remote-file-path"
941c0981da4SDimitry Andric class CommandObjectPlatformFileExists : public CommandObjectParsed {
942c0981da4SDimitry Andric public:
CommandObjectPlatformFileExists(CommandInterpreter & interpreter)943c0981da4SDimitry Andric CommandObjectPlatformFileExists(CommandInterpreter &interpreter)
944c0981da4SDimitry Andric : CommandObjectParsed(interpreter, "platform file-exists",
945c0981da4SDimitry Andric "Check if the file exists on the remote end.",
946c0981da4SDimitry Andric "platform file-exists <remote-file-spec>", 0) {
947c0981da4SDimitry Andric SetHelpLong(
948c0981da4SDimitry Andric R"(Examples:
949c0981da4SDimitry Andric
950c0981da4SDimitry Andric (lldb) platform file-exists /the/remote/file/path
951c0981da4SDimitry Andric
952c0981da4SDimitry Andric Check if /the/remote/file/path exists on the remote end.)");
953c0981da4SDimitry Andric
954ac9a064cSDimitry Andric AddSimpleArgumentList(eArgTypeRemoteFilename);
955c0981da4SDimitry Andric }
956c0981da4SDimitry Andric
957c0981da4SDimitry Andric ~CommandObjectPlatformFileExists() override = default;
958c0981da4SDimitry Andric
DoExecute(Args & args,CommandReturnObject & result)959b1c73532SDimitry Andric void DoExecute(Args &args, CommandReturnObject &result) override {
960c0981da4SDimitry Andric // If the number of arguments is incorrect, issue an error message.
961c0981da4SDimitry Andric if (args.GetArgumentCount() != 1) {
962c0981da4SDimitry Andric result.AppendError("required argument missing; specify the source file "
963c0981da4SDimitry Andric "path as the only argument");
964b1c73532SDimitry Andric return;
965c0981da4SDimitry Andric }
966c0981da4SDimitry Andric
967c0981da4SDimitry Andric PlatformSP platform_sp(
968c0981da4SDimitry Andric GetDebugger().GetPlatformList().GetSelectedPlatform());
969c0981da4SDimitry Andric if (platform_sp) {
970c0981da4SDimitry Andric std::string remote_file_path(args.GetArgumentAtIndex(0));
971c0981da4SDimitry Andric bool exists = platform_sp->GetFileExists(FileSpec(remote_file_path));
972c0981da4SDimitry Andric result.AppendMessageWithFormat(
973c0981da4SDimitry Andric "File %s (remote) %s\n",
974c0981da4SDimitry Andric remote_file_path.c_str(), exists ? "exists" : "does not exist");
975c0981da4SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishResult);
976c0981da4SDimitry Andric } else {
977c0981da4SDimitry Andric result.AppendError("no platform currently selected\n");
978c0981da4SDimitry Andric }
979c0981da4SDimitry Andric }
980c0981da4SDimitry Andric };
981c0981da4SDimitry Andric
982f21a844fSEd Maste // "platform put-file"
98314f1b3e8SDimitry Andric class CommandObjectPlatformPutFile : public CommandObjectParsed {
984f21a844fSEd Maste public:
CommandObjectPlatformPutFile(CommandInterpreter & interpreter)98514f1b3e8SDimitry Andric CommandObjectPlatformPutFile(CommandInterpreter &interpreter)
98614f1b3e8SDimitry Andric : CommandObjectParsed(
98714f1b3e8SDimitry Andric interpreter, "platform put-file",
988c0981da4SDimitry Andric "Transfer a file from this system to the remote end.",
989c0981da4SDimitry Andric "platform put-file <source> [<destination>]", 0) {
990c0981da4SDimitry Andric SetHelpLong(
991c0981da4SDimitry Andric R"(Examples:
992c0981da4SDimitry Andric
993c0981da4SDimitry Andric (lldb) platform put-file /source/foo.txt /destination/bar.txt
994c0981da4SDimitry Andric
995c0981da4SDimitry Andric (lldb) platform put-file /source/foo.txt
996c0981da4SDimitry Andric
997c0981da4SDimitry Andric Relative source file paths are resolved against lldb's local working directory.
998c0981da4SDimitry Andric
999c0981da4SDimitry Andric Omitting the destination places the file in the platform working directory.)");
1000145449b1SDimitry Andric CommandArgumentData source_arg{eArgTypePath, eArgRepeatPlain};
1001ac9a064cSDimitry Andric CommandArgumentData path_arg{eArgTypeRemotePath, eArgRepeatOptional};
1002145449b1SDimitry Andric m_arguments.push_back({source_arg});
1003145449b1SDimitry Andric m_arguments.push_back({path_arg});
1004f21a844fSEd Maste }
1005f21a844fSEd Maste
1006f3fbd1c0SDimitry Andric ~CommandObjectPlatformPutFile() override = default;
1007f21a844fSEd Maste
1008b60736ecSDimitry Andric void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)1009b60736ecSDimitry Andric HandleArgumentCompletion(CompletionRequest &request,
1010b60736ecSDimitry Andric OptionElementVector &opt_element_vector) override {
1011b60736ecSDimitry Andric if (request.GetCursorIndex() == 0)
10127fa27ce4SDimitry Andric lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
10137fa27ce4SDimitry Andric GetCommandInterpreter(), lldb::eDiskFileCompletion, request, nullptr);
1014b60736ecSDimitry Andric else if (request.GetCursorIndex() == 1)
10157fa27ce4SDimitry Andric lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
10167fa27ce4SDimitry Andric GetCommandInterpreter(), lldb::eRemoteDiskFileCompletion, request,
10177fa27ce4SDimitry Andric nullptr);
1018b60736ecSDimitry Andric }
1019b60736ecSDimitry Andric
DoExecute(Args & args,CommandReturnObject & result)1020b1c73532SDimitry Andric void DoExecute(Args &args, CommandReturnObject &result) override {
1021f21a844fSEd Maste const char *src = args.GetArgumentAtIndex(0);
1022f21a844fSEd Maste const char *dst = args.GetArgumentAtIndex(1);
1023f21a844fSEd Maste
102494994d37SDimitry Andric FileSpec src_fs(src);
102594994d37SDimitry Andric FileSystem::Instance().Resolve(src_fs);
102694994d37SDimitry Andric FileSpec dst_fs(dst ? dst : src_fs.GetFilename().GetCString());
1027f21a844fSEd Maste
102814f1b3e8SDimitry Andric PlatformSP platform_sp(
10295f29bb8aSDimitry Andric GetDebugger().GetPlatformList().GetSelectedPlatform());
103014f1b3e8SDimitry Andric if (platform_sp) {
1031b76161e4SDimitry Andric Status error(platform_sp->PutFile(src_fs, dst_fs));
103214f1b3e8SDimitry Andric if (error.Success()) {
1033f21a844fSEd Maste result.SetStatus(eReturnStatusSuccessFinishNoResult);
103414f1b3e8SDimitry Andric } else {
1035f21a844fSEd Maste result.AppendError(error.AsCString());
1036f21a844fSEd Maste }
103714f1b3e8SDimitry Andric } else {
1038f21a844fSEd Maste result.AppendError("no platform currently selected\n");
1039f21a844fSEd Maste }
1040f21a844fSEd Maste }
1041f21a844fSEd Maste };
1042f21a844fSEd Maste
1043f034231aSEd Maste // "platform process launch"
104414f1b3e8SDimitry Andric class CommandObjectPlatformProcessLaunch : public CommandObjectParsed {
1045f034231aSEd Maste public:
CommandObjectPlatformProcessLaunch(CommandInterpreter & interpreter)104614f1b3e8SDimitry Andric CommandObjectPlatformProcessLaunch(CommandInterpreter &interpreter)
104714f1b3e8SDimitry Andric : CommandObjectParsed(interpreter, "platform process launch",
1048f034231aSEd Maste "Launch a new process on a remote platform.",
1049f034231aSEd Maste "platform process launch program",
10507fa27ce4SDimitry Andric eCommandRequiresTarget | eCommandTryTargetAPILock),
10517fa27ce4SDimitry Andric m_class_options("scripted process", true, 'C', 'k', 'v', 0) {
1052344a3780SDimitry Andric m_all_options.Append(&m_options);
10537fa27ce4SDimitry Andric m_all_options.Append(&m_class_options, LLDB_OPT_SET_1 | LLDB_OPT_SET_2,
10547fa27ce4SDimitry Andric LLDB_OPT_SET_ALL);
1055344a3780SDimitry Andric m_all_options.Finalize();
1056ac9a064cSDimitry Andric AddSimpleArgumentList(eArgTypeRunArgs, eArgRepeatStar);
1057ac9a064cSDimitry Andric }
1058ac9a064cSDimitry Andric
1059ac9a064cSDimitry Andric void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)1060ac9a064cSDimitry Andric HandleArgumentCompletion(CompletionRequest &request,
1061ac9a064cSDimitry Andric OptionElementVector &opt_element_vector) override {
1062ac9a064cSDimitry Andric // I didn't make a type for RemoteRunArgs, but since we're going to run
1063ac9a064cSDimitry Andric // this on the remote system we should use the remote completer.
1064ac9a064cSDimitry Andric lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
1065ac9a064cSDimitry Andric GetCommandInterpreter(), lldb::eRemoteDiskFileCompletion, request,
1066ac9a064cSDimitry Andric nullptr);
1067344a3780SDimitry Andric }
1068f034231aSEd Maste
1069f3fbd1c0SDimitry Andric ~CommandObjectPlatformProcessLaunch() override = default;
1070f034231aSEd Maste
GetOptions()1071344a3780SDimitry Andric Options *GetOptions() override { return &m_all_options; }
1072f034231aSEd Maste
1073f034231aSEd Maste protected:
DoExecute(Args & args,CommandReturnObject & result)1074b1c73532SDimitry Andric void DoExecute(Args &args, CommandReturnObject &result) override {
10755f29bb8aSDimitry Andric Target *target = GetDebugger().GetSelectedTarget().get();
1076f034231aSEd Maste PlatformSP platform_sp;
107714f1b3e8SDimitry Andric if (target) {
1078f034231aSEd Maste platform_sp = target->GetPlatform();
1079f034231aSEd Maste }
108014f1b3e8SDimitry Andric if (!platform_sp) {
10815f29bb8aSDimitry Andric platform_sp = GetDebugger().GetPlatformList().GetSelectedPlatform();
1082f034231aSEd Maste }
1083f034231aSEd Maste
108414f1b3e8SDimitry Andric if (platform_sp) {
1085b76161e4SDimitry Andric Status error;
1086f034231aSEd Maste const size_t argc = args.GetArgumentCount();
1087f034231aSEd Maste Target *target = m_exe_ctx.GetTargetPtr();
1088f034231aSEd Maste Module *exe_module = target->GetExecutableModulePointer();
108914f1b3e8SDimitry Andric if (exe_module) {
1090f034231aSEd Maste m_options.launch_info.GetExecutableFile() = exe_module->GetFileSpec();
109194994d37SDimitry Andric llvm::SmallString<128> exe_path;
109214f1b3e8SDimitry Andric m_options.launch_info.GetExecutableFile().GetPath(exe_path);
109314f1b3e8SDimitry Andric if (!exe_path.empty())
1094f034231aSEd Maste m_options.launch_info.GetArguments().AppendArgument(exe_path);
1095f034231aSEd Maste m_options.launch_info.GetArchitecture() = exe_module->GetArchitecture();
1096f034231aSEd Maste }
1097f034231aSEd Maste
10987fa27ce4SDimitry Andric if (!m_class_options.GetName().empty()) {
10997fa27ce4SDimitry Andric m_options.launch_info.SetProcessPluginName("ScriptedProcess");
11007fa27ce4SDimitry Andric ScriptedMetadataSP metadata_sp = std::make_shared<ScriptedMetadata>(
11017fa27ce4SDimitry Andric m_class_options.GetName(), m_class_options.GetStructuredData());
11027fa27ce4SDimitry Andric m_options.launch_info.SetScriptedMetadata(metadata_sp);
11037fa27ce4SDimitry Andric target->SetProcessLaunchInfo(m_options.launch_info);
11047fa27ce4SDimitry Andric }
11057fa27ce4SDimitry Andric
110614f1b3e8SDimitry Andric if (argc > 0) {
110714f1b3e8SDimitry Andric if (m_options.launch_info.GetExecutableFile()) {
1108f73363f1SDimitry Andric // We already have an executable file, so we will use this and all
1109f73363f1SDimitry Andric // arguments to this function are extra arguments
1110f034231aSEd Maste m_options.launch_info.GetArguments().AppendArguments(args);
111114f1b3e8SDimitry Andric } else {
1112f034231aSEd Maste // We don't have any file yet, so the first argument is our
1113f034231aSEd Maste // executable, and the rest are program arguments
1114f034231aSEd Maste const bool first_arg_is_executable = true;
1115f034231aSEd Maste m_options.launch_info.SetArguments(args, first_arg_is_executable);
1116f034231aSEd Maste }
1117f034231aSEd Maste }
1118f034231aSEd Maste
111914f1b3e8SDimitry Andric if (m_options.launch_info.GetExecutableFile()) {
11205f29bb8aSDimitry Andric Debugger &debugger = GetDebugger();
1121f034231aSEd Maste
11227fa27ce4SDimitry Andric if (argc == 0) {
11237fa27ce4SDimitry Andric // If no arguments were given to the command, use target.run-args.
11247fa27ce4SDimitry Andric Args target_run_args;
11257fa27ce4SDimitry Andric target->GetRunArguments(target_run_args);
11267fa27ce4SDimitry Andric m_options.launch_info.GetArguments().AppendArguments(target_run_args);
11277fa27ce4SDimitry Andric }
1128f034231aSEd Maste
112914f1b3e8SDimitry Andric ProcessSP process_sp(platform_sp->DebugProcess(
1130c0981da4SDimitry Andric m_options.launch_info, debugger, *target, error));
11317fa27ce4SDimitry Andric
11327fa27ce4SDimitry Andric if (!process_sp && error.Success()) {
11337fa27ce4SDimitry Andric result.AppendError("failed to launch or debug process");
1134b1c73532SDimitry Andric return;
11357fa27ce4SDimitry Andric } else if (!error.Success()) {
11367fa27ce4SDimitry Andric result.AppendError(error.AsCString());
1137b1c73532SDimitry Andric return;
11387fa27ce4SDimitry Andric }
11397fa27ce4SDimitry Andric
11407fa27ce4SDimitry Andric const bool synchronous_execution =
11417fa27ce4SDimitry Andric debugger.GetCommandInterpreter().GetSynchronous();
11427fa27ce4SDimitry Andric auto launch_info = m_options.launch_info;
11437fa27ce4SDimitry Andric bool rebroadcast_first_stop =
11447fa27ce4SDimitry Andric !synchronous_execution &&
11457fa27ce4SDimitry Andric launch_info.GetFlags().Test(eLaunchFlagStopAtEntry);
11467fa27ce4SDimitry Andric
11477fa27ce4SDimitry Andric EventSP first_stop_event_sp;
11487fa27ce4SDimitry Andric StateType state = process_sp->WaitForProcessToStop(
11497fa27ce4SDimitry Andric std::nullopt, &first_stop_event_sp, rebroadcast_first_stop,
11507fa27ce4SDimitry Andric launch_info.GetHijackListener());
11517fa27ce4SDimitry Andric process_sp->RestoreProcessEvents();
11527fa27ce4SDimitry Andric
11537fa27ce4SDimitry Andric if (rebroadcast_first_stop) {
11547fa27ce4SDimitry Andric assert(first_stop_event_sp);
11557fa27ce4SDimitry Andric process_sp->BroadcastEvent(first_stop_event_sp);
1156b1c73532SDimitry Andric return;
11577fa27ce4SDimitry Andric }
11587fa27ce4SDimitry Andric
11597fa27ce4SDimitry Andric switch (state) {
11607fa27ce4SDimitry Andric case eStateStopped: {
11617fa27ce4SDimitry Andric if (launch_info.GetFlags().Test(eLaunchFlagStopAtEntry))
11627fa27ce4SDimitry Andric break;
11637fa27ce4SDimitry Andric if (synchronous_execution) {
11647fa27ce4SDimitry Andric // Now we have handled the stop-from-attach, and we are just
11657fa27ce4SDimitry Andric // switching to a synchronous resume. So we should switch to the
11667fa27ce4SDimitry Andric // SyncResume hijacker.
11677fa27ce4SDimitry Andric process_sp->ResumeSynchronous(&result.GetOutputStream());
11687fa27ce4SDimitry Andric } else {
11697fa27ce4SDimitry Andric error = process_sp->Resume();
11707fa27ce4SDimitry Andric if (!error.Success()) {
11717fa27ce4SDimitry Andric result.AppendErrorWithFormat(
11727fa27ce4SDimitry Andric "process resume at entry point failed: %s",
11737fa27ce4SDimitry Andric error.AsCString());
11747fa27ce4SDimitry Andric }
11757fa27ce4SDimitry Andric }
11767fa27ce4SDimitry Andric } break;
11777fa27ce4SDimitry Andric default:
11787fa27ce4SDimitry Andric result.AppendErrorWithFormat(
11797fa27ce4SDimitry Andric "initial process state wasn't stopped: %s",
11807fa27ce4SDimitry Andric StateAsCString(state));
11817fa27ce4SDimitry Andric break;
11827fa27ce4SDimitry Andric }
11837fa27ce4SDimitry Andric
118414f1b3e8SDimitry Andric if (process_sp && process_sp->IsAlive()) {
1185f034231aSEd Maste result.SetStatus(eReturnStatusSuccessFinishNoResult);
1186b1c73532SDimitry Andric return;
1187f034231aSEd Maste }
118814f1b3e8SDimitry Andric } else {
118914f1b3e8SDimitry Andric result.AppendError("'platform process launch' uses the current target "
119014f1b3e8SDimitry Andric "file and arguments, or the executable and its "
119114f1b3e8SDimitry Andric "arguments can be specified in this command");
1192b1c73532SDimitry Andric return;
1193f034231aSEd Maste }
119414f1b3e8SDimitry Andric } else {
1195f034231aSEd Maste result.AppendError("no platform is selected\n");
1196f034231aSEd Maste }
1197f034231aSEd Maste }
1198f034231aSEd Maste
1199b60736ecSDimitry Andric CommandOptionsProcessLaunch m_options;
12007fa27ce4SDimitry Andric OptionGroupPythonClassWithDict m_class_options;
1201344a3780SDimitry Andric OptionGroupOptions m_all_options;
1202f034231aSEd Maste };
1203f034231aSEd Maste
1204f034231aSEd Maste // "platform process list"
1205f034231aSEd Maste
1206ead24645SDimitry Andric static PosixPlatformCommandOptionValidator posix_validator;
1207ead24645SDimitry Andric #define LLDB_OPTIONS_platform_process_list
1208ead24645SDimitry Andric #include "CommandOptions.inc"
120914f1b3e8SDimitry Andric
121014f1b3e8SDimitry Andric class CommandObjectPlatformProcessList : public CommandObjectParsed {
121114f1b3e8SDimitry Andric public:
CommandObjectPlatformProcessList(CommandInterpreter & interpreter)121214f1b3e8SDimitry Andric CommandObjectPlatformProcessList(CommandInterpreter &interpreter)
121314f1b3e8SDimitry Andric : CommandObjectParsed(interpreter, "platform process list",
121414f1b3e8SDimitry Andric "List processes on a remote platform by name, pid, "
121514f1b3e8SDimitry Andric "or many other matching attributes.",
12166f8fc217SDimitry Andric "platform process list", 0) {}
121714f1b3e8SDimitry Andric
121814f1b3e8SDimitry Andric ~CommandObjectPlatformProcessList() override = default;
121914f1b3e8SDimitry Andric
GetOptions()122014f1b3e8SDimitry Andric Options *GetOptions() override { return &m_options; }
122114f1b3e8SDimitry Andric
122214f1b3e8SDimitry Andric protected:
DoExecute(Args & args,CommandReturnObject & result)1223b1c73532SDimitry Andric void DoExecute(Args &args, CommandReturnObject &result) override {
12245f29bb8aSDimitry Andric Target *target = GetDebugger().GetSelectedTarget().get();
122514f1b3e8SDimitry Andric PlatformSP platform_sp;
122614f1b3e8SDimitry Andric if (target) {
122714f1b3e8SDimitry Andric platform_sp = target->GetPlatform();
122814f1b3e8SDimitry Andric }
122914f1b3e8SDimitry Andric if (!platform_sp) {
12305f29bb8aSDimitry Andric platform_sp = GetDebugger().GetPlatformList().GetSelectedPlatform();
123114f1b3e8SDimitry Andric }
123214f1b3e8SDimitry Andric
123314f1b3e8SDimitry Andric if (platform_sp) {
1234b76161e4SDimitry Andric Status error;
123514f1b3e8SDimitry Andric if (platform_sp) {
123614f1b3e8SDimitry Andric Stream &ostrm = result.GetOutputStream();
123714f1b3e8SDimitry Andric
1238145449b1SDimitry Andric lldb::pid_t pid = m_options.match_info.GetProcessInfo().GetProcessID();
123914f1b3e8SDimitry Andric if (pid != LLDB_INVALID_PROCESS_ID) {
124014f1b3e8SDimitry Andric ProcessInstanceInfo proc_info;
124114f1b3e8SDimitry Andric if (platform_sp->GetProcessInfo(pid, proc_info)) {
12425f29bb8aSDimitry Andric ProcessInstanceInfo::DumpTableHeader(ostrm, m_options.show_args,
124314f1b3e8SDimitry Andric m_options.verbose);
12445f29bb8aSDimitry Andric proc_info.DumpAsTableRow(ostrm, platform_sp->GetUserIDResolver(),
124514f1b3e8SDimitry Andric m_options.show_args, m_options.verbose);
124614f1b3e8SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishResult);
124714f1b3e8SDimitry Andric } else {
124814f1b3e8SDimitry Andric result.AppendErrorWithFormat(
124914f1b3e8SDimitry Andric "no process found with pid = %" PRIu64 "\n", pid);
125014f1b3e8SDimitry Andric }
125114f1b3e8SDimitry Andric } else {
125214f1b3e8SDimitry Andric ProcessInstanceInfoList proc_infos;
125314f1b3e8SDimitry Andric const uint32_t matches =
125414f1b3e8SDimitry Andric platform_sp->FindProcesses(m_options.match_info, proc_infos);
125514f1b3e8SDimitry Andric const char *match_desc = nullptr;
125614f1b3e8SDimitry Andric const char *match_name =
125714f1b3e8SDimitry Andric m_options.match_info.GetProcessInfo().GetName();
125814f1b3e8SDimitry Andric if (match_name && match_name[0]) {
125914f1b3e8SDimitry Andric switch (m_options.match_info.GetNameMatchType()) {
126074a628f7SDimitry Andric case NameMatch::Ignore:
126114f1b3e8SDimitry Andric break;
126274a628f7SDimitry Andric case NameMatch::Equals:
126314f1b3e8SDimitry Andric match_desc = "matched";
126414f1b3e8SDimitry Andric break;
126574a628f7SDimitry Andric case NameMatch::Contains:
126614f1b3e8SDimitry Andric match_desc = "contained";
126714f1b3e8SDimitry Andric break;
126874a628f7SDimitry Andric case NameMatch::StartsWith:
126914f1b3e8SDimitry Andric match_desc = "started with";
127014f1b3e8SDimitry Andric break;
127174a628f7SDimitry Andric case NameMatch::EndsWith:
127214f1b3e8SDimitry Andric match_desc = "ended with";
127314f1b3e8SDimitry Andric break;
127474a628f7SDimitry Andric case NameMatch::RegularExpression:
127514f1b3e8SDimitry Andric match_desc = "matched the regular expression";
127614f1b3e8SDimitry Andric break;
127714f1b3e8SDimitry Andric }
127814f1b3e8SDimitry Andric }
127914f1b3e8SDimitry Andric
128014f1b3e8SDimitry Andric if (matches == 0) {
128114f1b3e8SDimitry Andric if (match_desc)
1282c0981da4SDimitry Andric result.AppendErrorWithFormatv(
1283c0981da4SDimitry Andric "no processes were found that {0} \"{1}\" on the \"{2}\" "
128414f1b3e8SDimitry Andric "platform\n",
1285145449b1SDimitry Andric match_desc, match_name, platform_sp->GetName());
128614f1b3e8SDimitry Andric else
1287c0981da4SDimitry Andric result.AppendErrorWithFormatv(
1288c0981da4SDimitry Andric "no processes were found on the \"{0}\" platform\n",
1289145449b1SDimitry Andric platform_sp->GetName());
129014f1b3e8SDimitry Andric } else {
1291145449b1SDimitry Andric result.AppendMessageWithFormatv(
1292145449b1SDimitry Andric "{0} matching process{1} found on \"{2}\"", matches,
1293145449b1SDimitry Andric matches > 1 ? "es were" : " was", platform_sp->GetName());
129414f1b3e8SDimitry Andric if (match_desc)
129514f1b3e8SDimitry Andric result.AppendMessageWithFormat(" whose name %s \"%s\"",
129614f1b3e8SDimitry Andric match_desc, match_name);
129714f1b3e8SDimitry Andric result.AppendMessageWithFormat("\n");
12985f29bb8aSDimitry Andric ProcessInstanceInfo::DumpTableHeader(ostrm, m_options.show_args,
129914f1b3e8SDimitry Andric m_options.verbose);
130014f1b3e8SDimitry Andric for (uint32_t i = 0; i < matches; ++i) {
1301cfca06d7SDimitry Andric proc_infos[i].DumpAsTableRow(
1302145449b1SDimitry Andric ostrm, platform_sp->GetUserIDResolver(), m_options.show_args,
1303145449b1SDimitry Andric m_options.verbose);
130414f1b3e8SDimitry Andric }
130514f1b3e8SDimitry Andric }
130614f1b3e8SDimitry Andric }
130714f1b3e8SDimitry Andric }
130814f1b3e8SDimitry Andric } else {
130914f1b3e8SDimitry Andric result.AppendError("no platform is selected\n");
131014f1b3e8SDimitry Andric }
131114f1b3e8SDimitry Andric }
131214f1b3e8SDimitry Andric
131314f1b3e8SDimitry Andric class CommandOptions : public Options {
131414f1b3e8SDimitry Andric public:
1315145449b1SDimitry Andric CommandOptions() = default;
131614f1b3e8SDimitry Andric
131714f1b3e8SDimitry Andric ~CommandOptions() override = default;
131814f1b3e8SDimitry Andric
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)1319b76161e4SDimitry Andric Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
132014f1b3e8SDimitry Andric ExecutionContext *execution_context) override {
1321b76161e4SDimitry Andric Status error;
132214f1b3e8SDimitry Andric const int short_option = m_getopt_table[option_idx].val;
132314f1b3e8SDimitry Andric bool success = false;
132414f1b3e8SDimitry Andric
132514f1b3e8SDimitry Andric uint32_t id = LLDB_INVALID_PROCESS_ID;
132614f1b3e8SDimitry Andric success = !option_arg.getAsInteger(0, id);
132714f1b3e8SDimitry Andric switch (short_option) {
132814f1b3e8SDimitry Andric case 'p': {
132914f1b3e8SDimitry Andric match_info.GetProcessInfo().SetProcessID(id);
133014f1b3e8SDimitry Andric if (!success)
133114f1b3e8SDimitry Andric error.SetErrorStringWithFormat("invalid process ID string: '%s'",
133214f1b3e8SDimitry Andric option_arg.str().c_str());
133314f1b3e8SDimitry Andric break;
133414f1b3e8SDimitry Andric }
133514f1b3e8SDimitry Andric case 'P':
133614f1b3e8SDimitry Andric match_info.GetProcessInfo().SetParentProcessID(id);
133714f1b3e8SDimitry Andric if (!success)
133814f1b3e8SDimitry Andric error.SetErrorStringWithFormat(
133914f1b3e8SDimitry Andric "invalid parent process ID string: '%s'",
134014f1b3e8SDimitry Andric option_arg.str().c_str());
134114f1b3e8SDimitry Andric break;
134214f1b3e8SDimitry Andric
134314f1b3e8SDimitry Andric case 'u':
134414f1b3e8SDimitry Andric match_info.GetProcessInfo().SetUserID(success ? id : UINT32_MAX);
134514f1b3e8SDimitry Andric if (!success)
134614f1b3e8SDimitry Andric error.SetErrorStringWithFormat("invalid user ID string: '%s'",
134714f1b3e8SDimitry Andric option_arg.str().c_str());
134814f1b3e8SDimitry Andric break;
134914f1b3e8SDimitry Andric
135014f1b3e8SDimitry Andric case 'U':
135114f1b3e8SDimitry Andric match_info.GetProcessInfo().SetEffectiveUserID(success ? id
135214f1b3e8SDimitry Andric : UINT32_MAX);
135314f1b3e8SDimitry Andric if (!success)
135414f1b3e8SDimitry Andric error.SetErrorStringWithFormat(
135514f1b3e8SDimitry Andric "invalid effective user ID string: '%s'",
135614f1b3e8SDimitry Andric option_arg.str().c_str());
135714f1b3e8SDimitry Andric break;
135814f1b3e8SDimitry Andric
135914f1b3e8SDimitry Andric case 'g':
136014f1b3e8SDimitry Andric match_info.GetProcessInfo().SetGroupID(success ? id : UINT32_MAX);
136114f1b3e8SDimitry Andric if (!success)
136214f1b3e8SDimitry Andric error.SetErrorStringWithFormat("invalid group ID string: '%s'",
136314f1b3e8SDimitry Andric option_arg.str().c_str());
136414f1b3e8SDimitry Andric break;
136514f1b3e8SDimitry Andric
136614f1b3e8SDimitry Andric case 'G':
136714f1b3e8SDimitry Andric match_info.GetProcessInfo().SetEffectiveGroupID(success ? id
136814f1b3e8SDimitry Andric : UINT32_MAX);
136914f1b3e8SDimitry Andric if (!success)
137014f1b3e8SDimitry Andric error.SetErrorStringWithFormat(
137114f1b3e8SDimitry Andric "invalid effective group ID string: '%s'",
137214f1b3e8SDimitry Andric option_arg.str().c_str());
137314f1b3e8SDimitry Andric break;
137414f1b3e8SDimitry Andric
137514f1b3e8SDimitry Andric case 'a': {
137614f1b3e8SDimitry Andric TargetSP target_sp =
137714f1b3e8SDimitry Andric execution_context ? execution_context->GetTargetSP() : TargetSP();
137814f1b3e8SDimitry Andric DebuggerSP debugger_sp =
137914f1b3e8SDimitry Andric target_sp ? target_sp->GetDebugger().shared_from_this()
138014f1b3e8SDimitry Andric : DebuggerSP();
138114f1b3e8SDimitry Andric PlatformSP platform_sp =
138214f1b3e8SDimitry Andric debugger_sp ? debugger_sp->GetPlatformList().GetSelectedPlatform()
138314f1b3e8SDimitry Andric : PlatformSP();
1384ef5d0b5eSDimitry Andric match_info.GetProcessInfo().GetArchitecture() =
1385ef5d0b5eSDimitry Andric Platform::GetAugmentedArchSpec(platform_sp.get(), option_arg);
138614f1b3e8SDimitry Andric } break;
138714f1b3e8SDimitry Andric
138814f1b3e8SDimitry Andric case 'n':
1389f73363f1SDimitry Andric match_info.GetProcessInfo().GetExecutableFile().SetFile(
139094994d37SDimitry Andric option_arg, FileSpec::Style::native);
139174a628f7SDimitry Andric match_info.SetNameMatchType(NameMatch::Equals);
139214f1b3e8SDimitry Andric break;
139314f1b3e8SDimitry Andric
139414f1b3e8SDimitry Andric case 'e':
1395f73363f1SDimitry Andric match_info.GetProcessInfo().GetExecutableFile().SetFile(
139694994d37SDimitry Andric option_arg, FileSpec::Style::native);
139774a628f7SDimitry Andric match_info.SetNameMatchType(NameMatch::EndsWith);
139814f1b3e8SDimitry Andric break;
139914f1b3e8SDimitry Andric
140014f1b3e8SDimitry Andric case 's':
1401f73363f1SDimitry Andric match_info.GetProcessInfo().GetExecutableFile().SetFile(
140294994d37SDimitry Andric option_arg, FileSpec::Style::native);
140374a628f7SDimitry Andric match_info.SetNameMatchType(NameMatch::StartsWith);
140414f1b3e8SDimitry Andric break;
140514f1b3e8SDimitry Andric
140614f1b3e8SDimitry Andric case 'c':
1407f73363f1SDimitry Andric match_info.GetProcessInfo().GetExecutableFile().SetFile(
140894994d37SDimitry Andric option_arg, FileSpec::Style::native);
140974a628f7SDimitry Andric match_info.SetNameMatchType(NameMatch::Contains);
141014f1b3e8SDimitry Andric break;
141114f1b3e8SDimitry Andric
141214f1b3e8SDimitry Andric case 'r':
1413f73363f1SDimitry Andric match_info.GetProcessInfo().GetExecutableFile().SetFile(
141494994d37SDimitry Andric option_arg, FileSpec::Style::native);
141574a628f7SDimitry Andric match_info.SetNameMatchType(NameMatch::RegularExpression);
141614f1b3e8SDimitry Andric break;
141714f1b3e8SDimitry Andric
141814f1b3e8SDimitry Andric case 'A':
141914f1b3e8SDimitry Andric show_args = true;
142014f1b3e8SDimitry Andric break;
142114f1b3e8SDimitry Andric
142214f1b3e8SDimitry Andric case 'v':
142314f1b3e8SDimitry Andric verbose = true;
142414f1b3e8SDimitry Andric break;
142514f1b3e8SDimitry Andric
1426ead24645SDimitry Andric case 'x':
1427ead24645SDimitry Andric match_info.SetMatchAllUsers(true);
142814f1b3e8SDimitry Andric break;
1429ead24645SDimitry Andric
1430ead24645SDimitry Andric default:
1431ead24645SDimitry Andric llvm_unreachable("Unimplemented option");
143214f1b3e8SDimitry Andric }
143314f1b3e8SDimitry Andric
143414f1b3e8SDimitry Andric return error;
143514f1b3e8SDimitry Andric }
143614f1b3e8SDimitry Andric
OptionParsingStarting(ExecutionContext * execution_context)143714f1b3e8SDimitry Andric void OptionParsingStarting(ExecutionContext *execution_context) override {
143814f1b3e8SDimitry Andric match_info.Clear();
143914f1b3e8SDimitry Andric show_args = false;
144014f1b3e8SDimitry Andric verbose = false;
144114f1b3e8SDimitry Andric }
144214f1b3e8SDimitry Andric
GetDefinitions()144314f1b3e8SDimitry Andric llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1444e3b55780SDimitry Andric return llvm::ArrayRef(g_platform_process_list_options);
144514f1b3e8SDimitry Andric }
144614f1b3e8SDimitry Andric
144714f1b3e8SDimitry Andric // Instance variables to hold the values for command options.
144814f1b3e8SDimitry Andric
144914f1b3e8SDimitry Andric ProcessInstanceInfoMatch match_info;
1450344a3780SDimitry Andric bool show_args = false;
1451344a3780SDimitry Andric bool verbose = false;
145214f1b3e8SDimitry Andric };
145314f1b3e8SDimitry Andric
145414f1b3e8SDimitry Andric CommandOptions m_options;
1455f034231aSEd Maste };
1456f034231aSEd Maste
1457f034231aSEd Maste // "platform process info"
145814f1b3e8SDimitry Andric class CommandObjectPlatformProcessInfo : public CommandObjectParsed {
1459f034231aSEd Maste public:
CommandObjectPlatformProcessInfo(CommandInterpreter & interpreter)146014f1b3e8SDimitry Andric CommandObjectPlatformProcessInfo(CommandInterpreter &interpreter)
146114f1b3e8SDimitry Andric : CommandObjectParsed(
146214f1b3e8SDimitry Andric interpreter, "platform process info",
1463f034231aSEd Maste "Get detailed information for one or more process by process ID.",
146414f1b3e8SDimitry Andric "platform process info <pid> [<pid> <pid> ...]", 0) {
1465ac9a064cSDimitry Andric AddSimpleArgumentList(eArgTypePid, eArgRepeatStar);
1466f034231aSEd Maste }
1467f034231aSEd Maste
1468f3fbd1c0SDimitry Andric ~CommandObjectPlatformProcessInfo() override = default;
1469f034231aSEd Maste
1470f034231aSEd Maste protected:
DoExecute(Args & args,CommandReturnObject & result)1471b1c73532SDimitry Andric void DoExecute(Args &args, CommandReturnObject &result) override {
14725f29bb8aSDimitry Andric Target *target = GetDebugger().GetSelectedTarget().get();
1473f034231aSEd Maste PlatformSP platform_sp;
147414f1b3e8SDimitry Andric if (target) {
1475f034231aSEd Maste platform_sp = target->GetPlatform();
1476f034231aSEd Maste }
147714f1b3e8SDimitry Andric if (!platform_sp) {
14785f29bb8aSDimitry Andric platform_sp = GetDebugger().GetPlatformList().GetSelectedPlatform();
1479f034231aSEd Maste }
1480f034231aSEd Maste
148114f1b3e8SDimitry Andric if (platform_sp) {
1482f034231aSEd Maste const size_t argc = args.GetArgumentCount();
148314f1b3e8SDimitry Andric if (argc > 0) {
1484b76161e4SDimitry Andric Status error;
1485f034231aSEd Maste
148614f1b3e8SDimitry Andric if (platform_sp->IsConnected()) {
1487f034231aSEd Maste Stream &ostrm = result.GetOutputStream();
148814f1b3e8SDimitry Andric for (auto &entry : args.entries()) {
148914f1b3e8SDimitry Andric lldb::pid_t pid;
1490ead24645SDimitry Andric if (entry.ref().getAsInteger(0, pid)) {
149114f1b3e8SDimitry Andric result.AppendErrorWithFormat("invalid process ID argument '%s'",
1492ead24645SDimitry Andric entry.ref().str().c_str());
149314f1b3e8SDimitry Andric break;
149414f1b3e8SDimitry Andric } else {
1495f034231aSEd Maste ProcessInstanceInfo proc_info;
149614f1b3e8SDimitry Andric if (platform_sp->GetProcessInfo(pid, proc_info)) {
149714f1b3e8SDimitry Andric ostrm.Printf("Process information for process %" PRIu64 ":\n",
149814f1b3e8SDimitry Andric pid);
14995f29bb8aSDimitry Andric proc_info.Dump(ostrm, platform_sp->GetUserIDResolver());
150014f1b3e8SDimitry Andric } else {
150114f1b3e8SDimitry Andric ostrm.Printf("error: no process information is available for "
150214f1b3e8SDimitry Andric "process %" PRIu64 "\n",
150314f1b3e8SDimitry Andric pid);
1504f034231aSEd Maste }
1505f034231aSEd Maste ostrm.EOL();
1506f034231aSEd Maste }
1507f034231aSEd Maste }
150814f1b3e8SDimitry Andric } else {
1509f034231aSEd Maste // Not connected...
1510c0981da4SDimitry Andric result.AppendErrorWithFormatv("not connected to '{0}'",
1511c0981da4SDimitry Andric platform_sp->GetPluginName());
1512f034231aSEd Maste }
151314f1b3e8SDimitry Andric } else {
1514f034231aSEd Maste // No args
1515f034231aSEd Maste result.AppendError("one or more process id(s) must be specified");
1516f034231aSEd Maste }
151714f1b3e8SDimitry Andric } else {
1518f034231aSEd Maste result.AppendError("no platform is currently selected");
1519f034231aSEd Maste }
1520f034231aSEd Maste }
1521f034231aSEd Maste };
1522f034231aSEd Maste
1523ead24645SDimitry Andric #define LLDB_OPTIONS_platform_process_attach
1524ead24645SDimitry Andric #include "CommandOptions.inc"
152514f1b3e8SDimitry Andric
152614f1b3e8SDimitry Andric class CommandObjectPlatformProcessAttach : public CommandObjectParsed {
1527f21a844fSEd Maste public:
CommandObjectPlatformProcessAttach(CommandInterpreter & interpreter)152814f1b3e8SDimitry Andric CommandObjectPlatformProcessAttach(CommandInterpreter &interpreter)
152914f1b3e8SDimitry Andric : CommandObjectParsed(interpreter, "platform process attach",
1530f21a844fSEd Maste "Attach to a process.",
15317fa27ce4SDimitry Andric "platform process attach <cmd-options>"),
15327fa27ce4SDimitry Andric m_class_options("scripted process", true, 'C', 'k', 'v', 0) {
15337fa27ce4SDimitry Andric m_all_options.Append(&m_options);
15347fa27ce4SDimitry Andric m_all_options.Append(&m_class_options, LLDB_OPT_SET_1 | LLDB_OPT_SET_2,
15357fa27ce4SDimitry Andric LLDB_OPT_SET_ALL);
15367fa27ce4SDimitry Andric m_all_options.Finalize();
15377fa27ce4SDimitry Andric }
1538f21a844fSEd Maste
1539f3fbd1c0SDimitry Andric ~CommandObjectPlatformProcessAttach() override = default;
1540f21a844fSEd Maste
DoExecute(Args & command,CommandReturnObject & result)1541b1c73532SDimitry Andric void DoExecute(Args &command, CommandReturnObject &result) override {
154214f1b3e8SDimitry Andric PlatformSP platform_sp(
15435f29bb8aSDimitry Andric GetDebugger().GetPlatformList().GetSelectedPlatform());
154414f1b3e8SDimitry Andric if (platform_sp) {
15457fa27ce4SDimitry Andric
15467fa27ce4SDimitry Andric if (!m_class_options.GetName().empty()) {
15477fa27ce4SDimitry Andric m_options.attach_info.SetProcessPluginName("ScriptedProcess");
15487fa27ce4SDimitry Andric ScriptedMetadataSP metadata_sp = std::make_shared<ScriptedMetadata>(
15497fa27ce4SDimitry Andric m_class_options.GetName(), m_class_options.GetStructuredData());
15507fa27ce4SDimitry Andric m_options.attach_info.SetScriptedMetadata(metadata_sp);
15517fa27ce4SDimitry Andric }
15527fa27ce4SDimitry Andric
1553b76161e4SDimitry Andric Status err;
155414f1b3e8SDimitry Andric ProcessSP remote_process_sp = platform_sp->Attach(
15555f29bb8aSDimitry Andric m_options.attach_info, GetDebugger(), nullptr, err);
155614f1b3e8SDimitry Andric if (err.Fail()) {
1557f21a844fSEd Maste result.AppendError(err.AsCString());
155814f1b3e8SDimitry Andric } else if (!remote_process_sp) {
1559f21a844fSEd Maste result.AppendError("could not attach: unknown reason");
156014f1b3e8SDimitry Andric } else
1561f21a844fSEd Maste result.SetStatus(eReturnStatusSuccessFinishResult);
156214f1b3e8SDimitry Andric } else {
1563f21a844fSEd Maste result.AppendError("no platform is currently selected");
1564f21a844fSEd Maste }
1565f21a844fSEd Maste }
1566f21a844fSEd Maste
GetOptions()15677fa27ce4SDimitry Andric Options *GetOptions() override { return &m_all_options; }
1568f21a844fSEd Maste
1569f21a844fSEd Maste protected:
15707fa27ce4SDimitry Andric CommandOptionsProcessAttach m_options;
15717fa27ce4SDimitry Andric OptionGroupPythonClassWithDict m_class_options;
15727fa27ce4SDimitry Andric OptionGroupOptions m_all_options;
1573f21a844fSEd Maste };
1574f21a844fSEd Maste
157514f1b3e8SDimitry Andric class CommandObjectPlatformProcess : public CommandObjectMultiword {
1576f034231aSEd Maste public:
1577f034231aSEd Maste // Constructors and Destructors
CommandObjectPlatformProcess(CommandInterpreter & interpreter)1578f3fbd1c0SDimitry Andric CommandObjectPlatformProcess(CommandInterpreter &interpreter)
1579f3fbd1c0SDimitry Andric : CommandObjectMultiword(interpreter, "platform process",
158014f1b3e8SDimitry Andric "Commands to query, launch and attach to "
158114f1b3e8SDimitry Andric "processes on the current platform.",
158214f1b3e8SDimitry Andric "platform process [attach|launch|list] ...") {
158314f1b3e8SDimitry Andric LoadSubCommand(
158414f1b3e8SDimitry Andric "attach",
158514f1b3e8SDimitry Andric CommandObjectSP(new CommandObjectPlatformProcessAttach(interpreter)));
158614f1b3e8SDimitry Andric LoadSubCommand(
158714f1b3e8SDimitry Andric "launch",
158814f1b3e8SDimitry Andric CommandObjectSP(new CommandObjectPlatformProcessLaunch(interpreter)));
158914f1b3e8SDimitry Andric LoadSubCommand("info", CommandObjectSP(new CommandObjectPlatformProcessInfo(
159014f1b3e8SDimitry Andric interpreter)));
159114f1b3e8SDimitry Andric LoadSubCommand("list", CommandObjectSP(new CommandObjectPlatformProcessList(
159214f1b3e8SDimitry Andric interpreter)));
1593f034231aSEd Maste }
1594f034231aSEd Maste
1595f3fbd1c0SDimitry Andric ~CommandObjectPlatformProcess() override = default;
1596f034231aSEd Maste
1597f034231aSEd Maste private:
1598f034231aSEd Maste // For CommandObjectPlatform only
1599cfca06d7SDimitry Andric CommandObjectPlatformProcess(const CommandObjectPlatformProcess &) = delete;
1600cfca06d7SDimitry Andric const CommandObjectPlatformProcess &
1601cfca06d7SDimitry Andric operator=(const CommandObjectPlatformProcess &) = delete;
1602f034231aSEd Maste };
1603f034231aSEd Maste
1604f21a844fSEd Maste // "platform shell"
1605ead24645SDimitry Andric #define LLDB_OPTIONS_platform_shell
1606ead24645SDimitry Andric #include "CommandOptions.inc"
160714f1b3e8SDimitry Andric
160814f1b3e8SDimitry Andric class CommandObjectPlatformShell : public CommandObjectRaw {
1609f034231aSEd Maste public:
161014f1b3e8SDimitry Andric class CommandOptions : public Options {
1611f21a844fSEd Maste public:
1612145449b1SDimitry Andric CommandOptions() = default;
1613f21a844fSEd Maste
1614f3fbd1c0SDimitry Andric ~CommandOptions() override = default;
1615f21a844fSEd Maste
GetDefinitions()161614f1b3e8SDimitry Andric llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1617e3b55780SDimitry Andric return llvm::ArrayRef(g_platform_shell_options);
1618f21a844fSEd Maste }
1619f21a844fSEd Maste
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)1620b76161e4SDimitry Andric Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
162114f1b3e8SDimitry Andric ExecutionContext *execution_context) override {
1622b76161e4SDimitry Andric Status error;
1623f21a844fSEd Maste
162414f1b3e8SDimitry Andric const char short_option = (char)GetDefinitions()[option_idx].short_option;
1625f21a844fSEd Maste
162614f1b3e8SDimitry Andric switch (short_option) {
1627cfca06d7SDimitry Andric case 'h':
1628cfca06d7SDimitry Andric m_use_host_platform = true;
1629cfca06d7SDimitry Andric break;
1630f21a844fSEd Maste case 't':
1631f73363f1SDimitry Andric uint32_t timeout_sec;
1632f73363f1SDimitry Andric if (option_arg.getAsInteger(10, timeout_sec))
163314f1b3e8SDimitry Andric error.SetErrorStringWithFormat(
163414f1b3e8SDimitry Andric "could not convert \"%s\" to a numeric value.",
163514f1b3e8SDimitry Andric option_arg.str().c_str());
1636f73363f1SDimitry Andric else
1637cfca06d7SDimitry Andric m_timeout = std::chrono::seconds(timeout_sec);
1638f21a844fSEd Maste break;
1639b60736ecSDimitry Andric case 's': {
1640b60736ecSDimitry Andric if (option_arg.empty()) {
1641b60736ecSDimitry Andric error.SetErrorStringWithFormat(
1642b60736ecSDimitry Andric "missing shell interpreter path for option -i|--interpreter.");
1643b60736ecSDimitry Andric return error;
1644b60736ecSDimitry Andric }
1645b60736ecSDimitry Andric
1646b60736ecSDimitry Andric m_shell_interpreter = option_arg.str();
1647b60736ecSDimitry Andric break;
1648b60736ecSDimitry Andric }
1649f21a844fSEd Maste default:
1650ead24645SDimitry Andric llvm_unreachable("Unimplemented option");
1651f21a844fSEd Maste }
1652f21a844fSEd Maste
1653f21a844fSEd Maste return error;
1654f21a844fSEd Maste }
1655f21a844fSEd Maste
OptionParsingStarting(ExecutionContext * execution_context)1656cfca06d7SDimitry Andric void OptionParsingStarting(ExecutionContext *execution_context) override {
1657cfca06d7SDimitry Andric m_timeout.reset();
1658cfca06d7SDimitry Andric m_use_host_platform = false;
1659b60736ecSDimitry Andric m_shell_interpreter.clear();
1660cfca06d7SDimitry Andric }
1661f21a844fSEd Maste
1662cfca06d7SDimitry Andric Timeout<std::micro> m_timeout = std::chrono::seconds(10);
1663cfca06d7SDimitry Andric bool m_use_host_platform;
1664b60736ecSDimitry Andric std::string m_shell_interpreter;
1665f21a844fSEd Maste };
1666f21a844fSEd Maste
CommandObjectPlatformShell(CommandInterpreter & interpreter)1667f3fbd1c0SDimitry Andric CommandObjectPlatformShell(CommandInterpreter &interpreter)
166814f1b3e8SDimitry Andric : CommandObjectRaw(interpreter, "platform shell",
166914f1b3e8SDimitry Andric "Run a shell command on the current platform.",
1670145449b1SDimitry Andric "platform shell <shell-command>", 0) {
1671ac9a064cSDimitry Andric AddSimpleArgumentList(eArgTypeNone, eArgRepeatStar);
1672145449b1SDimitry Andric }
1673f034231aSEd Maste
1674f3fbd1c0SDimitry Andric ~CommandObjectPlatformShell() override = default;
1675f034231aSEd Maste
GetOptions()167614f1b3e8SDimitry Andric Options *GetOptions() override { return &m_options; }
1677f21a844fSEd Maste
DoExecute(llvm::StringRef raw_command_line,CommandReturnObject & result)1678b1c73532SDimitry Andric void DoExecute(llvm::StringRef raw_command_line,
167914f1b3e8SDimitry Andric CommandReturnObject &result) override {
168014f1b3e8SDimitry Andric ExecutionContext exe_ctx = GetCommandInterpreter().GetExecutionContext();
168114f1b3e8SDimitry Andric m_options.NotifyOptionParsingStarting(&exe_ctx);
1682f21a844fSEd Maste
1683f21a844fSEd Maste // Print out an usage syntax on an empty command line.
1684f73363f1SDimitry Andric if (raw_command_line.empty()) {
168514f1b3e8SDimitry Andric result.GetOutputStream().Printf("%s\n", this->GetSyntax().str().c_str());
1686b1c73532SDimitry Andric return;
1687f21a844fSEd Maste }
1688f21a844fSEd Maste
1689cfca06d7SDimitry Andric const bool is_alias = !raw_command_line.contains("platform");
1690f73363f1SDimitry Andric OptionsWithRaw args(raw_command_line);
1691f21a844fSEd Maste
1692f73363f1SDimitry Andric if (args.HasArgs())
1693f73363f1SDimitry Andric if (!ParseOptions(args.GetArgs(), result))
1694b1c73532SDimitry Andric return;
1695f21a844fSEd Maste
1696cfca06d7SDimitry Andric if (args.GetRawPart().empty()) {
1697cfca06d7SDimitry Andric result.GetOutputStream().Printf("%s <shell-command>\n",
1698cfca06d7SDimitry Andric is_alias ? "shell" : "platform shell");
1699b1c73532SDimitry Andric return;
1700cfca06d7SDimitry Andric }
1701cfca06d7SDimitry Andric
1702b60736ecSDimitry Andric llvm::StringRef cmd = args.GetRawPart();
1703b60736ecSDimitry Andric
170414f1b3e8SDimitry Andric PlatformSP platform_sp(
1705cfca06d7SDimitry Andric m_options.m_use_host_platform
1706cfca06d7SDimitry Andric ? Platform::GetHostPlatform()
1707cfca06d7SDimitry Andric : GetDebugger().GetPlatformList().GetSelectedPlatform());
1708b76161e4SDimitry Andric Status error;
170914f1b3e8SDimitry Andric if (platform_sp) {
17105e95aa85SEd Maste FileSpec working_dir{};
1711f034231aSEd Maste std::string output;
1712f034231aSEd Maste int status = -1;
1713f034231aSEd Maste int signo = -1;
1714b60736ecSDimitry Andric error = (platform_sp->RunShellCommand(m_options.m_shell_interpreter, cmd,
1715b60736ecSDimitry Andric working_dir, &status, &signo,
1716cfca06d7SDimitry Andric &output, m_options.m_timeout));
1717f034231aSEd Maste if (!output.empty())
171814f1b3e8SDimitry Andric result.GetOutputStream().PutCString(output);
171914f1b3e8SDimitry Andric if (status > 0) {
172014f1b3e8SDimitry Andric if (signo > 0) {
1721f034231aSEd Maste const char *signo_cstr = Host::GetSignalAsCString(signo);
1722f034231aSEd Maste if (signo_cstr)
172314f1b3e8SDimitry Andric result.GetOutputStream().Printf(
172414f1b3e8SDimitry Andric "error: command returned with status %i and signal %s\n",
172514f1b3e8SDimitry Andric status, signo_cstr);
1726f034231aSEd Maste else
172714f1b3e8SDimitry Andric result.GetOutputStream().Printf(
172814f1b3e8SDimitry Andric "error: command returned with status %i and signal %i\n",
172914f1b3e8SDimitry Andric status, signo);
173014f1b3e8SDimitry Andric } else
173114f1b3e8SDimitry Andric result.GetOutputStream().Printf(
173214f1b3e8SDimitry Andric "error: command returned with status %i\n", status);
1733f034231aSEd Maste }
173414f1b3e8SDimitry Andric } else {
173514f1b3e8SDimitry Andric result.GetOutputStream().Printf(
173614f1b3e8SDimitry Andric "error: cannot run remote shell commands without a platform\n");
173714f1b3e8SDimitry Andric error.SetErrorString(
173814f1b3e8SDimitry Andric "error: cannot run remote shell commands without a platform");
1739f21a844fSEd Maste }
1740f034231aSEd Maste
174114f1b3e8SDimitry Andric if (error.Fail()) {
1742f034231aSEd Maste result.AppendError(error.AsCString());
174314f1b3e8SDimitry Andric } else {
1744f034231aSEd Maste result.SetStatus(eReturnStatusSuccessFinishResult);
1745f034231aSEd Maste }
1746f034231aSEd Maste }
1747f3fbd1c0SDimitry Andric
1748f21a844fSEd Maste CommandOptions m_options;
1749f21a844fSEd Maste };
1750f21a844fSEd Maste
1751f21a844fSEd Maste // "platform install" - install a target to a remote end
175214f1b3e8SDimitry Andric class CommandObjectPlatformInstall : public CommandObjectParsed {
1753f21a844fSEd Maste public:
CommandObjectPlatformInstall(CommandInterpreter & interpreter)175414f1b3e8SDimitry Andric CommandObjectPlatformInstall(CommandInterpreter &interpreter)
175514f1b3e8SDimitry Andric : CommandObjectParsed(
175614f1b3e8SDimitry Andric interpreter, "platform target-install",
1757f21a844fSEd Maste "Install a target (bundle or executable file) to the remote end.",
1758145449b1SDimitry Andric "platform target-install <local-thing> <remote-sandbox>", 0) {
1759145449b1SDimitry Andric CommandArgumentData local_arg{eArgTypePath, eArgRepeatPlain};
1760ac9a064cSDimitry Andric CommandArgumentData remote_arg{eArgTypeRemotePath, eArgRepeatPlain};
1761145449b1SDimitry Andric m_arguments.push_back({local_arg});
1762145449b1SDimitry Andric m_arguments.push_back({remote_arg});
1763145449b1SDimitry Andric }
1764f21a844fSEd Maste
1765f3fbd1c0SDimitry Andric ~CommandObjectPlatformInstall() override = default;
1766f21a844fSEd Maste
1767b60736ecSDimitry Andric void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)1768b60736ecSDimitry Andric HandleArgumentCompletion(CompletionRequest &request,
1769b60736ecSDimitry Andric OptionElementVector &opt_element_vector) override {
1770b60736ecSDimitry Andric if (request.GetCursorIndex())
1771b60736ecSDimitry Andric return;
17727fa27ce4SDimitry Andric lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
17737fa27ce4SDimitry Andric GetCommandInterpreter(), lldb::eDiskFileCompletion, request, nullptr);
1774b60736ecSDimitry Andric }
1775b60736ecSDimitry Andric
DoExecute(Args & args,CommandReturnObject & result)1776b1c73532SDimitry Andric void DoExecute(Args &args, CommandReturnObject &result) override {
177714f1b3e8SDimitry Andric if (args.GetArgumentCount() != 2) {
1778f21a844fSEd Maste result.AppendError("platform target-install takes two arguments");
1779b1c73532SDimitry Andric return;
1780f21a844fSEd Maste }
1781f21a844fSEd Maste // TODO: move the bulk of this code over to the platform itself
178294994d37SDimitry Andric FileSpec src(args.GetArgumentAtIndex(0));
178394994d37SDimitry Andric FileSystem::Instance().Resolve(src);
178494994d37SDimitry Andric FileSpec dst(args.GetArgumentAtIndex(1));
178594994d37SDimitry Andric if (!FileSystem::Instance().Exists(src)) {
1786f21a844fSEd Maste result.AppendError("source location does not exist or is not accessible");
1787b1c73532SDimitry Andric return;
1788f21a844fSEd Maste }
178914f1b3e8SDimitry Andric PlatformSP platform_sp(
17905f29bb8aSDimitry Andric GetDebugger().GetPlatformList().GetSelectedPlatform());
179114f1b3e8SDimitry Andric if (!platform_sp) {
1792f21a844fSEd Maste result.AppendError("no platform currently selected");
1793b1c73532SDimitry Andric return;
1794f21a844fSEd Maste }
179586758c71SEd Maste
1796b76161e4SDimitry Andric Status error = platform_sp->Install(src, dst);
179714f1b3e8SDimitry Andric if (error.Success()) {
1798f21a844fSEd Maste result.SetStatus(eReturnStatusSuccessFinishNoResult);
179914f1b3e8SDimitry Andric } else {
180086758c71SEd Maste result.AppendErrorWithFormat("install failed: %s", error.AsCString());
1801f21a844fSEd Maste }
1802f21a844fSEd Maste }
1803f034231aSEd Maste };
1804f034231aSEd Maste
CommandObjectPlatform(CommandInterpreter & interpreter)1805f3fbd1c0SDimitry Andric CommandObjectPlatform::CommandObjectPlatform(CommandInterpreter &interpreter)
180614f1b3e8SDimitry Andric : CommandObjectMultiword(
180714f1b3e8SDimitry Andric interpreter, "platform", "Commands to manage and create platforms.",
180814f1b3e8SDimitry Andric "platform [connect|disconnect|info|list|status|select] ...") {
180914f1b3e8SDimitry Andric LoadSubCommand("select",
181014f1b3e8SDimitry Andric CommandObjectSP(new CommandObjectPlatformSelect(interpreter)));
181114f1b3e8SDimitry Andric LoadSubCommand("list",
181214f1b3e8SDimitry Andric CommandObjectSP(new CommandObjectPlatformList(interpreter)));
181314f1b3e8SDimitry Andric LoadSubCommand("status",
181414f1b3e8SDimitry Andric CommandObjectSP(new CommandObjectPlatformStatus(interpreter)));
181514f1b3e8SDimitry Andric LoadSubCommand("connect", CommandObjectSP(
181614f1b3e8SDimitry Andric new CommandObjectPlatformConnect(interpreter)));
181714f1b3e8SDimitry Andric LoadSubCommand(
181814f1b3e8SDimitry Andric "disconnect",
181914f1b3e8SDimitry Andric CommandObjectSP(new CommandObjectPlatformDisconnect(interpreter)));
182014f1b3e8SDimitry Andric LoadSubCommand("settings", CommandObjectSP(new CommandObjectPlatformSettings(
182114f1b3e8SDimitry Andric interpreter)));
182214f1b3e8SDimitry Andric LoadSubCommand("mkdir",
182314f1b3e8SDimitry Andric CommandObjectSP(new CommandObjectPlatformMkDir(interpreter)));
182414f1b3e8SDimitry Andric LoadSubCommand("file",
182514f1b3e8SDimitry Andric CommandObjectSP(new CommandObjectPlatformFile(interpreter)));
1826c0981da4SDimitry Andric LoadSubCommand("file-exists",
1827c0981da4SDimitry Andric CommandObjectSP(new CommandObjectPlatformFileExists(interpreter)));
182814f1b3e8SDimitry Andric LoadSubCommand("get-file", CommandObjectSP(new CommandObjectPlatformGetFile(
182914f1b3e8SDimitry Andric interpreter)));
1830c0981da4SDimitry Andric LoadSubCommand("get-permissions",
1831c0981da4SDimitry Andric CommandObjectSP(new CommandObjectPlatformGetPermissions(interpreter)));
183214f1b3e8SDimitry Andric LoadSubCommand("get-size", CommandObjectSP(new CommandObjectPlatformGetSize(
183314f1b3e8SDimitry Andric interpreter)));
183414f1b3e8SDimitry Andric LoadSubCommand("put-file", CommandObjectSP(new CommandObjectPlatformPutFile(
183514f1b3e8SDimitry Andric interpreter)));
183614f1b3e8SDimitry Andric LoadSubCommand("process", CommandObjectSP(
183714f1b3e8SDimitry Andric new CommandObjectPlatformProcess(interpreter)));
183814f1b3e8SDimitry Andric LoadSubCommand("shell",
183914f1b3e8SDimitry Andric CommandObjectSP(new CommandObjectPlatformShell(interpreter)));
184014f1b3e8SDimitry Andric LoadSubCommand(
184114f1b3e8SDimitry Andric "target-install",
184214f1b3e8SDimitry Andric CommandObjectSP(new CommandObjectPlatformInstall(interpreter)));
1843f034231aSEd Maste }
1844f034231aSEd Maste
1845f3fbd1c0SDimitry Andric CommandObjectPlatform::~CommandObjectPlatform() = default;
1846