blob: 2859cd1387aaec44236010ac57c43e0a41da7658 [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;
Jason Molenda42077d92013-03-23 05:16:54 +0000224 case eFormatComplexInteger:
225 if (!byte_size_option_set)
226 byte_size_value = 8;
227 if (!num_per_line_option_set)
228 m_num_per_line = 1;
229 if (!count_option_set)
230 format_options.GetCountValue() = 8;
231 break;
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000232 case eFormatHex:
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000233 if (!byte_size_option_set)
Greg Claytona42880a2011-10-25 06:44:01 +0000234 byte_size_value = 4;
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000235 if (!num_per_line_option_set)
236 {
Greg Claytona42880a2011-10-25 06:44:01 +0000237 switch (byte_size_value)
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000238 {
239 case 1:
240 case 2:
241 m_num_per_line = 8;
242 break;
243 case 4:
244 m_num_per_line = 4;
245 break;
246 case 8:
247 m_num_per_line = 2;
248 break;
249 default:
250 m_num_per_line = 1;
251 break;
252 }
253 }
254 if (!count_option_set)
Greg Claytona42880a2011-10-25 06:44:01 +0000255 count_value = 8;
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000256 break;
257
258 case eFormatVectorOfChar:
259 case eFormatVectorOfSInt8:
260 case eFormatVectorOfUInt8:
261 case eFormatVectorOfSInt16:
262 case eFormatVectorOfUInt16:
263 case eFormatVectorOfSInt32:
264 case eFormatVectorOfUInt32:
265 case eFormatVectorOfSInt64:
266 case eFormatVectorOfUInt64:
267 case eFormatVectorOfFloat32:
268 case eFormatVectorOfFloat64:
269 case eFormatVectorOfUInt128:
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000270 if (!byte_size_option_set)
Greg Claytona42880a2011-10-25 06:44:01 +0000271 byte_size_value = 128;
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000272 if (!num_per_line_option_set)
273 m_num_per_line = 1;
274 if (!count_option_set)
Greg Claytona42880a2011-10-25 06:44:01 +0000275 count_value = 4;
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000276 break;
277 }
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000278 return error;
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000279 }
280
Greg Clayton902b5be2011-10-26 04:32:38 +0000281 bool
282 AnyOptionWasSet () const
283 {
284 return m_num_per_line.OptionWasSet() ||
285 m_output_as_binary ||
286 m_view_as_type.OptionWasSet();
287 }
288
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000289 OptionValueUInt64 m_num_per_line;
290 bool m_output_as_binary;
291 OptionValueString m_view_as_type;
Sean Callanan8a6f3e92012-04-28 01:27:38 +0000292 bool m_force;
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000293};
294
295
296
Chris Lattner24943d22010-06-08 16:52:24 +0000297//----------------------------------------------------------------------
298// Read memory from the inferior process
299//----------------------------------------------------------------------
Jim Inghamda26bd22012-06-08 21:56:10 +0000300class CommandObjectMemoryRead : public CommandObjectParsed
Chris Lattner24943d22010-06-08 16:52:24 +0000301{
302public:
303
Greg Clayton238c0a12010-09-18 01:14:36 +0000304 CommandObjectMemoryRead (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000305 CommandObjectParsed (interpreter,
306 "memory read",
307 "Read from the memory of the process being debugged.",
308 NULL,
Greg Claytonea0bb4d2013-01-09 19:44:40 +0000309 eFlagRequiresTarget | eFlagProcessMustBePaused),
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000310 m_option_group (interpreter),
Greg Claytona42880a2011-10-25 06:44:01 +0000311 m_format_options (eFormatBytesWithASCII, 1, 8),
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000312 m_memory_options (),
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000313 m_outfile_options (),
Greg Clayton902b5be2011-10-26 04:32:38 +0000314 m_varobj_options(),
315 m_next_addr(LLDB_INVALID_ADDRESS),
316 m_prev_byte_size(0),
317 m_prev_format_options (eFormatBytesWithASCII, 1, 8),
318 m_prev_memory_options (),
319 m_prev_outfile_options (),
320 m_prev_varobj_options()
Chris Lattner24943d22010-06-08 16:52:24 +0000321 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000322 CommandArgumentEntry arg1;
323 CommandArgumentEntry arg2;
324 CommandArgumentData start_addr_arg;
325 CommandArgumentData end_addr_arg;
326
327 // Define the first (and only) variant of this arg.
Enrico Granata4968ad82013-01-29 01:48:30 +0000328 start_addr_arg.arg_type = eArgTypeAddressOrExpression;
Caroline Tice43b014a2010-10-04 22:28:36 +0000329 start_addr_arg.arg_repetition = eArgRepeatPlain;
330
331 // There is only one variant this argument could be; put it into the argument entry.
332 arg1.push_back (start_addr_arg);
333
334 // Define the first (and only) variant of this arg.
Enrico Granata4968ad82013-01-29 01:48:30 +0000335 end_addr_arg.arg_type = eArgTypeAddressOrExpression;
Caroline Tice43b014a2010-10-04 22:28:36 +0000336 end_addr_arg.arg_repetition = eArgRepeatOptional;
337
338 // There is only one variant this argument could be; put it into the argument entry.
339 arg2.push_back (end_addr_arg);
340
341 // Push the data for the first argument into the m_arguments vector.
342 m_arguments.push_back (arg1);
343 m_arguments.push_back (arg2);
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000344
Greg Claytona42880a2011-10-25 06:44:01 +0000345 // Add the "--format" and "--count" options to group 1 and 3
346 m_option_group.Append (&m_format_options,
347 OptionGroupFormat::OPTION_GROUP_FORMAT | OptionGroupFormat::OPTION_GROUP_COUNT,
Greg Clayton31feaa82011-11-22 18:07:35 +0000348 LLDB_OPT_SET_1 | LLDB_OPT_SET_2 | LLDB_OPT_SET_3);
Greg Clayton24a6bd92011-10-27 17:55:14 +0000349 m_option_group.Append (&m_format_options,
350 OptionGroupFormat::OPTION_GROUP_GDB_FMT,
Greg Clayton31feaa82011-11-22 18:07:35 +0000351 LLDB_OPT_SET_1 | LLDB_OPT_SET_3);
Greg Claytona42880a2011-10-25 06:44:01 +0000352 // Add the "--size" option to group 1 and 2
353 m_option_group.Append (&m_format_options,
354 OptionGroupFormat::OPTION_GROUP_SIZE,
355 LLDB_OPT_SET_1 | LLDB_OPT_SET_2);
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000356 m_option_group.Append (&m_memory_options);
357 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 +0000358 m_option_group.Append (&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_3);
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000359 m_option_group.Finalize();
Chris Lattner24943d22010-06-08 16:52:24 +0000360 }
361
362 virtual
363 ~CommandObjectMemoryRead ()
364 {
365 }
366
367 Options *
368 GetOptions ()
369 {
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000370 return &m_option_group;
Chris Lattner24943d22010-06-08 16:52:24 +0000371 }
372
Greg Clayton902b5be2011-10-26 04:32:38 +0000373 virtual const char *GetRepeatCommand (Args &current_command_args, uint32_t index)
374 {
375 return m_cmd_name.c_str();
376 }
377
Jim Inghamda26bd22012-06-08 21:56:10 +0000378protected:
Chris Lattner24943d22010-06-08 16:52:24 +0000379 virtual bool
Greg Clayton49d888d2012-12-06 22:49:16 +0000380 DoExecute (Args& command, CommandReturnObject &result)
Chris Lattner24943d22010-06-08 16:52:24 +0000381 {
Greg Claytonea0bb4d2013-01-09 19:44:40 +0000382 // No need to check "target" for validity as eFlagRequiresTarget ensures it is valid
383 Target *target = m_exe_ctx.GetTargetPtr();
384
Chris Lattner24943d22010-06-08 16:52:24 +0000385 const size_t argc = command.GetArgumentCount();
386
Greg Clayton902b5be2011-10-26 04:32:38 +0000387 if ((argc == 0 && m_next_addr == LLDB_INVALID_ADDRESS) || argc > 2)
Chris Lattner24943d22010-06-08 16:52:24 +0000388 {
Greg Clayton49d888d2012-12-06 22:49:16 +0000389 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 +0000390 result.AppendRawWarning("Expressions should be quoted if they contain spaces or other special characters.\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000391 result.SetStatus(eReturnStatusFailed);
392 return false;
393 }
394
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000395 ClangASTType clang_ast_type;
396 Error error;
397
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000398 const char *view_as_type_cstr = m_memory_options.m_view_as_type.GetCurrentValue();
399 if (view_as_type_cstr && view_as_type_cstr[0])
Chris Lattner24943d22010-06-08 16:52:24 +0000400 {
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000401 // We are viewing memory as a type
Greg Claytonbad1c9e2012-12-15 02:08:17 +0000402
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000403 SymbolContext sc;
Greg Claytondc0a38c2012-03-26 23:03:23 +0000404 const bool exact_match = false;
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000405 TypeList type_list;
406 uint32_t reference_count = 0;
407 uint32_t pointer_count = 0;
408 size_t idx;
Sean Callananddb2ece2012-07-10 21:24:26 +0000409
410#define ALL_KEYWORDS \
411 KEYWORD("const") \
412 KEYWORD("volatile") \
413 KEYWORD("restrict") \
414 KEYWORD("struct") \
415 KEYWORD("class") \
416 KEYWORD("union")
417
418#define KEYWORD(s) s,
419 static const char *g_keywords[] =
420 {
421 ALL_KEYWORDS
422 };
423#undef KEYWORD
424
425#define KEYWORD(s) (sizeof(s) - 1),
426 static const int g_keyword_lengths[] =
427 {
428 ALL_KEYWORDS
429 };
430#undef KEYWORD
431
432#undef ALL_KEYWORDS
433
434 static size_t g_num_keywords = sizeof(g_keywords) / sizeof(const char *);
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000435 std::string type_str(view_as_type_cstr);
436
437 // Remove all instances of g_keywords that are followed by spaces
438 for (size_t i = 0; i < g_num_keywords; ++i)
439 {
440 const char *keyword = g_keywords[i];
Sean Callananddb2ece2012-07-10 21:24:26 +0000441 int keyword_len = g_keyword_lengths[i];
442
443 idx = 0;
444 while ((idx = type_str.find (keyword, idx)) != std::string::npos)
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000445 {
446 if (type_str[idx + keyword_len] == ' ' || type_str[idx + keyword_len] == '\t')
Sean Callananddb2ece2012-07-10 21:24:26 +0000447 {
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000448 type_str.erase(idx, keyword_len+1);
Sean Callananddb2ece2012-07-10 21:24:26 +0000449 idx = 0;
450 }
451 else
452 {
453 idx += keyword_len;
454 }
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000455 }
456 }
457 bool done = type_str.empty();
458 //
459 idx = type_str.find_first_not_of (" \t");
460 if (idx > 0 && idx != std::string::npos)
461 type_str.erase (0, idx);
462 while (!done)
463 {
464 // Strip trailing spaces
465 if (type_str.empty())
466 done = true;
467 else
468 {
469 switch (type_str[type_str.size()-1])
470 {
471 case '*':
472 ++pointer_count;
473 // fall through...
474 case ' ':
475 case '\t':
476 type_str.erase(type_str.size()-1);
477 break;
478
479 case '&':
480 if (reference_count == 0)
481 {
482 reference_count = 1;
483 type_str.erase(type_str.size()-1);
484 }
485 else
486 {
487 result.AppendErrorWithFormat ("invalid type string: '%s'\n", view_as_type_cstr);
488 result.SetStatus(eReturnStatusFailed);
489 return false;
490 }
491 break;
492
493 default:
494 done = true;
495 break;
496 }
497 }
498 }
499
500 ConstString lookup_type_name(type_str.c_str());
Greg Claytonea0bb4d2013-01-09 19:44:40 +0000501 StackFrame *frame = m_exe_ctx.GetFramePtr();
Greg Clayton567e7f32011-09-22 04:58:26 +0000502 if (frame)
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000503 {
Greg Clayton567e7f32011-09-22 04:58:26 +0000504 sc = frame->GetSymbolContext (eSymbolContextModule);
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000505 if (sc.module_sp)
506 {
Sean Callanan3e80cd92011-10-12 02:08:07 +0000507 sc.module_sp->FindTypes (sc,
508 lookup_type_name,
Greg Claytondc0a38c2012-03-26 23:03:23 +0000509 exact_match,
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000510 1,
511 type_list);
512 }
513 }
514 if (type_list.GetSize() == 0)
515 {
Greg Clayton9f95fb62012-04-06 17:41:13 +0000516 target->GetImages().FindTypes (sc,
Greg Clayton567e7f32011-09-22 04:58:26 +0000517 lookup_type_name,
Greg Claytondc0a38c2012-03-26 23:03:23 +0000518 exact_match,
Greg Clayton567e7f32011-09-22 04:58:26 +0000519 1,
520 type_list);
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000521 }
522
523 if (type_list.GetSize() == 0)
524 {
525 result.AppendErrorWithFormat ("unable to find any types that match the raw type '%s' for full type '%s'\n",
526 lookup_type_name.GetCString(),
527 view_as_type_cstr);
528 result.SetStatus(eReturnStatusFailed);
529 return false;
530 }
531
532 TypeSP type_sp (type_list.GetTypeAtIndex(0));
533 clang_ast_type.SetClangType (type_sp->GetClangAST(), type_sp->GetClangFullType());
534
535 while (pointer_count > 0)
536 {
537 clang_type_t pointer_type = ClangASTContext::CreatePointerType (clang_ast_type.GetASTContext(), clang_ast_type.GetOpaqueQualType());
538 if (pointer_type)
539 clang_ast_type.SetClangType (clang_ast_type.GetASTContext(), pointer_type);
540 else
541 {
542 result.AppendError ("unable make a pointer type\n");
543 result.SetStatus(eReturnStatusFailed);
544 return false;
545 }
546 --pointer_count;
547 }
548
Greg Claytonfe6dc6e2013-03-14 18:31:44 +0000549 m_format_options.GetByteSizeValue() = clang_ast_type.GetClangTypeByteSize();
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000550
Greg Claytona42880a2011-10-25 06:44:01 +0000551 if (m_format_options.GetByteSizeValue() == 0)
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000552 {
553 result.AppendErrorWithFormat ("unable to get the byte size of the type '%s'\n",
554 view_as_type_cstr);
555 result.SetStatus(eReturnStatusFailed);
556 return false;
557 }
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000558
Greg Claytona42880a2011-10-25 06:44:01 +0000559 if (!m_format_options.GetCountValue().OptionWasSet())
560 m_format_options.GetCountValue() = 1;
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000561 }
562 else
563 {
Greg Clayton567e7f32011-09-22 04:58:26 +0000564 error = m_memory_options.FinalizeSettings (target, m_format_options);
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000565 }
566
567 // Look for invalid combinations of settings
568 if (error.Fail())
569 {
Greg Clayton49d888d2012-12-06 22:49:16 +0000570 result.AppendError(error.AsCString());
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000571 result.SetStatus(eReturnStatusFailed);
572 return false;
Chris Lattner24943d22010-06-08 16:52:24 +0000573 }
574
Greg Clayton902b5be2011-10-26 04:32:38 +0000575 lldb::addr_t addr;
576 size_t total_byte_size = 0;
577 if (argc == 0)
578 {
579 // Use the last address and byte size and all options as they were
580 // if no options have been set
581 addr = m_next_addr;
582 total_byte_size = m_prev_byte_size;
Greg Claytonbad1c9e2012-12-15 02:08:17 +0000583 clang_ast_type = m_prev_clang_ast_type;
584 if (!m_format_options.AnyOptionWasSet() &&
Greg Clayton902b5be2011-10-26 04:32:38 +0000585 !m_memory_options.AnyOptionWasSet() &&
586 !m_outfile_options.AnyOptionWasSet() &&
587 !m_varobj_options.AnyOptionWasSet())
588 {
589 m_format_options = m_prev_format_options;
590 m_memory_options = m_prev_memory_options;
591 m_outfile_options = m_prev_outfile_options;
592 m_varobj_options = m_prev_varobj_options;
593 }
594 }
595
Greg Claytona42880a2011-10-25 06:44:01 +0000596 size_t item_count = m_format_options.GetCountValue().GetCurrentValue();
Enrico Granata45358912013-01-21 19:20:50 +0000597 size_t item_byte_size = m_format_options.GetByteSizeValue().GetCurrentValue();
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000598 const size_t num_per_line = m_memory_options.m_num_per_line.GetCurrentValue();
Chris Lattner24943d22010-06-08 16:52:24 +0000599
Chris Lattner24943d22010-06-08 16:52:24 +0000600 if (total_byte_size == 0)
Greg Clayton902b5be2011-10-26 04:32:38 +0000601 {
602 total_byte_size = item_count * item_byte_size;
603 if (total_byte_size == 0)
604 total_byte_size = 32;
605 }
Chris Lattner24943d22010-06-08 16:52:24 +0000606
Greg Clayton902b5be2011-10-26 04:32:38 +0000607 if (argc > 0)
Greg Claytonea0bb4d2013-01-09 19:44:40 +0000608 addr = Args::StringToAddress(&m_exe_ctx, command.GetArgumentAtIndex(0), LLDB_INVALID_ADDRESS, &error);
Chris Lattner24943d22010-06-08 16:52:24 +0000609
610 if (addr == LLDB_INVALID_ADDRESS)
611 {
Greg Clayton49d888d2012-12-06 22:49:16 +0000612 result.AppendError("invalid start address expression.");
613 result.AppendError(error.AsCString());
Chris Lattner24943d22010-06-08 16:52:24 +0000614 result.SetStatus(eReturnStatusFailed);
615 return false;
616 }
617
618 if (argc == 2)
619 {
Greg Claytonea0bb4d2013-01-09 19:44:40 +0000620 lldb::addr_t end_addr = Args::StringToAddress(&m_exe_ctx, command.GetArgumentAtIndex(1), LLDB_INVALID_ADDRESS, 0);
Chris Lattner24943d22010-06-08 16:52:24 +0000621 if (end_addr == LLDB_INVALID_ADDRESS)
622 {
Greg Clayton49d888d2012-12-06 22:49:16 +0000623 result.AppendError("invalid end address expression.");
624 result.AppendError(error.AsCString());
Chris Lattner24943d22010-06-08 16:52:24 +0000625 result.SetStatus(eReturnStatusFailed);
626 return false;
627 }
628 else if (end_addr <= addr)
629 {
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000630 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 +0000631 result.SetStatus(eReturnStatusFailed);
632 return false;
633 }
Greg Claytona42880a2011-10-25 06:44:01 +0000634 else if (m_format_options.GetCountValue().OptionWasSet())
Chris Lattner24943d22010-06-08 16:52:24 +0000635 {
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000636 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 +0000637 result.SetStatus(eReturnStatusFailed);
638 return false;
639 }
640
641 total_byte_size = end_addr - addr;
642 item_count = total_byte_size / item_byte_size;
643 }
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000644
Sean Callanan8a6f3e92012-04-28 01:27:38 +0000645 if (total_byte_size > 1024 && !m_memory_options.m_force)
646 {
647 result.AppendErrorWithFormat("Normally, \'memory read\' will not read over 1Kbyte of data.\n");
648 result.AppendErrorWithFormat("Please use --force to override this restriction.\n");
649 return false;
650 }
651
Enrico Granata45358912013-01-21 19:20:50 +0000652
653
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000654 DataBufferSP data_sp;
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000655 size_t bytes_read = 0;
Greg Claytonbad1c9e2012-12-15 02:08:17 +0000656 if (clang_ast_type.GetOpaqueQualType())
657 {
658 // Make sure we don't display our type as ASCII bytes like the default memory read
659 if (m_format_options.GetFormatValue().OptionWasSet() == false)
660 m_format_options.GetFormatValue().SetCurrentValue(eFormatDefault);
661
662 bytes_read = clang_ast_type.GetTypeByteSize() * m_format_options.GetCountValue().GetCurrentValue();
663 }
Enrico Granata45358912013-01-21 19:20:50 +0000664 else if (m_format_options.GetFormatValue().GetCurrentValue() != eFormatCString)
Chris Lattner24943d22010-06-08 16:52:24 +0000665 {
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000666 data_sp.reset (new DataBufferHeap (total_byte_size, '\0'));
Greg Clayton3508c382012-02-24 01:59:29 +0000667 Address address(addr, NULL);
Greg Clayton567e7f32011-09-22 04:58:26 +0000668 bytes_read = target->ReadMemory(address, false, data_sp->GetBytes (), data_sp->GetByteSize(), error);
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000669 if (bytes_read == 0)
670 {
Greg Clayton04e6ada2012-05-25 17:05:55 +0000671 const char *error_cstr = error.AsCString();
672 if (error_cstr && error_cstr[0])
673 {
674 result.AppendError(error_cstr);
675 }
676 else
677 {
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000678 result.AppendErrorWithFormat("failed to read memory from 0x%" PRIx64 ".\n", addr);
Greg Clayton04e6ada2012-05-25 17:05:55 +0000679 }
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000680 result.SetStatus(eReturnStatusFailed);
681 return false;
682 }
683
684 if (bytes_read < total_byte_size)
Jim Ingham40aa9032013-01-25 23:05:01 +0000685 result.AppendWarningWithFormat("Not all bytes (%lu/%lu) were able to be read from 0x%" PRIx64 ".\n", bytes_read, total_byte_size, addr);
Chris Lattner24943d22010-06-08 16:52:24 +0000686 }
Enrico Granata45358912013-01-21 19:20:50 +0000687 else
688 {
689 // we treat c-strings as a special case because they do not have a fixed size
690 if (m_format_options.GetByteSizeValue().OptionWasSet() && !m_format_options.HasGDBFormat())
691 item_byte_size = m_format_options.GetByteSizeValue().GetCurrentValue();
692 else
693 item_byte_size = target->GetMaximumSizeOfStringSummary();
694 if (!m_format_options.GetCountValue().OptionWasSet())
695 item_count = 1;
696 data_sp.reset (new DataBufferHeap ((item_byte_size+1) * item_count, '\0')); // account for NULLs as necessary
697 uint8_t *data_ptr = data_sp->GetBytes();
698 auto data_addr = addr;
699 auto count = item_count;
700 item_count = 0;
701 while (item_count < count)
702 {
703 std::string buffer;
704 buffer.resize(item_byte_size+1,0);
705 Error error;
706 size_t read = target->ReadCStringFromMemory(data_addr, &buffer[0], item_byte_size+1, error);
707 if (error.Fail())
708 {
709 result.AppendErrorWithFormat("failed to read memory from 0x%" PRIx64 ".\n", addr);
710 result.SetStatus(eReturnStatusFailed);
711 return false;
712 }
713 if (item_byte_size == read)
714 {
715 result.AppendWarningWithFormat("unable to find a NULL terminated string at 0x%" PRIx64 ".Consider increasing the maximum read length.\n", data_addr);
716 break;
717 }
718 read+=1; // account for final NULL byte
719 memcpy(data_ptr, &buffer[0], read);
720 data_ptr += read;
721 data_addr += read;
722 bytes_read += read;
723 item_count++; // if we break early we know we only read item_count strings
724 }
725 data_sp.reset(new DataBufferHeap(data_sp->GetBytes(),bytes_read+1));
726 }
Chris Lattner24943d22010-06-08 16:52:24 +0000727
Greg Claytonbad1c9e2012-12-15 02:08:17 +0000728 m_next_addr = addr + bytes_read;
729 m_prev_byte_size = bytes_read;
730 m_prev_format_options = m_format_options;
731 m_prev_memory_options = m_memory_options;
732 m_prev_outfile_options = m_outfile_options;
733 m_prev_varobj_options = m_varobj_options;
734 m_prev_clang_ast_type = clang_ast_type;
735
Greg Claytone9f5fbd2010-10-10 20:52:20 +0000736 StreamFile outfile_stream;
737 Stream *output_stream = NULL;
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000738 const FileSpec &outfile_spec = m_outfile_options.GetFile().GetCurrentValue();
739 if (outfile_spec)
Greg Claytone9f5fbd2010-10-10 20:52:20 +0000740 {
741 char path[PATH_MAX];
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000742 outfile_spec.GetPath (path, sizeof(path));
743
744 uint32_t open_options = File::eOpenOptionWrite | File::eOpenOptionCanCreate;
745 const bool append = m_outfile_options.GetAppend().GetCurrentValue();
746 if (append)
747 open_options |= File::eOpenOptionAppend;
748
749 if (outfile_stream.GetFile ().Open (path, open_options).Success())
Greg Claytone9f5fbd2010-10-10 20:52:20 +0000750 {
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000751 if (m_memory_options.m_output_as_binary)
Greg Claytone9f5fbd2010-10-10 20:52:20 +0000752 {
Greg Clayton36da2aa2013-01-25 18:06:21 +0000753 const size_t bytes_written = outfile_stream.Write (data_sp->GetBytes(), bytes_read);
Greg Claytone9f5fbd2010-10-10 20:52:20 +0000754 if (bytes_written > 0)
755 {
Greg Clayton36da2aa2013-01-25 18:06:21 +0000756 result.GetOutputStream().Printf ("%zi bytes %s to '%s'\n",
Greg Claytone9f5fbd2010-10-10 20:52:20 +0000757 bytes_written,
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000758 append ? "appended" : "written",
Greg Claytone9f5fbd2010-10-10 20:52:20 +0000759 path);
760 return true;
761 }
762 else
763 {
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000764 result.AppendErrorWithFormat("Failed to write %" PRIu64 " bytes to '%s'.\n", (uint64_t)bytes_read, path);
Greg Claytone9f5fbd2010-10-10 20:52:20 +0000765 result.SetStatus(eReturnStatusFailed);
766 return false;
767 }
768 }
769 else
770 {
771 // We are going to write ASCII to the file just point the
772 // output_stream to our outfile_stream...
773 output_stream = &outfile_stream;
774 }
775 }
776 else
777 {
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000778 result.AppendErrorWithFormat("Failed to open file '%s' for %s.\n", path, append ? "append" : "write");
Greg Claytone9f5fbd2010-10-10 20:52:20 +0000779 result.SetStatus(eReturnStatusFailed);
780 return false;
781 }
782 }
783 else
784 {
785 output_stream = &result.GetOutputStream();
786 }
787
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000788
Greg Claytonea0bb4d2013-01-09 19:44:40 +0000789 ExecutionContextScope *exe_scope = m_exe_ctx.GetBestExecutionContextScope();
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000790 if (clang_ast_type.GetOpaqueQualType())
791 {
792 for (uint32_t i = 0; i<item_count; ++i)
793 {
794 addr_t item_addr = addr + (i * item_byte_size);
Greg Clayton3508c382012-02-24 01:59:29 +0000795 Address address (item_addr);
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000796 StreamString name_strm;
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000797 name_strm.Printf ("0x%" PRIx64, item_addr);
Greg Clayton24a6bd92011-10-27 17:55:14 +0000798 ValueObjectSP valobj_sp (ValueObjectMemory::Create (exe_scope,
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000799 name_strm.GetString().c_str(),
800 address,
801 clang_ast_type));
802 if (valobj_sp)
803 {
Greg Claytonbad1c9e2012-12-15 02:08:17 +0000804 Format format = m_format_options.GetFormat();
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000805 if (format != eFormatDefault)
806 valobj_sp->SetFormat (format);
807
Enrico Granatac3f5cd82013-03-26 18:04:53 +0000808 ValueObject::DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions(false,format));
809
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000810 ValueObject::DumpValueObject (*output_stream,
811 valobj_sp.get(),
Enrico Granata3069c622012-03-01 04:24:26 +0000812 options);
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000813 }
814 else
815 {
816 result.AppendErrorWithFormat ("failed to create a value object for: (%s) %s\n",
817 view_as_type_cstr,
818 name_strm.GetString().c_str());
819 result.SetStatus(eReturnStatusFailed);
820 return false;
821 }
822 }
823 return true;
824 }
825
826 result.SetStatus(eReturnStatusSuccessFinishResult);
827 DataExtractor data (data_sp,
Greg Clayton567e7f32011-09-22 04:58:26 +0000828 target->GetArchitecture().GetByteOrder(),
829 target->GetArchitecture().GetAddressByteSize());
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000830
831
Greg Claytone9f5fbd2010-10-10 20:52:20 +0000832 assert (output_stream);
Greg Clayton36da2aa2013-01-25 18:06:21 +0000833 size_t bytes_dumped = data.Dump (output_stream,
834 0,
835 m_format_options.GetFormat(),
836 item_byte_size,
837 item_count,
838 num_per_line,
839 addr,
840 0,
841 0,
842 exe_scope);
Greg Clayton746979d2011-10-28 23:44:55 +0000843 m_next_addr = addr + bytes_dumped;
Greg Claytone9f5fbd2010-10-10 20:52:20 +0000844 output_stream->EOL();
Chris Lattner24943d22010-06-08 16:52:24 +0000845 return true;
846 }
847
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000848 OptionGroupOptions m_option_group;
849 OptionGroupFormat m_format_options;
850 OptionGroupReadMemory m_memory_options;
851 OptionGroupOutputFile m_outfile_options;
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000852 OptionGroupValueObjectDisplay m_varobj_options;
Greg Clayton902b5be2011-10-26 04:32:38 +0000853 lldb::addr_t m_next_addr;
854 lldb::addr_t m_prev_byte_size;
855 OptionGroupFormat m_prev_format_options;
856 OptionGroupReadMemory m_prev_memory_options;
857 OptionGroupOutputFile m_prev_outfile_options;
858 OptionGroupValueObjectDisplay m_prev_varobj_options;
Greg Claytonbad1c9e2012-12-15 02:08:17 +0000859 ClangASTType m_prev_clang_ast_type;
Chris Lattner24943d22010-06-08 16:52:24 +0000860};
861
Greg Claytona42880a2011-10-25 06:44:01 +0000862
863OptionDefinition
864g_memory_write_option_table[] =
865{
866{ LLDB_OPT_SET_1, true, "infile", 'i', required_argument, NULL, 0, eArgTypeFilename, "Write memory using the contents of a file."},
867{ LLDB_OPT_SET_1, false, "offset", 'o', required_argument, NULL, 0, eArgTypeOffset, "Start writng bytes from an offset within the input file."},
868};
869
870
Chris Lattner24943d22010-06-08 16:52:24 +0000871//----------------------------------------------------------------------
872// Write memory to the inferior process
873//----------------------------------------------------------------------
Jim Inghamda26bd22012-06-08 21:56:10 +0000874class CommandObjectMemoryWrite : public CommandObjectParsed
Chris Lattner24943d22010-06-08 16:52:24 +0000875{
876public:
877
Greg Claytona42880a2011-10-25 06:44:01 +0000878 class OptionGroupWriteMemory : public OptionGroup
Chris Lattner24943d22010-06-08 16:52:24 +0000879 {
880 public:
Greg Claytona42880a2011-10-25 06:44:01 +0000881 OptionGroupWriteMemory () :
882 OptionGroup()
Chris Lattner24943d22010-06-08 16:52:24 +0000883 {
Chris Lattner24943d22010-06-08 16:52:24 +0000884 }
885
886 virtual
Greg Claytona42880a2011-10-25 06:44:01 +0000887 ~OptionGroupWriteMemory ()
Chris Lattner24943d22010-06-08 16:52:24 +0000888 {
889 }
890
Greg Claytona42880a2011-10-25 06:44:01 +0000891 virtual uint32_t
892 GetNumDefinitions ()
893 {
894 return sizeof (g_memory_write_option_table) / sizeof (OptionDefinition);
895 }
896
897 virtual const OptionDefinition*
898 GetDefinitions ()
899 {
900 return g_memory_write_option_table;
901 }
902
Chris Lattner24943d22010-06-08 16:52:24 +0000903 virtual Error
Greg Claytona42880a2011-10-25 06:44:01 +0000904 SetOptionValue (CommandInterpreter &interpreter,
905 uint32_t option_idx,
906 const char *option_arg)
Chris Lattner24943d22010-06-08 16:52:24 +0000907 {
908 Error error;
Greg Clayton6475c422012-12-04 00:32:51 +0000909 const int short_option = g_memory_write_option_table[option_idx].short_option;
Greg Claytona42880a2011-10-25 06:44:01 +0000910
Chris Lattner24943d22010-06-08 16:52:24 +0000911 switch (short_option)
912 {
Greg Claytona42880a2011-10-25 06:44:01 +0000913 case 'i':
914 m_infile.SetFile (option_arg, true);
915 if (!m_infile.Exists())
Greg Claytone9f5fbd2010-10-10 20:52:20 +0000916 {
Greg Claytona42880a2011-10-25 06:44:01 +0000917 m_infile.Clear();
Greg Clayton9c236732011-10-26 00:56:27 +0000918 error.SetErrorStringWithFormat("input file does not exist: '%s'", option_arg);
Greg Claytone9f5fbd2010-10-10 20:52:20 +0000919 }
Greg Claytona42880a2011-10-25 06:44:01 +0000920 break;
921
922 case 'o':
923 {
924 bool success;
925 m_infile_offset = Args::StringToUInt64(option_arg, 0, 0, &success);
926 if (!success)
927 {
Greg Clayton9c236732011-10-26 00:56:27 +0000928 error.SetErrorStringWithFormat("invalid offset string '%s'", option_arg);
Greg Claytona42880a2011-10-25 06:44:01 +0000929 }
930 }
931 break;
932
933 default:
Greg Clayton9c236732011-10-26 00:56:27 +0000934 error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option);
Greg Claytona42880a2011-10-25 06:44:01 +0000935 break;
Chris Lattner24943d22010-06-08 16:52:24 +0000936 }
937 return error;
938 }
Greg Claytona42880a2011-10-25 06:44:01 +0000939
940 virtual void
941 OptionParsingStarting (CommandInterpreter &interpreter)
Chris Lattner24943d22010-06-08 16:52:24 +0000942 {
Greg Claytone9f5fbd2010-10-10 20:52:20 +0000943 m_infile.Clear();
944 m_infile_offset = 0;
Chris Lattner24943d22010-06-08 16:52:24 +0000945 }
946
Greg Claytone9f5fbd2010-10-10 20:52:20 +0000947 FileSpec m_infile;
948 off_t m_infile_offset;
Chris Lattner24943d22010-06-08 16:52:24 +0000949 };
950
Greg Clayton238c0a12010-09-18 01:14:36 +0000951 CommandObjectMemoryWrite (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000952 CommandObjectParsed (interpreter,
953 "memory write",
954 "Write to the memory of the process being debugged.",
955 NULL,
Greg Claytonea0bb4d2013-01-09 19:44:40 +0000956 eFlagRequiresProcess | eFlagProcessMustBeLaunched),
Greg Claytona42880a2011-10-25 06:44:01 +0000957 m_option_group (interpreter),
958 m_format_options (eFormatBytes, 1, UINT64_MAX),
959 m_memory_options ()
Chris Lattner24943d22010-06-08 16:52:24 +0000960 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000961 CommandArgumentEntry arg1;
962 CommandArgumentEntry arg2;
963 CommandArgumentData addr_arg;
964 CommandArgumentData value_arg;
965
966 // Define the first (and only) variant of this arg.
967 addr_arg.arg_type = eArgTypeAddress;
968 addr_arg.arg_repetition = eArgRepeatPlain;
969
970 // There is only one variant this argument could be; put it into the argument entry.
971 arg1.push_back (addr_arg);
972
973 // Define the first (and only) variant of this arg.
974 value_arg.arg_type = eArgTypeValue;
975 value_arg.arg_repetition = eArgRepeatPlus;
976
977 // There is only one variant this argument could be; put it into the argument entry.
978 arg2.push_back (value_arg);
979
980 // Push the data for the first argument into the m_arguments vector.
981 m_arguments.push_back (arg1);
982 m_arguments.push_back (arg2);
Greg Claytona42880a2011-10-25 06:44:01 +0000983
984 m_option_group.Append (&m_format_options, OptionGroupFormat::OPTION_GROUP_FORMAT, LLDB_OPT_SET_1);
985 m_option_group.Append (&m_format_options, OptionGroupFormat::OPTION_GROUP_SIZE , LLDB_OPT_SET_1|LLDB_OPT_SET_2);
986 m_option_group.Append (&m_memory_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_2);
987 m_option_group.Finalize();
988
Chris Lattner24943d22010-06-08 16:52:24 +0000989 }
990
991 virtual
992 ~CommandObjectMemoryWrite ()
993 {
994 }
995
996 Options *
997 GetOptions ()
998 {
Greg Claytona42880a2011-10-25 06:44:01 +0000999 return &m_option_group;
Chris Lattner24943d22010-06-08 16:52:24 +00001000 }
1001
1002 bool
1003 UIntValueIsValidForSize (uint64_t uval64, size_t total_byte_size)
1004 {
1005 if (total_byte_size > 8)
1006 return false;
1007
1008 if (total_byte_size == 8)
1009 return true;
1010
1011 const uint64_t max = ((uint64_t)1 << (uint64_t)(total_byte_size * 8)) - 1;
1012 return uval64 <= max;
1013 }
1014
1015 bool
1016 SIntValueIsValidForSize (int64_t sval64, size_t total_byte_size)
1017 {
1018 if (total_byte_size > 8)
1019 return false;
1020
1021 if (total_byte_size == 8)
1022 return true;
1023
1024 const int64_t max = ((int64_t)1 << (uint64_t)(total_byte_size * 8 - 1)) - 1;
1025 const int64_t min = ~(max);
1026 return min <= sval64 && sval64 <= max;
1027 }
1028
Jim Inghamda26bd22012-06-08 21:56:10 +00001029protected:
Chris Lattner24943d22010-06-08 16:52:24 +00001030 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +00001031 DoExecute (Args& command, CommandReturnObject &result)
Chris Lattner24943d22010-06-08 16:52:24 +00001032 {
Greg Claytonea0bb4d2013-01-09 19:44:40 +00001033 // No need to check "process" for validity as eFlagRequiresProcess ensures it is valid
1034 Process *process = m_exe_ctx.GetProcessPtr();
Chris Lattner24943d22010-06-08 16:52:24 +00001035
1036 const size_t argc = command.GetArgumentCount();
1037
Greg Claytona42880a2011-10-25 06:44:01 +00001038 if (m_memory_options.m_infile)
Chris Lattner24943d22010-06-08 16:52:24 +00001039 {
Greg Claytone9f5fbd2010-10-10 20:52:20 +00001040 if (argc < 1)
1041 {
1042 result.AppendErrorWithFormat ("%s takes a destination address when writing file contents.\n", m_cmd_name.c_str());
1043 result.SetStatus(eReturnStatusFailed);
1044 return false;
1045 }
1046 }
1047 else if (argc < 2)
1048 {
1049 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 +00001050 result.SetStatus(eReturnStatusFailed);
1051 return false;
1052 }
1053
Chris Lattner24943d22010-06-08 16:52:24 +00001054 StreamString buffer (Stream::eBinary,
Greg Clayton395fc332011-02-15 21:59:32 +00001055 process->GetTarget().GetArchitecture().GetAddressByteSize(),
1056 process->GetTarget().GetArchitecture().GetByteOrder());
Chris Lattner24943d22010-06-08 16:52:24 +00001057
Greg Claytona42880a2011-10-25 06:44:01 +00001058 OptionValueUInt64 &byte_size_value = m_format_options.GetByteSizeValue();
1059 size_t item_byte_size = byte_size_value.GetCurrentValue();
Greg Clayton54e7afa2010-07-09 20:39:50 +00001060
Greg Clayton49d888d2012-12-06 22:49:16 +00001061 Error error;
Greg Claytonea0bb4d2013-01-09 19:44:40 +00001062 lldb::addr_t addr = Args::StringToAddress (&m_exe_ctx,
Greg Clayton49d888d2012-12-06 22:49:16 +00001063 command.GetArgumentAtIndex(0),
1064 LLDB_INVALID_ADDRESS,
1065 &error);
Chris Lattner24943d22010-06-08 16:52:24 +00001066
1067 if (addr == LLDB_INVALID_ADDRESS)
1068 {
Greg Clayton49d888d2012-12-06 22:49:16 +00001069 result.AppendError("invalid address expression\n");
1070 result.AppendError(error.AsCString());
Chris Lattner24943d22010-06-08 16:52:24 +00001071 result.SetStatus(eReturnStatusFailed);
1072 return false;
1073 }
Greg Claytone9f5fbd2010-10-10 20:52:20 +00001074
Greg Claytona42880a2011-10-25 06:44:01 +00001075 if (m_memory_options.m_infile)
Greg Claytone9f5fbd2010-10-10 20:52:20 +00001076 {
1077 size_t length = SIZE_MAX;
Greg Claytona42880a2011-10-25 06:44:01 +00001078 if (item_byte_size > 0)
1079 length = item_byte_size;
1080 lldb::DataBufferSP data_sp (m_memory_options.m_infile.ReadFileContents (m_memory_options.m_infile_offset, length));
Greg Claytone9f5fbd2010-10-10 20:52:20 +00001081 if (data_sp)
1082 {
1083 length = data_sp->GetByteSize();
1084 if (length > 0)
1085 {
1086 Error error;
1087 size_t bytes_written = process->WriteMemory (addr, data_sp->GetBytes(), length, error);
1088
1089 if (bytes_written == length)
1090 {
1091 // All bytes written
Daniel Malea5f35a4b2012-11-29 21:49:15 +00001092 result.GetOutputStream().Printf("%" PRIu64 " bytes were written to 0x%" PRIx64 "\n", (uint64_t)bytes_written, addr);
Greg Claytone9f5fbd2010-10-10 20:52:20 +00001093 result.SetStatus(eReturnStatusSuccessFinishResult);
1094 }
1095 else if (bytes_written > 0)
1096 {
1097 // Some byte written
Daniel Malea5f35a4b2012-11-29 21:49:15 +00001098 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 +00001099 result.SetStatus(eReturnStatusSuccessFinishResult);
1100 }
1101 else
1102 {
Daniel Malea5f35a4b2012-11-29 21:49:15 +00001103 result.AppendErrorWithFormat ("Memory write to 0x%" PRIx64 " failed: %s.\n", addr, error.AsCString());
Greg Claytone9f5fbd2010-10-10 20:52:20 +00001104 result.SetStatus(eReturnStatusFailed);
1105 }
1106 }
1107 }
1108 else
1109 {
1110 result.AppendErrorWithFormat ("Unable to read contents of file.\n");
1111 result.SetStatus(eReturnStatusFailed);
1112 }
1113 return result.Succeeded();
1114 }
Greg Claytona42880a2011-10-25 06:44:01 +00001115 else if (item_byte_size == 0)
Greg Claytone9f5fbd2010-10-10 20:52:20 +00001116 {
Greg Claytona42880a2011-10-25 06:44:01 +00001117 if (m_format_options.GetFormat() == eFormatPointer)
Greg Claytone9f5fbd2010-10-10 20:52:20 +00001118 item_byte_size = buffer.GetAddressByteSize();
1119 else
1120 item_byte_size = 1;
1121 }
1122
Chris Lattner24943d22010-06-08 16:52:24 +00001123 command.Shift(); // shift off the address argument
1124 uint64_t uval64;
1125 int64_t sval64;
1126 bool success = false;
Greg Clayton36da2aa2013-01-25 18:06:21 +00001127 const size_t num_value_args = command.GetArgumentCount();
1128 for (size_t i=0; i<num_value_args; ++i)
Chris Lattner24943d22010-06-08 16:52:24 +00001129 {
1130 const char *value_str = command.GetArgumentAtIndex(i);
1131
Greg Claytona42880a2011-10-25 06:44:01 +00001132 switch (m_format_options.GetFormat())
Chris Lattner24943d22010-06-08 16:52:24 +00001133 {
Greg Clayton3182eff2011-06-23 21:22:24 +00001134 case kNumFormats:
Chris Lattner24943d22010-06-08 16:52:24 +00001135 case eFormatFloat: // TODO: add support for floats soon
1136 case eFormatCharPrintable:
1137 case eFormatBytesWithASCII:
1138 case eFormatComplex:
1139 case eFormatEnum:
1140 case eFormatUnicode16:
1141 case eFormatUnicode32:
1142 case eFormatVectorOfChar:
1143 case eFormatVectorOfSInt8:
1144 case eFormatVectorOfUInt8:
1145 case eFormatVectorOfSInt16:
1146 case eFormatVectorOfUInt16:
1147 case eFormatVectorOfSInt32:
1148 case eFormatVectorOfUInt32:
1149 case eFormatVectorOfSInt64:
1150 case eFormatVectorOfUInt64:
1151 case eFormatVectorOfFloat32:
1152 case eFormatVectorOfFloat64:
1153 case eFormatVectorOfUInt128:
Greg Clayton4fdf7602011-03-20 04:57:14 +00001154 case eFormatOSType:
1155 case eFormatComplexInteger:
Greg Clayton24a6bd92011-10-27 17:55:14 +00001156 case eFormatAddressInfo:
1157 case eFormatHexFloat:
1158 case eFormatInstruction:
Sean Callanan96abc622012-08-08 17:35:10 +00001159 case eFormatVoid:
Chris Lattner24943d22010-06-08 16:52:24 +00001160 result.AppendError("unsupported format for writing memory");
1161 result.SetStatus(eReturnStatusFailed);
1162 return false;
1163
1164 case eFormatDefault:
1165 case eFormatBytes:
1166 case eFormatHex:
Enrico Granata535543d2012-08-09 19:33:34 +00001167 case eFormatHexUppercase:
Greg Clayton54e7afa2010-07-09 20:39:50 +00001168 case eFormatPointer:
1169
Chris Lattner24943d22010-06-08 16:52:24 +00001170 // Decode hex bytes
1171 uval64 = Args::StringToUInt64(value_str, UINT64_MAX, 16, &success);
1172 if (!success)
1173 {
1174 result.AppendErrorWithFormat ("'%s' is not a valid hex string value.\n", value_str);
1175 result.SetStatus(eReturnStatusFailed);
1176 return false;
1177 }
1178 else if (!UIntValueIsValidForSize (uval64, item_byte_size))
1179 {
Daniel Malea5f35a4b2012-11-29 21:49:15 +00001180 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 +00001181 result.SetStatus(eReturnStatusFailed);
1182 return false;
1183 }
1184 buffer.PutMaxHex64 (uval64, item_byte_size);
1185 break;
1186
1187 case eFormatBoolean:
1188 uval64 = Args::StringToBoolean(value_str, false, &success);
1189 if (!success)
1190 {
1191 result.AppendErrorWithFormat ("'%s' is not a valid boolean string value.\n", value_str);
1192 result.SetStatus(eReturnStatusFailed);
1193 return false;
1194 }
1195 buffer.PutMaxHex64 (uval64, item_byte_size);
1196 break;
1197
1198 case eFormatBinary:
1199 uval64 = Args::StringToUInt64(value_str, UINT64_MAX, 2, &success);
1200 if (!success)
1201 {
1202 result.AppendErrorWithFormat ("'%s' is not a valid binary string value.\n", value_str);
1203 result.SetStatus(eReturnStatusFailed);
1204 return false;
1205 }
1206 else if (!UIntValueIsValidForSize (uval64, item_byte_size))
1207 {
Daniel Malea5f35a4b2012-11-29 21:49:15 +00001208 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 +00001209 result.SetStatus(eReturnStatusFailed);
1210 return false;
1211 }
1212 buffer.PutMaxHex64 (uval64, item_byte_size);
1213 break;
1214
Greg Clayton307fa072011-06-17 23:50:44 +00001215 case eFormatCharArray:
Chris Lattner24943d22010-06-08 16:52:24 +00001216 case eFormatChar:
1217 case eFormatCString:
1218 if (value_str[0])
1219 {
1220 size_t len = strlen (value_str);
1221 // Include the NULL for C strings...
Greg Claytona42880a2011-10-25 06:44:01 +00001222 if (m_format_options.GetFormat() == eFormatCString)
Chris Lattner24943d22010-06-08 16:52:24 +00001223 ++len;
1224 Error error;
1225 if (process->WriteMemory (addr, value_str, len, error) == len)
1226 {
1227 addr += len;
1228 }
1229 else
1230 {
Daniel Malea5f35a4b2012-11-29 21:49:15 +00001231 result.AppendErrorWithFormat ("Memory write to 0x%" PRIx64 " failed: %s.\n", addr, error.AsCString());
Chris Lattner24943d22010-06-08 16:52:24 +00001232 result.SetStatus(eReturnStatusFailed);
1233 return false;
1234 }
1235 }
1236 break;
1237
1238 case eFormatDecimal:
1239 sval64 = Args::StringToSInt64(value_str, INT64_MAX, 0, &success);
1240 if (!success)
1241 {
1242 result.AppendErrorWithFormat ("'%s' is not a valid signed decimal value.\n", value_str);
1243 result.SetStatus(eReturnStatusFailed);
1244 return false;
1245 }
1246 else if (!SIntValueIsValidForSize (sval64, item_byte_size))
1247 {
Daniel Malea5f35a4b2012-11-29 21:49:15 +00001248 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 +00001249 result.SetStatus(eReturnStatusFailed);
1250 return false;
1251 }
1252 buffer.PutMaxHex64 (sval64, item_byte_size);
1253 break;
1254
1255 case eFormatUnsigned:
1256 uval64 = Args::StringToUInt64(value_str, UINT64_MAX, 0, &success);
1257 if (!success)
1258 {
1259 result.AppendErrorWithFormat ("'%s' is not a valid unsigned decimal string value.\n", value_str);
1260 result.SetStatus(eReturnStatusFailed);
1261 return false;
1262 }
1263 else if (!UIntValueIsValidForSize (uval64, item_byte_size))
1264 {
Daniel Malea5f35a4b2012-11-29 21:49:15 +00001265 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 +00001266 result.SetStatus(eReturnStatusFailed);
1267 return false;
1268 }
1269 buffer.PutMaxHex64 (uval64, item_byte_size);
1270 break;
1271
1272 case eFormatOctal:
1273 uval64 = Args::StringToUInt64(value_str, UINT64_MAX, 8, &success);
1274 if (!success)
1275 {
1276 result.AppendErrorWithFormat ("'%s' is not a valid octal string value.\n", value_str);
1277 result.SetStatus(eReturnStatusFailed);
1278 return false;
1279 }
1280 else if (!UIntValueIsValidForSize (uval64, item_byte_size))
1281 {
Daniel Malea5f35a4b2012-11-29 21:49:15 +00001282 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 +00001283 result.SetStatus(eReturnStatusFailed);
1284 return false;
1285 }
1286 buffer.PutMaxHex64 (uval64, item_byte_size);
1287 break;
1288 }
1289 }
1290
1291 if (!buffer.GetString().empty())
1292 {
1293 Error error;
Greg Clayton53d68e72010-07-20 22:52:08 +00001294 if (process->WriteMemory (addr, buffer.GetString().c_str(), buffer.GetString().size(), error) == buffer.GetString().size())
Chris Lattner24943d22010-06-08 16:52:24 +00001295 return true;
1296 else
1297 {
Daniel Malea5f35a4b2012-11-29 21:49:15 +00001298 result.AppendErrorWithFormat ("Memory write to 0x%" PRIx64 " failed: %s.\n", addr, error.AsCString());
Chris Lattner24943d22010-06-08 16:52:24 +00001299 result.SetStatus(eReturnStatusFailed);
1300 return false;
1301 }
1302 }
1303 return true;
1304 }
1305
Greg Claytona42880a2011-10-25 06:44:01 +00001306 OptionGroupOptions m_option_group;
1307 OptionGroupFormat m_format_options;
1308 OptionGroupWriteMemory m_memory_options;
Chris Lattner24943d22010-06-08 16:52:24 +00001309};
1310
Chris Lattner24943d22010-06-08 16:52:24 +00001311
1312//-------------------------------------------------------------------------
1313// CommandObjectMemory
1314//-------------------------------------------------------------------------
1315
Greg Clayton63094e02010-06-23 01:19:29 +00001316CommandObjectMemory::CommandObjectMemory (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +00001317 CommandObjectMultiword (interpreter,
1318 "memory",
Caroline Ticec1ad82e2010-09-07 22:38:08 +00001319 "A set of commands for operating on memory.",
Chris Lattner24943d22010-06-08 16:52:24 +00001320 "memory <subcommand> [<subcommand-options>]")
1321{
Greg Clayton238c0a12010-09-18 01:14:36 +00001322 LoadSubCommand ("read", CommandObjectSP (new CommandObjectMemoryRead (interpreter)));
1323 LoadSubCommand ("write", CommandObjectSP (new CommandObjectMemoryWrite (interpreter)));
Chris Lattner24943d22010-06-08 16:52:24 +00001324}
1325
1326CommandObjectMemory::~CommandObjectMemory ()
1327{
1328}