blob: 947fc27a3c07d50ad849d01a32ba16103fe5ccd5 [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
Daniel Malead891f9b2012-12-05 00:20:57 +000010#include "lldb/lldb-python.h"
11
Chris Lattner24943d22010-06-08 16:52:24 +000012#include "CommandObjectMemory.h"
13
14// C Includes
15// C++ Includes
16// Other libraries and framework includes
17// Project includes
Chris Lattner24943d22010-06-08 16:52:24 +000018#include "lldb/Core/DataBufferHeap.h"
19#include "lldb/Core/DataExtractor.h"
Greg Clayton63094e02010-06-23 01:19:29 +000020#include "lldb/Core/Debugger.h"
Greg Clayton49ce8962012-08-29 21:13:06 +000021#include "lldb/Core/Module.h"
Chris Lattner24943d22010-06-08 16:52:24 +000022#include "lldb/Core/StreamString.h"
Greg Clayton57b3c6b2011-04-27 22:04:39 +000023#include "lldb/Core/ValueObjectMemory.h"
Greg Clayton63094e02010-06-23 01:19:29 +000024#include "lldb/Interpreter/Args.h"
Chris Lattner24943d22010-06-08 16:52:24 +000025#include "lldb/Interpreter/CommandReturnObject.h"
Greg Clayton63094e02010-06-23 01:19:29 +000026#include "lldb/Interpreter/CommandInterpreter.h"
27#include "lldb/Interpreter/Options.h"
Greg Clayton57b3c6b2011-04-27 22:04:39 +000028#include "lldb/Interpreter/OptionGroupFormat.h"
29#include "lldb/Interpreter/OptionGroupOutputFile.h"
Greg Clayton56bbdaf2011-04-28 20:55:26 +000030#include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
Greg Clayton73844aa2012-08-22 17:17:09 +000031#include "lldb/Interpreter/OptionValueString.h"
Greg Clayton49ce8962012-08-29 21:13:06 +000032#include "lldb/Symbol/TypeList.h"
Chris Lattner24943d22010-06-08 16:52:24 +000033#include "lldb/Target/Process.h"
Greg Clayton57b3c6b2011-04-27 22:04:39 +000034#include "lldb/Target/StackFrame.h"
Chris Lattner24943d22010-06-08 16:52:24 +000035
36using namespace lldb;
37using namespace lldb_private;
38
Greg Clayton56bbdaf2011-04-28 20:55:26 +000039static OptionDefinition
Greg Clayton57b3c6b2011-04-27 22:04:39 +000040g_option_table[] =
41{
Greg Clayton57b3c6b2011-04-27 22:04:39 +000042 { LLDB_OPT_SET_1, false, "num-per-line" ,'l', required_argument, NULL, 0, eArgTypeNumberPerLine ,"The number of items per line to display."},
43 { LLDB_OPT_SET_2, false, "binary" ,'b', no_argument , NULL, 0, eArgTypeNone ,"If true, memory will be saved as binary. If false, the memory is saved save as an ASCII dump that uses the format, size, count and number per line settings."},
Sean Callanan06dc17f2012-09-24 22:25:51 +000044 { LLDB_OPT_SET_3, true , "type" ,'t', required_argument, NULL, 0, eArgTypeNone ,"The name of a type to view memory as."},
Greg Clayton827baf62012-11-02 21:14:58 +000045 { LLDB_OPT_SET_1|
46 LLDB_OPT_SET_2|
47 LLDB_OPT_SET_3, false, "force" ,'r', no_argument, NULL, 0, eArgTypeNone ,"Necessary if reading over 1024 bytes of memory."},
Greg Clayton57b3c6b2011-04-27 22:04:39 +000048};
49
50
51
52class OptionGroupReadMemory : public OptionGroup
53{
54public:
55
56 OptionGroupReadMemory () :
Greg Clayton56bbdaf2011-04-28 20:55:26 +000057 m_num_per_line (1,1),
Greg Clayton57b3c6b2011-04-27 22:04:39 +000058 m_output_as_binary (false),
59 m_view_as_type()
60 {
61 }
62
63 virtual
64 ~OptionGroupReadMemory ()
65 {
66 }
67
68
69 virtual uint32_t
70 GetNumDefinitions ()
71 {
72 return sizeof (g_option_table) / sizeof (OptionDefinition);
73 }
74
75 virtual const OptionDefinition*
76 GetDefinitions ()
77 {
78 return g_option_table;
79 }
80
81 virtual Error
82 SetOptionValue (CommandInterpreter &interpreter,
83 uint32_t option_idx,
84 const char *option_arg)
85 {
86 Error error;
Greg Clayton6475c422012-12-04 00:32:51 +000087 const int short_option = g_option_table[option_idx].short_option;
Greg Clayton57b3c6b2011-04-27 22:04:39 +000088
89 switch (short_option)
90 {
91 case 'l':
92 error = m_num_per_line.SetValueFromCString (option_arg);
93 if (m_num_per_line.GetCurrentValue() == 0)
Greg Clayton9c236732011-10-26 00:56:27 +000094 error.SetErrorStringWithFormat("invalid value for --num-per-line option '%s'", option_arg);
Greg Clayton57b3c6b2011-04-27 22:04:39 +000095 break;
Greg Claytona42880a2011-10-25 06:44:01 +000096
Greg Clayton57b3c6b2011-04-27 22:04:39 +000097 case 'b':
98 m_output_as_binary = true;
99 break;
100
101 case 't':
102 error = m_view_as_type.SetValueFromCString (option_arg);
103 break;
Sean Callanan8a6f3e92012-04-28 01:27:38 +0000104
105 case 'r':
106 m_force = true;
107 break;
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000108
109 default:
Greg Clayton9c236732011-10-26 00:56:27 +0000110 error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option);
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000111 break;
112 }
113 return error;
114 }
115
116 virtual void
117 OptionParsingStarting (CommandInterpreter &interpreter)
118 {
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000119 m_num_per_line.Clear();
120 m_output_as_binary = false;
121 m_view_as_type.Clear();
122 }
123
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000124 Error
Greg Claytona42880a2011-10-25 06:44:01 +0000125 FinalizeSettings (Target *target, OptionGroupFormat& format_options)
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000126 {
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000127 Error error;
Greg Claytona42880a2011-10-25 06:44:01 +0000128 OptionValueUInt64 &byte_size_value = format_options.GetByteSizeValue();
129 OptionValueUInt64 &count_value = format_options.GetCountValue();
Greg Clayton9c236732011-10-26 00:56:27 +0000130 const bool byte_size_option_set = byte_size_value.OptionWasSet();
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000131 const bool num_per_line_option_set = m_num_per_line.OptionWasSet();
Greg Claytona42880a2011-10-25 06:44:01 +0000132 const bool count_option_set = format_options.GetCountValue().OptionWasSet();
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000133
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000134 switch (format_options.GetFormat())
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000135 {
136 default:
137 break;
138
139 case eFormatBoolean:
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000140 if (!byte_size_option_set)
Greg Claytona42880a2011-10-25 06:44:01 +0000141 byte_size_value = 1;
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000142 if (!num_per_line_option_set)
143 m_num_per_line = 1;
144 if (!count_option_set)
Greg Claytona42880a2011-10-25 06:44:01 +0000145 format_options.GetCountValue() = 8;
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000146 break;
147
148 case eFormatCString:
149 break;
Greg Clayton24a6bd92011-10-27 17:55:14 +0000150
151 case eFormatInstruction:
152 if (count_option_set)
Jim Inghamab885832012-11-07 01:52:04 +0000153 byte_size_value = target->GetArchitecture().GetMaximumOpcodeByteSize();
Greg Clayton24a6bd92011-10-27 17:55:14 +0000154 m_num_per_line = 1;
155 break;
156
157 case eFormatAddressInfo:
158 if (!byte_size_option_set)
159 byte_size_value = target->GetArchitecture().GetAddressByteSize();
160 m_num_per_line = 1;
161 if (!count_option_set)
162 format_options.GetCountValue() = 8;
163 break;
164
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000165 case eFormatPointer:
Greg Claytona42880a2011-10-25 06:44:01 +0000166 byte_size_value = target->GetArchitecture().GetAddressByteSize();
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000167 if (!num_per_line_option_set)
168 m_num_per_line = 4;
169 if (!count_option_set)
Greg Claytona42880a2011-10-25 06:44:01 +0000170 format_options.GetCountValue() = 8;
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000171 break;
172
173 case eFormatBinary:
174 case eFormatFloat:
175 case eFormatOctal:
176 case eFormatDecimal:
177 case eFormatEnum:
178 case eFormatUnicode16:
179 case eFormatUnicode32:
180 case eFormatUnsigned:
Greg Clayton24a6bd92011-10-27 17:55:14 +0000181 case eFormatHexFloat:
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000182 if (!byte_size_option_set)
Greg Claytona42880a2011-10-25 06:44:01 +0000183 byte_size_value = 4;
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000184 if (!num_per_line_option_set)
185 m_num_per_line = 1;
186 if (!count_option_set)
Greg Claytona42880a2011-10-25 06:44:01 +0000187 format_options.GetCountValue() = 8;
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000188 break;
Greg Clayton24a6bd92011-10-27 17:55:14 +0000189
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000190 case eFormatBytes:
191 case eFormatBytesWithASCII:
Greg Clayton9c236732011-10-26 00:56:27 +0000192 if (byte_size_option_set)
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000193 {
Greg Claytona42880a2011-10-25 06:44:01 +0000194 if (byte_size_value > 1)
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000195 error.SetErrorStringWithFormat ("display format (bytes/bytes with ascii) conflicts with the specified byte size %" PRIu64 "\n"
Johnny Chenbf9ba592012-03-06 01:17:59 +0000196 "\tconsider using a different display format or don't specify the byte size",
197 byte_size_value.GetCurrentValue());
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000198 }
199 else
Greg Claytona42880a2011-10-25 06:44:01 +0000200 byte_size_value = 1;
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000201 if (!num_per_line_option_set)
202 m_num_per_line = 16;
203 if (!count_option_set)
Greg Claytona42880a2011-10-25 06:44:01 +0000204 format_options.GetCountValue() = 32;
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000205 break;
Greg Clayton307fa072011-06-17 23:50:44 +0000206 case eFormatCharArray:
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000207 case eFormatChar:
208 case eFormatCharPrintable:
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000209 if (!byte_size_option_set)
Greg Claytona42880a2011-10-25 06:44:01 +0000210 byte_size_value = 1;
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000211 if (!num_per_line_option_set)
212 m_num_per_line = 32;
213 if (!count_option_set)
Greg Claytona42880a2011-10-25 06:44:01 +0000214 format_options.GetCountValue() = 64;
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000215 break;
216 case eFormatComplex:
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000217 if (!byte_size_option_set)
Greg Claytona42880a2011-10-25 06:44:01 +0000218 byte_size_value = 8;
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000219 if (!num_per_line_option_set)
220 m_num_per_line = 1;
221 if (!count_option_set)
Greg Claytona42880a2011-10-25 06:44:01 +0000222 format_options.GetCountValue() = 8;
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000223 break;
224 case eFormatHex:
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000225 if (!byte_size_option_set)
Greg Claytona42880a2011-10-25 06:44:01 +0000226 byte_size_value = 4;
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000227 if (!num_per_line_option_set)
228 {
Greg Claytona42880a2011-10-25 06:44:01 +0000229 switch (byte_size_value)
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000230 {
231 case 1:
232 case 2:
233 m_num_per_line = 8;
234 break;
235 case 4:
236 m_num_per_line = 4;
237 break;
238 case 8:
239 m_num_per_line = 2;
240 break;
241 default:
242 m_num_per_line = 1;
243 break;
244 }
245 }
246 if (!count_option_set)
Greg Claytona42880a2011-10-25 06:44:01 +0000247 count_value = 8;
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000248 break;
249
250 case eFormatVectorOfChar:
251 case eFormatVectorOfSInt8:
252 case eFormatVectorOfUInt8:
253 case eFormatVectorOfSInt16:
254 case eFormatVectorOfUInt16:
255 case eFormatVectorOfSInt32:
256 case eFormatVectorOfUInt32:
257 case eFormatVectorOfSInt64:
258 case eFormatVectorOfUInt64:
259 case eFormatVectorOfFloat32:
260 case eFormatVectorOfFloat64:
261 case eFormatVectorOfUInt128:
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000262 if (!byte_size_option_set)
Greg Claytona42880a2011-10-25 06:44:01 +0000263 byte_size_value = 128;
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000264 if (!num_per_line_option_set)
265 m_num_per_line = 1;
266 if (!count_option_set)
Greg Claytona42880a2011-10-25 06:44:01 +0000267 count_value = 4;
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000268 break;
269 }
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000270 return error;
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000271 }
272
Greg Clayton902b5be2011-10-26 04:32:38 +0000273 bool
274 AnyOptionWasSet () const
275 {
276 return m_num_per_line.OptionWasSet() ||
277 m_output_as_binary ||
278 m_view_as_type.OptionWasSet();
279 }
280
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000281 OptionValueUInt64 m_num_per_line;
282 bool m_output_as_binary;
283 OptionValueString m_view_as_type;
Sean Callanan8a6f3e92012-04-28 01:27:38 +0000284 bool m_force;
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000285};
286
287
288
Chris Lattner24943d22010-06-08 16:52:24 +0000289//----------------------------------------------------------------------
290// Read memory from the inferior process
291//----------------------------------------------------------------------
Jim Inghamda26bd22012-06-08 21:56:10 +0000292class CommandObjectMemoryRead : public CommandObjectParsed
Chris Lattner24943d22010-06-08 16:52:24 +0000293{
294public:
295
Greg Clayton238c0a12010-09-18 01:14:36 +0000296 CommandObjectMemoryRead (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000297 CommandObjectParsed (interpreter,
298 "memory read",
299 "Read from the memory of the process being debugged.",
300 NULL,
Greg Claytonea0bb4d2013-01-09 19:44:40 +0000301 eFlagRequiresTarget | eFlagProcessMustBePaused),
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000302 m_option_group (interpreter),
Greg Claytona42880a2011-10-25 06:44:01 +0000303 m_format_options (eFormatBytesWithASCII, 1, 8),
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000304 m_memory_options (),
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000305 m_outfile_options (),
Greg Clayton902b5be2011-10-26 04:32:38 +0000306 m_varobj_options(),
307 m_next_addr(LLDB_INVALID_ADDRESS),
308 m_prev_byte_size(0),
309 m_prev_format_options (eFormatBytesWithASCII, 1, 8),
310 m_prev_memory_options (),
311 m_prev_outfile_options (),
312 m_prev_varobj_options()
Chris Lattner24943d22010-06-08 16:52:24 +0000313 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000314 CommandArgumentEntry arg1;
315 CommandArgumentEntry arg2;
316 CommandArgumentData start_addr_arg;
317 CommandArgumentData end_addr_arg;
318
319 // Define the first (and only) variant of this arg.
320 start_addr_arg.arg_type = eArgTypeStartAddress;
321 start_addr_arg.arg_repetition = eArgRepeatPlain;
322
323 // There is only one variant this argument could be; put it into the argument entry.
324 arg1.push_back (start_addr_arg);
325
326 // Define the first (and only) variant of this arg.
327 end_addr_arg.arg_type = eArgTypeEndAddress;
328 end_addr_arg.arg_repetition = eArgRepeatOptional;
329
330 // There is only one variant this argument could be; put it into the argument entry.
331 arg2.push_back (end_addr_arg);
332
333 // Push the data for the first argument into the m_arguments vector.
334 m_arguments.push_back (arg1);
335 m_arguments.push_back (arg2);
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000336
Greg Claytona42880a2011-10-25 06:44:01 +0000337 // Add the "--format" and "--count" options to group 1 and 3
338 m_option_group.Append (&m_format_options,
339 OptionGroupFormat::OPTION_GROUP_FORMAT | OptionGroupFormat::OPTION_GROUP_COUNT,
Greg Clayton31feaa82011-11-22 18:07:35 +0000340 LLDB_OPT_SET_1 | LLDB_OPT_SET_2 | LLDB_OPT_SET_3);
Greg Clayton24a6bd92011-10-27 17:55:14 +0000341 m_option_group.Append (&m_format_options,
342 OptionGroupFormat::OPTION_GROUP_GDB_FMT,
Greg Clayton31feaa82011-11-22 18:07:35 +0000343 LLDB_OPT_SET_1 | LLDB_OPT_SET_3);
Greg Claytona42880a2011-10-25 06:44:01 +0000344 // Add the "--size" option to group 1 and 2
345 m_option_group.Append (&m_format_options,
346 OptionGroupFormat::OPTION_GROUP_SIZE,
347 LLDB_OPT_SET_1 | LLDB_OPT_SET_2);
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000348 m_option_group.Append (&m_memory_options);
349 m_option_group.Append (&m_outfile_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1 | LLDB_OPT_SET_2 | LLDB_OPT_SET_3);
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000350 m_option_group.Append (&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_3);
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000351 m_option_group.Finalize();
Chris Lattner24943d22010-06-08 16:52:24 +0000352 }
353
354 virtual
355 ~CommandObjectMemoryRead ()
356 {
357 }
358
359 Options *
360 GetOptions ()
361 {
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000362 return &m_option_group;
Chris Lattner24943d22010-06-08 16:52:24 +0000363 }
364
Greg Clayton902b5be2011-10-26 04:32:38 +0000365 virtual const char *GetRepeatCommand (Args &current_command_args, uint32_t index)
366 {
367 return m_cmd_name.c_str();
368 }
369
Jim Inghamda26bd22012-06-08 21:56:10 +0000370protected:
Chris Lattner24943d22010-06-08 16:52:24 +0000371 virtual bool
Greg Clayton49d888d2012-12-06 22:49:16 +0000372 DoExecute (Args& command, CommandReturnObject &result)
Chris Lattner24943d22010-06-08 16:52:24 +0000373 {
Greg Claytonea0bb4d2013-01-09 19:44:40 +0000374 // No need to check "target" for validity as eFlagRequiresTarget ensures it is valid
375 Target *target = m_exe_ctx.GetTargetPtr();
376
Chris Lattner24943d22010-06-08 16:52:24 +0000377 const size_t argc = command.GetArgumentCount();
378
Greg Clayton902b5be2011-10-26 04:32:38 +0000379 if ((argc == 0 && m_next_addr == LLDB_INVALID_ADDRESS) || argc > 2)
Chris Lattner24943d22010-06-08 16:52:24 +0000380 {
Greg Clayton49d888d2012-12-06 22:49:16 +0000381 result.AppendErrorWithFormat ("%s takes a start address expression with an optional end address expression.\n", m_cmd_name.c_str());
Greg Claytonbad1c9e2012-12-15 02:08:17 +0000382 result.AppendRawWarning("Expressions should be quoted if they contain spaces or other special characters.\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000383 result.SetStatus(eReturnStatusFailed);
384 return false;
385 }
386
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000387 ClangASTType clang_ast_type;
388 Error error;
389
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000390 const char *view_as_type_cstr = m_memory_options.m_view_as_type.GetCurrentValue();
391 if (view_as_type_cstr && view_as_type_cstr[0])
Chris Lattner24943d22010-06-08 16:52:24 +0000392 {
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000393 // We are viewing memory as a type
Greg Claytonbad1c9e2012-12-15 02:08:17 +0000394
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000395 SymbolContext sc;
Greg Claytondc0a38c2012-03-26 23:03:23 +0000396 const bool exact_match = false;
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000397 TypeList type_list;
398 uint32_t reference_count = 0;
399 uint32_t pointer_count = 0;
400 size_t idx;
Sean Callananddb2ece2012-07-10 21:24:26 +0000401
402#define ALL_KEYWORDS \
403 KEYWORD("const") \
404 KEYWORD("volatile") \
405 KEYWORD("restrict") \
406 KEYWORD("struct") \
407 KEYWORD("class") \
408 KEYWORD("union")
409
410#define KEYWORD(s) s,
411 static const char *g_keywords[] =
412 {
413 ALL_KEYWORDS
414 };
415#undef KEYWORD
416
417#define KEYWORD(s) (sizeof(s) - 1),
418 static const int g_keyword_lengths[] =
419 {
420 ALL_KEYWORDS
421 };
422#undef KEYWORD
423
424#undef ALL_KEYWORDS
425
426 static size_t g_num_keywords = sizeof(g_keywords) / sizeof(const char *);
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000427 std::string type_str(view_as_type_cstr);
428
429 // Remove all instances of g_keywords that are followed by spaces
430 for (size_t i = 0; i < g_num_keywords; ++i)
431 {
432 const char *keyword = g_keywords[i];
Sean Callananddb2ece2012-07-10 21:24:26 +0000433 int keyword_len = g_keyword_lengths[i];
434
435 idx = 0;
436 while ((idx = type_str.find (keyword, idx)) != std::string::npos)
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000437 {
438 if (type_str[idx + keyword_len] == ' ' || type_str[idx + keyword_len] == '\t')
Sean Callananddb2ece2012-07-10 21:24:26 +0000439 {
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000440 type_str.erase(idx, keyword_len+1);
Sean Callananddb2ece2012-07-10 21:24:26 +0000441 idx = 0;
442 }
443 else
444 {
445 idx += keyword_len;
446 }
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000447 }
448 }
449 bool done = type_str.empty();
450 //
451 idx = type_str.find_first_not_of (" \t");
452 if (idx > 0 && idx != std::string::npos)
453 type_str.erase (0, idx);
454 while (!done)
455 {
456 // Strip trailing spaces
457 if (type_str.empty())
458 done = true;
459 else
460 {
461 switch (type_str[type_str.size()-1])
462 {
463 case '*':
464 ++pointer_count;
465 // fall through...
466 case ' ':
467 case '\t':
468 type_str.erase(type_str.size()-1);
469 break;
470
471 case '&':
472 if (reference_count == 0)
473 {
474 reference_count = 1;
475 type_str.erase(type_str.size()-1);
476 }
477 else
478 {
479 result.AppendErrorWithFormat ("invalid type string: '%s'\n", view_as_type_cstr);
480 result.SetStatus(eReturnStatusFailed);
481 return false;
482 }
483 break;
484
485 default:
486 done = true;
487 break;
488 }
489 }
490 }
491
492 ConstString lookup_type_name(type_str.c_str());
Greg Claytonea0bb4d2013-01-09 19:44:40 +0000493 StackFrame *frame = m_exe_ctx.GetFramePtr();
Greg Clayton567e7f32011-09-22 04:58:26 +0000494 if (frame)
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000495 {
Greg Clayton567e7f32011-09-22 04:58:26 +0000496 sc = frame->GetSymbolContext (eSymbolContextModule);
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000497 if (sc.module_sp)
498 {
Sean Callanan3e80cd92011-10-12 02:08:07 +0000499 sc.module_sp->FindTypes (sc,
500 lookup_type_name,
Greg Claytondc0a38c2012-03-26 23:03:23 +0000501 exact_match,
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000502 1,
503 type_list);
504 }
505 }
506 if (type_list.GetSize() == 0)
507 {
Greg Clayton9f95fb62012-04-06 17:41:13 +0000508 target->GetImages().FindTypes (sc,
Greg Clayton567e7f32011-09-22 04:58:26 +0000509 lookup_type_name,
Greg Claytondc0a38c2012-03-26 23:03:23 +0000510 exact_match,
Greg Clayton567e7f32011-09-22 04:58:26 +0000511 1,
512 type_list);
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000513 }
514
515 if (type_list.GetSize() == 0)
516 {
517 result.AppendErrorWithFormat ("unable to find any types that match the raw type '%s' for full type '%s'\n",
518 lookup_type_name.GetCString(),
519 view_as_type_cstr);
520 result.SetStatus(eReturnStatusFailed);
521 return false;
522 }
523
524 TypeSP type_sp (type_list.GetTypeAtIndex(0));
525 clang_ast_type.SetClangType (type_sp->GetClangAST(), type_sp->GetClangFullType());
526
527 while (pointer_count > 0)
528 {
529 clang_type_t pointer_type = ClangASTContext::CreatePointerType (clang_ast_type.GetASTContext(), clang_ast_type.GetOpaqueQualType());
530 if (pointer_type)
531 clang_ast_type.SetClangType (clang_ast_type.GetASTContext(), pointer_type);
532 else
533 {
534 result.AppendError ("unable make a pointer type\n");
535 result.SetStatus(eReturnStatusFailed);
536 return false;
537 }
538 --pointer_count;
539 }
540
Greg Claytona42880a2011-10-25 06:44:01 +0000541 m_format_options.GetByteSizeValue() = (clang_ast_type.GetClangTypeBitWidth () + 7) / 8;
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000542
Greg Claytona42880a2011-10-25 06:44:01 +0000543 if (m_format_options.GetByteSizeValue() == 0)
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000544 {
545 result.AppendErrorWithFormat ("unable to get the byte size of the type '%s'\n",
546 view_as_type_cstr);
547 result.SetStatus(eReturnStatusFailed);
548 return false;
549 }
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000550
Greg Claytona42880a2011-10-25 06:44:01 +0000551 if (!m_format_options.GetCountValue().OptionWasSet())
552 m_format_options.GetCountValue() = 1;
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000553 }
554 else
555 {
Greg Clayton567e7f32011-09-22 04:58:26 +0000556 error = m_memory_options.FinalizeSettings (target, m_format_options);
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000557 }
558
559 // Look for invalid combinations of settings
560 if (error.Fail())
561 {
Greg Clayton49d888d2012-12-06 22:49:16 +0000562 result.AppendError(error.AsCString());
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000563 result.SetStatus(eReturnStatusFailed);
564 return false;
Chris Lattner24943d22010-06-08 16:52:24 +0000565 }
566
Greg Clayton902b5be2011-10-26 04:32:38 +0000567 lldb::addr_t addr;
568 size_t total_byte_size = 0;
569 if (argc == 0)
570 {
571 // Use the last address and byte size and all options as they were
572 // if no options have been set
573 addr = m_next_addr;
574 total_byte_size = m_prev_byte_size;
Greg Claytonbad1c9e2012-12-15 02:08:17 +0000575 clang_ast_type = m_prev_clang_ast_type;
576 if (!m_format_options.AnyOptionWasSet() &&
Greg Clayton902b5be2011-10-26 04:32:38 +0000577 !m_memory_options.AnyOptionWasSet() &&
578 !m_outfile_options.AnyOptionWasSet() &&
579 !m_varobj_options.AnyOptionWasSet())
580 {
581 m_format_options = m_prev_format_options;
582 m_memory_options = m_prev_memory_options;
583 m_outfile_options = m_prev_outfile_options;
584 m_varobj_options = m_prev_varobj_options;
585 }
586 }
587
Greg Claytona42880a2011-10-25 06:44:01 +0000588 size_t item_count = m_format_options.GetCountValue().GetCurrentValue();
589 const size_t item_byte_size = m_format_options.GetByteSizeValue().GetCurrentValue();
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000590 const size_t num_per_line = m_memory_options.m_num_per_line.GetCurrentValue();
Chris Lattner24943d22010-06-08 16:52:24 +0000591
Chris Lattner24943d22010-06-08 16:52:24 +0000592 if (total_byte_size == 0)
Greg Clayton902b5be2011-10-26 04:32:38 +0000593 {
594 total_byte_size = item_count * item_byte_size;
595 if (total_byte_size == 0)
596 total_byte_size = 32;
597 }
Chris Lattner24943d22010-06-08 16:52:24 +0000598
Greg Clayton902b5be2011-10-26 04:32:38 +0000599 if (argc > 0)
Greg Claytonea0bb4d2013-01-09 19:44:40 +0000600 addr = Args::StringToAddress(&m_exe_ctx, command.GetArgumentAtIndex(0), LLDB_INVALID_ADDRESS, &error);
Chris Lattner24943d22010-06-08 16:52:24 +0000601
602 if (addr == LLDB_INVALID_ADDRESS)
603 {
Greg Clayton49d888d2012-12-06 22:49:16 +0000604 result.AppendError("invalid start address expression.");
605 result.AppendError(error.AsCString());
Chris Lattner24943d22010-06-08 16:52:24 +0000606 result.SetStatus(eReturnStatusFailed);
607 return false;
608 }
609
610 if (argc == 2)
611 {
Greg Claytonea0bb4d2013-01-09 19:44:40 +0000612 lldb::addr_t end_addr = Args::StringToAddress(&m_exe_ctx, command.GetArgumentAtIndex(1), LLDB_INVALID_ADDRESS, 0);
Chris Lattner24943d22010-06-08 16:52:24 +0000613 if (end_addr == LLDB_INVALID_ADDRESS)
614 {
Greg Clayton49d888d2012-12-06 22:49:16 +0000615 result.AppendError("invalid end address expression.");
616 result.AppendError(error.AsCString());
Chris Lattner24943d22010-06-08 16:52:24 +0000617 result.SetStatus(eReturnStatusFailed);
618 return false;
619 }
620 else if (end_addr <= addr)
621 {
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000622 result.AppendErrorWithFormat("end address (0x%" PRIx64 ") must be greater that the start address (0x%" PRIx64 ").\n", end_addr, addr);
Chris Lattner24943d22010-06-08 16:52:24 +0000623 result.SetStatus(eReturnStatusFailed);
624 return false;
625 }
Greg Claytona42880a2011-10-25 06:44:01 +0000626 else if (m_format_options.GetCountValue().OptionWasSet())
Chris Lattner24943d22010-06-08 16:52:24 +0000627 {
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000628 result.AppendErrorWithFormat("specify either the end address (0x%" PRIx64 ") or the count (--count %lu), not both.\n", end_addr, item_count);
Chris Lattner24943d22010-06-08 16:52:24 +0000629 result.SetStatus(eReturnStatusFailed);
630 return false;
631 }
632
633 total_byte_size = end_addr - addr;
634 item_count = total_byte_size / item_byte_size;
635 }
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000636
Sean Callanan8a6f3e92012-04-28 01:27:38 +0000637 if (total_byte_size > 1024 && !m_memory_options.m_force)
638 {
639 result.AppendErrorWithFormat("Normally, \'memory read\' will not read over 1Kbyte of data.\n");
640 result.AppendErrorWithFormat("Please use --force to override this restriction.\n");
641 return false;
642 }
643
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000644 DataBufferSP data_sp;
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000645 size_t bytes_read = 0;
Greg Claytonbad1c9e2012-12-15 02:08:17 +0000646 if (clang_ast_type.GetOpaqueQualType())
647 {
648 // Make sure we don't display our type as ASCII bytes like the default memory read
649 if (m_format_options.GetFormatValue().OptionWasSet() == false)
650 m_format_options.GetFormatValue().SetCurrentValue(eFormatDefault);
651
652 bytes_read = clang_ast_type.GetTypeByteSize() * m_format_options.GetCountValue().GetCurrentValue();
653 }
654 else
Chris Lattner24943d22010-06-08 16:52:24 +0000655 {
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000656 data_sp.reset (new DataBufferHeap (total_byte_size, '\0'));
Greg Clayton3508c382012-02-24 01:59:29 +0000657 Address address(addr, NULL);
Greg Clayton567e7f32011-09-22 04:58:26 +0000658 bytes_read = target->ReadMemory(address, false, data_sp->GetBytes (), data_sp->GetByteSize(), error);
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000659 if (bytes_read == 0)
660 {
Greg Clayton04e6ada2012-05-25 17:05:55 +0000661 const char *error_cstr = error.AsCString();
662 if (error_cstr && error_cstr[0])
663 {
664 result.AppendError(error_cstr);
665 }
666 else
667 {
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000668 result.AppendErrorWithFormat("failed to read memory from 0x%" PRIx64 ".\n", addr);
Greg Clayton04e6ada2012-05-25 17:05:55 +0000669 }
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000670 result.SetStatus(eReturnStatusFailed);
671 return false;
672 }
673
674 if (bytes_read < total_byte_size)
Greg Clayton49d888d2012-12-06 22:49:16 +0000675 result.AppendWarningWithFormat("Not all bytes (%lu/%lu) were able to be read from 0x%" PRIx64 ".", bytes_read, total_byte_size, addr);
Chris Lattner24943d22010-06-08 16:52:24 +0000676 }
677
Greg Claytonbad1c9e2012-12-15 02:08:17 +0000678 m_next_addr = addr + bytes_read;
679 m_prev_byte_size = bytes_read;
680 m_prev_format_options = m_format_options;
681 m_prev_memory_options = m_memory_options;
682 m_prev_outfile_options = m_outfile_options;
683 m_prev_varobj_options = m_varobj_options;
684 m_prev_clang_ast_type = clang_ast_type;
685
Greg Claytone9f5fbd2010-10-10 20:52:20 +0000686 StreamFile outfile_stream;
687 Stream *output_stream = NULL;
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000688 const FileSpec &outfile_spec = m_outfile_options.GetFile().GetCurrentValue();
689 if (outfile_spec)
Greg Claytone9f5fbd2010-10-10 20:52:20 +0000690 {
691 char path[PATH_MAX];
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000692 outfile_spec.GetPath (path, sizeof(path));
693
694 uint32_t open_options = File::eOpenOptionWrite | File::eOpenOptionCanCreate;
695 const bool append = m_outfile_options.GetAppend().GetCurrentValue();
696 if (append)
697 open_options |= File::eOpenOptionAppend;
698
699 if (outfile_stream.GetFile ().Open (path, open_options).Success())
Greg Claytone9f5fbd2010-10-10 20:52:20 +0000700 {
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000701 if (m_memory_options.m_output_as_binary)
Greg Claytone9f5fbd2010-10-10 20:52:20 +0000702 {
703 int bytes_written = outfile_stream.Write (data_sp->GetBytes(), bytes_read);
704 if (bytes_written > 0)
705 {
706 result.GetOutputStream().Printf ("%i bytes %s to '%s'\n",
707 bytes_written,
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000708 append ? "appended" : "written",
Greg Claytone9f5fbd2010-10-10 20:52:20 +0000709 path);
710 return true;
711 }
712 else
713 {
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000714 result.AppendErrorWithFormat("Failed to write %" PRIu64 " bytes to '%s'.\n", (uint64_t)bytes_read, path);
Greg Claytone9f5fbd2010-10-10 20:52:20 +0000715 result.SetStatus(eReturnStatusFailed);
716 return false;
717 }
718 }
719 else
720 {
721 // We are going to write ASCII to the file just point the
722 // output_stream to our outfile_stream...
723 output_stream = &outfile_stream;
724 }
725 }
726 else
727 {
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000728 result.AppendErrorWithFormat("Failed to open file '%s' for %s.\n", path, append ? "append" : "write");
Greg Claytone9f5fbd2010-10-10 20:52:20 +0000729 result.SetStatus(eReturnStatusFailed);
730 return false;
731 }
732 }
733 else
734 {
735 output_stream = &result.GetOutputStream();
736 }
737
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000738
Greg Claytonea0bb4d2013-01-09 19:44:40 +0000739 ExecutionContextScope *exe_scope = m_exe_ctx.GetBestExecutionContextScope();
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000740 if (clang_ast_type.GetOpaqueQualType())
741 {
742 for (uint32_t i = 0; i<item_count; ++i)
743 {
744 addr_t item_addr = addr + (i * item_byte_size);
Greg Clayton3508c382012-02-24 01:59:29 +0000745 Address address (item_addr);
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000746 StreamString name_strm;
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000747 name_strm.Printf ("0x%" PRIx64, item_addr);
Greg Clayton24a6bd92011-10-27 17:55:14 +0000748 ValueObjectSP valobj_sp (ValueObjectMemory::Create (exe_scope,
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000749 name_strm.GetString().c_str(),
750 address,
751 clang_ast_type));
752 if (valobj_sp)
753 {
Greg Claytonbad1c9e2012-12-15 02:08:17 +0000754 Format format = m_format_options.GetFormat();
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000755 if (format != eFormatDefault)
756 valobj_sp->SetFormat (format);
757
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000758 bool scope_already_checked = true;
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000759
Enrico Granata3069c622012-03-01 04:24:26 +0000760 ValueObject::DumpValueObjectOptions options;
761 options.SetMaximumPointerDepth(m_varobj_options.ptr_depth)
762 .SetMaximumDepth(m_varobj_options.max_depth)
763 .SetShowLocation(m_varobj_options.show_location)
764 .SetShowTypes(m_varobj_options.show_types)
765 .SetUseObjectiveC(m_varobj_options.use_objc)
766 .SetScopeChecked(scope_already_checked)
767 .SetFlatOutput(m_varobj_options.flat_output)
Enrico Granatacf09f882012-03-19 22:58:49 +0000768 .SetUseSyntheticValue(m_varobj_options.be_raw ? false : m_varobj_options.use_synth)
Enrico Granata3069c622012-03-01 04:24:26 +0000769 .SetOmitSummaryDepth(m_varobj_options.be_raw ? UINT32_MAX : m_varobj_options.no_summary_depth)
770 .SetIgnoreCap(m_varobj_options.be_raw ? true : m_varobj_options.ignore_cap)
771 .SetFormat(format)
772 .SetSummary();
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000773 ValueObject::DumpValueObject (*output_stream,
774 valobj_sp.get(),
Enrico Granata3069c622012-03-01 04:24:26 +0000775 options);
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000776 }
777 else
778 {
779 result.AppendErrorWithFormat ("failed to create a value object for: (%s) %s\n",
780 view_as_type_cstr,
781 name_strm.GetString().c_str());
782 result.SetStatus(eReturnStatusFailed);
783 return false;
784 }
785 }
786 return true;
787 }
788
789 result.SetStatus(eReturnStatusSuccessFinishResult);
790 DataExtractor data (data_sp,
Greg Clayton567e7f32011-09-22 04:58:26 +0000791 target->GetArchitecture().GetByteOrder(),
792 target->GetArchitecture().GetAddressByteSize());
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000793
794
Greg Claytone9f5fbd2010-10-10 20:52:20 +0000795 assert (output_stream);
Greg Clayton746979d2011-10-28 23:44:55 +0000796 uint32_t bytes_dumped = data.Dump (output_stream,
797 0,
798 m_format_options.GetFormat(),
799 item_byte_size,
800 item_count,
801 num_per_line,
802 addr,
803 0,
804 0,
805 exe_scope);
806 m_next_addr = addr + bytes_dumped;
Greg Claytone9f5fbd2010-10-10 20:52:20 +0000807 output_stream->EOL();
Chris Lattner24943d22010-06-08 16:52:24 +0000808 return true;
809 }
810
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000811 OptionGroupOptions m_option_group;
812 OptionGroupFormat m_format_options;
813 OptionGroupReadMemory m_memory_options;
814 OptionGroupOutputFile m_outfile_options;
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000815 OptionGroupValueObjectDisplay m_varobj_options;
Greg Clayton902b5be2011-10-26 04:32:38 +0000816 lldb::addr_t m_next_addr;
817 lldb::addr_t m_prev_byte_size;
818 OptionGroupFormat m_prev_format_options;
819 OptionGroupReadMemory m_prev_memory_options;
820 OptionGroupOutputFile m_prev_outfile_options;
821 OptionGroupValueObjectDisplay m_prev_varobj_options;
Greg Claytonbad1c9e2012-12-15 02:08:17 +0000822 ClangASTType m_prev_clang_ast_type;
Chris Lattner24943d22010-06-08 16:52:24 +0000823};
824
Greg Claytona42880a2011-10-25 06:44:01 +0000825
826OptionDefinition
827g_memory_write_option_table[] =
828{
829{ LLDB_OPT_SET_1, true, "infile", 'i', required_argument, NULL, 0, eArgTypeFilename, "Write memory using the contents of a file."},
830{ LLDB_OPT_SET_1, false, "offset", 'o', required_argument, NULL, 0, eArgTypeOffset, "Start writng bytes from an offset within the input file."},
831};
832
833
Chris Lattner24943d22010-06-08 16:52:24 +0000834//----------------------------------------------------------------------
835// Write memory to the inferior process
836//----------------------------------------------------------------------
Jim Inghamda26bd22012-06-08 21:56:10 +0000837class CommandObjectMemoryWrite : public CommandObjectParsed
Chris Lattner24943d22010-06-08 16:52:24 +0000838{
839public:
840
Greg Claytona42880a2011-10-25 06:44:01 +0000841 class OptionGroupWriteMemory : public OptionGroup
Chris Lattner24943d22010-06-08 16:52:24 +0000842 {
843 public:
Greg Claytona42880a2011-10-25 06:44:01 +0000844 OptionGroupWriteMemory () :
845 OptionGroup()
Chris Lattner24943d22010-06-08 16:52:24 +0000846 {
Chris Lattner24943d22010-06-08 16:52:24 +0000847 }
848
849 virtual
Greg Claytona42880a2011-10-25 06:44:01 +0000850 ~OptionGroupWriteMemory ()
Chris Lattner24943d22010-06-08 16:52:24 +0000851 {
852 }
853
Greg Claytona42880a2011-10-25 06:44:01 +0000854 virtual uint32_t
855 GetNumDefinitions ()
856 {
857 return sizeof (g_memory_write_option_table) / sizeof (OptionDefinition);
858 }
859
860 virtual const OptionDefinition*
861 GetDefinitions ()
862 {
863 return g_memory_write_option_table;
864 }
865
Chris Lattner24943d22010-06-08 16:52:24 +0000866 virtual Error
Greg Claytona42880a2011-10-25 06:44:01 +0000867 SetOptionValue (CommandInterpreter &interpreter,
868 uint32_t option_idx,
869 const char *option_arg)
Chris Lattner24943d22010-06-08 16:52:24 +0000870 {
871 Error error;
Greg Clayton6475c422012-12-04 00:32:51 +0000872 const int short_option = g_memory_write_option_table[option_idx].short_option;
Greg Claytona42880a2011-10-25 06:44:01 +0000873
Chris Lattner24943d22010-06-08 16:52:24 +0000874 switch (short_option)
875 {
Greg Claytona42880a2011-10-25 06:44:01 +0000876 case 'i':
877 m_infile.SetFile (option_arg, true);
878 if (!m_infile.Exists())
Greg Claytone9f5fbd2010-10-10 20:52:20 +0000879 {
Greg Claytona42880a2011-10-25 06:44:01 +0000880 m_infile.Clear();
Greg Clayton9c236732011-10-26 00:56:27 +0000881 error.SetErrorStringWithFormat("input file does not exist: '%s'", option_arg);
Greg Claytone9f5fbd2010-10-10 20:52:20 +0000882 }
Greg Claytona42880a2011-10-25 06:44:01 +0000883 break;
884
885 case 'o':
886 {
887 bool success;
888 m_infile_offset = Args::StringToUInt64(option_arg, 0, 0, &success);
889 if (!success)
890 {
Greg Clayton9c236732011-10-26 00:56:27 +0000891 error.SetErrorStringWithFormat("invalid offset string '%s'", option_arg);
Greg Claytona42880a2011-10-25 06:44:01 +0000892 }
893 }
894 break;
895
896 default:
Greg Clayton9c236732011-10-26 00:56:27 +0000897 error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option);
Greg Claytona42880a2011-10-25 06:44:01 +0000898 break;
Chris Lattner24943d22010-06-08 16:52:24 +0000899 }
900 return error;
901 }
Greg Claytona42880a2011-10-25 06:44:01 +0000902
903 virtual void
904 OptionParsingStarting (CommandInterpreter &interpreter)
Chris Lattner24943d22010-06-08 16:52:24 +0000905 {
Greg Claytone9f5fbd2010-10-10 20:52:20 +0000906 m_infile.Clear();
907 m_infile_offset = 0;
Chris Lattner24943d22010-06-08 16:52:24 +0000908 }
909
Greg Claytone9f5fbd2010-10-10 20:52:20 +0000910 FileSpec m_infile;
911 off_t m_infile_offset;
Chris Lattner24943d22010-06-08 16:52:24 +0000912 };
913
Greg Clayton238c0a12010-09-18 01:14:36 +0000914 CommandObjectMemoryWrite (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000915 CommandObjectParsed (interpreter,
916 "memory write",
917 "Write to the memory of the process being debugged.",
918 NULL,
Greg Claytonea0bb4d2013-01-09 19:44:40 +0000919 eFlagRequiresProcess | eFlagProcessMustBeLaunched),
Greg Claytona42880a2011-10-25 06:44:01 +0000920 m_option_group (interpreter),
921 m_format_options (eFormatBytes, 1, UINT64_MAX),
922 m_memory_options ()
Chris Lattner24943d22010-06-08 16:52:24 +0000923 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000924 CommandArgumentEntry arg1;
925 CommandArgumentEntry arg2;
926 CommandArgumentData addr_arg;
927 CommandArgumentData value_arg;
928
929 // Define the first (and only) variant of this arg.
930 addr_arg.arg_type = eArgTypeAddress;
931 addr_arg.arg_repetition = eArgRepeatPlain;
932
933 // There is only one variant this argument could be; put it into the argument entry.
934 arg1.push_back (addr_arg);
935
936 // Define the first (and only) variant of this arg.
937 value_arg.arg_type = eArgTypeValue;
938 value_arg.arg_repetition = eArgRepeatPlus;
939
940 // There is only one variant this argument could be; put it into the argument entry.
941 arg2.push_back (value_arg);
942
943 // Push the data for the first argument into the m_arguments vector.
944 m_arguments.push_back (arg1);
945 m_arguments.push_back (arg2);
Greg Claytona42880a2011-10-25 06:44:01 +0000946
947 m_option_group.Append (&m_format_options, OptionGroupFormat::OPTION_GROUP_FORMAT, LLDB_OPT_SET_1);
948 m_option_group.Append (&m_format_options, OptionGroupFormat::OPTION_GROUP_SIZE , LLDB_OPT_SET_1|LLDB_OPT_SET_2);
949 m_option_group.Append (&m_memory_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_2);
950 m_option_group.Finalize();
951
Chris Lattner24943d22010-06-08 16:52:24 +0000952 }
953
954 virtual
955 ~CommandObjectMemoryWrite ()
956 {
957 }
958
959 Options *
960 GetOptions ()
961 {
Greg Claytona42880a2011-10-25 06:44:01 +0000962 return &m_option_group;
Chris Lattner24943d22010-06-08 16:52:24 +0000963 }
964
965 bool
966 UIntValueIsValidForSize (uint64_t uval64, size_t total_byte_size)
967 {
968 if (total_byte_size > 8)
969 return false;
970
971 if (total_byte_size == 8)
972 return true;
973
974 const uint64_t max = ((uint64_t)1 << (uint64_t)(total_byte_size * 8)) - 1;
975 return uval64 <= max;
976 }
977
978 bool
979 SIntValueIsValidForSize (int64_t sval64, size_t total_byte_size)
980 {
981 if (total_byte_size > 8)
982 return false;
983
984 if (total_byte_size == 8)
985 return true;
986
987 const int64_t max = ((int64_t)1 << (uint64_t)(total_byte_size * 8 - 1)) - 1;
988 const int64_t min = ~(max);
989 return min <= sval64 && sval64 <= max;
990 }
991
Jim Inghamda26bd22012-06-08 21:56:10 +0000992protected:
Chris Lattner24943d22010-06-08 16:52:24 +0000993 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000994 DoExecute (Args& command, CommandReturnObject &result)
Chris Lattner24943d22010-06-08 16:52:24 +0000995 {
Greg Claytonea0bb4d2013-01-09 19:44:40 +0000996 // No need to check "process" for validity as eFlagRequiresProcess ensures it is valid
997 Process *process = m_exe_ctx.GetProcessPtr();
Chris Lattner24943d22010-06-08 16:52:24 +0000998
999 const size_t argc = command.GetArgumentCount();
1000
Greg Claytona42880a2011-10-25 06:44:01 +00001001 if (m_memory_options.m_infile)
Chris Lattner24943d22010-06-08 16:52:24 +00001002 {
Greg Claytone9f5fbd2010-10-10 20:52:20 +00001003 if (argc < 1)
1004 {
1005 result.AppendErrorWithFormat ("%s takes a destination address when writing file contents.\n", m_cmd_name.c_str());
1006 result.SetStatus(eReturnStatusFailed);
1007 return false;
1008 }
1009 }
1010 else if (argc < 2)
1011 {
1012 result.AppendErrorWithFormat ("%s takes a destination address and at least one value.\n", m_cmd_name.c_str());
Chris Lattner24943d22010-06-08 16:52:24 +00001013 result.SetStatus(eReturnStatusFailed);
1014 return false;
1015 }
1016
Chris Lattner24943d22010-06-08 16:52:24 +00001017 StreamString buffer (Stream::eBinary,
Greg Clayton395fc332011-02-15 21:59:32 +00001018 process->GetTarget().GetArchitecture().GetAddressByteSize(),
1019 process->GetTarget().GetArchitecture().GetByteOrder());
Chris Lattner24943d22010-06-08 16:52:24 +00001020
Greg Claytona42880a2011-10-25 06:44:01 +00001021 OptionValueUInt64 &byte_size_value = m_format_options.GetByteSizeValue();
1022 size_t item_byte_size = byte_size_value.GetCurrentValue();
Greg Clayton54e7afa2010-07-09 20:39:50 +00001023
Greg Clayton49d888d2012-12-06 22:49:16 +00001024 Error error;
Greg Claytonea0bb4d2013-01-09 19:44:40 +00001025 lldb::addr_t addr = Args::StringToAddress (&m_exe_ctx,
Greg Clayton49d888d2012-12-06 22:49:16 +00001026 command.GetArgumentAtIndex(0),
1027 LLDB_INVALID_ADDRESS,
1028 &error);
Chris Lattner24943d22010-06-08 16:52:24 +00001029
1030 if (addr == LLDB_INVALID_ADDRESS)
1031 {
Greg Clayton49d888d2012-12-06 22:49:16 +00001032 result.AppendError("invalid address expression\n");
1033 result.AppendError(error.AsCString());
Chris Lattner24943d22010-06-08 16:52:24 +00001034 result.SetStatus(eReturnStatusFailed);
1035 return false;
1036 }
Greg Claytone9f5fbd2010-10-10 20:52:20 +00001037
Greg Claytona42880a2011-10-25 06:44:01 +00001038 if (m_memory_options.m_infile)
Greg Claytone9f5fbd2010-10-10 20:52:20 +00001039 {
1040 size_t length = SIZE_MAX;
Greg Claytona42880a2011-10-25 06:44:01 +00001041 if (item_byte_size > 0)
1042 length = item_byte_size;
1043 lldb::DataBufferSP data_sp (m_memory_options.m_infile.ReadFileContents (m_memory_options.m_infile_offset, length));
Greg Claytone9f5fbd2010-10-10 20:52:20 +00001044 if (data_sp)
1045 {
1046 length = data_sp->GetByteSize();
1047 if (length > 0)
1048 {
1049 Error error;
1050 size_t bytes_written = process->WriteMemory (addr, data_sp->GetBytes(), length, error);
1051
1052 if (bytes_written == length)
1053 {
1054 // All bytes written
Daniel Malea5f35a4b2012-11-29 21:49:15 +00001055 result.GetOutputStream().Printf("%" PRIu64 " bytes were written to 0x%" PRIx64 "\n", (uint64_t)bytes_written, addr);
Greg Claytone9f5fbd2010-10-10 20:52:20 +00001056 result.SetStatus(eReturnStatusSuccessFinishResult);
1057 }
1058 else if (bytes_written > 0)
1059 {
1060 // Some byte written
Daniel Malea5f35a4b2012-11-29 21:49:15 +00001061 result.GetOutputStream().Printf("%" PRIu64 " bytes of %" PRIu64 " requested were written to 0x%" PRIx64 "\n", (uint64_t)bytes_written, (uint64_t)length, addr);
Greg Claytone9f5fbd2010-10-10 20:52:20 +00001062 result.SetStatus(eReturnStatusSuccessFinishResult);
1063 }
1064 else
1065 {
Daniel Malea5f35a4b2012-11-29 21:49:15 +00001066 result.AppendErrorWithFormat ("Memory write to 0x%" PRIx64 " failed: %s.\n", addr, error.AsCString());
Greg Claytone9f5fbd2010-10-10 20:52:20 +00001067 result.SetStatus(eReturnStatusFailed);
1068 }
1069 }
1070 }
1071 else
1072 {
1073 result.AppendErrorWithFormat ("Unable to read contents of file.\n");
1074 result.SetStatus(eReturnStatusFailed);
1075 }
1076 return result.Succeeded();
1077 }
Greg Claytona42880a2011-10-25 06:44:01 +00001078 else if (item_byte_size == 0)
Greg Claytone9f5fbd2010-10-10 20:52:20 +00001079 {
Greg Claytona42880a2011-10-25 06:44:01 +00001080 if (m_format_options.GetFormat() == eFormatPointer)
Greg Claytone9f5fbd2010-10-10 20:52:20 +00001081 item_byte_size = buffer.GetAddressByteSize();
1082 else
1083 item_byte_size = 1;
1084 }
1085
Chris Lattner24943d22010-06-08 16:52:24 +00001086 command.Shift(); // shift off the address argument
1087 uint64_t uval64;
1088 int64_t sval64;
1089 bool success = false;
1090 const uint32_t num_value_args = command.GetArgumentCount();
1091 uint32_t i;
1092 for (i=0; i<num_value_args; ++i)
1093 {
1094 const char *value_str = command.GetArgumentAtIndex(i);
1095
Greg Claytona42880a2011-10-25 06:44:01 +00001096 switch (m_format_options.GetFormat())
Chris Lattner24943d22010-06-08 16:52:24 +00001097 {
Greg Clayton3182eff2011-06-23 21:22:24 +00001098 case kNumFormats:
Chris Lattner24943d22010-06-08 16:52:24 +00001099 case eFormatFloat: // TODO: add support for floats soon
1100 case eFormatCharPrintable:
1101 case eFormatBytesWithASCII:
1102 case eFormatComplex:
1103 case eFormatEnum:
1104 case eFormatUnicode16:
1105 case eFormatUnicode32:
1106 case eFormatVectorOfChar:
1107 case eFormatVectorOfSInt8:
1108 case eFormatVectorOfUInt8:
1109 case eFormatVectorOfSInt16:
1110 case eFormatVectorOfUInt16:
1111 case eFormatVectorOfSInt32:
1112 case eFormatVectorOfUInt32:
1113 case eFormatVectorOfSInt64:
1114 case eFormatVectorOfUInt64:
1115 case eFormatVectorOfFloat32:
1116 case eFormatVectorOfFloat64:
1117 case eFormatVectorOfUInt128:
Greg Clayton4fdf7602011-03-20 04:57:14 +00001118 case eFormatOSType:
1119 case eFormatComplexInteger:
Greg Clayton24a6bd92011-10-27 17:55:14 +00001120 case eFormatAddressInfo:
1121 case eFormatHexFloat:
1122 case eFormatInstruction:
Sean Callanan96abc622012-08-08 17:35:10 +00001123 case eFormatVoid:
Chris Lattner24943d22010-06-08 16:52:24 +00001124 result.AppendError("unsupported format for writing memory");
1125 result.SetStatus(eReturnStatusFailed);
1126 return false;
1127
1128 case eFormatDefault:
1129 case eFormatBytes:
1130 case eFormatHex:
Enrico Granata535543d2012-08-09 19:33:34 +00001131 case eFormatHexUppercase:
Greg Clayton54e7afa2010-07-09 20:39:50 +00001132 case eFormatPointer:
1133
Chris Lattner24943d22010-06-08 16:52:24 +00001134 // Decode hex bytes
1135 uval64 = Args::StringToUInt64(value_str, UINT64_MAX, 16, &success);
1136 if (!success)
1137 {
1138 result.AppendErrorWithFormat ("'%s' is not a valid hex string value.\n", value_str);
1139 result.SetStatus(eReturnStatusFailed);
1140 return false;
1141 }
1142 else if (!UIntValueIsValidForSize (uval64, item_byte_size))
1143 {
Daniel Malea5f35a4b2012-11-29 21:49:15 +00001144 result.AppendErrorWithFormat ("Value 0x%" PRIx64 " is too large to fit in a %lu byte unsigned integer value.\n", uval64, item_byte_size);
Chris Lattner24943d22010-06-08 16:52:24 +00001145 result.SetStatus(eReturnStatusFailed);
1146 return false;
1147 }
1148 buffer.PutMaxHex64 (uval64, item_byte_size);
1149 break;
1150
1151 case eFormatBoolean:
1152 uval64 = Args::StringToBoolean(value_str, false, &success);
1153 if (!success)
1154 {
1155 result.AppendErrorWithFormat ("'%s' is not a valid boolean string value.\n", value_str);
1156 result.SetStatus(eReturnStatusFailed);
1157 return false;
1158 }
1159 buffer.PutMaxHex64 (uval64, item_byte_size);
1160 break;
1161
1162 case eFormatBinary:
1163 uval64 = Args::StringToUInt64(value_str, UINT64_MAX, 2, &success);
1164 if (!success)
1165 {
1166 result.AppendErrorWithFormat ("'%s' is not a valid binary string value.\n", value_str);
1167 result.SetStatus(eReturnStatusFailed);
1168 return false;
1169 }
1170 else if (!UIntValueIsValidForSize (uval64, item_byte_size))
1171 {
Daniel Malea5f35a4b2012-11-29 21:49:15 +00001172 result.AppendErrorWithFormat ("Value 0x%" PRIx64 " is too large to fit in a %lu byte unsigned integer value.\n", uval64, item_byte_size);
Chris Lattner24943d22010-06-08 16:52:24 +00001173 result.SetStatus(eReturnStatusFailed);
1174 return false;
1175 }
1176 buffer.PutMaxHex64 (uval64, item_byte_size);
1177 break;
1178
Greg Clayton307fa072011-06-17 23:50:44 +00001179 case eFormatCharArray:
Chris Lattner24943d22010-06-08 16:52:24 +00001180 case eFormatChar:
1181 case eFormatCString:
1182 if (value_str[0])
1183 {
1184 size_t len = strlen (value_str);
1185 // Include the NULL for C strings...
Greg Claytona42880a2011-10-25 06:44:01 +00001186 if (m_format_options.GetFormat() == eFormatCString)
Chris Lattner24943d22010-06-08 16:52:24 +00001187 ++len;
1188 Error error;
1189 if (process->WriteMemory (addr, value_str, len, error) == len)
1190 {
1191 addr += len;
1192 }
1193 else
1194 {
Daniel Malea5f35a4b2012-11-29 21:49:15 +00001195 result.AppendErrorWithFormat ("Memory write to 0x%" PRIx64 " failed: %s.\n", addr, error.AsCString());
Chris Lattner24943d22010-06-08 16:52:24 +00001196 result.SetStatus(eReturnStatusFailed);
1197 return false;
1198 }
1199 }
1200 break;
1201
1202 case eFormatDecimal:
1203 sval64 = Args::StringToSInt64(value_str, INT64_MAX, 0, &success);
1204 if (!success)
1205 {
1206 result.AppendErrorWithFormat ("'%s' is not a valid signed decimal value.\n", value_str);
1207 result.SetStatus(eReturnStatusFailed);
1208 return false;
1209 }
1210 else if (!SIntValueIsValidForSize (sval64, item_byte_size))
1211 {
Daniel Malea5f35a4b2012-11-29 21:49:15 +00001212 result.AppendErrorWithFormat ("Value %" PRIi64 " is too large or small to fit in a %lu byte signed integer value.\n", sval64, item_byte_size);
Chris Lattner24943d22010-06-08 16:52:24 +00001213 result.SetStatus(eReturnStatusFailed);
1214 return false;
1215 }
1216 buffer.PutMaxHex64 (sval64, item_byte_size);
1217 break;
1218
1219 case eFormatUnsigned:
1220 uval64 = Args::StringToUInt64(value_str, UINT64_MAX, 0, &success);
1221 if (!success)
1222 {
1223 result.AppendErrorWithFormat ("'%s' is not a valid unsigned decimal string value.\n", value_str);
1224 result.SetStatus(eReturnStatusFailed);
1225 return false;
1226 }
1227 else if (!UIntValueIsValidForSize (uval64, item_byte_size))
1228 {
Daniel Malea5f35a4b2012-11-29 21:49:15 +00001229 result.AppendErrorWithFormat ("Value %" PRIu64 " is too large to fit in a %lu byte unsigned integer value.\n", uval64, item_byte_size);
Chris Lattner24943d22010-06-08 16:52:24 +00001230 result.SetStatus(eReturnStatusFailed);
1231 return false;
1232 }
1233 buffer.PutMaxHex64 (uval64, item_byte_size);
1234 break;
1235
1236 case eFormatOctal:
1237 uval64 = Args::StringToUInt64(value_str, UINT64_MAX, 8, &success);
1238 if (!success)
1239 {
1240 result.AppendErrorWithFormat ("'%s' is not a valid octal string value.\n", value_str);
1241 result.SetStatus(eReturnStatusFailed);
1242 return false;
1243 }
1244 else if (!UIntValueIsValidForSize (uval64, item_byte_size))
1245 {
Daniel Malea5f35a4b2012-11-29 21:49:15 +00001246 result.AppendErrorWithFormat ("Value %" PRIo64 " is too large to fit in a %lu byte unsigned integer value.\n", uval64, item_byte_size);
Chris Lattner24943d22010-06-08 16:52:24 +00001247 result.SetStatus(eReturnStatusFailed);
1248 return false;
1249 }
1250 buffer.PutMaxHex64 (uval64, item_byte_size);
1251 break;
1252 }
1253 }
1254
1255 if (!buffer.GetString().empty())
1256 {
1257 Error error;
Greg Clayton53d68e72010-07-20 22:52:08 +00001258 if (process->WriteMemory (addr, buffer.GetString().c_str(), buffer.GetString().size(), error) == buffer.GetString().size())
Chris Lattner24943d22010-06-08 16:52:24 +00001259 return true;
1260 else
1261 {
Daniel Malea5f35a4b2012-11-29 21:49:15 +00001262 result.AppendErrorWithFormat ("Memory write to 0x%" PRIx64 " failed: %s.\n", addr, error.AsCString());
Chris Lattner24943d22010-06-08 16:52:24 +00001263 result.SetStatus(eReturnStatusFailed);
1264 return false;
1265 }
1266 }
1267 return true;
1268 }
1269
Greg Claytona42880a2011-10-25 06:44:01 +00001270 OptionGroupOptions m_option_group;
1271 OptionGroupFormat m_format_options;
1272 OptionGroupWriteMemory m_memory_options;
Chris Lattner24943d22010-06-08 16:52:24 +00001273};
1274
Chris Lattner24943d22010-06-08 16:52:24 +00001275
1276//-------------------------------------------------------------------------
1277// CommandObjectMemory
1278//-------------------------------------------------------------------------
1279
Greg Clayton63094e02010-06-23 01:19:29 +00001280CommandObjectMemory::CommandObjectMemory (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +00001281 CommandObjectMultiword (interpreter,
1282 "memory",
Caroline Ticec1ad82e2010-09-07 22:38:08 +00001283 "A set of commands for operating on memory.",
Chris Lattner24943d22010-06-08 16:52:24 +00001284 "memory <subcommand> [<subcommand-options>]")
1285{
Greg Clayton238c0a12010-09-18 01:14:36 +00001286 LoadSubCommand ("read", CommandObjectSP (new CommandObjectMemoryRead (interpreter)));
1287 LoadSubCommand ("write", CommandObjectSP (new CommandObjectMemoryWrite (interpreter)));
Chris Lattner24943d22010-06-08 16:52:24 +00001288}
1289
1290CommandObjectMemory::~CommandObjectMemory ()
1291{
1292}