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