blob: 46e913587ef97dbbb27dc1c430fe34f2a6a1fba8 [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- CommandObjectMemory.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
10#include "CommandObjectMemory.h"
11
12// C Includes
13// C++ Includes
14// Other libraries and framework includes
15// Project includes
Chris Lattner24943d22010-06-08 16:52:24 +000016#include "lldb/Core/DataBufferHeap.h"
17#include "lldb/Core/DataExtractor.h"
Greg Clayton63094e02010-06-23 01:19:29 +000018#include "lldb/Core/Debugger.h"
Chris Lattner24943d22010-06-08 16:52:24 +000019#include "lldb/Core/StreamString.h"
Greg Clayton63094e02010-06-23 01:19:29 +000020#include "lldb/Interpreter/Args.h"
Chris Lattner24943d22010-06-08 16:52:24 +000021#include "lldb/Interpreter/CommandReturnObject.h"
Greg Clayton63094e02010-06-23 01:19:29 +000022#include "lldb/Interpreter/CommandInterpreter.h"
23#include "lldb/Interpreter/Options.h"
Chris Lattner24943d22010-06-08 16:52:24 +000024#include "lldb/Target/Process.h"
25
26using namespace lldb;
27using namespace lldb_private;
28
29//----------------------------------------------------------------------
30// Read memory from the inferior process
31//----------------------------------------------------------------------
32class CommandObjectMemoryRead : public CommandObject
33{
34public:
35
36 class CommandOptions : public Options
37 {
38 public:
39 CommandOptions () :
40 Options()
41 {
42 ResetOptionValues();
43 }
44
45 virtual
46 ~CommandOptions ()
47 {
48 }
49
50 virtual Error
51 SetOptionValue (int option_idx, const char *option_arg)
52 {
53 Error error;
54 char short_option = (char) m_getopt_table[option_idx].val;
55
56 switch (short_option)
57 {
58 case 'f':
59 error = Args::StringToFormat (option_arg, m_format);
60
61 switch (m_format)
62 {
63 default:
64 break;
65
66 case eFormatBoolean:
67 if (m_byte_size == 0)
68 m_byte_size = 1;
69 if (m_num_per_line == 0)
70 m_num_per_line = 1;
71 break;
72
73 case eFormatCString:
74 if (m_num_per_line == 0)
75 m_num_per_line = 1;
76 break;
77
78 case eFormatPointer:
79 break;
80
81 case eFormatBinary:
82 case eFormatFloat:
83 case eFormatOctal:
84 case eFormatDecimal:
85 case eFormatEnum:
86 case eFormatUnicode16:
87 case eFormatUnicode32:
88 case eFormatUnsigned:
89 if (m_byte_size == 0)
90 m_byte_size = 4;
91 if (m_num_per_line == 0)
92 m_num_per_line = 1;
93 break;
94
95 case eFormatBytes:
96 case eFormatBytesWithASCII:
97 case eFormatChar:
98 case eFormatCharPrintable:
99 if (m_byte_size == 0)
100 m_byte_size = 1;
101 break;
102 case eFormatComplex:
103 if (m_byte_size == 0)
104 m_byte_size = 8;
105 break;
106 case eFormatHex:
107 if (m_byte_size == 0)
108 m_byte_size = 4;
109 break;
110
111 case eFormatVectorOfChar:
112 case eFormatVectorOfSInt8:
113 case eFormatVectorOfUInt8:
114 case eFormatVectorOfSInt16:
115 case eFormatVectorOfUInt16:
116 case eFormatVectorOfSInt32:
117 case eFormatVectorOfUInt32:
118 case eFormatVectorOfSInt64:
119 case eFormatVectorOfUInt64:
120 case eFormatVectorOfFloat32:
121 case eFormatVectorOfFloat64:
122 case eFormatVectorOfUInt128:
123 break;
124 }
125 break;
126
127 case 'l':
128 m_num_per_line = Args::StringToUInt32 (option_arg, 0);
129 if (m_num_per_line == 0)
130 error.SetErrorStringWithFormat("Invalid value for --num-per-line option '%s'. Must be positive integer value.\n", option_arg);
131 break;
132
133 case 'c':
134 m_count = Args::StringToUInt32 (option_arg, 0);
135 if (m_count == 0)
136 error.SetErrorStringWithFormat("Invalid value for --count option '%s'. Must be positive integer value.\n", option_arg);
137 break;
138
139 case 's':
140 m_byte_size = Args::StringToUInt32 (option_arg, 0);
141 if (m_byte_size == 0)
142 error.SetErrorStringWithFormat("Invalid value for --size option '%s'. Must be positive integer value.\n", option_arg);
143 break;
144
145 default:
146 error.SetErrorStringWithFormat("Unrecognized short option '%c'.\n", short_option);
147 break;
148 }
149 return error;
150 }
151
152 void
153 ResetOptionValues ()
154 {
155 Options::ResetOptionValues();
156 m_format = eFormatBytesWithASCII;
157 m_byte_size = 0;
158 m_count = 0;
159 m_num_per_line = 0;
160 }
161
162 const lldb::OptionDefinition*
163 GetDefinitions ()
164 {
165 return g_option_table;
166 }
167
168 // Options table: Required for subclasses of Options.
169
170 static lldb::OptionDefinition g_option_table[];
171
172 // Instance variables to hold the values for command options.
173 lldb::Format m_format;
174 uint32_t m_byte_size;
175 uint32_t m_count;
176 uint32_t m_num_per_line;
177 };
178
Greg Clayton238c0a12010-09-18 01:14:36 +0000179 CommandObjectMemoryRead (CommandInterpreter &interpreter) :
180 CommandObject (interpreter,
181 "memory read",
Caroline Ticeabb507a2010-09-08 21:06:11 +0000182 "Read from the memory of the process being debugged.",
Caroline Tice43b014a2010-10-04 22:28:36 +0000183 NULL,
Chris Lattner24943d22010-06-08 16:52:24 +0000184 eFlagProcessMustBeLaunched)
185 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000186 CommandArgumentEntry arg1;
187 CommandArgumentEntry arg2;
188 CommandArgumentData start_addr_arg;
189 CommandArgumentData end_addr_arg;
190
191 // Define the first (and only) variant of this arg.
192 start_addr_arg.arg_type = eArgTypeStartAddress;
193 start_addr_arg.arg_repetition = eArgRepeatPlain;
194
195 // There is only one variant this argument could be; put it into the argument entry.
196 arg1.push_back (start_addr_arg);
197
198 // Define the first (and only) variant of this arg.
199 end_addr_arg.arg_type = eArgTypeEndAddress;
200 end_addr_arg.arg_repetition = eArgRepeatOptional;
201
202 // There is only one variant this argument could be; put it into the argument entry.
203 arg2.push_back (end_addr_arg);
204
205 // Push the data for the first argument into the m_arguments vector.
206 m_arguments.push_back (arg1);
207 m_arguments.push_back (arg2);
Chris Lattner24943d22010-06-08 16:52:24 +0000208 }
209
210 virtual
211 ~CommandObjectMemoryRead ()
212 {
213 }
214
215 Options *
216 GetOptions ()
217 {
218 return &m_options;
219 }
220
221 virtual bool
Greg Clayton238c0a12010-09-18 01:14:36 +0000222 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000223 CommandReturnObject &result)
224 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000225 Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
Chris Lattner24943d22010-06-08 16:52:24 +0000226 if (process == NULL)
227 {
228 result.AppendError("need a process to read memory");
229 result.SetStatus(eReturnStatusFailed);
230 return false;
231 }
232 const size_t argc = command.GetArgumentCount();
233
234 if (argc == 0 || argc > 2)
235 {
236 result.AppendErrorWithFormat ("%s takes 1 or two args.\n", m_cmd_name.c_str());
237 result.SetStatus(eReturnStatusFailed);
238 return false;
239 }
240
241 size_t item_byte_size = m_options.m_byte_size;
242 if (item_byte_size == 0)
243 {
244 if (m_options.m_format == eFormatPointer)
245 item_byte_size = process->GetAddressByteSize();
246 else
247 item_byte_size = 1;
248 }
249
250 size_t item_count = m_options.m_count;
251
252 size_t num_per_line = m_options.m_num_per_line;
253 if (num_per_line == 0)
254 {
255 num_per_line = (16/item_byte_size);
256 if (num_per_line == 0)
257 num_per_line = 1;
258 }
259
260 size_t total_byte_size = m_options.m_count * item_byte_size;
261 if (total_byte_size == 0)
262 total_byte_size = 32;
263
264 lldb::addr_t addr = Args::StringToUInt64(command.GetArgumentAtIndex(0), LLDB_INVALID_ADDRESS, 0);
265
266 if (addr == LLDB_INVALID_ADDRESS)
267 {
268 result.AppendErrorWithFormat("invalid start address string '%s'.\n", command.GetArgumentAtIndex(0));
269 result.SetStatus(eReturnStatusFailed);
270 return false;
271 }
272
273 if (argc == 2)
274 {
275 lldb::addr_t end_addr = Args::StringToUInt64(command.GetArgumentAtIndex(1), LLDB_INVALID_ADDRESS, 0);
276 if (end_addr == LLDB_INVALID_ADDRESS)
277 {
278 result.AppendErrorWithFormat("Invalid end address string '%s'.\n", command.GetArgumentAtIndex(1));
279 result.SetStatus(eReturnStatusFailed);
280 return false;
281 }
282 else if (end_addr <= addr)
283 {
284 result.AppendErrorWithFormat("End address (0x%llx) must be greater that the start address (0x%llx).\n", end_addr, addr);
285 result.SetStatus(eReturnStatusFailed);
286 return false;
287 }
288 else if (item_count != 0)
289 {
290 result.AppendErrorWithFormat("Specify either the end address (0x%llx) or the count (--count %u), not both.\n", end_addr, item_count);
291 result.SetStatus(eReturnStatusFailed);
292 return false;
293 }
294
295 total_byte_size = end_addr - addr;
296 item_count = total_byte_size / item_byte_size;
297 }
298 else
299 {
300 if (item_count == 0)
301 item_count = 32;
302 }
303
304 DataBufferSP data_sp(new DataBufferHeap (total_byte_size, '\0'));
305 Error error;
306 size_t bytes_read = process->ReadMemory(addr, data_sp->GetBytes (), data_sp->GetByteSize(), error);
307 if (bytes_read == 0)
308 {
309 result.AppendWarningWithFormat("Read from 0x%llx failed.\n", addr);
310 result.AppendError(error.AsCString());
311 result.SetStatus(eReturnStatusFailed);
312 return false;
313 }
314
315 if (bytes_read < total_byte_size)
316 result.AppendWarningWithFormat("Not all bytes (%u/%u) were able to be read from 0x%llx.\n", bytes_read, total_byte_size, addr);
317
318 result.SetStatus(eReturnStatusSuccessFinishResult);
319 DataExtractor data(data_sp, process->GetByteOrder(), process->GetAddressByteSize());
320
321 Stream &output_stream = result.GetOutputStream();
322 data.Dump(&output_stream,
323 0,
324 m_options.m_format,
325 item_byte_size,
326 item_count,
327 num_per_line,
328 addr,
329 0,
330 0);
331 output_stream.EOL();
332 return true;
333 }
334
335protected:
336 CommandOptions m_options;
337};
338
339lldb::OptionDefinition
340CommandObjectMemoryRead::CommandOptions::g_option_table[] =
341{
Caroline Tice4d6675c2010-10-01 19:59:14 +0000342 { LLDB_OPT_SET_1, false, "format", 'f', required_argument, NULL, 0, eArgTypeFormat, "The format that will be used to display the memory. Defaults to bytes with ASCII (--format=Y)."},
343 { LLDB_OPT_SET_1, false, "size", 's', required_argument, NULL, 0, eArgTypeByteSize,"The size in bytes to use when displaying with the selected format."},
344 { LLDB_OPT_SET_1, false, "num-per-line", 'l', required_argument, NULL, 0, eArgTypeNumberPerLine, "The number of items per line to display."},
345 { LLDB_OPT_SET_1, false, "count", 'c', required_argument, NULL, 0, eArgTypeCount, "The number of total items to display."},
346 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Chris Lattner24943d22010-06-08 16:52:24 +0000347};
348
349
350//----------------------------------------------------------------------
351// Write memory to the inferior process
352//----------------------------------------------------------------------
353class CommandObjectMemoryWrite : public CommandObject
354{
355public:
356
357 class CommandOptions : public Options
358 {
359 public:
360 CommandOptions () :
361 Options()
362 {
363 ResetOptionValues();
364 }
365
366 virtual
367 ~CommandOptions ()
368 {
369 }
370
371 virtual Error
372 SetOptionValue (int option_idx, const char *option_arg)
373 {
374 Error error;
375 char short_option = (char) m_getopt_table[option_idx].val;
376 switch (short_option)
377 {
378 case 'f':
379 error = Args::StringToFormat (option_arg, m_format);
380 break;
381
382 case 's':
383 m_byte_size = Args::StringToUInt32 (option_arg, 0);
384 if (m_byte_size == 0)
385 error.SetErrorStringWithFormat("Invalid value for --size option '%s'. Must be positive integer value.\n", option_arg);
386 break;
387
388
389 default:
390 error.SetErrorStringWithFormat("Unrecognized short option '%c'\n", short_option);
391 break;
392 }
393 return error;
394 }
395
396 void
397 ResetOptionValues ()
398 {
399 Options::ResetOptionValues();
400 m_format = eFormatBytes;
401 m_byte_size = 1;
402 }
403
404 const lldb::OptionDefinition*
405 GetDefinitions ()
406 {
407 return g_option_table;
408 }
409
410 // Options table: Required for subclasses of Options.
411
412 static lldb::OptionDefinition g_option_table[];
413
414 // Instance variables to hold the values for command options.
415 lldb::Format m_format;
416 uint32_t m_byte_size;
417 };
418
Greg Clayton238c0a12010-09-18 01:14:36 +0000419 CommandObjectMemoryWrite (CommandInterpreter &interpreter) :
420 CommandObject (interpreter,
421 "memory write",
Caroline Ticeabb507a2010-09-08 21:06:11 +0000422 "Write to the memory of the process being debugged.",
Caroline Tice43b014a2010-10-04 22:28:36 +0000423 //"memory write [<cmd-options>] <addr> [value1 value2 ...]",
424 NULL,
Chris Lattner24943d22010-06-08 16:52:24 +0000425 eFlagProcessMustBeLaunched)
426 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000427 CommandArgumentEntry arg1;
428 CommandArgumentEntry arg2;
429 CommandArgumentData addr_arg;
430 CommandArgumentData value_arg;
431
432 // Define the first (and only) variant of this arg.
433 addr_arg.arg_type = eArgTypeAddress;
434 addr_arg.arg_repetition = eArgRepeatPlain;
435
436 // There is only one variant this argument could be; put it into the argument entry.
437 arg1.push_back (addr_arg);
438
439 // Define the first (and only) variant of this arg.
440 value_arg.arg_type = eArgTypeValue;
441 value_arg.arg_repetition = eArgRepeatPlus;
442
443 // There is only one variant this argument could be; put it into the argument entry.
444 arg2.push_back (value_arg);
445
446 // Push the data for the first argument into the m_arguments vector.
447 m_arguments.push_back (arg1);
448 m_arguments.push_back (arg2);
Chris Lattner24943d22010-06-08 16:52:24 +0000449 }
450
451 virtual
452 ~CommandObjectMemoryWrite ()
453 {
454 }
455
456 Options *
457 GetOptions ()
458 {
459 return &m_options;
460 }
461
462 bool
463 UIntValueIsValidForSize (uint64_t uval64, size_t total_byte_size)
464 {
465 if (total_byte_size > 8)
466 return false;
467
468 if (total_byte_size == 8)
469 return true;
470
471 const uint64_t max = ((uint64_t)1 << (uint64_t)(total_byte_size * 8)) - 1;
472 return uval64 <= max;
473 }
474
475 bool
476 SIntValueIsValidForSize (int64_t sval64, size_t total_byte_size)
477 {
478 if (total_byte_size > 8)
479 return false;
480
481 if (total_byte_size == 8)
482 return true;
483
484 const int64_t max = ((int64_t)1 << (uint64_t)(total_byte_size * 8 - 1)) - 1;
485 const int64_t min = ~(max);
486 return min <= sval64 && sval64 <= max;
487 }
488
489 virtual bool
Greg Clayton238c0a12010-09-18 01:14:36 +0000490 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000491 CommandReturnObject &result)
492 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000493 Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
Chris Lattner24943d22010-06-08 16:52:24 +0000494 if (process == NULL)
495 {
496 result.AppendError("need a process to read memory");
497 result.SetStatus(eReturnStatusFailed);
498 return false;
499 }
500
501 const size_t argc = command.GetArgumentCount();
502
503 if (argc < 2)
504 {
505 result.AppendErrorWithFormat ("%s takes an address and at least one value.\n", m_cmd_name.c_str());
506 result.SetStatus(eReturnStatusFailed);
507 return false;
508 }
509
Chris Lattner24943d22010-06-08 16:52:24 +0000510 StreamString buffer (Stream::eBinary,
511 process->GetAddressByteSize(),
512 process->GetByteOrder());
513
Greg Clayton54e7afa2010-07-09 20:39:50 +0000514 size_t item_byte_size = m_options.m_byte_size;
515
516 if (m_options.m_byte_size == 0)
517 {
518 if (m_options.m_format == eFormatPointer)
519 item_byte_size = buffer.GetAddressByteSize();
520 else
521 item_byte_size = 1;
522 }
523
Chris Lattner24943d22010-06-08 16:52:24 +0000524 lldb::addr_t addr = Args::StringToUInt64(command.GetArgumentAtIndex(0), LLDB_INVALID_ADDRESS, 0);
525
526 if (addr == LLDB_INVALID_ADDRESS)
527 {
528 result.AppendErrorWithFormat("Invalid address string '%s'.\n", command.GetArgumentAtIndex(0));
529 result.SetStatus(eReturnStatusFailed);
530 return false;
531 }
532 command.Shift(); // shift off the address argument
533 uint64_t uval64;
534 int64_t sval64;
535 bool success = false;
536 const uint32_t num_value_args = command.GetArgumentCount();
537 uint32_t i;
538 for (i=0; i<num_value_args; ++i)
539 {
540 const char *value_str = command.GetArgumentAtIndex(i);
541
542 switch (m_options.m_format)
543 {
544 case eFormatFloat: // TODO: add support for floats soon
545 case eFormatCharPrintable:
546 case eFormatBytesWithASCII:
547 case eFormatComplex:
548 case eFormatEnum:
549 case eFormatUnicode16:
550 case eFormatUnicode32:
551 case eFormatVectorOfChar:
552 case eFormatVectorOfSInt8:
553 case eFormatVectorOfUInt8:
554 case eFormatVectorOfSInt16:
555 case eFormatVectorOfUInt16:
556 case eFormatVectorOfSInt32:
557 case eFormatVectorOfUInt32:
558 case eFormatVectorOfSInt64:
559 case eFormatVectorOfUInt64:
560 case eFormatVectorOfFloat32:
561 case eFormatVectorOfFloat64:
562 case eFormatVectorOfUInt128:
563 result.AppendError("unsupported format for writing memory");
564 result.SetStatus(eReturnStatusFailed);
565 return false;
566
567 case eFormatDefault:
568 case eFormatBytes:
569 case eFormatHex:
Greg Clayton54e7afa2010-07-09 20:39:50 +0000570 case eFormatPointer:
571
Chris Lattner24943d22010-06-08 16:52:24 +0000572 // Decode hex bytes
573 uval64 = Args::StringToUInt64(value_str, UINT64_MAX, 16, &success);
574 if (!success)
575 {
576 result.AppendErrorWithFormat ("'%s' is not a valid hex string value.\n", value_str);
577 result.SetStatus(eReturnStatusFailed);
578 return false;
579 }
580 else if (!UIntValueIsValidForSize (uval64, item_byte_size))
581 {
582 result.AppendErrorWithFormat ("Value 0x%llx is too large to fit in a %u byte unsigned integer value.\n", uval64, item_byte_size);
583 result.SetStatus(eReturnStatusFailed);
584 return false;
585 }
586 buffer.PutMaxHex64 (uval64, item_byte_size);
587 break;
588
589 case eFormatBoolean:
590 uval64 = Args::StringToBoolean(value_str, false, &success);
591 if (!success)
592 {
593 result.AppendErrorWithFormat ("'%s' is not a valid boolean string value.\n", value_str);
594 result.SetStatus(eReturnStatusFailed);
595 return false;
596 }
597 buffer.PutMaxHex64 (uval64, item_byte_size);
598 break;
599
600 case eFormatBinary:
601 uval64 = Args::StringToUInt64(value_str, UINT64_MAX, 2, &success);
602 if (!success)
603 {
604 result.AppendErrorWithFormat ("'%s' is not a valid binary string value.\n", value_str);
605 result.SetStatus(eReturnStatusFailed);
606 return false;
607 }
608 else if (!UIntValueIsValidForSize (uval64, item_byte_size))
609 {
610 result.AppendErrorWithFormat ("Value 0x%llx is too large to fit in a %u byte unsigned integer value.\n", uval64, item_byte_size);
611 result.SetStatus(eReturnStatusFailed);
612 return false;
613 }
614 buffer.PutMaxHex64 (uval64, item_byte_size);
615 break;
616
617 case eFormatChar:
618 case eFormatCString:
619 if (value_str[0])
620 {
621 size_t len = strlen (value_str);
622 // Include the NULL for C strings...
623 if (m_options.m_format == eFormatCString)
624 ++len;
625 Error error;
626 if (process->WriteMemory (addr, value_str, len, error) == len)
627 {
628 addr += len;
629 }
630 else
631 {
632 result.AppendErrorWithFormat ("Memory write to 0x%llx failed: %s.\n", addr, error.AsCString());
633 result.SetStatus(eReturnStatusFailed);
634 return false;
635 }
636 }
637 break;
638
639 case eFormatDecimal:
640 sval64 = Args::StringToSInt64(value_str, INT64_MAX, 0, &success);
641 if (!success)
642 {
643 result.AppendErrorWithFormat ("'%s' is not a valid signed decimal value.\n", value_str);
644 result.SetStatus(eReturnStatusFailed);
645 return false;
646 }
647 else if (!SIntValueIsValidForSize (sval64, item_byte_size))
648 {
649 result.AppendErrorWithFormat ("Value %lli is too large or small to fit in a %u byte signed integer value.\n", sval64, item_byte_size);
650 result.SetStatus(eReturnStatusFailed);
651 return false;
652 }
653 buffer.PutMaxHex64 (sval64, item_byte_size);
654 break;
655
656 case eFormatUnsigned:
657 uval64 = Args::StringToUInt64(value_str, UINT64_MAX, 0, &success);
658 if (!success)
659 {
660 result.AppendErrorWithFormat ("'%s' is not a valid unsigned decimal string value.\n", value_str);
661 result.SetStatus(eReturnStatusFailed);
662 return false;
663 }
664 else if (!UIntValueIsValidForSize (uval64, item_byte_size))
665 {
666 result.AppendErrorWithFormat ("Value %llu is too large to fit in a %u byte unsigned integer value.\n", uval64, item_byte_size);
667 result.SetStatus(eReturnStatusFailed);
668 return false;
669 }
670 buffer.PutMaxHex64 (uval64, item_byte_size);
671 break;
672
673 case eFormatOctal:
674 uval64 = Args::StringToUInt64(value_str, UINT64_MAX, 8, &success);
675 if (!success)
676 {
677 result.AppendErrorWithFormat ("'%s' is not a valid octal string value.\n", value_str);
678 result.SetStatus(eReturnStatusFailed);
679 return false;
680 }
681 else if (!UIntValueIsValidForSize (uval64, item_byte_size))
682 {
683 result.AppendErrorWithFormat ("Value %llo is too large to fit in a %u byte unsigned integer value.\n", uval64, item_byte_size);
684 result.SetStatus(eReturnStatusFailed);
685 return false;
686 }
687 buffer.PutMaxHex64 (uval64, item_byte_size);
688 break;
689 }
690 }
691
692 if (!buffer.GetString().empty())
693 {
694 Error error;
Greg Clayton53d68e72010-07-20 22:52:08 +0000695 if (process->WriteMemory (addr, buffer.GetString().c_str(), buffer.GetString().size(), error) == buffer.GetString().size())
Chris Lattner24943d22010-06-08 16:52:24 +0000696 return true;
697 else
698 {
699 result.AppendErrorWithFormat ("Memory write to 0x%llx failed: %s.\n", addr, error.AsCString());
700 result.SetStatus(eReturnStatusFailed);
701 return false;
702 }
703 }
704 return true;
705 }
706
707protected:
708 CommandOptions m_options;
709};
710
711lldb::OptionDefinition
712CommandObjectMemoryWrite::CommandOptions::g_option_table[] =
713{
Caroline Tice4d6675c2010-10-01 19:59:14 +0000714 { LLDB_OPT_SET_1, false, "format", 'f', required_argument, NULL, 0, eArgTypeFormat, "The format value types that will be decoded and written to memory."},
715 { LLDB_OPT_SET_1, false, "size", 's', required_argument, NULL, 0, eArgTypeByteSize,"The size in bytes of the values to write to memory."},
716 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Chris Lattner24943d22010-06-08 16:52:24 +0000717};
718
719
720//-------------------------------------------------------------------------
721// CommandObjectMemory
722//-------------------------------------------------------------------------
723
Greg Clayton63094e02010-06-23 01:19:29 +0000724CommandObjectMemory::CommandObjectMemory (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +0000725 CommandObjectMultiword (interpreter,
726 "memory",
Caroline Ticec1ad82e2010-09-07 22:38:08 +0000727 "A set of commands for operating on memory.",
Chris Lattner24943d22010-06-08 16:52:24 +0000728 "memory <subcommand> [<subcommand-options>]")
729{
Greg Clayton238c0a12010-09-18 01:14:36 +0000730 LoadSubCommand ("read", CommandObjectSP (new CommandObjectMemoryRead (interpreter)));
731 LoadSubCommand ("write", CommandObjectSP (new CommandObjectMemoryWrite (interpreter)));
Chris Lattner24943d22010-06-08 16:52:24 +0000732}
733
734CommandObjectMemory::~CommandObjectMemory ()
735{
736}