blob: 8369d859303304275635826dd04f0bacc2eb7110 [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,
301 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 Clayton57b3c6b2011-04-27 22:04:39 +0000374 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
Greg Clayton567e7f32011-09-22 04:58:26 +0000375 Target *target = exe_ctx.GetTargetPtr();
376 if (target == NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000377 {
Jim Ingham8cc3f692011-07-09 00:55:34 +0000378 result.AppendError("need at least a target to read memory");
Chris Lattner24943d22010-06-08 16:52:24 +0000379 result.SetStatus(eReturnStatusFailed);
380 return false;
381 }
382 const size_t argc = command.GetArgumentCount();
383
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000384
Greg Clayton902b5be2011-10-26 04:32:38 +0000385 if ((argc == 0 && m_next_addr == LLDB_INVALID_ADDRESS) || argc > 2)
Chris Lattner24943d22010-06-08 16:52:24 +0000386 {
Greg Clayton49d888d2012-12-06 22:49:16 +0000387 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 +0000388 result.AppendRawWarning("Expressions should be quoted if they contain spaces or other special characters.\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000389 result.SetStatus(eReturnStatusFailed);
390 return false;
391 }
392
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000393 ClangASTType clang_ast_type;
394 Error error;
395
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000396 const char *view_as_type_cstr = m_memory_options.m_view_as_type.GetCurrentValue();
397 if (view_as_type_cstr && view_as_type_cstr[0])
Chris Lattner24943d22010-06-08 16:52:24 +0000398 {
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000399 // We are viewing memory as a type
Greg Claytonbad1c9e2012-12-15 02:08:17 +0000400
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000401 SymbolContext sc;
Greg Claytondc0a38c2012-03-26 23:03:23 +0000402 const bool exact_match = false;
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000403 TypeList type_list;
404 uint32_t reference_count = 0;
405 uint32_t pointer_count = 0;
406 size_t idx;
Sean Callananddb2ece2012-07-10 21:24:26 +0000407
408#define ALL_KEYWORDS \
409 KEYWORD("const") \
410 KEYWORD("volatile") \
411 KEYWORD("restrict") \
412 KEYWORD("struct") \
413 KEYWORD("class") \
414 KEYWORD("union")
415
416#define KEYWORD(s) s,
417 static const char *g_keywords[] =
418 {
419 ALL_KEYWORDS
420 };
421#undef KEYWORD
422
423#define KEYWORD(s) (sizeof(s) - 1),
424 static const int g_keyword_lengths[] =
425 {
426 ALL_KEYWORDS
427 };
428#undef KEYWORD
429
430#undef ALL_KEYWORDS
431
432 static size_t g_num_keywords = sizeof(g_keywords) / sizeof(const char *);
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000433 std::string type_str(view_as_type_cstr);
434
435 // Remove all instances of g_keywords that are followed by spaces
436 for (size_t i = 0; i < g_num_keywords; ++i)
437 {
438 const char *keyword = g_keywords[i];
Sean Callananddb2ece2012-07-10 21:24:26 +0000439 int keyword_len = g_keyword_lengths[i];
440
441 idx = 0;
442 while ((idx = type_str.find (keyword, idx)) != std::string::npos)
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000443 {
444 if (type_str[idx + keyword_len] == ' ' || type_str[idx + keyword_len] == '\t')
Sean Callananddb2ece2012-07-10 21:24:26 +0000445 {
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000446 type_str.erase(idx, keyword_len+1);
Sean Callananddb2ece2012-07-10 21:24:26 +0000447 idx = 0;
448 }
449 else
450 {
451 idx += keyword_len;
452 }
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000453 }
454 }
455 bool done = type_str.empty();
456 //
457 idx = type_str.find_first_not_of (" \t");
458 if (idx > 0 && idx != std::string::npos)
459 type_str.erase (0, idx);
460 while (!done)
461 {
462 // Strip trailing spaces
463 if (type_str.empty())
464 done = true;
465 else
466 {
467 switch (type_str[type_str.size()-1])
468 {
469 case '*':
470 ++pointer_count;
471 // fall through...
472 case ' ':
473 case '\t':
474 type_str.erase(type_str.size()-1);
475 break;
476
477 case '&':
478 if (reference_count == 0)
479 {
480 reference_count = 1;
481 type_str.erase(type_str.size()-1);
482 }
483 else
484 {
485 result.AppendErrorWithFormat ("invalid type string: '%s'\n", view_as_type_cstr);
486 result.SetStatus(eReturnStatusFailed);
487 return false;
488 }
489 break;
490
491 default:
492 done = true;
493 break;
494 }
495 }
496 }
497
498 ConstString lookup_type_name(type_str.c_str());
Greg Clayton567e7f32011-09-22 04:58:26 +0000499 StackFrame *frame = exe_ctx.GetFramePtr();
500 if (frame)
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000501 {
Greg Clayton567e7f32011-09-22 04:58:26 +0000502 sc = frame->GetSymbolContext (eSymbolContextModule);
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000503 if (sc.module_sp)
504 {
Sean Callanan3e80cd92011-10-12 02:08:07 +0000505 sc.module_sp->FindTypes (sc,
506 lookup_type_name,
Greg Claytondc0a38c2012-03-26 23:03:23 +0000507 exact_match,
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000508 1,
509 type_list);
510 }
511 }
512 if (type_list.GetSize() == 0)
513 {
Greg Clayton9f95fb62012-04-06 17:41:13 +0000514 target->GetImages().FindTypes (sc,
Greg Clayton567e7f32011-09-22 04:58:26 +0000515 lookup_type_name,
Greg Claytondc0a38c2012-03-26 23:03:23 +0000516 exact_match,
Greg Clayton567e7f32011-09-22 04:58:26 +0000517 1,
518 type_list);
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000519 }
520
521 if (type_list.GetSize() == 0)
522 {
523 result.AppendErrorWithFormat ("unable to find any types that match the raw type '%s' for full type '%s'\n",
524 lookup_type_name.GetCString(),
525 view_as_type_cstr);
526 result.SetStatus(eReturnStatusFailed);
527 return false;
528 }
529
530 TypeSP type_sp (type_list.GetTypeAtIndex(0));
531 clang_ast_type.SetClangType (type_sp->GetClangAST(), type_sp->GetClangFullType());
532
533 while (pointer_count > 0)
534 {
535 clang_type_t pointer_type = ClangASTContext::CreatePointerType (clang_ast_type.GetASTContext(), clang_ast_type.GetOpaqueQualType());
536 if (pointer_type)
537 clang_ast_type.SetClangType (clang_ast_type.GetASTContext(), pointer_type);
538 else
539 {
540 result.AppendError ("unable make a pointer type\n");
541 result.SetStatus(eReturnStatusFailed);
542 return false;
543 }
544 --pointer_count;
545 }
546
Greg Claytona42880a2011-10-25 06:44:01 +0000547 m_format_options.GetByteSizeValue() = (clang_ast_type.GetClangTypeBitWidth () + 7) / 8;
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000548
Greg Claytona42880a2011-10-25 06:44:01 +0000549 if (m_format_options.GetByteSizeValue() == 0)
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000550 {
551 result.AppendErrorWithFormat ("unable to get the byte size of the type '%s'\n",
552 view_as_type_cstr);
553 result.SetStatus(eReturnStatusFailed);
554 return false;
555 }
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000556
Greg Claytona42880a2011-10-25 06:44:01 +0000557 if (!m_format_options.GetCountValue().OptionWasSet())
558 m_format_options.GetCountValue() = 1;
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000559 }
560 else
561 {
Greg Clayton567e7f32011-09-22 04:58:26 +0000562 error = m_memory_options.FinalizeSettings (target, m_format_options);
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000563 }
564
565 // Look for invalid combinations of settings
566 if (error.Fail())
567 {
Greg Clayton49d888d2012-12-06 22:49:16 +0000568 result.AppendError(error.AsCString());
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000569 result.SetStatus(eReturnStatusFailed);
570 return false;
Chris Lattner24943d22010-06-08 16:52:24 +0000571 }
572
Greg Clayton902b5be2011-10-26 04:32:38 +0000573 lldb::addr_t addr;
574 size_t total_byte_size = 0;
575 if (argc == 0)
576 {
577 // Use the last address and byte size and all options as they were
578 // if no options have been set
579 addr = m_next_addr;
580 total_byte_size = m_prev_byte_size;
Greg Claytonbad1c9e2012-12-15 02:08:17 +0000581 clang_ast_type = m_prev_clang_ast_type;
582 if (!m_format_options.AnyOptionWasSet() &&
Greg Clayton902b5be2011-10-26 04:32:38 +0000583 !m_memory_options.AnyOptionWasSet() &&
584 !m_outfile_options.AnyOptionWasSet() &&
585 !m_varobj_options.AnyOptionWasSet())
586 {
587 m_format_options = m_prev_format_options;
588 m_memory_options = m_prev_memory_options;
589 m_outfile_options = m_prev_outfile_options;
590 m_varobj_options = m_prev_varobj_options;
591 }
592 }
593
Greg Claytona42880a2011-10-25 06:44:01 +0000594 size_t item_count = m_format_options.GetCountValue().GetCurrentValue();
595 const size_t item_byte_size = m_format_options.GetByteSizeValue().GetCurrentValue();
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000596 const size_t num_per_line = m_memory_options.m_num_per_line.GetCurrentValue();
Chris Lattner24943d22010-06-08 16:52:24 +0000597
Chris Lattner24943d22010-06-08 16:52:24 +0000598 if (total_byte_size == 0)
Greg Clayton902b5be2011-10-26 04:32:38 +0000599 {
600 total_byte_size = item_count * item_byte_size;
601 if (total_byte_size == 0)
602 total_byte_size = 32;
603 }
Chris Lattner24943d22010-06-08 16:52:24 +0000604
Greg Clayton902b5be2011-10-26 04:32:38 +0000605 if (argc > 0)
Greg Clayton49d888d2012-12-06 22:49:16 +0000606 addr = Args::StringToAddress(&exe_ctx, command.GetArgumentAtIndex(0), LLDB_INVALID_ADDRESS, &error);
Chris Lattner24943d22010-06-08 16:52:24 +0000607
608 if (addr == LLDB_INVALID_ADDRESS)
609 {
Greg Clayton49d888d2012-12-06 22:49:16 +0000610 result.AppendError("invalid start address expression.");
611 result.AppendError(error.AsCString());
Chris Lattner24943d22010-06-08 16:52:24 +0000612 result.SetStatus(eReturnStatusFailed);
613 return false;
614 }
615
616 if (argc == 2)
617 {
Greg Clayton49d888d2012-12-06 22:49:16 +0000618 lldb::addr_t end_addr = Args::StringToAddress(&exe_ctx, command.GetArgumentAtIndex(1), LLDB_INVALID_ADDRESS, 0);
Chris Lattner24943d22010-06-08 16:52:24 +0000619 if (end_addr == LLDB_INVALID_ADDRESS)
620 {
Greg Clayton49d888d2012-12-06 22:49:16 +0000621 result.AppendError("invalid end address expression.");
622 result.AppendError(error.AsCString());
Chris Lattner24943d22010-06-08 16:52:24 +0000623 result.SetStatus(eReturnStatusFailed);
624 return false;
625 }
626 else if (end_addr <= addr)
627 {
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000628 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 +0000629 result.SetStatus(eReturnStatusFailed);
630 return false;
631 }
Greg Claytona42880a2011-10-25 06:44:01 +0000632 else if (m_format_options.GetCountValue().OptionWasSet())
Chris Lattner24943d22010-06-08 16:52:24 +0000633 {
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000634 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 +0000635 result.SetStatus(eReturnStatusFailed);
636 return false;
637 }
638
639 total_byte_size = end_addr - addr;
640 item_count = total_byte_size / item_byte_size;
641 }
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000642
Sean Callanan8a6f3e92012-04-28 01:27:38 +0000643 if (total_byte_size > 1024 && !m_memory_options.m_force)
644 {
645 result.AppendErrorWithFormat("Normally, \'memory read\' will not read over 1Kbyte of data.\n");
646 result.AppendErrorWithFormat("Please use --force to override this restriction.\n");
647 return false;
648 }
649
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000650 DataBufferSP data_sp;
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000651 size_t bytes_read = 0;
Greg Claytonbad1c9e2012-12-15 02:08:17 +0000652 if (clang_ast_type.GetOpaqueQualType())
653 {
654 // Make sure we don't display our type as ASCII bytes like the default memory read
655 if (m_format_options.GetFormatValue().OptionWasSet() == false)
656 m_format_options.GetFormatValue().SetCurrentValue(eFormatDefault);
657
658 bytes_read = clang_ast_type.GetTypeByteSize() * m_format_options.GetCountValue().GetCurrentValue();
659 }
660 else
Chris Lattner24943d22010-06-08 16:52:24 +0000661 {
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000662 data_sp.reset (new DataBufferHeap (total_byte_size, '\0'));
Greg Clayton3508c382012-02-24 01:59:29 +0000663 Address address(addr, NULL);
Greg Clayton567e7f32011-09-22 04:58:26 +0000664 bytes_read = target->ReadMemory(address, false, data_sp->GetBytes (), data_sp->GetByteSize(), error);
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000665 if (bytes_read == 0)
666 {
Greg Clayton04e6ada2012-05-25 17:05:55 +0000667 const char *error_cstr = error.AsCString();
668 if (error_cstr && error_cstr[0])
669 {
670 result.AppendError(error_cstr);
671 }
672 else
673 {
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000674 result.AppendErrorWithFormat("failed to read memory from 0x%" PRIx64 ".\n", addr);
Greg Clayton04e6ada2012-05-25 17:05:55 +0000675 }
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000676 result.SetStatus(eReturnStatusFailed);
677 return false;
678 }
679
680 if (bytes_read < total_byte_size)
Greg Clayton49d888d2012-12-06 22:49:16 +0000681 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 +0000682 }
683
Greg Claytonbad1c9e2012-12-15 02:08:17 +0000684 m_next_addr = addr + bytes_read;
685 m_prev_byte_size = bytes_read;
686 m_prev_format_options = m_format_options;
687 m_prev_memory_options = m_memory_options;
688 m_prev_outfile_options = m_outfile_options;
689 m_prev_varobj_options = m_varobj_options;
690 m_prev_clang_ast_type = clang_ast_type;
691
Greg Claytone9f5fbd2010-10-10 20:52:20 +0000692 StreamFile outfile_stream;
693 Stream *output_stream = NULL;
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000694 const FileSpec &outfile_spec = m_outfile_options.GetFile().GetCurrentValue();
695 if (outfile_spec)
Greg Claytone9f5fbd2010-10-10 20:52:20 +0000696 {
697 char path[PATH_MAX];
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000698 outfile_spec.GetPath (path, sizeof(path));
699
700 uint32_t open_options = File::eOpenOptionWrite | File::eOpenOptionCanCreate;
701 const bool append = m_outfile_options.GetAppend().GetCurrentValue();
702 if (append)
703 open_options |= File::eOpenOptionAppend;
704
705 if (outfile_stream.GetFile ().Open (path, open_options).Success())
Greg Claytone9f5fbd2010-10-10 20:52:20 +0000706 {
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000707 if (m_memory_options.m_output_as_binary)
Greg Claytone9f5fbd2010-10-10 20:52:20 +0000708 {
709 int bytes_written = outfile_stream.Write (data_sp->GetBytes(), bytes_read);
710 if (bytes_written > 0)
711 {
712 result.GetOutputStream().Printf ("%i bytes %s to '%s'\n",
713 bytes_written,
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000714 append ? "appended" : "written",
Greg Claytone9f5fbd2010-10-10 20:52:20 +0000715 path);
716 return true;
717 }
718 else
719 {
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000720 result.AppendErrorWithFormat("Failed to write %" PRIu64 " bytes to '%s'.\n", (uint64_t)bytes_read, path);
Greg Claytone9f5fbd2010-10-10 20:52:20 +0000721 result.SetStatus(eReturnStatusFailed);
722 return false;
723 }
724 }
725 else
726 {
727 // We are going to write ASCII to the file just point the
728 // output_stream to our outfile_stream...
729 output_stream = &outfile_stream;
730 }
731 }
732 else
733 {
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000734 result.AppendErrorWithFormat("Failed to open file '%s' for %s.\n", path, append ? "append" : "write");
Greg Claytone9f5fbd2010-10-10 20:52:20 +0000735 result.SetStatus(eReturnStatusFailed);
736 return false;
737 }
738 }
739 else
740 {
741 output_stream = &result.GetOutputStream();
742 }
743
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000744
Greg Clayton24a6bd92011-10-27 17:55:14 +0000745 ExecutionContextScope *exe_scope = exe_ctx.GetBestExecutionContextScope();
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000746 if (clang_ast_type.GetOpaqueQualType())
747 {
748 for (uint32_t i = 0; i<item_count; ++i)
749 {
750 addr_t item_addr = addr + (i * item_byte_size);
Greg Clayton3508c382012-02-24 01:59:29 +0000751 Address address (item_addr);
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000752 StreamString name_strm;
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000753 name_strm.Printf ("0x%" PRIx64, item_addr);
Greg Clayton24a6bd92011-10-27 17:55:14 +0000754 ValueObjectSP valobj_sp (ValueObjectMemory::Create (exe_scope,
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000755 name_strm.GetString().c_str(),
756 address,
757 clang_ast_type));
758 if (valobj_sp)
759 {
Greg Claytonbad1c9e2012-12-15 02:08:17 +0000760 Format format = m_format_options.GetFormat();
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000761 if (format != eFormatDefault)
762 valobj_sp->SetFormat (format);
763
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000764 bool scope_already_checked = true;
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000765
Enrico Granata3069c622012-03-01 04:24:26 +0000766 ValueObject::DumpValueObjectOptions options;
767 options.SetMaximumPointerDepth(m_varobj_options.ptr_depth)
768 .SetMaximumDepth(m_varobj_options.max_depth)
769 .SetShowLocation(m_varobj_options.show_location)
770 .SetShowTypes(m_varobj_options.show_types)
771 .SetUseObjectiveC(m_varobj_options.use_objc)
772 .SetScopeChecked(scope_already_checked)
773 .SetFlatOutput(m_varobj_options.flat_output)
Enrico Granatacf09f882012-03-19 22:58:49 +0000774 .SetUseSyntheticValue(m_varobj_options.be_raw ? false : m_varobj_options.use_synth)
Enrico Granata3069c622012-03-01 04:24:26 +0000775 .SetOmitSummaryDepth(m_varobj_options.be_raw ? UINT32_MAX : m_varobj_options.no_summary_depth)
776 .SetIgnoreCap(m_varobj_options.be_raw ? true : m_varobj_options.ignore_cap)
777 .SetFormat(format)
778 .SetSummary();
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000779 ValueObject::DumpValueObject (*output_stream,
780 valobj_sp.get(),
Enrico Granata3069c622012-03-01 04:24:26 +0000781 options);
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000782 }
783 else
784 {
785 result.AppendErrorWithFormat ("failed to create a value object for: (%s) %s\n",
786 view_as_type_cstr,
787 name_strm.GetString().c_str());
788 result.SetStatus(eReturnStatusFailed);
789 return false;
790 }
791 }
792 return true;
793 }
794
795 result.SetStatus(eReturnStatusSuccessFinishResult);
796 DataExtractor data (data_sp,
Greg Clayton567e7f32011-09-22 04:58:26 +0000797 target->GetArchitecture().GetByteOrder(),
798 target->GetArchitecture().GetAddressByteSize());
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000799
800
Greg Claytone9f5fbd2010-10-10 20:52:20 +0000801 assert (output_stream);
Greg Clayton746979d2011-10-28 23:44:55 +0000802 uint32_t bytes_dumped = data.Dump (output_stream,
803 0,
804 m_format_options.GetFormat(),
805 item_byte_size,
806 item_count,
807 num_per_line,
808 addr,
809 0,
810 0,
811 exe_scope);
812 m_next_addr = addr + bytes_dumped;
Greg Claytone9f5fbd2010-10-10 20:52:20 +0000813 output_stream->EOL();
Chris Lattner24943d22010-06-08 16:52:24 +0000814 return true;
815 }
816
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000817 OptionGroupOptions m_option_group;
818 OptionGroupFormat m_format_options;
819 OptionGroupReadMemory m_memory_options;
820 OptionGroupOutputFile m_outfile_options;
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000821 OptionGroupValueObjectDisplay m_varobj_options;
Greg Clayton902b5be2011-10-26 04:32:38 +0000822 lldb::addr_t m_next_addr;
823 lldb::addr_t m_prev_byte_size;
824 OptionGroupFormat m_prev_format_options;
825 OptionGroupReadMemory m_prev_memory_options;
826 OptionGroupOutputFile m_prev_outfile_options;
827 OptionGroupValueObjectDisplay m_prev_varobj_options;
Greg Claytonbad1c9e2012-12-15 02:08:17 +0000828 ClangASTType m_prev_clang_ast_type;
Chris Lattner24943d22010-06-08 16:52:24 +0000829};
830
Greg Claytona42880a2011-10-25 06:44:01 +0000831
832OptionDefinition
833g_memory_write_option_table[] =
834{
835{ LLDB_OPT_SET_1, true, "infile", 'i', required_argument, NULL, 0, eArgTypeFilename, "Write memory using the contents of a file."},
836{ LLDB_OPT_SET_1, false, "offset", 'o', required_argument, NULL, 0, eArgTypeOffset, "Start writng bytes from an offset within the input file."},
837};
838
839
Chris Lattner24943d22010-06-08 16:52:24 +0000840//----------------------------------------------------------------------
841// Write memory to the inferior process
842//----------------------------------------------------------------------
Jim Inghamda26bd22012-06-08 21:56:10 +0000843class CommandObjectMemoryWrite : public CommandObjectParsed
Chris Lattner24943d22010-06-08 16:52:24 +0000844{
845public:
846
Greg Claytona42880a2011-10-25 06:44:01 +0000847 class OptionGroupWriteMemory : public OptionGroup
Chris Lattner24943d22010-06-08 16:52:24 +0000848 {
849 public:
Greg Claytona42880a2011-10-25 06:44:01 +0000850 OptionGroupWriteMemory () :
851 OptionGroup()
Chris Lattner24943d22010-06-08 16:52:24 +0000852 {
Chris Lattner24943d22010-06-08 16:52:24 +0000853 }
854
855 virtual
Greg Claytona42880a2011-10-25 06:44:01 +0000856 ~OptionGroupWriteMemory ()
Chris Lattner24943d22010-06-08 16:52:24 +0000857 {
858 }
859
Greg Claytona42880a2011-10-25 06:44:01 +0000860 virtual uint32_t
861 GetNumDefinitions ()
862 {
863 return sizeof (g_memory_write_option_table) / sizeof (OptionDefinition);
864 }
865
866 virtual const OptionDefinition*
867 GetDefinitions ()
868 {
869 return g_memory_write_option_table;
870 }
871
Chris Lattner24943d22010-06-08 16:52:24 +0000872 virtual Error
Greg Claytona42880a2011-10-25 06:44:01 +0000873 SetOptionValue (CommandInterpreter &interpreter,
874 uint32_t option_idx,
875 const char *option_arg)
Chris Lattner24943d22010-06-08 16:52:24 +0000876 {
877 Error error;
Greg Clayton6475c422012-12-04 00:32:51 +0000878 const int short_option = g_memory_write_option_table[option_idx].short_option;
Greg Claytona42880a2011-10-25 06:44:01 +0000879
Chris Lattner24943d22010-06-08 16:52:24 +0000880 switch (short_option)
881 {
Greg Claytona42880a2011-10-25 06:44:01 +0000882 case 'i':
883 m_infile.SetFile (option_arg, true);
884 if (!m_infile.Exists())
Greg Claytone9f5fbd2010-10-10 20:52:20 +0000885 {
Greg Claytona42880a2011-10-25 06:44:01 +0000886 m_infile.Clear();
Greg Clayton9c236732011-10-26 00:56:27 +0000887 error.SetErrorStringWithFormat("input file does not exist: '%s'", option_arg);
Greg Claytone9f5fbd2010-10-10 20:52:20 +0000888 }
Greg Claytona42880a2011-10-25 06:44:01 +0000889 break;
890
891 case 'o':
892 {
893 bool success;
894 m_infile_offset = Args::StringToUInt64(option_arg, 0, 0, &success);
895 if (!success)
896 {
Greg Clayton9c236732011-10-26 00:56:27 +0000897 error.SetErrorStringWithFormat("invalid offset string '%s'", option_arg);
Greg Claytona42880a2011-10-25 06:44:01 +0000898 }
899 }
900 break;
901
902 default:
Greg Clayton9c236732011-10-26 00:56:27 +0000903 error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option);
Greg Claytona42880a2011-10-25 06:44:01 +0000904 break;
Chris Lattner24943d22010-06-08 16:52:24 +0000905 }
906 return error;
907 }
Greg Claytona42880a2011-10-25 06:44:01 +0000908
909 virtual void
910 OptionParsingStarting (CommandInterpreter &interpreter)
Chris Lattner24943d22010-06-08 16:52:24 +0000911 {
Greg Claytone9f5fbd2010-10-10 20:52:20 +0000912 m_infile.Clear();
913 m_infile_offset = 0;
Chris Lattner24943d22010-06-08 16:52:24 +0000914 }
915
Greg Claytone9f5fbd2010-10-10 20:52:20 +0000916 FileSpec m_infile;
917 off_t m_infile_offset;
Chris Lattner24943d22010-06-08 16:52:24 +0000918 };
919
Greg Clayton238c0a12010-09-18 01:14:36 +0000920 CommandObjectMemoryWrite (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000921 CommandObjectParsed (interpreter,
922 "memory write",
923 "Write to the memory of the process being debugged.",
924 NULL,
925 eFlagProcessMustBeLaunched),
Greg Claytona42880a2011-10-25 06:44:01 +0000926 m_option_group (interpreter),
927 m_format_options (eFormatBytes, 1, UINT64_MAX),
928 m_memory_options ()
Chris Lattner24943d22010-06-08 16:52:24 +0000929 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000930 CommandArgumentEntry arg1;
931 CommandArgumentEntry arg2;
932 CommandArgumentData addr_arg;
933 CommandArgumentData value_arg;
934
935 // Define the first (and only) variant of this arg.
936 addr_arg.arg_type = eArgTypeAddress;
937 addr_arg.arg_repetition = eArgRepeatPlain;
938
939 // There is only one variant this argument could be; put it into the argument entry.
940 arg1.push_back (addr_arg);
941
942 // Define the first (and only) variant of this arg.
943 value_arg.arg_type = eArgTypeValue;
944 value_arg.arg_repetition = eArgRepeatPlus;
945
946 // There is only one variant this argument could be; put it into the argument entry.
947 arg2.push_back (value_arg);
948
949 // Push the data for the first argument into the m_arguments vector.
950 m_arguments.push_back (arg1);
951 m_arguments.push_back (arg2);
Greg Claytona42880a2011-10-25 06:44:01 +0000952
953 m_option_group.Append (&m_format_options, OptionGroupFormat::OPTION_GROUP_FORMAT, LLDB_OPT_SET_1);
954 m_option_group.Append (&m_format_options, OptionGroupFormat::OPTION_GROUP_SIZE , LLDB_OPT_SET_1|LLDB_OPT_SET_2);
955 m_option_group.Append (&m_memory_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_2);
956 m_option_group.Finalize();
957
Chris Lattner24943d22010-06-08 16:52:24 +0000958 }
959
960 virtual
961 ~CommandObjectMemoryWrite ()
962 {
963 }
964
965 Options *
966 GetOptions ()
967 {
Greg Claytona42880a2011-10-25 06:44:01 +0000968 return &m_option_group;
Chris Lattner24943d22010-06-08 16:52:24 +0000969 }
970
971 bool
972 UIntValueIsValidForSize (uint64_t uval64, size_t total_byte_size)
973 {
974 if (total_byte_size > 8)
975 return false;
976
977 if (total_byte_size == 8)
978 return true;
979
980 const uint64_t max = ((uint64_t)1 << (uint64_t)(total_byte_size * 8)) - 1;
981 return uval64 <= max;
982 }
983
984 bool
985 SIntValueIsValidForSize (int64_t sval64, size_t total_byte_size)
986 {
987 if (total_byte_size > 8)
988 return false;
989
990 if (total_byte_size == 8)
991 return true;
992
993 const int64_t max = ((int64_t)1 << (uint64_t)(total_byte_size * 8 - 1)) - 1;
994 const int64_t min = ~(max);
995 return min <= sval64 && sval64 <= max;
996 }
997
Jim Inghamda26bd22012-06-08 21:56:10 +0000998protected:
Chris Lattner24943d22010-06-08 16:52:24 +0000999 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +00001000 DoExecute (Args& command, CommandReturnObject &result)
Chris Lattner24943d22010-06-08 16:52:24 +00001001 {
Greg Clayton49d888d2012-12-06 22:49:16 +00001002 ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
1003 Process *process = exe_ctx.GetProcessPtr();
Chris Lattner24943d22010-06-08 16:52:24 +00001004 if (process == NULL)
1005 {
1006 result.AppendError("need a process to read memory");
1007 result.SetStatus(eReturnStatusFailed);
1008 return false;
1009 }
1010
1011 const size_t argc = command.GetArgumentCount();
1012
Greg Claytona42880a2011-10-25 06:44:01 +00001013 if (m_memory_options.m_infile)
Chris Lattner24943d22010-06-08 16:52:24 +00001014 {
Greg Claytone9f5fbd2010-10-10 20:52:20 +00001015 if (argc < 1)
1016 {
1017 result.AppendErrorWithFormat ("%s takes a destination address when writing file contents.\n", m_cmd_name.c_str());
1018 result.SetStatus(eReturnStatusFailed);
1019 return false;
1020 }
1021 }
1022 else if (argc < 2)
1023 {
1024 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 +00001025 result.SetStatus(eReturnStatusFailed);
1026 return false;
1027 }
1028
Chris Lattner24943d22010-06-08 16:52:24 +00001029 StreamString buffer (Stream::eBinary,
Greg Clayton395fc332011-02-15 21:59:32 +00001030 process->GetTarget().GetArchitecture().GetAddressByteSize(),
1031 process->GetTarget().GetArchitecture().GetByteOrder());
Chris Lattner24943d22010-06-08 16:52:24 +00001032
Greg Claytona42880a2011-10-25 06:44:01 +00001033 OptionValueUInt64 &byte_size_value = m_format_options.GetByteSizeValue();
1034 size_t item_byte_size = byte_size_value.GetCurrentValue();
Greg Clayton54e7afa2010-07-09 20:39:50 +00001035
Greg Clayton49d888d2012-12-06 22:49:16 +00001036 Error error;
1037 lldb::addr_t addr = Args::StringToAddress (&exe_ctx,
1038 command.GetArgumentAtIndex(0),
1039 LLDB_INVALID_ADDRESS,
1040 &error);
Chris Lattner24943d22010-06-08 16:52:24 +00001041
1042 if (addr == LLDB_INVALID_ADDRESS)
1043 {
Greg Clayton49d888d2012-12-06 22:49:16 +00001044 result.AppendError("invalid address expression\n");
1045 result.AppendError(error.AsCString());
Chris Lattner24943d22010-06-08 16:52:24 +00001046 result.SetStatus(eReturnStatusFailed);
1047 return false;
1048 }
Greg Claytone9f5fbd2010-10-10 20:52:20 +00001049
Greg Claytona42880a2011-10-25 06:44:01 +00001050 if (m_memory_options.m_infile)
Greg Claytone9f5fbd2010-10-10 20:52:20 +00001051 {
1052 size_t length = SIZE_MAX;
Greg Claytona42880a2011-10-25 06:44:01 +00001053 if (item_byte_size > 0)
1054 length = item_byte_size;
1055 lldb::DataBufferSP data_sp (m_memory_options.m_infile.ReadFileContents (m_memory_options.m_infile_offset, length));
Greg Claytone9f5fbd2010-10-10 20:52:20 +00001056 if (data_sp)
1057 {
1058 length = data_sp->GetByteSize();
1059 if (length > 0)
1060 {
1061 Error error;
1062 size_t bytes_written = process->WriteMemory (addr, data_sp->GetBytes(), length, error);
1063
1064 if (bytes_written == length)
1065 {
1066 // All bytes written
Daniel Malea5f35a4b2012-11-29 21:49:15 +00001067 result.GetOutputStream().Printf("%" PRIu64 " bytes were written to 0x%" PRIx64 "\n", (uint64_t)bytes_written, addr);
Greg Claytone9f5fbd2010-10-10 20:52:20 +00001068 result.SetStatus(eReturnStatusSuccessFinishResult);
1069 }
1070 else if (bytes_written > 0)
1071 {
1072 // Some byte written
Daniel Malea5f35a4b2012-11-29 21:49:15 +00001073 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 +00001074 result.SetStatus(eReturnStatusSuccessFinishResult);
1075 }
1076 else
1077 {
Daniel Malea5f35a4b2012-11-29 21:49:15 +00001078 result.AppendErrorWithFormat ("Memory write to 0x%" PRIx64 " failed: %s.\n", addr, error.AsCString());
Greg Claytone9f5fbd2010-10-10 20:52:20 +00001079 result.SetStatus(eReturnStatusFailed);
1080 }
1081 }
1082 }
1083 else
1084 {
1085 result.AppendErrorWithFormat ("Unable to read contents of file.\n");
1086 result.SetStatus(eReturnStatusFailed);
1087 }
1088 return result.Succeeded();
1089 }
Greg Claytona42880a2011-10-25 06:44:01 +00001090 else if (item_byte_size == 0)
Greg Claytone9f5fbd2010-10-10 20:52:20 +00001091 {
Greg Claytona42880a2011-10-25 06:44:01 +00001092 if (m_format_options.GetFormat() == eFormatPointer)
Greg Claytone9f5fbd2010-10-10 20:52:20 +00001093 item_byte_size = buffer.GetAddressByteSize();
1094 else
1095 item_byte_size = 1;
1096 }
1097
Chris Lattner24943d22010-06-08 16:52:24 +00001098 command.Shift(); // shift off the address argument
1099 uint64_t uval64;
1100 int64_t sval64;
1101 bool success = false;
1102 const uint32_t num_value_args = command.GetArgumentCount();
1103 uint32_t i;
1104 for (i=0; i<num_value_args; ++i)
1105 {
1106 const char *value_str = command.GetArgumentAtIndex(i);
1107
Greg Claytona42880a2011-10-25 06:44:01 +00001108 switch (m_format_options.GetFormat())
Chris Lattner24943d22010-06-08 16:52:24 +00001109 {
Greg Clayton3182eff2011-06-23 21:22:24 +00001110 case kNumFormats:
Chris Lattner24943d22010-06-08 16:52:24 +00001111 case eFormatFloat: // TODO: add support for floats soon
1112 case eFormatCharPrintable:
1113 case eFormatBytesWithASCII:
1114 case eFormatComplex:
1115 case eFormatEnum:
1116 case eFormatUnicode16:
1117 case eFormatUnicode32:
1118 case eFormatVectorOfChar:
1119 case eFormatVectorOfSInt8:
1120 case eFormatVectorOfUInt8:
1121 case eFormatVectorOfSInt16:
1122 case eFormatVectorOfUInt16:
1123 case eFormatVectorOfSInt32:
1124 case eFormatVectorOfUInt32:
1125 case eFormatVectorOfSInt64:
1126 case eFormatVectorOfUInt64:
1127 case eFormatVectorOfFloat32:
1128 case eFormatVectorOfFloat64:
1129 case eFormatVectorOfUInt128:
Greg Clayton4fdf7602011-03-20 04:57:14 +00001130 case eFormatOSType:
1131 case eFormatComplexInteger:
Greg Clayton24a6bd92011-10-27 17:55:14 +00001132 case eFormatAddressInfo:
1133 case eFormatHexFloat:
1134 case eFormatInstruction:
Sean Callanan96abc622012-08-08 17:35:10 +00001135 case eFormatVoid:
Chris Lattner24943d22010-06-08 16:52:24 +00001136 result.AppendError("unsupported format for writing memory");
1137 result.SetStatus(eReturnStatusFailed);
1138 return false;
1139
1140 case eFormatDefault:
1141 case eFormatBytes:
1142 case eFormatHex:
Enrico Granata535543d2012-08-09 19:33:34 +00001143 case eFormatHexUppercase:
Greg Clayton54e7afa2010-07-09 20:39:50 +00001144 case eFormatPointer:
1145
Chris Lattner24943d22010-06-08 16:52:24 +00001146 // Decode hex bytes
1147 uval64 = Args::StringToUInt64(value_str, UINT64_MAX, 16, &success);
1148 if (!success)
1149 {
1150 result.AppendErrorWithFormat ("'%s' is not a valid hex string value.\n", value_str);
1151 result.SetStatus(eReturnStatusFailed);
1152 return false;
1153 }
1154 else if (!UIntValueIsValidForSize (uval64, item_byte_size))
1155 {
Daniel Malea5f35a4b2012-11-29 21:49:15 +00001156 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 +00001157 result.SetStatus(eReturnStatusFailed);
1158 return false;
1159 }
1160 buffer.PutMaxHex64 (uval64, item_byte_size);
1161 break;
1162
1163 case eFormatBoolean:
1164 uval64 = Args::StringToBoolean(value_str, false, &success);
1165 if (!success)
1166 {
1167 result.AppendErrorWithFormat ("'%s' is not a valid boolean string value.\n", value_str);
1168 result.SetStatus(eReturnStatusFailed);
1169 return false;
1170 }
1171 buffer.PutMaxHex64 (uval64, item_byte_size);
1172 break;
1173
1174 case eFormatBinary:
1175 uval64 = Args::StringToUInt64(value_str, UINT64_MAX, 2, &success);
1176 if (!success)
1177 {
1178 result.AppendErrorWithFormat ("'%s' is not a valid binary string value.\n", value_str);
1179 result.SetStatus(eReturnStatusFailed);
1180 return false;
1181 }
1182 else if (!UIntValueIsValidForSize (uval64, item_byte_size))
1183 {
Daniel Malea5f35a4b2012-11-29 21:49:15 +00001184 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 +00001185 result.SetStatus(eReturnStatusFailed);
1186 return false;
1187 }
1188 buffer.PutMaxHex64 (uval64, item_byte_size);
1189 break;
1190
Greg Clayton307fa072011-06-17 23:50:44 +00001191 case eFormatCharArray:
Chris Lattner24943d22010-06-08 16:52:24 +00001192 case eFormatChar:
1193 case eFormatCString:
1194 if (value_str[0])
1195 {
1196 size_t len = strlen (value_str);
1197 // Include the NULL for C strings...
Greg Claytona42880a2011-10-25 06:44:01 +00001198 if (m_format_options.GetFormat() == eFormatCString)
Chris Lattner24943d22010-06-08 16:52:24 +00001199 ++len;
1200 Error error;
1201 if (process->WriteMemory (addr, value_str, len, error) == len)
1202 {
1203 addr += len;
1204 }
1205 else
1206 {
Daniel Malea5f35a4b2012-11-29 21:49:15 +00001207 result.AppendErrorWithFormat ("Memory write to 0x%" PRIx64 " failed: %s.\n", addr, error.AsCString());
Chris Lattner24943d22010-06-08 16:52:24 +00001208 result.SetStatus(eReturnStatusFailed);
1209 return false;
1210 }
1211 }
1212 break;
1213
1214 case eFormatDecimal:
1215 sval64 = Args::StringToSInt64(value_str, INT64_MAX, 0, &success);
1216 if (!success)
1217 {
1218 result.AppendErrorWithFormat ("'%s' is not a valid signed decimal value.\n", value_str);
1219 result.SetStatus(eReturnStatusFailed);
1220 return false;
1221 }
1222 else if (!SIntValueIsValidForSize (sval64, item_byte_size))
1223 {
Daniel Malea5f35a4b2012-11-29 21:49:15 +00001224 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 +00001225 result.SetStatus(eReturnStatusFailed);
1226 return false;
1227 }
1228 buffer.PutMaxHex64 (sval64, item_byte_size);
1229 break;
1230
1231 case eFormatUnsigned:
1232 uval64 = Args::StringToUInt64(value_str, UINT64_MAX, 0, &success);
1233 if (!success)
1234 {
1235 result.AppendErrorWithFormat ("'%s' is not a valid unsigned decimal string value.\n", value_str);
1236 result.SetStatus(eReturnStatusFailed);
1237 return false;
1238 }
1239 else if (!UIntValueIsValidForSize (uval64, item_byte_size))
1240 {
Daniel Malea5f35a4b2012-11-29 21:49:15 +00001241 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 +00001242 result.SetStatus(eReturnStatusFailed);
1243 return false;
1244 }
1245 buffer.PutMaxHex64 (uval64, item_byte_size);
1246 break;
1247
1248 case eFormatOctal:
1249 uval64 = Args::StringToUInt64(value_str, UINT64_MAX, 8, &success);
1250 if (!success)
1251 {
1252 result.AppendErrorWithFormat ("'%s' is not a valid octal string value.\n", value_str);
1253 result.SetStatus(eReturnStatusFailed);
1254 return false;
1255 }
1256 else if (!UIntValueIsValidForSize (uval64, item_byte_size))
1257 {
Daniel Malea5f35a4b2012-11-29 21:49:15 +00001258 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 +00001259 result.SetStatus(eReturnStatusFailed);
1260 return false;
1261 }
1262 buffer.PutMaxHex64 (uval64, item_byte_size);
1263 break;
1264 }
1265 }
1266
1267 if (!buffer.GetString().empty())
1268 {
1269 Error error;
Greg Clayton53d68e72010-07-20 22:52:08 +00001270 if (process->WriteMemory (addr, buffer.GetString().c_str(), buffer.GetString().size(), error) == buffer.GetString().size())
Chris Lattner24943d22010-06-08 16:52:24 +00001271 return true;
1272 else
1273 {
Daniel Malea5f35a4b2012-11-29 21:49:15 +00001274 result.AppendErrorWithFormat ("Memory write to 0x%" PRIx64 " failed: %s.\n", addr, error.AsCString());
Chris Lattner24943d22010-06-08 16:52:24 +00001275 result.SetStatus(eReturnStatusFailed);
1276 return false;
1277 }
1278 }
1279 return true;
1280 }
1281
Greg Claytona42880a2011-10-25 06:44:01 +00001282 OptionGroupOptions m_option_group;
1283 OptionGroupFormat m_format_options;
1284 OptionGroupWriteMemory m_memory_options;
Chris Lattner24943d22010-06-08 16:52:24 +00001285};
1286
Chris Lattner24943d22010-06-08 16:52:24 +00001287
1288//-------------------------------------------------------------------------
1289// CommandObjectMemory
1290//-------------------------------------------------------------------------
1291
Greg Clayton63094e02010-06-23 01:19:29 +00001292CommandObjectMemory::CommandObjectMemory (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +00001293 CommandObjectMultiword (interpreter,
1294 "memory",
Caroline Ticec1ad82e2010-09-07 22:38:08 +00001295 "A set of commands for operating on memory.",
Chris Lattner24943d22010-06-08 16:52:24 +00001296 "memory <subcommand> [<subcommand-options>]")
1297{
Greg Clayton238c0a12010-09-18 01:14:36 +00001298 LoadSubCommand ("read", CommandObjectSP (new CommandObjectMemoryRead (interpreter)));
1299 LoadSubCommand ("write", CommandObjectSP (new CommandObjectMemoryWrite (interpreter)));
Chris Lattner24943d22010-06-08 16:52:24 +00001300}
1301
1302CommandObjectMemory::~CommandObjectMemory ()
1303{
1304}