blob: ace1ef5b53fb3597547aa1ceb9840514e7922d5b [file] [log] [blame]
Greg Claytonded470d2011-03-19 01:12:21 +00001//===-- CommandObjectPlatform.cpp -------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Daniel Malea93a64302012-12-05 00:20:57 +000010#include "lldb/lldb-python.h"
11
Greg Claytonded470d2011-03-19 01:12:21 +000012#include "CommandObjectPlatform.h"
13
14// C Includes
15// C++ Includes
16// Other libraries and framework includes
17// Project includes
18#include "lldb/Core/DataExtractor.h"
19#include "lldb/Core/Debugger.h"
Greg Clayton1f746072012-08-29 21:13:06 +000020#include "lldb/Core/Module.h"
Greg Claytonded470d2011-03-19 01:12:21 +000021#include "lldb/Core/PluginManager.h"
22#include "lldb/Interpreter/Args.h"
23#include "lldb/Interpreter/CommandInterpreter.h"
24#include "lldb/Interpreter/CommandReturnObject.h"
Greg Clayton7260f622011-04-18 08:33:37 +000025#include "lldb/Interpreter/OptionGroupPlatform.h"
Greg Claytonded470d2011-03-19 01:12:21 +000026#include "lldb/Target/ExecutionContext.h"
27#include "lldb/Target/Platform.h"
Greg Claytoneb0103f2011-04-07 22:46:35 +000028#include "lldb/Target/Process.h"
Daniel Maleae0f8f572013-08-26 23:57:52 +000029#include "lldb/Utility/Utils.h"
Greg Claytonded470d2011-03-19 01:12:21 +000030
31using namespace lldb;
32using namespace lldb_private;
33
Daniel Maleae0f8f572013-08-26 23:57:52 +000034static mode_t
35ParsePermissionString(const char* permissions)
36{
37 if (strlen(permissions) != 9)
38 return (mode_t)(-1);
39 bool user_r,user_w,user_x,
40 group_r,group_w,group_x,
41 world_r,world_w,world_x;
42
43 user_r = (permissions[0] == 'r');
44 user_w = (permissions[1] == 'w');
45 user_x = (permissions[2] == 'x');
46
47 group_r = (permissions[3] == 'r');
48 group_w = (permissions[4] == 'w');
49 group_x = (permissions[5] == 'x');
50
51 world_r = (permissions[6] == 'r');
52 world_w = (permissions[7] == 'w');
53 world_x = (permissions[8] == 'x');
54
55 mode_t user,group,world;
56 user = (user_r ? 4 : 0) | (user_w ? 2 : 0) | (user_x ? 1 : 0);
57 group = (group_r ? 4 : 0) | (group_w ? 2 : 0) | (group_x ? 1 : 0);
58 world = (world_r ? 4 : 0) | (world_w ? 2 : 0) | (world_x ? 1 : 0);
59
60 return user | group | world;
61}
62
63static OptionDefinition
64g_permissions_options[] =
65{
Virgile Belloe2607b52013-09-05 16:42:23 +000066 { LLDB_OPT_SET_ALL, false, "permissions-value", 'v', OptionParser::eRequiredArgument, NULL, 0, eArgTypePermissionsNumber , "Give out the numeric value for permissions (e.g. 757)" },
67 { LLDB_OPT_SET_ALL, false, "permissions-string",'s', OptionParser::eRequiredArgument, NULL, 0, eArgTypePermissionsString , "Give out the string value for permissions (e.g. rwxr-xr--)." },
68 { LLDB_OPT_SET_ALL, false, "user-read", 'r', OptionParser::eNoArgument, NULL, 0, eArgTypeNone , "Allow user to read." },
69 { LLDB_OPT_SET_ALL, false, "user-write", 'w', OptionParser::eNoArgument, NULL, 0, eArgTypeNone , "Allow user to write." },
70 { LLDB_OPT_SET_ALL, false, "user-exec", 'x', OptionParser::eNoArgument, NULL, 0, eArgTypeNone , "Allow user to execute." },
Daniel Maleae0f8f572013-08-26 23:57:52 +000071
Virgile Belloe2607b52013-09-05 16:42:23 +000072 { LLDB_OPT_SET_ALL, false, "group-read", 'R', OptionParser::eNoArgument, NULL, 0, eArgTypeNone , "Allow group to read." },
73 { LLDB_OPT_SET_ALL, false, "group-write", 'W', OptionParser::eNoArgument, NULL, 0, eArgTypeNone , "Allow group to write." },
74 { LLDB_OPT_SET_ALL, false, "group-exec", 'X', OptionParser::eNoArgument, NULL, 0, eArgTypeNone , "Allow group to execute." },
Daniel Maleae0f8f572013-08-26 23:57:52 +000075
Virgile Belloe2607b52013-09-05 16:42:23 +000076 { LLDB_OPT_SET_ALL, false, "world-read", 'd', OptionParser::eNoArgument, NULL, 0, eArgTypeNone , "Allow world to read." },
77 { LLDB_OPT_SET_ALL, false, "world-write", 't', OptionParser::eNoArgument, NULL, 0, eArgTypeNone , "Allow world to write." },
78 { LLDB_OPT_SET_ALL, false, "world-exec", 'e', OptionParser::eNoArgument, NULL, 0, eArgTypeNone , "Allow world to execute." },
Daniel Maleae0f8f572013-08-26 23:57:52 +000079
80};
81
82class OptionPermissions : public lldb_private::OptionGroup
83{
84public:
85 OptionPermissions ()
86 {
87 }
88
89 virtual
90 ~OptionPermissions ()
91 {
92 }
93
94 virtual lldb_private::Error
95 SetOptionValue (CommandInterpreter &interpreter,
96 uint32_t option_idx,
97 const char *option_arg)
98 {
99 Error error;
100 char short_option = (char) GetDefinitions()[option_idx].short_option;
101 switch (short_option)
102 {
103 case 'v':
104 {
105 bool ok;
106 uint32_t perms = Args::StringToUInt32(option_arg, 777, 8, &ok);
107 if (!ok)
108 error.SetErrorStringWithFormat("invalid value for permissions: %s", option_arg);
109 else
110 m_permissions = perms;
111 }
112 break;
113 case 's':
114 {
115 mode_t perms = ParsePermissionString(option_arg);
116 if (perms == (mode_t)-1)
117 error.SetErrorStringWithFormat("invalid value for permissions: %s", option_arg);
118 else
119 m_permissions = perms;
120 }
121 case 'r':
122 m_permissions |= File::ePermissionsUserRead;
123 break;
124 case 'w':
125 m_permissions |= File::ePermissionsUserWrite;
126 break;
127 case 'x':
128 m_permissions |= File::ePermissionsUserExecute;
129 break;
130 case 'R':
131 m_permissions |= File::ePermissionsGroupRead;
132 break;
133 case 'W':
134 m_permissions |= File::ePermissionsGroupWrite;
135 break;
136 case 'X':
137 m_permissions |= File::ePermissionsGroupExecute;
138 break;
139 case 'd':
140 m_permissions |= File::ePermissionsWorldRead;
141 break;
142 case 't':
143 m_permissions |= File::ePermissionsWorldWrite;
144 break;
145 case 'e':
146 m_permissions |= File::ePermissionsWorldExecute;
147 break;
148
149 default:
150 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
151 break;
152 }
153
154 return error;
155 }
156
157 void
158 OptionParsingStarting (CommandInterpreter &interpreter)
159 {
160 m_permissions = 0;
161 }
162
163 virtual uint32_t
164 GetNumDefinitions ()
165 {
166 return llvm::array_lengthof(g_permissions_options);
167 }
168
169 const lldb_private::OptionDefinition*
170 GetDefinitions ()
171 {
172 return g_permissions_options;
173 }
174
175 // Instance variables to hold the values for command options.
176
177 uint32_t m_permissions;
178private:
179 DISALLOW_COPY_AND_ASSIGN(OptionPermissions);
180};
Greg Claytonf6b8b582011-04-13 00:18:08 +0000181
Greg Claytonded470d2011-03-19 01:12:21 +0000182//----------------------------------------------------------------------
Greg Clayton7260f622011-04-18 08:33:37 +0000183// "platform select <platform-name>"
Greg Claytonded470d2011-03-19 01:12:21 +0000184//----------------------------------------------------------------------
Jim Ingham5a988412012-06-08 21:56:10 +0000185class CommandObjectPlatformSelect : public CommandObjectParsed
Greg Claytonded470d2011-03-19 01:12:21 +0000186{
187public:
Greg Claytonf6b8b582011-04-13 00:18:08 +0000188 CommandObjectPlatformSelect (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +0000189 CommandObjectParsed (interpreter,
190 "platform select",
191 "Create a platform if needed and select it as the current platform.",
192 "platform select <platform-name>",
193 0),
Greg Claytonf6b8b582011-04-13 00:18:08 +0000194 m_option_group (interpreter),
195 m_platform_options (false) // Don't include the "--platform" option by passing false
Greg Claytonded470d2011-03-19 01:12:21 +0000196 {
Greg Claytonab65b342011-04-13 22:47:15 +0000197 m_option_group.Append (&m_platform_options, LLDB_OPT_SET_ALL, 1);
Greg Claytonf6b8b582011-04-13 00:18:08 +0000198 m_option_group.Finalize();
Greg Claytonded470d2011-03-19 01:12:21 +0000199 }
200
201 virtual
Greg Claytonf6b8b582011-04-13 00:18:08 +0000202 ~CommandObjectPlatformSelect ()
Greg Claytonded470d2011-03-19 01:12:21 +0000203 {
204 }
205
Jim Ingham5a988412012-06-08 21:56:10 +0000206 virtual int
207 HandleCompletion (Args &input,
208 int &cursor_index,
209 int &cursor_char_position,
210 int match_start_point,
211 int max_return_elements,
212 bool &word_complete,
213 StringList &matches)
214 {
215 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
216 completion_str.erase (cursor_char_position);
217
218 CommandCompletions::PlatformPluginNames (m_interpreter,
219 completion_str.c_str(),
220 match_start_point,
221 max_return_elements,
222 NULL,
223 word_complete,
224 matches);
225 return matches.GetSize();
226 }
227
228 virtual Options *
229 GetOptions ()
230 {
231 return &m_option_group;
232 }
233
234protected:
Greg Claytonded470d2011-03-19 01:12:21 +0000235 virtual bool
Jim Ingham5a988412012-06-08 21:56:10 +0000236 DoExecute (Args& args, CommandReturnObject &result)
Greg Claytonded470d2011-03-19 01:12:21 +0000237 {
Greg Claytonded470d2011-03-19 01:12:21 +0000238 if (args.GetArgumentCount() == 1)
239 {
Greg Claytonab65b342011-04-13 22:47:15 +0000240 const char *platform_name = args.GetArgumentAtIndex (0);
241 if (platform_name && platform_name[0])
242 {
243 const bool select = true;
Greg Clayton7260f622011-04-18 08:33:37 +0000244 m_platform_options.SetPlatformName (platform_name);
Greg Claytonab65b342011-04-13 22:47:15 +0000245 Error error;
Greg Clayton70512312012-05-08 01:45:38 +0000246 ArchSpec platform_arch;
247 PlatformSP platform_sp (m_platform_options.CreatePlatformWithOptions (m_interpreter, ArchSpec(), select, error, platform_arch));
Greg Claytonab65b342011-04-13 22:47:15 +0000248 if (platform_sp)
249 {
250 platform_sp->GetStatus (result.GetOutputStream());
251 result.SetStatus (eReturnStatusSuccessFinishResult);
252 }
253 else
254 {
255 result.AppendError(error.AsCString());
256 result.SetStatus (eReturnStatusFailed);
257 }
258 }
259 else
260 {
261 result.AppendError ("invalid platform name");
262 result.SetStatus (eReturnStatusFailed);
263 }
Greg Claytonded470d2011-03-19 01:12:21 +0000264 }
265 else
266 {
Greg Clayton32e0a752011-03-30 18:16:51 +0000267 result.AppendError ("platform create takes a platform name as an argument\n");
Greg Claytonded470d2011-03-19 01:12:21 +0000268 result.SetStatus (eReturnStatusFailed);
269 }
270 return result.Succeeded();
271 }
Greg Clayton7260f622011-04-18 08:33:37 +0000272
Greg Claytonf6b8b582011-04-13 00:18:08 +0000273 OptionGroupOptions m_option_group;
Greg Clayton7260f622011-04-18 08:33:37 +0000274 OptionGroupPlatform m_platform_options;
Greg Claytonded470d2011-03-19 01:12:21 +0000275};
276
277//----------------------------------------------------------------------
278// "platform list"
279//----------------------------------------------------------------------
Jim Ingham5a988412012-06-08 21:56:10 +0000280class CommandObjectPlatformList : public CommandObjectParsed
Greg Claytonded470d2011-03-19 01:12:21 +0000281{
282public:
283 CommandObjectPlatformList (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +0000284 CommandObjectParsed (interpreter,
285 "platform list",
286 "List all platforms that are available.",
287 NULL,
288 0)
Greg Claytonded470d2011-03-19 01:12:21 +0000289 {
290 }
291
292 virtual
293 ~CommandObjectPlatformList ()
294 {
295 }
296
Jim Ingham5a988412012-06-08 21:56:10 +0000297protected:
Greg Claytonded470d2011-03-19 01:12:21 +0000298 virtual bool
Jim Ingham5a988412012-06-08 21:56:10 +0000299 DoExecute (Args& args, CommandReturnObject &result)
Greg Claytonded470d2011-03-19 01:12:21 +0000300 {
301 Stream &ostrm = result.GetOutputStream();
302 ostrm.Printf("Available platforms:\n");
303
304 PlatformSP host_platform_sp (Platform::GetDefaultPlatform());
305 ostrm.Printf ("%s: %s\n",
Greg Clayton57abc5d2013-05-10 21:47:16 +0000306 host_platform_sp->GetPluginName().GetCString(),
Greg Claytonded470d2011-03-19 01:12:21 +0000307 host_platform_sp->GetDescription());
308
309 uint32_t idx;
310 for (idx = 0; 1; ++idx)
311 {
312 const char *plugin_name = PluginManager::GetPlatformPluginNameAtIndex (idx);
313 if (plugin_name == NULL)
314 break;
315 const char *plugin_desc = PluginManager::GetPlatformPluginDescriptionAtIndex (idx);
316 if (plugin_desc == NULL)
317 break;
318 ostrm.Printf("%s: %s\n", plugin_name, plugin_desc);
319 }
320
321 if (idx == 0)
322 {
Greg Clayton1cb64962011-03-24 04:28:38 +0000323 result.AppendError ("no platforms are available\n");
Greg Claytonded470d2011-03-19 01:12:21 +0000324 result.SetStatus (eReturnStatusFailed);
325 }
Johnny Chenc6401792011-03-30 21:19:59 +0000326 else
327 result.SetStatus (eReturnStatusSuccessFinishResult);
Greg Claytonded470d2011-03-19 01:12:21 +0000328 return result.Succeeded();
329 }
330};
331
332//----------------------------------------------------------------------
333// "platform status"
334//----------------------------------------------------------------------
Jim Ingham5a988412012-06-08 21:56:10 +0000335class CommandObjectPlatformStatus : public CommandObjectParsed
Greg Claytonded470d2011-03-19 01:12:21 +0000336{
337public:
338 CommandObjectPlatformStatus (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +0000339 CommandObjectParsed (interpreter,
340 "platform status",
341 "Display status for the currently selected platform.",
342 NULL,
343 0)
Greg Claytonded470d2011-03-19 01:12:21 +0000344 {
345 }
346
347 virtual
348 ~CommandObjectPlatformStatus ()
349 {
350 }
351
Jim Ingham5a988412012-06-08 21:56:10 +0000352protected:
Greg Claytonded470d2011-03-19 01:12:21 +0000353 virtual bool
Jim Ingham5a988412012-06-08 21:56:10 +0000354 DoExecute (Args& args, CommandReturnObject &result)
Greg Claytonded470d2011-03-19 01:12:21 +0000355 {
356 Stream &ostrm = result.GetOutputStream();
357
Jason Molenda8c1157c2013-04-05 02:59:09 +0000358 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
359 PlatformSP platform_sp;
360 if (target)
361 {
362 platform_sp = target->GetPlatform();
363 }
364 if (!platform_sp)
365 {
366 platform_sp = m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform();
367 }
Greg Clayton95bf0fd2011-04-01 00:29:43 +0000368 if (platform_sp)
Greg Claytonded470d2011-03-19 01:12:21 +0000369 {
Greg Clayton95bf0fd2011-04-01 00:29:43 +0000370 platform_sp->GetStatus (ostrm);
Greg Claytonded470d2011-03-19 01:12:21 +0000371 result.SetStatus (eReturnStatusSuccessFinishResult);
372 }
373 else
374 {
Greg Clayton1cb64962011-03-24 04:28:38 +0000375 result.AppendError ("no platform us currently selected\n");
Greg Claytonded470d2011-03-19 01:12:21 +0000376 result.SetStatus (eReturnStatusFailed);
377 }
378 return result.Succeeded();
379 }
380};
381
Greg Claytond314e812011-03-23 00:09:55 +0000382//----------------------------------------------------------------------
383// "platform connect <connect-url>"
384//----------------------------------------------------------------------
Jim Ingham5a988412012-06-08 21:56:10 +0000385class CommandObjectPlatformConnect : public CommandObjectParsed
Greg Claytond314e812011-03-23 00:09:55 +0000386{
387public:
388 CommandObjectPlatformConnect (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +0000389 CommandObjectParsed (interpreter,
390 "platform connect",
391 "Connect a platform by name to be the currently selected platform.",
392 "platform connect <connect-url>",
393 0)
Greg Claytond314e812011-03-23 00:09:55 +0000394 {
395 }
396
397 virtual
398 ~CommandObjectPlatformConnect ()
399 {
400 }
401
Jim Ingham5a988412012-06-08 21:56:10 +0000402protected:
Greg Claytond314e812011-03-23 00:09:55 +0000403 virtual bool
Jim Ingham5a988412012-06-08 21:56:10 +0000404 DoExecute (Args& args, CommandReturnObject &result)
Greg Claytond314e812011-03-23 00:09:55 +0000405 {
406 Stream &ostrm = result.GetOutputStream();
407
Greg Clayton95bf0fd2011-04-01 00:29:43 +0000408 PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
409 if (platform_sp)
Greg Claytond314e812011-03-23 00:09:55 +0000410 {
Greg Clayton95bf0fd2011-04-01 00:29:43 +0000411 Error error (platform_sp->ConnectRemote (args));
Greg Claytond314e812011-03-23 00:09:55 +0000412 if (error.Success())
413 {
Greg Clayton95bf0fd2011-04-01 00:29:43 +0000414 platform_sp->GetStatus (ostrm);
Greg Claytond314e812011-03-23 00:09:55 +0000415 result.SetStatus (eReturnStatusSuccessFinishResult);
416 }
417 else
418 {
Greg Clayton1cb64962011-03-24 04:28:38 +0000419 result.AppendErrorWithFormat ("%s\n", error.AsCString());
Greg Claytond314e812011-03-23 00:09:55 +0000420 result.SetStatus (eReturnStatusFailed);
421 }
422 }
423 else
424 {
Daniel Maleae0f8f572013-08-26 23:57:52 +0000425 result.AppendError ("no platform is currently selected\n");
Greg Claytond314e812011-03-23 00:09:55 +0000426 result.SetStatus (eReturnStatusFailed);
427 }
428 return result.Succeeded();
429 }
Daniel Maleae0f8f572013-08-26 23:57:52 +0000430
431 virtual Options *
432 GetOptions ()
433 {
434 PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
435 OptionGroupOptions* m_platform_options = NULL;
436 if (platform_sp)
437 {
438 m_platform_options = platform_sp->GetConnectionOptions(m_interpreter);
439 if (m_platform_options != NULL && !m_platform_options->m_did_finalize)
440 m_platform_options->Finalize();
441 }
442 return m_platform_options;
443 }
444
Greg Claytond314e812011-03-23 00:09:55 +0000445};
446
447//----------------------------------------------------------------------
448// "platform disconnect"
449//----------------------------------------------------------------------
Jim Ingham5a988412012-06-08 21:56:10 +0000450class CommandObjectPlatformDisconnect : public CommandObjectParsed
Greg Claytond314e812011-03-23 00:09:55 +0000451{
452public:
453 CommandObjectPlatformDisconnect (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +0000454 CommandObjectParsed (interpreter,
455 "platform disconnect",
456 "Disconnect a platform by name to be the currently selected platform.",
457 "platform disconnect",
458 0)
Greg Claytond314e812011-03-23 00:09:55 +0000459 {
460 }
461
462 virtual
463 ~CommandObjectPlatformDisconnect ()
464 {
465 }
466
Jim Ingham5a988412012-06-08 21:56:10 +0000467protected:
Greg Claytond314e812011-03-23 00:09:55 +0000468 virtual bool
Jim Ingham5a988412012-06-08 21:56:10 +0000469 DoExecute (Args& args, CommandReturnObject &result)
Greg Claytond314e812011-03-23 00:09:55 +0000470 {
Greg Clayton95bf0fd2011-04-01 00:29:43 +0000471 PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
472 if (platform_sp)
Greg Claytond314e812011-03-23 00:09:55 +0000473 {
474 if (args.GetArgumentCount() == 0)
475 {
476 Error error;
477
Greg Clayton95bf0fd2011-04-01 00:29:43 +0000478 if (platform_sp->IsConnected())
Greg Claytond314e812011-03-23 00:09:55 +0000479 {
480 // Cache the instance name if there is one since we are
481 // about to disconnect and the name might go with it.
Greg Clayton95bf0fd2011-04-01 00:29:43 +0000482 const char *hostname_cstr = platform_sp->GetHostname();
Greg Clayton1cb64962011-03-24 04:28:38 +0000483 std::string hostname;
484 if (hostname_cstr)
485 hostname.assign (hostname_cstr);
Greg Claytond314e812011-03-23 00:09:55 +0000486
Greg Clayton95bf0fd2011-04-01 00:29:43 +0000487 error = platform_sp->DisconnectRemote ();
Greg Claytond314e812011-03-23 00:09:55 +0000488 if (error.Success())
489 {
490 Stream &ostrm = result.GetOutputStream();
Greg Clayton1cb64962011-03-24 04:28:38 +0000491 if (hostname.empty())
Greg Clayton57abc5d2013-05-10 21:47:16 +0000492 ostrm.Printf ("Disconnected from \"%s\"\n", platform_sp->GetPluginName().GetCString());
Greg Claytond314e812011-03-23 00:09:55 +0000493 else
Greg Clayton1cb64962011-03-24 04:28:38 +0000494 ostrm.Printf ("Disconnected from \"%s\"\n", hostname.c_str());
Greg Claytond314e812011-03-23 00:09:55 +0000495 result.SetStatus (eReturnStatusSuccessFinishResult);
496 }
497 else
498 {
Greg Clayton1cb64962011-03-24 04:28:38 +0000499 result.AppendErrorWithFormat ("%s", error.AsCString());
Greg Claytond314e812011-03-23 00:09:55 +0000500 result.SetStatus (eReturnStatusFailed);
501 }
502 }
503 else
504 {
505 // Not connected...
Greg Clayton57abc5d2013-05-10 21:47:16 +0000506 result.AppendErrorWithFormat ("not connected to '%s'", platform_sp->GetPluginName().GetCString());
Greg Claytond314e812011-03-23 00:09:55 +0000507 result.SetStatus (eReturnStatusFailed);
508 }
509 }
510 else
511 {
512 // Bad args
513 result.AppendError ("\"platform disconnect\" doesn't take any arguments");
514 result.SetStatus (eReturnStatusFailed);
515 }
516 }
517 else
518 {
Greg Clayton1cb64962011-03-24 04:28:38 +0000519 result.AppendError ("no platform is currently selected");
Greg Claytond314e812011-03-23 00:09:55 +0000520 result.SetStatus (eReturnStatusFailed);
521 }
522 return result.Succeeded();
523 }
524};
Daniel Maleae0f8f572013-08-26 23:57:52 +0000525
526//----------------------------------------------------------------------
527// "platform mkdir"
528//----------------------------------------------------------------------
529class CommandObjectPlatformMkDir : public CommandObjectParsed
530{
531public:
532 CommandObjectPlatformMkDir (CommandInterpreter &interpreter) :
533 CommandObjectParsed (interpreter,
Enrico Granatafff25892013-09-09 22:35:18 +0000534 "platform mkdir",
Daniel Maleae0f8f572013-08-26 23:57:52 +0000535 "Make a new directory on the remote end.",
536 NULL,
537 0),
538 m_options(interpreter)
539 {
540 }
541
542 virtual
543 ~CommandObjectPlatformMkDir ()
544 {
545 }
546
547 virtual bool
548 DoExecute (Args& args, CommandReturnObject &result)
549 {
550 PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
551 if (platform_sp)
552 {
553 std::string cmd_line;
554 args.GetCommandString(cmd_line);
555 mode_t perms;
556 const OptionPermissions* options_permissions = (OptionPermissions*)m_options.GetGroupWithOption('r');
557 if (options_permissions)
558 perms = options_permissions->m_permissions;
559 else
560 perms = 0000700 | 0000070 | 0000007;
561 uint32_t retcode = platform_sp->MakeDirectory(cmd_line,perms);
562 result.AppendMessageWithFormat("Status = %d\n",retcode);
563 result.SetStatus (eReturnStatusSuccessFinishResult);
564 }
565 else
566 {
567 result.AppendError ("no platform currently selected\n");
568 result.SetStatus (eReturnStatusFailed);
569 }
570 return result.Succeeded();
571 }
572
573 virtual Options *
574 GetOptions ()
575 {
576 if (m_options.DidFinalize() == false)
577 {
578 m_options.Append(new OptionPermissions());
579 m_options.Finalize();
580 }
581 return &m_options;
582 }
583 OptionGroupOptions m_options;
584
585};
586
587//----------------------------------------------------------------------
588// "platform fopen"
589//----------------------------------------------------------------------
590class CommandObjectPlatformFOpen : public CommandObjectParsed
591{
592public:
593 CommandObjectPlatformFOpen (CommandInterpreter &interpreter) :
594 CommandObjectParsed (interpreter,
595 "platform file open",
596 "Open a file on the remote end.",
597 NULL,
598 0),
599 m_options(interpreter)
600 {
601 }
602
603 virtual
604 ~CommandObjectPlatformFOpen ()
605 {
606 }
607
608 virtual bool
609 DoExecute (Args& args, CommandReturnObject &result)
610 {
611 PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
612 if (platform_sp)
613 {
614 Error error;
615 std::string cmd_line;
616 args.GetCommandString(cmd_line);
617 mode_t perms;
618 const OptionPermissions* options_permissions = (OptionPermissions*)m_options.GetGroupWithOption('r');
619 if (options_permissions)
620 perms = options_permissions->m_permissions;
621 else
622 perms = 0000700 | 0000070 | 0000007;
623 lldb::user_id_t fd = platform_sp->OpenFile(FileSpec(cmd_line.c_str(),false),
624 File::eOpenOptionRead | File::eOpenOptionWrite |
625 File::eOpenOptionAppend | File::eOpenOptionCanCreate,
626 perms,
627 error);
628 if (error.Success())
629 {
630 result.AppendMessageWithFormat("File Descriptor = %" PRIu64 "\n",fd);
631 result.SetStatus (eReturnStatusSuccessFinishResult);
632 }
633 else
634 {
635 result.AppendError(error.AsCString());
636 result.SetStatus (eReturnStatusFailed);
637 }
638 }
639 else
640 {
641 result.AppendError ("no platform currently selected\n");
642 result.SetStatus (eReturnStatusFailed);
643 }
644 return result.Succeeded();
645 }
646 virtual Options *
647 GetOptions ()
648 {
649 if (m_options.DidFinalize() == false)
650 {
651 m_options.Append(new OptionPermissions());
652 m_options.Finalize();
653 }
654 return &m_options;
655 }
656 OptionGroupOptions m_options;
657};
658
659//----------------------------------------------------------------------
660// "platform fclose"
661//----------------------------------------------------------------------
662class CommandObjectPlatformFClose : public CommandObjectParsed
663{
664public:
665 CommandObjectPlatformFClose (CommandInterpreter &interpreter) :
666 CommandObjectParsed (interpreter,
667 "platform file close",
668 "Close a file on the remote end.",
669 NULL,
670 0)
671 {
672 }
673
674 virtual
675 ~CommandObjectPlatformFClose ()
676 {
677 }
678
679 virtual bool
680 DoExecute (Args& args, CommandReturnObject &result)
681 {
682 PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
683 if (platform_sp)
684 {
685 std::string cmd_line;
686 args.GetCommandString(cmd_line);
687 const lldb::user_id_t fd = Args::StringToUInt64(cmd_line.c_str(), UINT64_MAX);
688 Error error;
689 bool success = platform_sp->CloseFile(fd, error);
690 if (success)
691 {
692 result.AppendMessageWithFormat("file %" PRIu64 " closed.\n", fd);
693 result.SetStatus (eReturnStatusSuccessFinishResult);
694 }
695 else
696 {
697 result.AppendError(error.AsCString());
698 result.SetStatus (eReturnStatusFailed);
699 }
700 }
701 else
702 {
703 result.AppendError ("no platform currently selected\n");
704 result.SetStatus (eReturnStatusFailed);
705 }
706 return result.Succeeded();
707 }
708};
709
710//----------------------------------------------------------------------
711// "platform fread"
712//----------------------------------------------------------------------
713class CommandObjectPlatformFRead : public CommandObjectParsed
714{
715public:
716 CommandObjectPlatformFRead (CommandInterpreter &interpreter) :
717 CommandObjectParsed (interpreter,
718 "platform file read",
719 "Read data from a file on the remote end.",
720 NULL,
721 0),
722 m_options (interpreter)
723 {
724 }
725
726 virtual
727 ~CommandObjectPlatformFRead ()
728 {
729 }
730
731 virtual bool
732 DoExecute (Args& args, CommandReturnObject &result)
733 {
734 PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
735 if (platform_sp)
736 {
737 std::string cmd_line;
738 args.GetCommandString(cmd_line);
739 const lldb::user_id_t fd = Args::StringToUInt64(cmd_line.c_str(), UINT64_MAX);
740 std::string buffer(m_options.m_count,0);
741 Error error;
742 uint32_t retcode = platform_sp->ReadFile(fd, m_options.m_offset, &buffer[0], m_options.m_count, error);
743 result.AppendMessageWithFormat("Return = %d\n",retcode);
744 result.AppendMessageWithFormat("Data = \"%s\"\n",buffer.c_str());
745 result.SetStatus (eReturnStatusSuccessFinishResult);
746 }
747 else
748 {
749 result.AppendError ("no platform currently selected\n");
750 result.SetStatus (eReturnStatusFailed);
751 }
752 return result.Succeeded();
753 }
754 virtual Options *
755 GetOptions ()
756 {
757 return &m_options;
758 }
759
760protected:
761 class CommandOptions : public Options
762 {
763 public:
764
765 CommandOptions (CommandInterpreter &interpreter) :
766 Options (interpreter)
767 {
768 }
769
770 virtual
771 ~CommandOptions ()
772 {
773 }
774
775 virtual Error
776 SetOptionValue (uint32_t option_idx, const char *option_arg)
777 {
778 Error error;
779 char short_option = (char) m_getopt_table[option_idx].val;
780 bool success = false;
781
782 switch (short_option)
783 {
784 case 'o':
785 m_offset = Args::StringToUInt32(option_arg, 0, 0, &success);
786 if (!success)
787 error.SetErrorStringWithFormat("invalid offset: '%s'", option_arg);
788 break;
789 case 'c':
790 m_count = Args::StringToUInt32(option_arg, 0, 0, &success);
791 if (!success)
792 error.SetErrorStringWithFormat("invalid offset: '%s'", option_arg);
793 break;
794
795 default:
796 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
797 break;
798 }
799
800 return error;
801 }
802
803 void
804 OptionParsingStarting ()
805 {
806 m_offset = 0;
807 m_count = 1;
808 }
809
810 const OptionDefinition*
811 GetDefinitions ()
812 {
813 return g_option_table;
814 }
815
816 // Options table: Required for subclasses of Options.
817
818 static OptionDefinition g_option_table[];
819
820 // Instance variables to hold the values for command options.
821
822 uint32_t m_offset;
823 uint32_t m_count;
824 };
825 CommandOptions m_options;
826};
827OptionDefinition
828CommandObjectPlatformFRead::CommandOptions::g_option_table[] =
829{
Virgile Belloe2607b52013-09-05 16:42:23 +0000830 { LLDB_OPT_SET_1, false, "offset" , 'o', OptionParser::eRequiredArgument, NULL, 0, eArgTypeIndex , "Offset into the file at which to start reading." },
831 { LLDB_OPT_SET_1, false, "count" , 'c', OptionParser::eRequiredArgument, NULL, 0, eArgTypeCount , "Number of bytes to read from the file." },
Daniel Maleae0f8f572013-08-26 23:57:52 +0000832 { 0 , false, NULL , 0 , 0 , NULL, 0, eArgTypeNone , NULL }
833};
834
835
836//----------------------------------------------------------------------
837// "platform fwrite"
838//----------------------------------------------------------------------
839class CommandObjectPlatformFWrite : public CommandObjectParsed
840{
841public:
842 CommandObjectPlatformFWrite (CommandInterpreter &interpreter) :
843 CommandObjectParsed (interpreter,
844 "platform file write",
845 "Write data to a file on the remote end.",
846 NULL,
847 0),
848 m_options (interpreter)
849 {
850 }
851
852 virtual
853 ~CommandObjectPlatformFWrite ()
854 {
855 }
856
857 virtual bool
858 DoExecute (Args& args, CommandReturnObject &result)
859 {
860 PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
861 if (platform_sp)
862 {
863 std::string cmd_line;
864 args.GetCommandString(cmd_line);
865 Error error;
866 const lldb::user_id_t fd = Args::StringToUInt64(cmd_line.c_str(), UINT64_MAX);
867 uint32_t retcode = platform_sp->WriteFile (fd,
868 m_options.m_offset,
869 &m_options.m_data[0],
870 m_options.m_data.size(),
871 error);
872 result.AppendMessageWithFormat("Return = %d\n",retcode);
873 result.SetStatus (eReturnStatusSuccessFinishResult);
874 }
875 else
876 {
877 result.AppendError ("no platform currently selected\n");
878 result.SetStatus (eReturnStatusFailed);
879 }
880 return result.Succeeded();
881 }
882 virtual Options *
883 GetOptions ()
884 {
885 return &m_options;
886 }
887
888protected:
889 class CommandOptions : public Options
890 {
891 public:
892
893 CommandOptions (CommandInterpreter &interpreter) :
894 Options (interpreter)
895 {
896 }
897
898 virtual
899 ~CommandOptions ()
900 {
901 }
902
903 virtual Error
904 SetOptionValue (uint32_t option_idx, const char *option_arg)
905 {
906 Error error;
907 char short_option = (char) m_getopt_table[option_idx].val;
908 bool success = false;
909
910 switch (short_option)
911 {
912 case 'o':
913 m_offset = Args::StringToUInt32(option_arg, 0, 0, &success);
914 if (!success)
915 error.SetErrorStringWithFormat("invalid offset: '%s'", option_arg);
916 break;
917 case 'd':
918 m_data.assign(option_arg);
919 break;
920
921 default:
922 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
923 break;
924 }
925
926 return error;
927 }
928
929 void
930 OptionParsingStarting ()
931 {
932 m_offset = 0;
933 m_data.clear();
934 }
935
936 const OptionDefinition*
937 GetDefinitions ()
938 {
939 return g_option_table;
940 }
941
942 // Options table: Required for subclasses of Options.
943
944 static OptionDefinition g_option_table[];
945
946 // Instance variables to hold the values for command options.
947
948 uint32_t m_offset;
949 std::string m_data;
950 };
951 CommandOptions m_options;
952};
953OptionDefinition
954CommandObjectPlatformFWrite::CommandOptions::g_option_table[] =
955{
Virgile Belloe2607b52013-09-05 16:42:23 +0000956 { LLDB_OPT_SET_1, false, "offset" , 'o', OptionParser::eRequiredArgument, NULL, 0, eArgTypeIndex , "Offset into the file at which to start reading." },
957 { LLDB_OPT_SET_1, false, "data" , 'd', OptionParser::eRequiredArgument, NULL, 0, eArgTypeValue , "Text to write to the file." },
Daniel Maleae0f8f572013-08-26 23:57:52 +0000958 { 0 , false, NULL , 0 , 0 , NULL, 0, eArgTypeNone , NULL }
959};
960
961class CommandObjectPlatformFile : public CommandObjectMultiword
962{
963public:
964 //------------------------------------------------------------------
965 // Constructors and Destructors
966 //------------------------------------------------------------------
967 CommandObjectPlatformFile (CommandInterpreter &interpreter) :
968 CommandObjectMultiword (interpreter,
969 "platform file",
970 "A set of commands to manage file access through a platform",
971 "platform file [open|close|read|write] ...")
972 {
973 LoadSubCommand ("open", CommandObjectSP (new CommandObjectPlatformFOpen (interpreter)));
974 LoadSubCommand ("close", CommandObjectSP (new CommandObjectPlatformFClose (interpreter)));
975 LoadSubCommand ("read", CommandObjectSP (new CommandObjectPlatformFRead (interpreter)));
976 LoadSubCommand ("write", CommandObjectSP (new CommandObjectPlatformFWrite (interpreter)));
977 }
978
979 virtual
980 ~CommandObjectPlatformFile ()
981 {
982 }
983
984private:
985 //------------------------------------------------------------------
986 // For CommandObjectPlatform only
987 //------------------------------------------------------------------
988 DISALLOW_COPY_AND_ASSIGN (CommandObjectPlatformFile);
989};
990
991//----------------------------------------------------------------------
992// "platform get-file remote-file-path host-file-path"
993//----------------------------------------------------------------------
994class CommandObjectPlatformGetFile : public CommandObjectParsed
995{
996public:
997 CommandObjectPlatformGetFile (CommandInterpreter &interpreter) :
998 CommandObjectParsed (interpreter,
999 "platform get-file",
1000 "Transfer a file from the remote end to the local host.",
1001 "platform get-file <remote-file-spec> <local-file-spec>",
1002 0)
1003 {
1004 SetHelpLong(
1005"Examples: \n\
1006\n\
1007 platform get-file /the/remote/file/path /the/local/file/path\n\
1008 # Transfer a file from the remote end with file path /the/remote/file/path to the local host.\n");
1009
1010 CommandArgumentEntry arg1, arg2;
1011 CommandArgumentData file_arg_remote, file_arg_host;
1012
1013 // Define the first (and only) variant of this arg.
1014 file_arg_remote.arg_type = eArgTypeFilename;
1015 file_arg_remote.arg_repetition = eArgRepeatPlain;
1016 // There is only one variant this argument could be; put it into the argument entry.
1017 arg1.push_back (file_arg_remote);
1018
1019 // Define the second (and only) variant of this arg.
1020 file_arg_host.arg_type = eArgTypeFilename;
1021 file_arg_host.arg_repetition = eArgRepeatPlain;
1022 // There is only one variant this argument could be; put it into the argument entry.
1023 arg2.push_back (file_arg_host);
1024
1025 // Push the data for the first and the second arguments into the m_arguments vector.
1026 m_arguments.push_back (arg1);
1027 m_arguments.push_back (arg2);
1028 }
1029
1030 virtual
1031 ~CommandObjectPlatformGetFile ()
1032 {
1033 }
1034
1035 virtual bool
1036 DoExecute (Args& args, CommandReturnObject &result)
1037 {
1038 // If the number of arguments is incorrect, issue an error message.
1039 if (args.GetArgumentCount() != 2)
1040 {
1041 result.GetErrorStream().Printf("error: required arguments missing; specify both the source and destination file paths\n");
1042 result.SetStatus(eReturnStatusFailed);
1043 return false;
1044 }
1045
1046 PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
1047 if (platform_sp)
1048 {
1049 const char *remote_file_path = args.GetArgumentAtIndex(0);
1050 const char *local_file_path = args.GetArgumentAtIndex(1);
1051 Error error = platform_sp->GetFile(FileSpec(remote_file_path, false),
1052 FileSpec(local_file_path, false));
1053 if (error.Success())
1054 {
1055 result.AppendMessageWithFormat("successfully get-file from %s (remote) to %s (host)\n",
1056 remote_file_path, local_file_path);
1057 result.SetStatus (eReturnStatusSuccessFinishResult);
1058 }
1059 else
1060 {
1061 result.AppendMessageWithFormat("get-file failed: %s\n", error.AsCString());
1062 result.SetStatus (eReturnStatusFailed);
1063 }
1064 }
1065 else
1066 {
1067 result.AppendError ("no platform currently selected\n");
1068 result.SetStatus (eReturnStatusFailed);
1069 }
1070 return result.Succeeded();
1071 }
1072};
1073
1074//----------------------------------------------------------------------
1075// "platform get-size remote-file-path"
1076//----------------------------------------------------------------------
1077class CommandObjectPlatformGetSize : public CommandObjectParsed
1078{
1079public:
1080 CommandObjectPlatformGetSize (CommandInterpreter &interpreter) :
1081 CommandObjectParsed (interpreter,
1082 "platform get-size",
1083 "Get the file size from the remote end.",
1084 "platform get-size <remote-file-spec>",
1085 0)
1086 {
1087 SetHelpLong(
1088"Examples: \n\
1089\n\
1090 platform get-size /the/remote/file/path\n\
1091 # Get the file size from the remote end with path /the/remote/file/path.\n");
1092
1093 CommandArgumentEntry arg1;
1094 CommandArgumentData file_arg_remote;
1095
1096 // Define the first (and only) variant of this arg.
1097 file_arg_remote.arg_type = eArgTypeFilename;
1098 file_arg_remote.arg_repetition = eArgRepeatPlain;
1099 // There is only one variant this argument could be; put it into the argument entry.
1100 arg1.push_back (file_arg_remote);
1101
1102 // Push the data for the first argument into the m_arguments vector.
1103 m_arguments.push_back (arg1);
1104 }
1105
1106 virtual
1107 ~CommandObjectPlatformGetSize ()
1108 {
1109 }
1110
1111 virtual bool
1112 DoExecute (Args& args, CommandReturnObject &result)
1113 {
1114 // If the number of arguments is incorrect, issue an error message.
1115 if (args.GetArgumentCount() != 1)
1116 {
1117 result.GetErrorStream().Printf("error: required argument missing; specify the source file path as the only argument\n");
1118 result.SetStatus(eReturnStatusFailed);
1119 return false;
1120 }
1121
1122 PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
1123 if (platform_sp)
1124 {
1125 std::string remote_file_path(args.GetArgumentAtIndex(0));
1126 user_id_t size = platform_sp->GetFileSize(FileSpec(remote_file_path.c_str(), false));
1127 if (size != UINT64_MAX)
1128 {
1129 result.AppendMessageWithFormat("File size of %s (remote): %" PRIu64 "\n", remote_file_path.c_str(), size);
1130 result.SetStatus (eReturnStatusSuccessFinishResult);
1131 }
1132 else
1133 {
1134 result.AppendMessageWithFormat("Eroor getting file size of %s (remote)\n", remote_file_path.c_str());
1135 result.SetStatus (eReturnStatusFailed);
1136 }
1137 }
1138 else
1139 {
1140 result.AppendError ("no platform currently selected\n");
1141 result.SetStatus (eReturnStatusFailed);
1142 }
1143 return result.Succeeded();
1144 }
1145};
1146
1147//----------------------------------------------------------------------
1148// "platform put-file"
1149//----------------------------------------------------------------------
1150class CommandObjectPlatformPutFile : public CommandObjectParsed
1151{
1152public:
1153 CommandObjectPlatformPutFile (CommandInterpreter &interpreter) :
1154 CommandObjectParsed (interpreter,
1155 "platform put-file",
1156 "Transfer a file from this system to the remote end.",
1157 NULL,
1158 0)
1159 {
1160 }
1161
1162 virtual
1163 ~CommandObjectPlatformPutFile ()
1164 {
1165 }
1166
1167 virtual bool
1168 DoExecute (Args& args, CommandReturnObject &result)
1169 {
1170 const char* src = args.GetArgumentAtIndex(0);
1171 const char* dst = args.GetArgumentAtIndex(1);
1172
1173 FileSpec src_fs(src, true);
1174 FileSpec dst_fs(dst, false);
1175
1176 PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
1177 if (platform_sp)
1178 {
1179 Error error (platform_sp->PutFile(src_fs, dst_fs));
1180 if (error.Success())
1181 {
1182 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1183 }
1184 else
1185 {
1186 result.AppendError (error.AsCString());
1187 result.SetStatus (eReturnStatusFailed);
1188 }
1189 }
1190 else
1191 {
1192 result.AppendError ("no platform currently selected\n");
1193 result.SetStatus (eReturnStatusFailed);
1194 }
1195 return result.Succeeded();
1196 }
1197};
1198
Greg Clayton8b82f082011-04-12 05:54:46 +00001199//----------------------------------------------------------------------
1200// "platform process launch"
1201//----------------------------------------------------------------------
Jim Ingham5a988412012-06-08 21:56:10 +00001202class CommandObjectPlatformProcessLaunch : public CommandObjectParsed
Greg Clayton8b82f082011-04-12 05:54:46 +00001203{
1204public:
1205 CommandObjectPlatformProcessLaunch (CommandInterpreter &interpreter) :
Greg Claytonf9fc6092013-01-09 19:44:40 +00001206 CommandObjectParsed (interpreter,
Jim Ingham5a988412012-06-08 21:56:10 +00001207 "platform process launch",
1208 "Launch a new process on a remote platform.",
1209 "platform process launch program",
Greg Claytonf9fc6092013-01-09 19:44:40 +00001210 eFlagRequiresTarget | eFlagTryTargetAPILock),
Greg Clayton8b82f082011-04-12 05:54:46 +00001211 m_options (interpreter)
1212 {
1213 }
1214
1215 virtual
1216 ~CommandObjectPlatformProcessLaunch ()
1217 {
1218 }
1219
Jim Ingham5a988412012-06-08 21:56:10 +00001220 virtual Options *
1221 GetOptions ()
1222 {
1223 return &m_options;
1224 }
1225
1226protected:
Greg Clayton8b82f082011-04-12 05:54:46 +00001227 virtual bool
Jim Ingham5a988412012-06-08 21:56:10 +00001228 DoExecute (Args& args, CommandReturnObject &result)
Greg Clayton8b82f082011-04-12 05:54:46 +00001229 {
Jason Molenda8c1157c2013-04-05 02:59:09 +00001230 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1231 PlatformSP platform_sp;
1232 if (target)
1233 {
1234 platform_sp = target->GetPlatform();
1235 }
1236 if (!platform_sp)
1237 {
1238 platform_sp = m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform();
1239 }
1240
Greg Clayton8b82f082011-04-12 05:54:46 +00001241 if (platform_sp)
1242 {
1243 Error error;
Greg Claytonc7bece562013-01-25 18:06:21 +00001244 const size_t argc = args.GetArgumentCount();
Greg Claytonf9fc6092013-01-09 19:44:40 +00001245 Target *target = m_exe_ctx.GetTargetPtr();
Greg Clayton1d885962011-11-08 02:43:13 +00001246 Module *exe_module = target->GetExecutableModulePointer();
1247 if (exe_module)
1248 {
1249 m_options.launch_info.GetExecutableFile () = exe_module->GetFileSpec();
1250 char exe_path[PATH_MAX];
1251 if (m_options.launch_info.GetExecutableFile ().GetPath (exe_path, sizeof(exe_path)))
1252 m_options.launch_info.GetArguments().AppendArgument (exe_path);
1253 m_options.launch_info.GetArchitecture() = exe_module->GetArchitecture();
Greg Clayton8b82f082011-04-12 05:54:46 +00001254 }
1255
1256 if (argc > 0)
1257 {
1258 if (m_options.launch_info.GetExecutableFile ())
1259 {
1260 // We already have an executable file, so we will use this
1261 // and all arguments to this function are extra arguments
1262 m_options.launch_info.GetArguments().AppendArguments (args);
1263 }
1264 else
1265 {
1266 // We don't have any file yet, so the first argument is our
1267 // executable, and the rest are program arguments
1268 const bool first_arg_is_executable = true;
Greg Clayton45392552012-10-17 22:57:12 +00001269 m_options.launch_info.SetArguments (args, first_arg_is_executable);
Greg Clayton8b82f082011-04-12 05:54:46 +00001270 }
1271 }
1272
1273 if (m_options.launch_info.GetExecutableFile ())
1274 {
1275 Debugger &debugger = m_interpreter.GetDebugger();
1276
1277 if (argc == 0)
Greg Clayton67cc0632012-08-22 17:17:09 +00001278 target->GetRunArguments(m_options.launch_info.GetArguments());
Greg Clayton8b82f082011-04-12 05:54:46 +00001279
1280 ProcessSP process_sp (platform_sp->DebugProcess (m_options.launch_info,
1281 debugger,
1282 target,
1283 debugger.GetListener(),
1284 error));
1285 if (process_sp && process_sp->IsAlive())
1286 {
1287 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1288 return true;
1289 }
1290
1291 if (error.Success())
1292 result.AppendError ("process launch failed");
1293 else
1294 result.AppendError (error.AsCString());
1295 result.SetStatus (eReturnStatusFailed);
1296 }
1297 else
1298 {
1299 result.AppendError ("'platform process launch' uses the current target file and arguments, or the executable and its arguments can be specified in this command");
1300 result.SetStatus (eReturnStatusFailed);
1301 return false;
1302 }
1303 }
1304 else
1305 {
1306 result.AppendError ("no platform is selected\n");
1307 }
1308 return result.Succeeded();
1309 }
1310
Greg Clayton8b82f082011-04-12 05:54:46 +00001311protected:
1312 ProcessLaunchCommandOptions m_options;
1313};
1314
Greg Claytond314e812011-03-23 00:09:55 +00001315
1316
Greg Clayton32e0a752011-03-30 18:16:51 +00001317//----------------------------------------------------------------------
1318// "platform process list"
1319//----------------------------------------------------------------------
Jim Ingham5a988412012-06-08 21:56:10 +00001320class CommandObjectPlatformProcessList : public CommandObjectParsed
Greg Clayton32e0a752011-03-30 18:16:51 +00001321{
1322public:
1323 CommandObjectPlatformProcessList (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +00001324 CommandObjectParsed (interpreter,
1325 "platform process list",
1326 "List processes on a remote platform by name, pid, or many other matching attributes.",
1327 "platform process list",
1328 0),
Greg Claytoneb0103f2011-04-07 22:46:35 +00001329 m_options (interpreter)
Greg Clayton32e0a752011-03-30 18:16:51 +00001330 {
1331 }
1332
1333 virtual
1334 ~CommandObjectPlatformProcessList ()
1335 {
1336 }
1337
Jim Ingham5a988412012-06-08 21:56:10 +00001338 virtual Options *
1339 GetOptions ()
1340 {
1341 return &m_options;
1342 }
1343
1344protected:
Greg Clayton32e0a752011-03-30 18:16:51 +00001345 virtual bool
Jim Ingham5a988412012-06-08 21:56:10 +00001346 DoExecute (Args& args, CommandReturnObject &result)
Greg Clayton32e0a752011-03-30 18:16:51 +00001347 {
Jason Molenda8c1157c2013-04-05 02:59:09 +00001348 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1349 PlatformSP platform_sp;
1350 if (target)
1351 {
1352 platform_sp = target->GetPlatform();
1353 }
1354 if (!platform_sp)
1355 {
1356 platform_sp = m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform();
1357 }
Greg Clayton32e0a752011-03-30 18:16:51 +00001358
1359 if (platform_sp)
1360 {
1361 Error error;
1362 if (args.GetArgumentCount() == 0)
1363 {
1364
1365 if (platform_sp)
1366 {
Greg Clayton95bf0fd2011-04-01 00:29:43 +00001367 Stream &ostrm = result.GetOutputStream();
1368
Greg Clayton32e0a752011-03-30 18:16:51 +00001369 lldb::pid_t pid = m_options.match_info.GetProcessInfo().GetProcessID();
1370 if (pid != LLDB_INVALID_PROCESS_ID)
1371 {
Greg Clayton8b82f082011-04-12 05:54:46 +00001372 ProcessInstanceInfo proc_info;
Greg Clayton32e0a752011-03-30 18:16:51 +00001373 if (platform_sp->GetProcessInfo (pid, proc_info))
1374 {
Greg Clayton8b82f082011-04-12 05:54:46 +00001375 ProcessInstanceInfo::DumpTableHeader (ostrm, platform_sp.get(), m_options.show_args, m_options.verbose);
1376 proc_info.DumpAsTableRow(ostrm, platform_sp.get(), m_options.show_args, m_options.verbose);
Greg Clayton32e0a752011-03-30 18:16:51 +00001377 result.SetStatus (eReturnStatusSuccessFinishResult);
1378 }
1379 else
1380 {
Daniel Malead01b2952012-11-29 21:49:15 +00001381 result.AppendErrorWithFormat ("no process found with pid = %" PRIu64 "\n", pid);
Greg Clayton32e0a752011-03-30 18:16:51 +00001382 result.SetStatus (eReturnStatusFailed);
1383 }
1384 }
1385 else
1386 {
Greg Clayton8b82f082011-04-12 05:54:46 +00001387 ProcessInstanceInfoList proc_infos;
Greg Clayton32e0a752011-03-30 18:16:51 +00001388 const uint32_t matches = platform_sp->FindProcesses (m_options.match_info, proc_infos);
Greg Clayton8b82f082011-04-12 05:54:46 +00001389 const char *match_desc = NULL;
1390 const char *match_name = m_options.match_info.GetProcessInfo().GetName();
1391 if (match_name && match_name[0])
1392 {
1393 switch (m_options.match_info.GetNameMatchType())
1394 {
1395 case eNameMatchIgnore: break;
1396 case eNameMatchEquals: match_desc = "matched"; break;
1397 case eNameMatchContains: match_desc = "contained"; break;
1398 case eNameMatchStartsWith: match_desc = "started with"; break;
1399 case eNameMatchEndsWith: match_desc = "ended with"; break;
1400 case eNameMatchRegularExpression: match_desc = "matched the regular expression"; break;
1401 }
1402 }
1403
Greg Clayton32e0a752011-03-30 18:16:51 +00001404 if (matches == 0)
1405 {
Greg Clayton32e0a752011-03-30 18:16:51 +00001406 if (match_desc)
1407 result.AppendErrorWithFormat ("no processes were found that %s \"%s\" on the \"%s\" platform\n",
1408 match_desc,
1409 match_name,
Greg Clayton57abc5d2013-05-10 21:47:16 +00001410 platform_sp->GetPluginName().GetCString());
Greg Clayton32e0a752011-03-30 18:16:51 +00001411 else
Greg Clayton57abc5d2013-05-10 21:47:16 +00001412 result.AppendErrorWithFormat ("no processes were found on the \"%s\" platform\n", platform_sp->GetPluginName().GetCString());
Greg Clayton32e0a752011-03-30 18:16:51 +00001413 result.SetStatus (eReturnStatusFailed);
1414 }
1415 else
1416 {
Greg Clayton8b82f082011-04-12 05:54:46 +00001417 result.AppendMessageWithFormat ("%u matching process%s found on \"%s\"",
1418 matches,
1419 matches > 1 ? "es were" : " was",
Greg Clayton57abc5d2013-05-10 21:47:16 +00001420 platform_sp->GetName().GetCString());
Greg Clayton8b82f082011-04-12 05:54:46 +00001421 if (match_desc)
1422 result.AppendMessageWithFormat (" whose name %s \"%s\"",
1423 match_desc,
1424 match_name);
1425 result.AppendMessageWithFormat ("\n");
1426 ProcessInstanceInfo::DumpTableHeader (ostrm, platform_sp.get(), m_options.show_args, m_options.verbose);
Greg Clayton32e0a752011-03-30 18:16:51 +00001427 for (uint32_t i=0; i<matches; ++i)
1428 {
Greg Clayton8b82f082011-04-12 05:54:46 +00001429 proc_infos.GetProcessInfoAtIndex(i).DumpAsTableRow(ostrm, platform_sp.get(), m_options.show_args, m_options.verbose);
Greg Clayton32e0a752011-03-30 18:16:51 +00001430 }
1431 }
1432 }
1433 }
1434 }
1435 else
1436 {
1437 result.AppendError ("invalid args: process list takes only options\n");
1438 result.SetStatus (eReturnStatusFailed);
1439 }
1440 }
1441 else
1442 {
1443 result.AppendError ("no platform is selected\n");
1444 result.SetStatus (eReturnStatusFailed);
1445 }
1446 return result.Succeeded();
1447 }
1448
Greg Clayton32e0a752011-03-30 18:16:51 +00001449 class CommandOptions : public Options
1450 {
1451 public:
1452
Greg Claytoneb0103f2011-04-07 22:46:35 +00001453 CommandOptions (CommandInterpreter &interpreter) :
1454 Options (interpreter),
Greg Clayton32e0a752011-03-30 18:16:51 +00001455 match_info ()
1456 {
1457 }
1458
1459 virtual
1460 ~CommandOptions ()
1461 {
1462 }
1463
1464 virtual Error
Greg Claytonf6b8b582011-04-13 00:18:08 +00001465 SetOptionValue (uint32_t option_idx, const char *option_arg)
Greg Clayton32e0a752011-03-30 18:16:51 +00001466 {
1467 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +00001468 const int short_option = m_getopt_table[option_idx].val;
Greg Clayton32e0a752011-03-30 18:16:51 +00001469 bool success = false;
1470
1471 switch (short_option)
1472 {
1473 case 'p':
1474 match_info.GetProcessInfo().SetProcessID (Args::StringToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success));
1475 if (!success)
1476 error.SetErrorStringWithFormat("invalid process ID string: '%s'", option_arg);
1477 break;
1478
1479 case 'P':
1480 match_info.GetProcessInfo().SetParentProcessID (Args::StringToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success));
1481 if (!success)
1482 error.SetErrorStringWithFormat("invalid parent process ID string: '%s'", option_arg);
1483 break;
1484
1485 case 'u':
Greg Clayton8b82f082011-04-12 05:54:46 +00001486 match_info.GetProcessInfo().SetUserID (Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success));
Greg Clayton32e0a752011-03-30 18:16:51 +00001487 if (!success)
1488 error.SetErrorStringWithFormat("invalid user ID string: '%s'", option_arg);
1489 break;
1490
1491 case 'U':
1492 match_info.GetProcessInfo().SetEffectiveUserID (Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success));
1493 if (!success)
1494 error.SetErrorStringWithFormat("invalid effective user ID string: '%s'", option_arg);
1495 break;
1496
1497 case 'g':
Greg Clayton8b82f082011-04-12 05:54:46 +00001498 match_info.GetProcessInfo().SetGroupID (Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success));
Greg Clayton32e0a752011-03-30 18:16:51 +00001499 if (!success)
1500 error.SetErrorStringWithFormat("invalid group ID string: '%s'", option_arg);
1501 break;
1502
1503 case 'G':
1504 match_info.GetProcessInfo().SetEffectiveGroupID (Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success));
1505 if (!success)
1506 error.SetErrorStringWithFormat("invalid effective group ID string: '%s'", option_arg);
1507 break;
1508
1509 case 'a':
Greg Claytoneb0103f2011-04-07 22:46:35 +00001510 match_info.GetProcessInfo().GetArchitecture().SetTriple (option_arg, m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform().get());
Greg Clayton32e0a752011-03-30 18:16:51 +00001511 break;
1512
1513 case 'n':
Greg Clayton144f3a92011-11-15 03:53:30 +00001514 match_info.GetProcessInfo().GetExecutableFile().SetFile (option_arg, false);
Greg Clayton8b82f082011-04-12 05:54:46 +00001515 match_info.SetNameMatchType (eNameMatchEquals);
Greg Clayton32e0a752011-03-30 18:16:51 +00001516 break;
1517
1518 case 'e':
Greg Clayton144f3a92011-11-15 03:53:30 +00001519 match_info.GetProcessInfo().GetExecutableFile().SetFile (option_arg, false);
Greg Clayton32e0a752011-03-30 18:16:51 +00001520 match_info.SetNameMatchType (eNameMatchEndsWith);
1521 break;
1522
1523 case 's':
Greg Clayton144f3a92011-11-15 03:53:30 +00001524 match_info.GetProcessInfo().GetExecutableFile().SetFile (option_arg, false);
Greg Clayton32e0a752011-03-30 18:16:51 +00001525 match_info.SetNameMatchType (eNameMatchStartsWith);
1526 break;
1527
1528 case 'c':
Greg Clayton144f3a92011-11-15 03:53:30 +00001529 match_info.GetProcessInfo().GetExecutableFile().SetFile (option_arg, false);
Greg Clayton32e0a752011-03-30 18:16:51 +00001530 match_info.SetNameMatchType (eNameMatchContains);
1531 break;
1532
1533 case 'r':
Greg Clayton144f3a92011-11-15 03:53:30 +00001534 match_info.GetProcessInfo().GetExecutableFile().SetFile (option_arg, false);
Greg Clayton32e0a752011-03-30 18:16:51 +00001535 match_info.SetNameMatchType (eNameMatchRegularExpression);
1536 break;
1537
Greg Clayton8b82f082011-04-12 05:54:46 +00001538 case 'A':
1539 show_args = true;
1540 break;
1541
1542 case 'v':
1543 verbose = true;
1544 break;
1545
Greg Clayton32e0a752011-03-30 18:16:51 +00001546 default:
1547 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1548 break;
1549 }
1550
1551 return error;
1552 }
1553
1554 void
Greg Claytonf6b8b582011-04-13 00:18:08 +00001555 OptionParsingStarting ()
Greg Clayton32e0a752011-03-30 18:16:51 +00001556 {
1557 match_info.Clear();
Greg Clayton8b82f082011-04-12 05:54:46 +00001558 show_args = false;
1559 verbose = false;
Greg Clayton32e0a752011-03-30 18:16:51 +00001560 }
1561
1562 const OptionDefinition*
1563 GetDefinitions ()
1564 {
1565 return g_option_table;
1566 }
1567
1568 // Options table: Required for subclasses of Options.
1569
1570 static OptionDefinition g_option_table[];
1571
1572 // Instance variables to hold the values for command options.
1573
Greg Clayton8b82f082011-04-12 05:54:46 +00001574 ProcessInstanceInfoMatch match_info;
1575 bool show_args;
1576 bool verbose;
Greg Clayton32e0a752011-03-30 18:16:51 +00001577 };
1578 CommandOptions m_options;
1579};
1580
1581OptionDefinition
1582CommandObjectPlatformProcessList::CommandOptions::g_option_table[] =
1583{
Virgile Belloe2607b52013-09-05 16:42:23 +00001584{ LLDB_OPT_SET_1 , false, "pid" , 'p', OptionParser::eRequiredArgument, NULL, 0, eArgTypePid , "List the process info for a specific process ID." },
1585{ LLDB_OPT_SET_2 , true , "name" , 'n', OptionParser::eRequiredArgument, NULL, 0, eArgTypeProcessName , "Find processes with executable basenames that match a string." },
1586{ LLDB_OPT_SET_3 , true , "ends-with" , 'e', OptionParser::eRequiredArgument, NULL, 0, eArgTypeProcessName , "Find processes with executable basenames that end with a string." },
1587{ LLDB_OPT_SET_4 , true , "starts-with", 's', OptionParser::eRequiredArgument, NULL, 0, eArgTypeProcessName , "Find processes with executable basenames that start with a string." },
1588{ LLDB_OPT_SET_5 , true , "contains" , 'c', OptionParser::eRequiredArgument, NULL, 0, eArgTypeProcessName , "Find processes with executable basenames that contain a string." },
1589{ LLDB_OPT_SET_6 , true , "regex" , 'r', OptionParser::eRequiredArgument, NULL, 0, eArgTypeRegularExpression, "Find processes with executable basenames that match a regular expression." },
1590{ LLDB_OPT_SET_FROM_TO(2, 6), false, "parent" , 'P', OptionParser::eRequiredArgument, NULL, 0, eArgTypePid , "Find processes that have a matching parent process ID." },
1591{ LLDB_OPT_SET_FROM_TO(2, 6), false, "uid" , 'u', OptionParser::eRequiredArgument, NULL, 0, eArgTypeUnsignedInteger , "Find processes that have a matching user ID." },
1592{ LLDB_OPT_SET_FROM_TO(2, 6), false, "euid" , 'U', OptionParser::eRequiredArgument, NULL, 0, eArgTypeUnsignedInteger , "Find processes that have a matching effective user ID." },
1593{ LLDB_OPT_SET_FROM_TO(2, 6), false, "gid" , 'g', OptionParser::eRequiredArgument, NULL, 0, eArgTypeUnsignedInteger , "Find processes that have a matching group ID." },
1594{ LLDB_OPT_SET_FROM_TO(2, 6), false, "egid" , 'G', OptionParser::eRequiredArgument, NULL, 0, eArgTypeUnsignedInteger , "Find processes that have a matching effective group ID." },
1595{ LLDB_OPT_SET_FROM_TO(2, 6), false, "arch" , 'a', OptionParser::eRequiredArgument, NULL, 0, eArgTypeArchitecture , "Find processes that have a matching architecture." },
1596{ LLDB_OPT_SET_FROM_TO(1, 6), false, "show-args" , 'A', OptionParser::eNoArgument , NULL, 0, eArgTypeNone , "Show process arguments instead of the process executable basename." },
1597{ LLDB_OPT_SET_FROM_TO(1, 6), false, "verbose" , 'v', OptionParser::eNoArgument , NULL, 0, eArgTypeNone , "Enable verbose output." },
Greg Claytonc7fef742013-04-18 20:17:32 +00001598{ 0 , false, NULL , 0 , 0 , NULL, 0, eArgTypeNone , NULL }
Greg Clayton32e0a752011-03-30 18:16:51 +00001599};
1600
Greg Clayton95bf0fd2011-04-01 00:29:43 +00001601//----------------------------------------------------------------------
1602// "platform process info"
1603//----------------------------------------------------------------------
Jim Ingham5a988412012-06-08 21:56:10 +00001604class CommandObjectPlatformProcessInfo : public CommandObjectParsed
Greg Clayton95bf0fd2011-04-01 00:29:43 +00001605{
1606public:
1607 CommandObjectPlatformProcessInfo (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +00001608 CommandObjectParsed (interpreter,
1609 "platform process info",
1610 "Get detailed information for one or more process by process ID.",
1611 "platform process info <pid> [<pid> <pid> ...]",
1612 0)
Greg Clayton95bf0fd2011-04-01 00:29:43 +00001613 {
1614 CommandArgumentEntry arg;
1615 CommandArgumentData pid_args;
1616
1617 // Define the first (and only) variant of this arg.
1618 pid_args.arg_type = eArgTypePid;
1619 pid_args.arg_repetition = eArgRepeatStar;
1620
1621 // There is only one variant this argument could be; put it into the argument entry.
1622 arg.push_back (pid_args);
1623
1624 // Push the data for the first argument into the m_arguments vector.
1625 m_arguments.push_back (arg);
1626 }
1627
1628 virtual
1629 ~CommandObjectPlatformProcessInfo ()
1630 {
1631 }
1632
Jim Ingham5a988412012-06-08 21:56:10 +00001633protected:
Greg Clayton95bf0fd2011-04-01 00:29:43 +00001634 virtual bool
Jim Ingham5a988412012-06-08 21:56:10 +00001635 DoExecute (Args& args, CommandReturnObject &result)
Greg Clayton95bf0fd2011-04-01 00:29:43 +00001636 {
Jason Molenda8c1157c2013-04-05 02:59:09 +00001637 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1638 PlatformSP platform_sp;
1639 if (target)
1640 {
1641 platform_sp = target->GetPlatform();
1642 }
1643 if (!platform_sp)
1644 {
1645 platform_sp = m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform();
1646 }
1647
Greg Clayton95bf0fd2011-04-01 00:29:43 +00001648 if (platform_sp)
1649 {
1650 const size_t argc = args.GetArgumentCount();
1651 if (argc > 0)
1652 {
1653 Error error;
1654
1655 if (platform_sp->IsConnected())
1656 {
1657 Stream &ostrm = result.GetOutputStream();
1658 bool success;
1659 for (size_t i=0; i<argc; ++ i)
1660 {
1661 const char *arg = args.GetArgumentAtIndex(i);
1662 lldb::pid_t pid = Args::StringToUInt32 (arg, LLDB_INVALID_PROCESS_ID, 0, &success);
1663 if (success)
1664 {
Greg Clayton8b82f082011-04-12 05:54:46 +00001665 ProcessInstanceInfo proc_info;
Greg Clayton95bf0fd2011-04-01 00:29:43 +00001666 if (platform_sp->GetProcessInfo (pid, proc_info))
1667 {
Daniel Malead01b2952012-11-29 21:49:15 +00001668 ostrm.Printf ("Process information for process %" PRIu64 ":\n", pid);
Greg Clayton95bf0fd2011-04-01 00:29:43 +00001669 proc_info.Dump (ostrm, platform_sp.get());
1670 }
1671 else
1672 {
Daniel Malead01b2952012-11-29 21:49:15 +00001673 ostrm.Printf ("error: no process information is available for process %" PRIu64 "\n", pid);
Greg Clayton95bf0fd2011-04-01 00:29:43 +00001674 }
1675 ostrm.EOL();
1676 }
1677 else
1678 {
1679 result.AppendErrorWithFormat ("invalid process ID argument '%s'", arg);
1680 result.SetStatus (eReturnStatusFailed);
1681 break;
1682 }
1683 }
1684 }
1685 else
1686 {
1687 // Not connected...
Greg Clayton57abc5d2013-05-10 21:47:16 +00001688 result.AppendErrorWithFormat ("not connected to '%s'", platform_sp->GetPluginName().GetCString());
Greg Clayton95bf0fd2011-04-01 00:29:43 +00001689 result.SetStatus (eReturnStatusFailed);
1690 }
1691 }
1692 else
1693 {
Johnny Chen3173e272011-05-09 19:05:46 +00001694 // No args
1695 result.AppendError ("one or more process id(s) must be specified");
Greg Clayton95bf0fd2011-04-01 00:29:43 +00001696 result.SetStatus (eReturnStatusFailed);
1697 }
1698 }
1699 else
1700 {
1701 result.AppendError ("no platform is currently selected");
1702 result.SetStatus (eReturnStatusFailed);
1703 }
1704 return result.Succeeded();
1705 }
1706};
1707
Daniel Maleae0f8f572013-08-26 23:57:52 +00001708class CommandObjectPlatformProcessAttach : public CommandObjectParsed
1709{
1710public:
1711
1712 class CommandOptions : public Options
1713 {
1714 public:
1715
1716 CommandOptions (CommandInterpreter &interpreter) :
1717 Options(interpreter)
1718 {
1719 // Keep default values of all options in one place: OptionParsingStarting ()
1720 OptionParsingStarting ();
1721 }
1722
1723 ~CommandOptions ()
1724 {
1725 }
1726
1727 Error
1728 SetOptionValue (uint32_t option_idx, const char *option_arg)
1729 {
1730 Error error;
1731 char short_option = (char) m_getopt_table[option_idx].val;
1732 bool success = false;
1733 switch (short_option)
1734 {
1735 case 'p':
1736 {
1737 lldb::pid_t pid = Args::StringToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success);
1738 if (!success || pid == LLDB_INVALID_PROCESS_ID)
1739 {
1740 error.SetErrorStringWithFormat("invalid process ID '%s'", option_arg);
1741 }
1742 else
1743 {
1744 attach_info.SetProcessID (pid);
1745 }
1746 }
1747 break;
1748
1749 case 'P':
1750 attach_info.SetProcessPluginName (option_arg);
1751 break;
1752
1753 case 'n':
1754 attach_info.GetExecutableFile().SetFile(option_arg, false);
1755 break;
1756
1757 case 'w':
1758 attach_info.SetWaitForLaunch(true);
1759 break;
1760
1761 default:
1762 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
1763 break;
1764 }
1765 return error;
1766 }
1767
1768 void
1769 OptionParsingStarting ()
1770 {
1771 attach_info.Clear();
1772 }
1773
1774 const OptionDefinition*
1775 GetDefinitions ()
1776 {
1777 return g_option_table;
1778 }
1779
1780 virtual bool
1781 HandleOptionArgumentCompletion (Args &input,
1782 int cursor_index,
1783 int char_pos,
1784 OptionElementVector &opt_element_vector,
1785 int opt_element_index,
1786 int match_start_point,
1787 int max_return_elements,
1788 bool &word_complete,
1789 StringList &matches)
1790 {
1791 int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos;
1792 int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index;
1793
1794 // We are only completing the name option for now...
1795
1796 const OptionDefinition *opt_defs = GetDefinitions();
1797 if (opt_defs[opt_defs_index].short_option == 'n')
1798 {
1799 // Are we in the name?
1800
1801 // Look to see if there is a -P argument provided, and if so use that plugin, otherwise
1802 // use the default plugin.
1803
1804 const char *partial_name = NULL;
1805 partial_name = input.GetArgumentAtIndex(opt_arg_pos);
1806
1807 PlatformSP platform_sp (m_interpreter.GetPlatform (true));
1808 if (platform_sp)
1809 {
1810 ProcessInstanceInfoList process_infos;
1811 ProcessInstanceInfoMatch match_info;
1812 if (partial_name)
1813 {
1814 match_info.GetProcessInfo().GetExecutableFile().SetFile(partial_name, false);
1815 match_info.SetNameMatchType(eNameMatchStartsWith);
1816 }
1817 platform_sp->FindProcesses (match_info, process_infos);
1818 const uint32_t num_matches = process_infos.GetSize();
1819 if (num_matches > 0)
1820 {
1821 for (uint32_t i=0; i<num_matches; ++i)
1822 {
1823 matches.AppendString (process_infos.GetProcessNameAtIndex(i),
1824 process_infos.GetProcessNameLengthAtIndex(i));
1825 }
1826 }
1827 }
1828 }
1829
1830 return false;
1831 }
1832
1833 // Options table: Required for subclasses of Options.
1834
1835 static OptionDefinition g_option_table[];
1836
1837 // Instance variables to hold the values for command options.
1838
1839 ProcessAttachInfo attach_info;
1840 };
1841
1842 CommandObjectPlatformProcessAttach (CommandInterpreter &interpreter) :
1843 CommandObjectParsed (interpreter,
1844 "platform process attach",
1845 "Attach to a process.",
1846 "platform process attach <cmd-options>"),
1847 m_options (interpreter)
1848 {
1849 }
1850
1851 ~CommandObjectPlatformProcessAttach ()
1852 {
1853 }
1854
1855 bool
1856 DoExecute (Args& command,
1857 CommandReturnObject &result)
1858 {
1859 PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
1860 if (platform_sp)
1861 {
1862 Error err;
1863 ProcessSP remote_process_sp =
1864 platform_sp->Attach(m_options.attach_info, m_interpreter.GetDebugger(), NULL, m_interpreter.GetDebugger().GetListener(), err);
1865 if (err.Fail())
1866 {
1867 result.AppendError(err.AsCString());
1868 result.SetStatus (eReturnStatusFailed);
1869 }
1870 else if (remote_process_sp.get() == NULL)
1871 {
1872 result.AppendError("could not attach: unknown reason");
1873 result.SetStatus (eReturnStatusFailed);
1874 }
1875 else
1876 result.SetStatus (eReturnStatusSuccessFinishResult);
1877 }
1878 else
1879 {
1880 result.AppendError ("no platform is currently selected");
1881 result.SetStatus (eReturnStatusFailed);
1882 }
1883 return result.Succeeded();
1884 }
1885
1886 Options *
1887 GetOptions ()
1888 {
1889 return &m_options;
1890 }
1891
1892protected:
1893
1894 CommandOptions m_options;
1895};
Greg Clayton95bf0fd2011-04-01 00:29:43 +00001896
1897
Daniel Maleae0f8f572013-08-26 23:57:52 +00001898OptionDefinition
1899CommandObjectPlatformProcessAttach::CommandOptions::g_option_table[] =
1900{
Virgile Belloe2607b52013-09-05 16:42:23 +00001901 { LLDB_OPT_SET_ALL, false, "plugin", 'P', OptionParser::eRequiredArgument, NULL, 0, eArgTypePlugin, "Name of the process plugin you want to use."},
1902 { LLDB_OPT_SET_1, false, "pid", 'p', OptionParser::eRequiredArgument, NULL, 0, eArgTypePid, "The process ID of an existing process to attach to."},
1903 { LLDB_OPT_SET_2, false, "name", 'n', OptionParser::eRequiredArgument, NULL, 0, eArgTypeProcessName, "The name of the process to attach to."},
1904 { LLDB_OPT_SET_2, false, "waitfor",'w', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Wait for the the process with <process-name> to launch."},
Daniel Maleae0f8f572013-08-26 23:57:52 +00001905 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1906};
1907
Greg Clayton95bf0fd2011-04-01 00:29:43 +00001908
Greg Clayton32e0a752011-03-30 18:16:51 +00001909class CommandObjectPlatformProcess : public CommandObjectMultiword
1910{
1911public:
1912 //------------------------------------------------------------------
1913 // Constructors and Destructors
1914 //------------------------------------------------------------------
1915 CommandObjectPlatformProcess (CommandInterpreter &interpreter) :
1916 CommandObjectMultiword (interpreter,
1917 "platform process",
1918 "A set of commands to query, launch and attach to platform processes",
1919 "platform process [attach|launch|list] ...")
1920 {
Daniel Maleae0f8f572013-08-26 23:57:52 +00001921 LoadSubCommand ("attach", CommandObjectSP (new CommandObjectPlatformProcessAttach (interpreter)));
Greg Clayton8b82f082011-04-12 05:54:46 +00001922 LoadSubCommand ("launch", CommandObjectSP (new CommandObjectPlatformProcessLaunch (interpreter)));
Greg Clayton95bf0fd2011-04-01 00:29:43 +00001923 LoadSubCommand ("info" , CommandObjectSP (new CommandObjectPlatformProcessInfo (interpreter)));
Greg Clayton32e0a752011-03-30 18:16:51 +00001924 LoadSubCommand ("list" , CommandObjectSP (new CommandObjectPlatformProcessList (interpreter)));
1925
1926 }
1927
1928 virtual
1929 ~CommandObjectPlatformProcess ()
1930 {
1931 }
1932
1933private:
1934 //------------------------------------------------------------------
1935 // For CommandObjectPlatform only
1936 //------------------------------------------------------------------
1937 DISALLOW_COPY_AND_ASSIGN (CommandObjectPlatformProcess);
1938};
Greg Claytonded470d2011-03-19 01:12:21 +00001939
Daniel Maleae0f8f572013-08-26 23:57:52 +00001940//----------------------------------------------------------------------
1941// "platform shell"
1942//----------------------------------------------------------------------
Jim Ingham5a988412012-06-08 21:56:10 +00001943class CommandObjectPlatformShell : public CommandObjectRaw
Greg Claytond1cf11a2012-04-14 01:42:46 +00001944{
1945public:
Daniel Maleae0f8f572013-08-26 23:57:52 +00001946
1947 class CommandOptions : public Options
1948 {
1949 public:
1950
1951 CommandOptions (CommandInterpreter &interpreter) :
Daniel Maleabb247fb2013-08-27 21:01:01 +00001952 Options(interpreter),
1953 timeout(10)
Daniel Maleae0f8f572013-08-26 23:57:52 +00001954 {
1955 }
1956
1957 virtual
1958 ~CommandOptions ()
1959 {
1960 }
1961
1962 virtual uint32_t
1963 GetNumDefinitions ()
1964 {
1965 return 1;
1966 }
1967
1968 virtual const OptionDefinition*
1969 GetDefinitions ()
1970 {
1971 return g_option_table;
1972 }
1973
1974 virtual Error
1975 SetOptionValue (uint32_t option_idx,
1976 const char *option_value)
1977 {
1978 Error error;
1979
1980 const char short_option = (char) g_option_table[option_idx].short_option;
1981
1982 switch (short_option)
1983 {
1984 case 't':
1985 {
1986 bool success;
1987 timeout = Args::StringToUInt32(option_value, 10, 10, &success);
1988 if (!success)
1989 error.SetErrorStringWithFormat("could not convert \"%s\" to a numeric value.", option_value);
1990 break;
1991 }
1992 default:
1993 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
1994 break;
1995 }
1996
1997 return error;
1998 }
1999
2000 virtual void
2001 OptionParsingStarting ()
2002 {
Daniel Maleae0f8f572013-08-26 23:57:52 +00002003 }
2004
2005 // Options table: Required for subclasses of Options.
2006
2007 static OptionDefinition g_option_table[];
2008 uint32_t timeout;
2009 };
2010
Greg Claytond1cf11a2012-04-14 01:42:46 +00002011 CommandObjectPlatformShell (CommandInterpreter &interpreter) :
Daniel Maleae0f8f572013-08-26 23:57:52 +00002012 CommandObjectRaw (interpreter,
2013 "platform shell",
2014 "Run a shell command on a the selected platform.",
2015 "platform shell <shell-command>",
2016 0),
2017 m_options(interpreter)
Greg Claytond1cf11a2012-04-14 01:42:46 +00002018 {
2019 }
2020
2021 virtual
2022 ~CommandObjectPlatformShell ()
2023 {
2024 }
2025
Enrico Granatafff25892013-09-09 22:35:18 +00002026 virtual
2027 Options *
2028 GetOptions ()
2029 {
2030 return &m_options;
2031 }
2032
Greg Claytond1cf11a2012-04-14 01:42:46 +00002033 virtual bool
Jim Ingham5a988412012-06-08 21:56:10 +00002034 DoExecute (const char *raw_command_line, CommandReturnObject &result)
Greg Claytond1cf11a2012-04-14 01:42:46 +00002035 {
Enrico Granatafff25892013-09-09 22:35:18 +00002036 m_options.NotifyOptionParsingStarting();
2037
Daniel Maleae0f8f572013-08-26 23:57:52 +00002038 const char* expr = NULL;
2039
2040 // Print out an usage syntax on an empty command line.
2041 if (raw_command_line[0] == '\0')
Greg Claytond1cf11a2012-04-14 01:42:46 +00002042 {
Daniel Maleae0f8f572013-08-26 23:57:52 +00002043 result.GetOutputStream().Printf("%s\n", this->GetSyntax());
2044 return true;
2045 }
2046
2047 if (raw_command_line[0] == '-')
2048 {
2049 // We have some options and these options MUST end with --.
2050 const char *end_options = NULL;
2051 const char *s = raw_command_line;
2052 while (s && s[0])
Greg Claytond1cf11a2012-04-14 01:42:46 +00002053 {
Daniel Maleae0f8f572013-08-26 23:57:52 +00002054 end_options = ::strstr (s, "--");
2055 if (end_options)
2056 {
2057 end_options += 2; // Get past the "--"
2058 if (::isspace (end_options[0]))
2059 {
2060 expr = end_options;
2061 while (::isspace (*expr))
2062 ++expr;
2063 break;
2064 }
2065 }
2066 s = end_options;
Greg Claytond1cf11a2012-04-14 01:42:46 +00002067 }
Daniel Maleae0f8f572013-08-26 23:57:52 +00002068
2069 if (end_options)
2070 {
2071 Args args (raw_command_line, end_options - raw_command_line);
2072 if (!ParseOptions (args, result))
2073 return false;
2074 }
2075 }
2076
2077 if (expr == NULL)
2078 expr = raw_command_line;
2079
2080 PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
2081 Error error;
2082 if (platform_sp)
2083 {
2084 const char *working_dir = NULL;
2085 std::string output;
2086 int status = -1;
2087 int signo = -1;
2088 error = (platform_sp->RunShellCommand (expr, working_dir, &status, &signo, &output, m_options.timeout));
2089 if (!output.empty())
2090 result.GetOutputStream().PutCString(output.c_str());
2091 if (status > 0)
2092 {
2093 if (signo > 0)
2094 {
2095 const char *signo_cstr = Host::GetSignalAsCString(signo);
2096 if (signo_cstr)
2097 result.GetOutputStream().Printf("error: command returned with status %i and signal %s\n", status, signo_cstr);
2098 else
2099 result.GetOutputStream().Printf("error: command returned with status %i and signal %i\n", status, signo);
2100 }
2101 else
2102 result.GetOutputStream().Printf("error: command returned with status %i\n", status);
2103 }
2104 }
2105 else
2106 {
2107 result.GetOutputStream().Printf("error: cannot run remote shell commands without a platform\n");
2108 error.SetErrorString("error: cannot run remote shell commands without a platform");
Greg Claytond1cf11a2012-04-14 01:42:46 +00002109 }
2110
2111 if (error.Fail())
2112 {
2113 result.AppendError(error.AsCString());
2114 result.SetStatus (eReturnStatusFailed);
2115 }
2116 else
2117 {
2118 result.SetStatus (eReturnStatusSuccessFinishResult);
2119 }
2120 return true;
2121 }
Daniel Maleae0f8f572013-08-26 23:57:52 +00002122 CommandOptions m_options;
2123};
2124
2125OptionDefinition
2126CommandObjectPlatformShell::CommandOptions::g_option_table[] =
2127{
Virgile Belloe2607b52013-09-05 16:42:23 +00002128 { LLDB_OPT_SET_ALL, false, "timeout", 't', OptionParser::eRequiredArgument, NULL, 0, eArgTypeValue, "Seconds to wait for the remote host to finish running the command."},
Enrico Granatafff25892013-09-09 22:35:18 +00002129 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Daniel Maleae0f8f572013-08-26 23:57:52 +00002130};
2131
2132struct RecurseCopyBaton
2133{
2134 const std::string& destination;
2135 const PlatformSP& platform_sp;
2136 Error error;
2137};
2138
2139
2140static FileSpec::EnumerateDirectoryResult
2141RecurseCopy_Callback (void *baton,
2142 FileSpec::FileType file_type,
2143 const FileSpec &spec)
2144{
2145 RecurseCopyBaton* rc_baton = (RecurseCopyBaton*)baton;
2146 switch (file_type)
2147 {
2148 case FileSpec::eFileTypePipe:
2149 case FileSpec::eFileTypeSocket:
2150 // we have no way to copy pipes and sockets - ignore them and continue
2151 return FileSpec::eEnumerateDirectoryResultNext;
2152 break;
2153
2154 case FileSpec::eFileTypeSymbolicLink:
2155 // what to do for symlinks?
2156 return FileSpec::eEnumerateDirectoryResultNext;
2157 break;
2158
2159 case FileSpec::eFileTypeDirectory:
2160 {
2161 // make the new directory and get in there
2162 FileSpec new_directory(rc_baton->destination.c_str(),false);
2163 new_directory.AppendPathComponent(spec.GetLastPathComponent());
2164 uint32_t errcode = rc_baton->platform_sp->MakeDirectory(new_directory, 0777);
2165 std::string new_directory_path (new_directory.GetPath());
2166 if (errcode != 0)
2167 {
2168 rc_baton->error.SetErrorStringWithFormat("unable to setup directory %s on remote end",new_directory_path.c_str());
2169 return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out
2170 }
2171
2172 // now recurse
2173 std::string local_path (spec.GetPath());
2174 RecurseCopyBaton rc_baton2 = { new_directory_path, rc_baton->platform_sp, Error() };
2175 FileSpec::EnumerateDirectory(local_path.c_str(), true, true, true, RecurseCopy_Callback, &rc_baton2);
2176 if (rc_baton2.error.Fail())
2177 {
2178 rc_baton->error.SetErrorString(rc_baton2.error.AsCString());
2179 return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out
2180 }
2181 return FileSpec::eEnumerateDirectoryResultNext;
2182 }
2183 break;
2184
2185 case FileSpec::eFileTypeRegular:
2186 {
2187 // copy the file and keep going
2188 std::string dest(rc_baton->destination);
2189 dest.append(spec.GetFilename().GetCString());
2190 Error err = rc_baton->platform_sp->PutFile(spec, FileSpec(dest.c_str(), false));
2191 if (err.Fail())
2192 {
2193 rc_baton->error.SetErrorString(err.AsCString());
2194 return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out
2195 }
2196 return FileSpec::eEnumerateDirectoryResultNext;
2197 }
2198 break;
2199
2200 case FileSpec::eFileTypeInvalid:
2201 case FileSpec::eFileTypeOther:
2202 case FileSpec::eFileTypeUnknown:
Daniel Maleae0f8f572013-08-26 23:57:52 +00002203 rc_baton->error.SetErrorStringWithFormat("invalid file detected during copy: %s/%s", spec.GetDirectory().GetCString(), spec.GetFilename().GetCString());
2204 return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out
2205 break;
2206 }
2207}
2208
2209//----------------------------------------------------------------------
2210// "platform install" - install a target to a remote end
2211//----------------------------------------------------------------------
2212class CommandObjectPlatformInstall : public CommandObjectParsed
2213{
2214public:
2215 CommandObjectPlatformInstall (CommandInterpreter &interpreter) :
2216 CommandObjectParsed (interpreter,
2217 "platform target-install",
2218 "Install a target (bundle or executable file) to the remote end.",
2219 "platform target-install <local-thing> <remote-sandbox>",
2220 0)
2221 {
2222 }
2223
2224 virtual
2225 ~CommandObjectPlatformInstall ()
2226 {
2227 }
2228
2229 virtual bool
2230 DoExecute (Args& args, CommandReturnObject &result)
2231 {
2232 if (args.GetArgumentCount() != 2)
2233 {
2234 result.AppendError("platform target-install takes two arguments");
2235 result.SetStatus(eReturnStatusFailed);
2236 return false;
2237 }
2238 // TODO: move the bulk of this code over to the platform itself
2239 std::string local_thing(args.GetArgumentAtIndex(0));
2240 std::string remote_sandbox(args.GetArgumentAtIndex(1));
2241 FileSpec source(local_thing.c_str(), true);
2242 if (source.Exists() == false)
2243 {
2244 result.AppendError("source location does not exist or is not accessible");
2245 result.SetStatus(eReturnStatusFailed);
2246 return false;
2247 }
2248 PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
2249 if (!platform_sp)
2250 {
2251 result.AppendError ("no platform currently selected");
2252 result.SetStatus (eReturnStatusFailed);
2253 return false;
2254 }
2255 FileSpec::FileType source_type(source.GetFileType());
2256 if (source_type == FileSpec::eFileTypeDirectory)
2257 {
2258 if (platform_sp->GetSupportsRSync())
2259 {
2260 FileSpec remote_folder(remote_sandbox.c_str(), false);
2261 Error rsync_err = platform_sp->PutFile(source, remote_folder);
2262 if (rsync_err.Success())
2263 {
2264 result.SetStatus(eReturnStatusSuccessFinishResult);
2265 return result.Succeeded();
2266 }
2267 }
2268 FileSpec remote_folder(remote_sandbox.c_str(), false);
2269 remote_folder.AppendPathComponent(source.GetLastPathComponent());
2270 // TODO: default permissions are bad
2271 uint32_t errcode = platform_sp->MakeDirectory(remote_folder, 0777);
2272 if (errcode != 0)
2273 {
2274 result.AppendError("unable to setup target directory on remote end");
2275 result.SetStatus(eReturnStatusSuccessFinishNoResult);
2276 return result.Succeeded();
2277 }
2278 // now recurse
2279 std::string remote_folder_path (remote_folder.GetPath());
2280 Error err = RecurseCopy(source,remote_folder_path,platform_sp);
2281 if (err.Fail())
2282 {
2283 result.AppendError(err.AsCString());
2284 result.SetStatus(eReturnStatusFailed);
2285 }
2286 else
2287 result.SetStatus(eReturnStatusSuccessFinishResult);
2288 return result.Succeeded();
2289 }
2290 else if (source_type == FileSpec::eFileTypeRegular)
2291 {
2292 // just a plain file - push it to remote and be done
2293 remote_sandbox.append(source.GetFilename().GetCString());
2294 FileSpec destination(remote_sandbox.c_str(),false);
2295 Error err = platform_sp->PutFile(source, destination);
2296 if (err.Success())
2297 result.SetStatus(eReturnStatusSuccessFinishResult);
2298 else
2299 {
2300 result.AppendError(err.AsCString());
2301 result.SetStatus(eReturnStatusFailed);
2302 }
2303 return result.Succeeded();
2304 }
2305 else
2306 {
2307 result.AppendError("source is not a known type of file");
2308 result.SetStatus(eReturnStatusFailed);
2309 return result.Succeeded();
2310 }
2311 }
2312private:
2313
2314 Error
2315 RecurseCopy (const FileSpec& source,
2316 const std::string& destination,
2317 const PlatformSP& platform_sp)
2318 {
2319 std::string source_path (source.GetPath());
2320 RecurseCopyBaton baton = { destination, platform_sp, Error() };
2321 FileSpec::EnumerateDirectory(source_path.c_str(), true, true, true, RecurseCopy_Callback, &baton);
2322 return baton.error;
2323 }
Greg Claytond1cf11a2012-04-14 01:42:46 +00002324};
2325
Greg Claytonded470d2011-03-19 01:12:21 +00002326//----------------------------------------------------------------------
2327// CommandObjectPlatform constructor
2328//----------------------------------------------------------------------
2329CommandObjectPlatform::CommandObjectPlatform(CommandInterpreter &interpreter) :
2330 CommandObjectMultiword (interpreter,
2331 "platform",
2332 "A set of commands to manage and create platforms.",
Greg Claytonf6b8b582011-04-13 00:18:08 +00002333 "platform [connect|disconnect|info|list|status|select] ...")
Greg Claytonded470d2011-03-19 01:12:21 +00002334{
Greg Claytonded470d2011-03-19 01:12:21 +00002335 LoadSubCommand ("select", CommandObjectSP (new CommandObjectPlatformSelect (interpreter)));
Greg Claytonf6b8b582011-04-13 00:18:08 +00002336 LoadSubCommand ("list" , CommandObjectSP (new CommandObjectPlatformList (interpreter)));
Greg Claytonded470d2011-03-19 01:12:21 +00002337 LoadSubCommand ("status", CommandObjectSP (new CommandObjectPlatformStatus (interpreter)));
Greg Claytond314e812011-03-23 00:09:55 +00002338 LoadSubCommand ("connect", CommandObjectSP (new CommandObjectPlatformConnect (interpreter)));
2339 LoadSubCommand ("disconnect", CommandObjectSP (new CommandObjectPlatformDisconnect (interpreter)));
Daniel Maleae0f8f572013-08-26 23:57:52 +00002340#ifdef LLDB_CONFIGURATION_DEBUG
2341 LoadSubCommand ("mkdir", CommandObjectSP (new CommandObjectPlatformMkDir (interpreter)));
2342 LoadSubCommand ("file", CommandObjectSP (new CommandObjectPlatformFile (interpreter)));
2343 LoadSubCommand ("get-file", CommandObjectSP (new CommandObjectPlatformGetFile (interpreter)));
2344 LoadSubCommand ("get-size", CommandObjectSP (new CommandObjectPlatformGetSize (interpreter)));
2345 LoadSubCommand ("put-file", CommandObjectSP (new CommandObjectPlatformPutFile (interpreter)));
2346#endif
Greg Clayton32e0a752011-03-30 18:16:51 +00002347 LoadSubCommand ("process", CommandObjectSP (new CommandObjectPlatformProcess (interpreter)));
Greg Claytond1cf11a2012-04-14 01:42:46 +00002348 LoadSubCommand ("shell", CommandObjectSP (new CommandObjectPlatformShell (interpreter)));
Daniel Maleae0f8f572013-08-26 23:57:52 +00002349 LoadSubCommand ("target-install", CommandObjectSP (new CommandObjectPlatformInstall (interpreter)));
Greg Claytonded470d2011-03-19 01:12:21 +00002350}
2351
2352
2353//----------------------------------------------------------------------
2354// Destructor
2355//----------------------------------------------------------------------
2356CommandObjectPlatform::~CommandObjectPlatform()
2357{
2358}