blob: ea8feed873a3bd1320cc9254457116fa75326f61 [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- CommandObjectMemory.cpp ---------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Daniel Malead891f9b2012-12-05 00:20:57 +000010#include "lldb/lldb-python.h"
11
Chris Lattner24943d22010-06-08 16:52:24 +000012#include "CommandObjectMemory.h"
13
14// C Includes
15// C++ Includes
16// Other libraries and framework includes
17// Project includes
Chris Lattner24943d22010-06-08 16:52:24 +000018#include "lldb/Core/DataBufferHeap.h"
19#include "lldb/Core/DataExtractor.h"
Greg Clayton63094e02010-06-23 01:19:29 +000020#include "lldb/Core/Debugger.h"
Greg Clayton49ce8962012-08-29 21:13:06 +000021#include "lldb/Core/Module.h"
Chris Lattner24943d22010-06-08 16:52:24 +000022#include "lldb/Core/StreamString.h"
Greg Clayton57b3c6b2011-04-27 22:04:39 +000023#include "lldb/Core/ValueObjectMemory.h"
Greg Clayton63094e02010-06-23 01:19:29 +000024#include "lldb/Interpreter/Args.h"
Chris Lattner24943d22010-06-08 16:52:24 +000025#include "lldb/Interpreter/CommandReturnObject.h"
Greg Clayton63094e02010-06-23 01:19:29 +000026#include "lldb/Interpreter/CommandInterpreter.h"
27#include "lldb/Interpreter/Options.h"
Greg Clayton57b3c6b2011-04-27 22:04:39 +000028#include "lldb/Interpreter/OptionGroupFormat.h"
29#include "lldb/Interpreter/OptionGroupOutputFile.h"
Greg Clayton56bbdaf2011-04-28 20:55:26 +000030#include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
Greg Clayton73844aa2012-08-22 17:17:09 +000031#include "lldb/Interpreter/OptionValueString.h"
Greg Clayton49ce8962012-08-29 21:13:06 +000032#include "lldb/Symbol/TypeList.h"
Chris Lattner24943d22010-06-08 16:52:24 +000033#include "lldb/Target/Process.h"
Greg Clayton57b3c6b2011-04-27 22:04:39 +000034#include "lldb/Target/StackFrame.h"
Chris Lattner24943d22010-06-08 16:52:24 +000035
36using namespace lldb;
37using namespace lldb_private;
38
Greg Clayton56bbdaf2011-04-28 20:55:26 +000039static OptionDefinition
Greg Clayton57b3c6b2011-04-27 22:04:39 +000040g_option_table[] =
41{
Greg Clayton57b3c6b2011-04-27 22:04:39 +000042 { LLDB_OPT_SET_1, false, "num-per-line" ,'l', required_argument, NULL, 0, eArgTypeNumberPerLine ,"The number of items per line to display."},
43 { LLDB_OPT_SET_2, false, "binary" ,'b', no_argument , NULL, 0, eArgTypeNone ,"If true, memory will be saved as binary. If false, the memory is saved save as an ASCII dump that uses the format, size, count and number per line settings."},
Sean Callanan06dc17f2012-09-24 22:25:51 +000044 { LLDB_OPT_SET_3, true , "type" ,'t', required_argument, NULL, 0, eArgTypeNone ,"The name of a type to view memory as."},
Greg Clayton827baf62012-11-02 21:14:58 +000045 { LLDB_OPT_SET_1|
46 LLDB_OPT_SET_2|
47 LLDB_OPT_SET_3, false, "force" ,'r', no_argument, NULL, 0, eArgTypeNone ,"Necessary if reading over 1024 bytes of memory."},
Greg Clayton57b3c6b2011-04-27 22:04:39 +000048};
49
50
51
52class OptionGroupReadMemory : public OptionGroup
53{
54public:
55
56 OptionGroupReadMemory () :
Greg Clayton56bbdaf2011-04-28 20:55:26 +000057 m_num_per_line (1,1),
Greg Clayton57b3c6b2011-04-27 22:04:39 +000058 m_output_as_binary (false),
59 m_view_as_type()
60 {
61 }
62
63 virtual
64 ~OptionGroupReadMemory ()
65 {
66 }
67
68
69 virtual uint32_t
70 GetNumDefinitions ()
71 {
72 return sizeof (g_option_table) / sizeof (OptionDefinition);
73 }
74
75 virtual const OptionDefinition*
76 GetDefinitions ()
77 {
78 return g_option_table;
79 }
80
81 virtual Error
82 SetOptionValue (CommandInterpreter &interpreter,
83 uint32_t option_idx,
84 const char *option_arg)
85 {
86 Error error;
Greg Clayton6475c422012-12-04 00:32:51 +000087 const int short_option = g_option_table[option_idx].short_option;
Greg Clayton57b3c6b2011-04-27 22:04:39 +000088
89 switch (short_option)
90 {
91 case 'l':
92 error = m_num_per_line.SetValueFromCString (option_arg);
93 if (m_num_per_line.GetCurrentValue() == 0)
Greg Clayton9c236732011-10-26 00:56:27 +000094 error.SetErrorStringWithFormat("invalid value for --num-per-line option '%s'", option_arg);
Greg Clayton57b3c6b2011-04-27 22:04:39 +000095 break;
Greg Claytona42880a2011-10-25 06:44:01 +000096
Greg Clayton57b3c6b2011-04-27 22:04:39 +000097 case 'b':
98 m_output_as_binary = true;
99 break;
100
101 case 't':
102 error = m_view_as_type.SetValueFromCString (option_arg);
103 break;
Sean Callanan8a6f3e92012-04-28 01:27:38 +0000104
105 case 'r':
106 m_force = true;
107 break;
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000108
109 default:
Greg Clayton9c236732011-10-26 00:56:27 +0000110 error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option);
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000111 break;
112 }
113 return error;
114 }
115
116 virtual void
117 OptionParsingStarting (CommandInterpreter &interpreter)
118 {
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000119 m_num_per_line.Clear();
120 m_output_as_binary = false;
121 m_view_as_type.Clear();
122 }
123
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000124 Error
Greg Claytona42880a2011-10-25 06:44:01 +0000125 FinalizeSettings (Target *target, OptionGroupFormat& format_options)
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000126 {
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000127 Error error;
Greg Claytona42880a2011-10-25 06:44:01 +0000128 OptionValueUInt64 &byte_size_value = format_options.GetByteSizeValue();
129 OptionValueUInt64 &count_value = format_options.GetCountValue();
Greg Clayton9c236732011-10-26 00:56:27 +0000130 const bool byte_size_option_set = byte_size_value.OptionWasSet();
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000131 const bool num_per_line_option_set = m_num_per_line.OptionWasSet();
Greg Claytona42880a2011-10-25 06:44:01 +0000132 const bool count_option_set = format_options.GetCountValue().OptionWasSet();
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000133
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000134 switch (format_options.GetFormat())
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000135 {
136 default:
137 break;
138
139 case eFormatBoolean:
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000140 if (!byte_size_option_set)
Greg Claytona42880a2011-10-25 06:44:01 +0000141 byte_size_value = 1;
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000142 if (!num_per_line_option_set)
143 m_num_per_line = 1;
144 if (!count_option_set)
Greg Claytona42880a2011-10-25 06:44:01 +0000145 format_options.GetCountValue() = 8;
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000146 break;
147
148 case eFormatCString:
149 break;
Greg Clayton24a6bd92011-10-27 17:55:14 +0000150
151 case eFormatInstruction:
152 if (count_option_set)
Jim Inghamab885832012-11-07 01:52:04 +0000153 byte_size_value = target->GetArchitecture().GetMaximumOpcodeByteSize();
Greg Clayton24a6bd92011-10-27 17:55:14 +0000154 m_num_per_line = 1;
155 break;
156
157 case eFormatAddressInfo:
158 if (!byte_size_option_set)
159 byte_size_value = target->GetArchitecture().GetAddressByteSize();
160 m_num_per_line = 1;
161 if (!count_option_set)
162 format_options.GetCountValue() = 8;
163 break;
164
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000165 case eFormatPointer:
Greg Claytona42880a2011-10-25 06:44:01 +0000166 byte_size_value = target->GetArchitecture().GetAddressByteSize();
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000167 if (!num_per_line_option_set)
168 m_num_per_line = 4;
169 if (!count_option_set)
Greg Claytona42880a2011-10-25 06:44:01 +0000170 format_options.GetCountValue() = 8;
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000171 break;
172
173 case eFormatBinary:
174 case eFormatFloat:
175 case eFormatOctal:
176 case eFormatDecimal:
177 case eFormatEnum:
178 case eFormatUnicode16:
179 case eFormatUnicode32:
180 case eFormatUnsigned:
Greg Clayton24a6bd92011-10-27 17:55:14 +0000181 case eFormatHexFloat:
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000182 if (!byte_size_option_set)
Greg Claytona42880a2011-10-25 06:44:01 +0000183 byte_size_value = 4;
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000184 if (!num_per_line_option_set)
185 m_num_per_line = 1;
186 if (!count_option_set)
Greg Claytona42880a2011-10-25 06:44:01 +0000187 format_options.GetCountValue() = 8;
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000188 break;
Greg Clayton24a6bd92011-10-27 17:55:14 +0000189
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000190 case eFormatBytes:
191 case eFormatBytesWithASCII:
Greg Clayton9c236732011-10-26 00:56:27 +0000192 if (byte_size_option_set)
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000193 {
Greg Claytona42880a2011-10-25 06:44:01 +0000194 if (byte_size_value > 1)
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000195 error.SetErrorStringWithFormat ("display format (bytes/bytes with ascii) conflicts with the specified byte size %" PRIu64 "\n"
Johnny Chenbf9ba592012-03-06 01:17:59 +0000196 "\tconsider using a different display format or don't specify the byte size",
197 byte_size_value.GetCurrentValue());
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000198 }
199 else
Greg Claytona42880a2011-10-25 06:44:01 +0000200 byte_size_value = 1;
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000201 if (!num_per_line_option_set)
202 m_num_per_line = 16;
203 if (!count_option_set)
Greg Claytona42880a2011-10-25 06:44:01 +0000204 format_options.GetCountValue() = 32;
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000205 break;
Greg Clayton307fa072011-06-17 23:50:44 +0000206 case eFormatCharArray:
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000207 case eFormatChar:
208 case eFormatCharPrintable:
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000209 if (!byte_size_option_set)
Greg Claytona42880a2011-10-25 06:44:01 +0000210 byte_size_value = 1;
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000211 if (!num_per_line_option_set)
212 m_num_per_line = 32;
213 if (!count_option_set)
Greg Claytona42880a2011-10-25 06:44:01 +0000214 format_options.GetCountValue() = 64;
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000215 break;
216 case eFormatComplex:
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000217 if (!byte_size_option_set)
Greg Claytona42880a2011-10-25 06:44:01 +0000218 byte_size_value = 8;
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000219 if (!num_per_line_option_set)
220 m_num_per_line = 1;
221 if (!count_option_set)
Greg Claytona42880a2011-10-25 06:44:01 +0000222 format_options.GetCountValue() = 8;
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000223 break;
224 case eFormatHex:
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000225 if (!byte_size_option_set)
Greg Claytona42880a2011-10-25 06:44:01 +0000226 byte_size_value = 4;
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000227 if (!num_per_line_option_set)
228 {
Greg Claytona42880a2011-10-25 06:44:01 +0000229 switch (byte_size_value)
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000230 {
231 case 1:
232 case 2:
233 m_num_per_line = 8;
234 break;
235 case 4:
236 m_num_per_line = 4;
237 break;
238 case 8:
239 m_num_per_line = 2;
240 break;
241 default:
242 m_num_per_line = 1;
243 break;
244 }
245 }
246 if (!count_option_set)
Greg Claytona42880a2011-10-25 06:44:01 +0000247 count_value = 8;
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000248 break;
249
250 case eFormatVectorOfChar:
251 case eFormatVectorOfSInt8:
252 case eFormatVectorOfUInt8:
253 case eFormatVectorOfSInt16:
254 case eFormatVectorOfUInt16:
255 case eFormatVectorOfSInt32:
256 case eFormatVectorOfUInt32:
257 case eFormatVectorOfSInt64:
258 case eFormatVectorOfUInt64:
259 case eFormatVectorOfFloat32:
260 case eFormatVectorOfFloat64:
261 case eFormatVectorOfUInt128:
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000262 if (!byte_size_option_set)
Greg Claytona42880a2011-10-25 06:44:01 +0000263 byte_size_value = 128;
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000264 if (!num_per_line_option_set)
265 m_num_per_line = 1;
266 if (!count_option_set)
Greg Claytona42880a2011-10-25 06:44:01 +0000267 count_value = 4;
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000268 break;
269 }
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000270 return error;
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000271 }
272
Greg Clayton902b5be2011-10-26 04:32:38 +0000273 bool
274 AnyOptionWasSet () const
275 {
276 return m_num_per_line.OptionWasSet() ||
277 m_output_as_binary ||
278 m_view_as_type.OptionWasSet();
279 }
280
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000281 OptionValueUInt64 m_num_per_line;
282 bool m_output_as_binary;
283 OptionValueString m_view_as_type;
Sean Callanan8a6f3e92012-04-28 01:27:38 +0000284 bool m_force;
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000285};
286
287
288
Chris Lattner24943d22010-06-08 16:52:24 +0000289//----------------------------------------------------------------------
290// Read memory from the inferior process
291//----------------------------------------------------------------------
Jim Inghamda26bd22012-06-08 21:56:10 +0000292class CommandObjectMemoryRead : public CommandObjectParsed
Chris Lattner24943d22010-06-08 16:52:24 +0000293{
294public:
295
Greg Clayton238c0a12010-09-18 01:14:36 +0000296 CommandObjectMemoryRead (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000297 CommandObjectParsed (interpreter,
298 "memory read",
299 "Read from the memory of the process being debugged.",
300 NULL,
Greg Claytonea0bb4d2013-01-09 19:44:40 +0000301 eFlagRequiresTarget | eFlagProcessMustBePaused),
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000302 m_option_group (interpreter),
Greg Claytona42880a2011-10-25 06:44:01 +0000303 m_format_options (eFormatBytesWithASCII, 1, 8),
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000304 m_memory_options (),
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000305 m_outfile_options (),
Greg Clayton902b5be2011-10-26 04:32:38 +0000306 m_varobj_options(),
307 m_next_addr(LLDB_INVALID_ADDRESS),
308 m_prev_byte_size(0),
309 m_prev_format_options (eFormatBytesWithASCII, 1, 8),
310 m_prev_memory_options (),
311 m_prev_outfile_options (),
312 m_prev_varobj_options()
Chris Lattner24943d22010-06-08 16:52:24 +0000313 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000314 CommandArgumentEntry arg1;
315 CommandArgumentEntry arg2;
316 CommandArgumentData start_addr_arg;
317 CommandArgumentData end_addr_arg;
318
319 // Define the first (and only) variant of this arg.
Enrico Granata4968ad82013-01-29 01:48:30 +0000320 start_addr_arg.arg_type = eArgTypeAddressOrExpression;
Caroline Tice43b014a2010-10-04 22:28:36 +0000321 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.
Enrico Granata4968ad82013-01-29 01:48:30 +0000327 end_addr_arg.arg_type = eArgTypeAddressOrExpression;
Caroline Tice43b014a2010-10-04 22:28:36 +0000328 end_addr_arg.arg_repetition = eArgRepeatOptional;
329
330 // There is only one variant this argument could be; put it into the argument entry.
331 arg2.push_back (end_addr_arg);
332
333 // Push the data for the first argument into the m_arguments vector.
334 m_arguments.push_back (arg1);
335 m_arguments.push_back (arg2);
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000336
Greg Claytona42880a2011-10-25 06:44:01 +0000337 // Add the "--format" and "--count" options to group 1 and 3
338 m_option_group.Append (&m_format_options,
339 OptionGroupFormat::OPTION_GROUP_FORMAT | OptionGroupFormat::OPTION_GROUP_COUNT,
Greg Clayton31feaa82011-11-22 18:07:35 +0000340 LLDB_OPT_SET_1 | LLDB_OPT_SET_2 | LLDB_OPT_SET_3);
Greg Clayton24a6bd92011-10-27 17:55:14 +0000341 m_option_group.Append (&m_format_options,
342 OptionGroupFormat::OPTION_GROUP_GDB_FMT,
Greg Clayton31feaa82011-11-22 18:07:35 +0000343 LLDB_OPT_SET_1 | LLDB_OPT_SET_3);
Greg Claytona42880a2011-10-25 06:44:01 +0000344 // Add the "--size" option to group 1 and 2
345 m_option_group.Append (&m_format_options,
346 OptionGroupFormat::OPTION_GROUP_SIZE,
347 LLDB_OPT_SET_1 | LLDB_OPT_SET_2);
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000348 m_option_group.Append (&m_memory_options);
349 m_option_group.Append (&m_outfile_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1 | LLDB_OPT_SET_2 | LLDB_OPT_SET_3);
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000350 m_option_group.Append (&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_3);
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000351 m_option_group.Finalize();
Chris Lattner24943d22010-06-08 16:52:24 +0000352 }
353
354 virtual
355 ~CommandObjectMemoryRead ()
356 {
357 }
358
359 Options *
360 GetOptions ()
361 {
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000362 return &m_option_group;
Chris Lattner24943d22010-06-08 16:52:24 +0000363 }
364
Greg Clayton902b5be2011-10-26 04:32:38 +0000365 virtual const char *GetRepeatCommand (Args &current_command_args, uint32_t index)
366 {
367 return m_cmd_name.c_str();
368 }
369
Jim Inghamda26bd22012-06-08 21:56:10 +0000370protected:
Chris Lattner24943d22010-06-08 16:52:24 +0000371 virtual bool
Greg Clayton49d888d2012-12-06 22:49:16 +0000372 DoExecute (Args& command, CommandReturnObject &result)
Chris Lattner24943d22010-06-08 16:52:24 +0000373 {
Greg Claytonea0bb4d2013-01-09 19:44:40 +0000374 // No need to check "target" for validity as eFlagRequiresTarget ensures it is valid
375 Target *target = m_exe_ctx.GetTargetPtr();
376
Chris Lattner24943d22010-06-08 16:52:24 +0000377 const size_t argc = command.GetArgumentCount();
378
Greg Clayton902b5be2011-10-26 04:32:38 +0000379 if ((argc == 0 && m_next_addr == LLDB_INVALID_ADDRESS) || argc > 2)
Chris Lattner24943d22010-06-08 16:52:24 +0000380 {
Greg Clayton49d888d2012-12-06 22:49:16 +0000381 result.AppendErrorWithFormat ("%s takes a start address expression with an optional end address expression.\n", m_cmd_name.c_str());
Greg Claytonbad1c9e2012-12-15 02:08:17 +0000382 result.AppendRawWarning("Expressions should be quoted if they contain spaces or other special characters.\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000383 result.SetStatus(eReturnStatusFailed);
384 return false;
385 }
386
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000387 ClangASTType clang_ast_type;
388 Error error;
389
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000390 const char *view_as_type_cstr = m_memory_options.m_view_as_type.GetCurrentValue();
391 if (view_as_type_cstr && view_as_type_cstr[0])
Chris Lattner24943d22010-06-08 16:52:24 +0000392 {
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000393 // We are viewing memory as a type
Greg Claytonbad1c9e2012-12-15 02:08:17 +0000394
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000395 SymbolContext sc;
Greg Claytondc0a38c2012-03-26 23:03:23 +0000396 const bool exact_match = false;
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000397 TypeList type_list;
398 uint32_t reference_count = 0;
399 uint32_t pointer_count = 0;
400 size_t idx;
Sean Callananddb2ece2012-07-10 21:24:26 +0000401
402#define ALL_KEYWORDS \
403 KEYWORD("const") \
404 KEYWORD("volatile") \
405 KEYWORD("restrict") \
406 KEYWORD("struct") \
407 KEYWORD("class") \
408 KEYWORD("union")
409
410#define KEYWORD(s) s,
411 static const char *g_keywords[] =
412 {
413 ALL_KEYWORDS
414 };
415#undef KEYWORD
416
417#define KEYWORD(s) (sizeof(s) - 1),
418 static const int g_keyword_lengths[] =
419 {
420 ALL_KEYWORDS
421 };
422#undef KEYWORD
423
424#undef ALL_KEYWORDS
425
426 static size_t g_num_keywords = sizeof(g_keywords) / sizeof(const char *);
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000427 std::string type_str(view_as_type_cstr);
428
429 // Remove all instances of g_keywords that are followed by spaces
430 for (size_t i = 0; i < g_num_keywords; ++i)
431 {
432 const char *keyword = g_keywords[i];
Sean Callananddb2ece2012-07-10 21:24:26 +0000433 int keyword_len = g_keyword_lengths[i];
434
435 idx = 0;
436 while ((idx = type_str.find (keyword, idx)) != std::string::npos)
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000437 {
438 if (type_str[idx + keyword_len] == ' ' || type_str[idx + keyword_len] == '\t')
Sean Callananddb2ece2012-07-10 21:24:26 +0000439 {
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000440 type_str.erase(idx, keyword_len+1);
Sean Callananddb2ece2012-07-10 21:24:26 +0000441 idx = 0;
442 }
443 else
444 {
445 idx += keyword_len;
446 }
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000447 }
448 }
449 bool done = type_str.empty();
450 //
451 idx = type_str.find_first_not_of (" \t");
452 if (idx > 0 && idx != std::string::npos)
453 type_str.erase (0, idx);
454 while (!done)
455 {
456 // Strip trailing spaces
457 if (type_str.empty())
458 done = true;
459 else
460 {
461 switch (type_str[type_str.size()-1])
462 {
463 case '*':
464 ++pointer_count;
465 // fall through...
466 case ' ':
467 case '\t':
468 type_str.erase(type_str.size()-1);
469 break;
470
471 case '&':
472 if (reference_count == 0)
473 {
474 reference_count = 1;
475 type_str.erase(type_str.size()-1);
476 }
477 else
478 {
479 result.AppendErrorWithFormat ("invalid type string: '%s'\n", view_as_type_cstr);
480 result.SetStatus(eReturnStatusFailed);
481 return false;
482 }
483 break;
484
485 default:
486 done = true;
487 break;
488 }
489 }
490 }
491
492 ConstString lookup_type_name(type_str.c_str());
Greg Claytonea0bb4d2013-01-09 19:44:40 +0000493 StackFrame *frame = m_exe_ctx.GetFramePtr();
Greg Clayton567e7f32011-09-22 04:58:26 +0000494 if (frame)
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000495 {
Greg Clayton567e7f32011-09-22 04:58:26 +0000496 sc = frame->GetSymbolContext (eSymbolContextModule);
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000497 if (sc.module_sp)
498 {
Sean Callanan3e80cd92011-10-12 02:08:07 +0000499 sc.module_sp->FindTypes (sc,
500 lookup_type_name,
Greg Claytondc0a38c2012-03-26 23:03:23 +0000501 exact_match,
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000502 1,
503 type_list);
504 }
505 }
506 if (type_list.GetSize() == 0)
507 {
Greg Clayton9f95fb62012-04-06 17:41:13 +0000508 target->GetImages().FindTypes (sc,
Greg Clayton567e7f32011-09-22 04:58:26 +0000509 lookup_type_name,
Greg Claytondc0a38c2012-03-26 23:03:23 +0000510 exact_match,
Greg Clayton567e7f32011-09-22 04:58:26 +0000511 1,
512 type_list);
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000513 }
514
515 if (type_list.GetSize() == 0)
516 {
517 result.AppendErrorWithFormat ("unable to find any types that match the raw type '%s' for full type '%s'\n",
518 lookup_type_name.GetCString(),
519 view_as_type_cstr);
520 result.SetStatus(eReturnStatusFailed);
521 return false;
522 }
523
524 TypeSP type_sp (type_list.GetTypeAtIndex(0));
525 clang_ast_type.SetClangType (type_sp->GetClangAST(), type_sp->GetClangFullType());
526
527 while (pointer_count > 0)
528 {
529 clang_type_t pointer_type = ClangASTContext::CreatePointerType (clang_ast_type.GetASTContext(), clang_ast_type.GetOpaqueQualType());
530 if (pointer_type)
531 clang_ast_type.SetClangType (clang_ast_type.GetASTContext(), pointer_type);
532 else
533 {
534 result.AppendError ("unable make a pointer type\n");
535 result.SetStatus(eReturnStatusFailed);
536 return false;
537 }
538 --pointer_count;
539 }
540
Greg Claytonfe6dc6e2013-03-14 18:31:44 +0000541 m_format_options.GetByteSizeValue() = clang_ast_type.GetClangTypeByteSize();
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000542
Greg Claytona42880a2011-10-25 06:44:01 +0000543 if (m_format_options.GetByteSizeValue() == 0)
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000544 {
545 result.AppendErrorWithFormat ("unable to get the byte size of the type '%s'\n",
546 view_as_type_cstr);
547 result.SetStatus(eReturnStatusFailed);
548 return false;
549 }
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000550
Greg Claytona42880a2011-10-25 06:44:01 +0000551 if (!m_format_options.GetCountValue().OptionWasSet())
552 m_format_options.GetCountValue() = 1;
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000553 }
554 else
555 {
Greg Clayton567e7f32011-09-22 04:58:26 +0000556 error = m_memory_options.FinalizeSettings (target, m_format_options);
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000557 }
558
559 // Look for invalid combinations of settings
560 if (error.Fail())
561 {
Greg Clayton49d888d2012-12-06 22:49:16 +0000562 result.AppendError(error.AsCString());
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000563 result.SetStatus(eReturnStatusFailed);
564 return false;
Chris Lattner24943d22010-06-08 16:52:24 +0000565 }
566
Greg Clayton902b5be2011-10-26 04:32:38 +0000567 lldb::addr_t addr;
568 size_t total_byte_size = 0;
569 if (argc == 0)
570 {
571 // Use the last address and byte size and all options as they were
572 // if no options have been set
573 addr = m_next_addr;
574 total_byte_size = m_prev_byte_size;
Greg Claytonbad1c9e2012-12-15 02:08:17 +0000575 clang_ast_type = m_prev_clang_ast_type;
576 if (!m_format_options.AnyOptionWasSet() &&
Greg Clayton902b5be2011-10-26 04:32:38 +0000577 !m_memory_options.AnyOptionWasSet() &&
578 !m_outfile_options.AnyOptionWasSet() &&
579 !m_varobj_options.AnyOptionWasSet())
580 {
581 m_format_options = m_prev_format_options;
582 m_memory_options = m_prev_memory_options;
583 m_outfile_options = m_prev_outfile_options;
584 m_varobj_options = m_prev_varobj_options;
585 }
586 }
587
Greg Claytona42880a2011-10-25 06:44:01 +0000588 size_t item_count = m_format_options.GetCountValue().GetCurrentValue();
Enrico Granata45358912013-01-21 19:20:50 +0000589 size_t item_byte_size = m_format_options.GetByteSizeValue().GetCurrentValue();
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000590 const size_t num_per_line = m_memory_options.m_num_per_line.GetCurrentValue();
Chris Lattner24943d22010-06-08 16:52:24 +0000591
Chris Lattner24943d22010-06-08 16:52:24 +0000592 if (total_byte_size == 0)
Greg Clayton902b5be2011-10-26 04:32:38 +0000593 {
594 total_byte_size = item_count * item_byte_size;
595 if (total_byte_size == 0)
596 total_byte_size = 32;
597 }
Chris Lattner24943d22010-06-08 16:52:24 +0000598
Greg Clayton902b5be2011-10-26 04:32:38 +0000599 if (argc > 0)
Greg Claytonea0bb4d2013-01-09 19:44:40 +0000600 addr = Args::StringToAddress(&m_exe_ctx, command.GetArgumentAtIndex(0), LLDB_INVALID_ADDRESS, &error);
Chris Lattner24943d22010-06-08 16:52:24 +0000601
602 if (addr == LLDB_INVALID_ADDRESS)
603 {
Greg Clayton49d888d2012-12-06 22:49:16 +0000604 result.AppendError("invalid start address expression.");
605 result.AppendError(error.AsCString());
Chris Lattner24943d22010-06-08 16:52:24 +0000606 result.SetStatus(eReturnStatusFailed);
607 return false;
608 }
609
610 if (argc == 2)
611 {
Greg Claytonea0bb4d2013-01-09 19:44:40 +0000612 lldb::addr_t end_addr = Args::StringToAddress(&m_exe_ctx, command.GetArgumentAtIndex(1), LLDB_INVALID_ADDRESS, 0);
Chris Lattner24943d22010-06-08 16:52:24 +0000613 if (end_addr == LLDB_INVALID_ADDRESS)
614 {
Greg Clayton49d888d2012-12-06 22:49:16 +0000615 result.AppendError("invalid end address expression.");
616 result.AppendError(error.AsCString());
Chris Lattner24943d22010-06-08 16:52:24 +0000617 result.SetStatus(eReturnStatusFailed);
618 return false;
619 }
620 else if (end_addr <= addr)
621 {
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000622 result.AppendErrorWithFormat("end address (0x%" PRIx64 ") must be greater that the start address (0x%" PRIx64 ").\n", end_addr, addr);
Chris Lattner24943d22010-06-08 16:52:24 +0000623 result.SetStatus(eReturnStatusFailed);
624 return false;
625 }
Greg Claytona42880a2011-10-25 06:44:01 +0000626 else if (m_format_options.GetCountValue().OptionWasSet())
Chris Lattner24943d22010-06-08 16:52:24 +0000627 {
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000628 result.AppendErrorWithFormat("specify either the end address (0x%" PRIx64 ") or the count (--count %lu), not both.\n", end_addr, item_count);
Chris Lattner24943d22010-06-08 16:52:24 +0000629 result.SetStatus(eReturnStatusFailed);
630 return false;
631 }
632
633 total_byte_size = end_addr - addr;
634 item_count = total_byte_size / item_byte_size;
635 }
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000636
Sean Callanan8a6f3e92012-04-28 01:27:38 +0000637 if (total_byte_size > 1024 && !m_memory_options.m_force)
638 {
639 result.AppendErrorWithFormat("Normally, \'memory read\' will not read over 1Kbyte of data.\n");
640 result.AppendErrorWithFormat("Please use --force to override this restriction.\n");
641 return false;
642 }
643
Enrico Granata45358912013-01-21 19:20:50 +0000644
645
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000646 DataBufferSP data_sp;
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000647 size_t bytes_read = 0;
Greg Claytonbad1c9e2012-12-15 02:08:17 +0000648 if (clang_ast_type.GetOpaqueQualType())
649 {
650 // Make sure we don't display our type as ASCII bytes like the default memory read
651 if (m_format_options.GetFormatValue().OptionWasSet() == false)
652 m_format_options.GetFormatValue().SetCurrentValue(eFormatDefault);
653
654 bytes_read = clang_ast_type.GetTypeByteSize() * m_format_options.GetCountValue().GetCurrentValue();
655 }
Enrico Granata45358912013-01-21 19:20:50 +0000656 else if (m_format_options.GetFormatValue().GetCurrentValue() != eFormatCString)
Chris Lattner24943d22010-06-08 16:52:24 +0000657 {
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000658 data_sp.reset (new DataBufferHeap (total_byte_size, '\0'));
Greg Clayton3508c382012-02-24 01:59:29 +0000659 Address address(addr, NULL);
Greg Clayton567e7f32011-09-22 04:58:26 +0000660 bytes_read = target->ReadMemory(address, false, data_sp->GetBytes (), data_sp->GetByteSize(), error);
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000661 if (bytes_read == 0)
662 {
Greg Clayton04e6ada2012-05-25 17:05:55 +0000663 const char *error_cstr = error.AsCString();
664 if (error_cstr && error_cstr[0])
665 {
666 result.AppendError(error_cstr);
667 }
668 else
669 {
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000670 result.AppendErrorWithFormat("failed to read memory from 0x%" PRIx64 ".\n", addr);
Greg Clayton04e6ada2012-05-25 17:05:55 +0000671 }
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000672 result.SetStatus(eReturnStatusFailed);
673 return false;
674 }
675
676 if (bytes_read < total_byte_size)
Jim Ingham40aa9032013-01-25 23:05:01 +0000677 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 +0000678 }
Enrico Granata45358912013-01-21 19:20:50 +0000679 else
680 {
681 // we treat c-strings as a special case because they do not have a fixed size
682 if (m_format_options.GetByteSizeValue().OptionWasSet() && !m_format_options.HasGDBFormat())
683 item_byte_size = m_format_options.GetByteSizeValue().GetCurrentValue();
684 else
685 item_byte_size = target->GetMaximumSizeOfStringSummary();
686 if (!m_format_options.GetCountValue().OptionWasSet())
687 item_count = 1;
688 data_sp.reset (new DataBufferHeap ((item_byte_size+1) * item_count, '\0')); // account for NULLs as necessary
689 uint8_t *data_ptr = data_sp->GetBytes();
690 auto data_addr = addr;
691 auto count = item_count;
692 item_count = 0;
693 while (item_count < count)
694 {
695 std::string buffer;
696 buffer.resize(item_byte_size+1,0);
697 Error error;
698 size_t read = target->ReadCStringFromMemory(data_addr, &buffer[0], item_byte_size+1, error);
699 if (error.Fail())
700 {
701 result.AppendErrorWithFormat("failed to read memory from 0x%" PRIx64 ".\n", addr);
702 result.SetStatus(eReturnStatusFailed);
703 return false;
704 }
705 if (item_byte_size == read)
706 {
707 result.AppendWarningWithFormat("unable to find a NULL terminated string at 0x%" PRIx64 ".Consider increasing the maximum read length.\n", data_addr);
708 break;
709 }
710 read+=1; // account for final NULL byte
711 memcpy(data_ptr, &buffer[0], read);
712 data_ptr += read;
713 data_addr += read;
714 bytes_read += read;
715 item_count++; // if we break early we know we only read item_count strings
716 }
717 data_sp.reset(new DataBufferHeap(data_sp->GetBytes(),bytes_read+1));
718 }
Chris Lattner24943d22010-06-08 16:52:24 +0000719
Greg Claytonbad1c9e2012-12-15 02:08:17 +0000720 m_next_addr = addr + bytes_read;
721 m_prev_byte_size = bytes_read;
722 m_prev_format_options = m_format_options;
723 m_prev_memory_options = m_memory_options;
724 m_prev_outfile_options = m_outfile_options;
725 m_prev_varobj_options = m_varobj_options;
726 m_prev_clang_ast_type = clang_ast_type;
727
Greg Claytone9f5fbd2010-10-10 20:52:20 +0000728 StreamFile outfile_stream;
729 Stream *output_stream = NULL;
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000730 const FileSpec &outfile_spec = m_outfile_options.GetFile().GetCurrentValue();
731 if (outfile_spec)
Greg Claytone9f5fbd2010-10-10 20:52:20 +0000732 {
733 char path[PATH_MAX];
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000734 outfile_spec.GetPath (path, sizeof(path));
735
736 uint32_t open_options = File::eOpenOptionWrite | File::eOpenOptionCanCreate;
737 const bool append = m_outfile_options.GetAppend().GetCurrentValue();
738 if (append)
739 open_options |= File::eOpenOptionAppend;
740
741 if (outfile_stream.GetFile ().Open (path, open_options).Success())
Greg Claytone9f5fbd2010-10-10 20:52:20 +0000742 {
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000743 if (m_memory_options.m_output_as_binary)
Greg Claytone9f5fbd2010-10-10 20:52:20 +0000744 {
Greg Clayton36da2aa2013-01-25 18:06:21 +0000745 const size_t bytes_written = outfile_stream.Write (data_sp->GetBytes(), bytes_read);
Greg Claytone9f5fbd2010-10-10 20:52:20 +0000746 if (bytes_written > 0)
747 {
Greg Clayton36da2aa2013-01-25 18:06:21 +0000748 result.GetOutputStream().Printf ("%zi bytes %s to '%s'\n",
Greg Claytone9f5fbd2010-10-10 20:52:20 +0000749 bytes_written,
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000750 append ? "appended" : "written",
Greg Claytone9f5fbd2010-10-10 20:52:20 +0000751 path);
752 return true;
753 }
754 else
755 {
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000756 result.AppendErrorWithFormat("Failed to write %" PRIu64 " bytes to '%s'.\n", (uint64_t)bytes_read, path);
Greg Claytone9f5fbd2010-10-10 20:52:20 +0000757 result.SetStatus(eReturnStatusFailed);
758 return false;
759 }
760 }
761 else
762 {
763 // We are going to write ASCII to the file just point the
764 // output_stream to our outfile_stream...
765 output_stream = &outfile_stream;
766 }
767 }
768 else
769 {
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000770 result.AppendErrorWithFormat("Failed to open file '%s' for %s.\n", path, append ? "append" : "write");
Greg Claytone9f5fbd2010-10-10 20:52:20 +0000771 result.SetStatus(eReturnStatusFailed);
772 return false;
773 }
774 }
775 else
776 {
777 output_stream = &result.GetOutputStream();
778 }
779
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000780
Greg Claytonea0bb4d2013-01-09 19:44:40 +0000781 ExecutionContextScope *exe_scope = m_exe_ctx.GetBestExecutionContextScope();
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000782 if (clang_ast_type.GetOpaqueQualType())
783 {
784 for (uint32_t i = 0; i<item_count; ++i)
785 {
786 addr_t item_addr = addr + (i * item_byte_size);
Greg Clayton3508c382012-02-24 01:59:29 +0000787 Address address (item_addr);
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000788 StreamString name_strm;
Daniel Malea5f35a4b2012-11-29 21:49:15 +0000789 name_strm.Printf ("0x%" PRIx64, item_addr);
Greg Clayton24a6bd92011-10-27 17:55:14 +0000790 ValueObjectSP valobj_sp (ValueObjectMemory::Create (exe_scope,
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000791 name_strm.GetString().c_str(),
792 address,
793 clang_ast_type));
794 if (valobj_sp)
795 {
Greg Claytonbad1c9e2012-12-15 02:08:17 +0000796 Format format = m_format_options.GetFormat();
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000797 if (format != eFormatDefault)
798 valobj_sp->SetFormat (format);
799
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000800 bool scope_already_checked = true;
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000801
Enrico Granata3069c622012-03-01 04:24:26 +0000802 ValueObject::DumpValueObjectOptions options;
803 options.SetMaximumPointerDepth(m_varobj_options.ptr_depth)
804 .SetMaximumDepth(m_varobj_options.max_depth)
805 .SetShowLocation(m_varobj_options.show_location)
806 .SetShowTypes(m_varobj_options.show_types)
807 .SetUseObjectiveC(m_varobj_options.use_objc)
808 .SetScopeChecked(scope_already_checked)
809 .SetFlatOutput(m_varobj_options.flat_output)
Enrico Granatacf09f882012-03-19 22:58:49 +0000810 .SetUseSyntheticValue(m_varobj_options.be_raw ? false : m_varobj_options.use_synth)
Enrico Granata3069c622012-03-01 04:24:26 +0000811 .SetOmitSummaryDepth(m_varobj_options.be_raw ? UINT32_MAX : m_varobj_options.no_summary_depth)
812 .SetIgnoreCap(m_varobj_options.be_raw ? true : m_varobj_options.ignore_cap)
813 .SetFormat(format)
814 .SetSummary();
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000815 ValueObject::DumpValueObject (*output_stream,
816 valobj_sp.get(),
Enrico Granata3069c622012-03-01 04:24:26 +0000817 options);
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000818 }
819 else
820 {
821 result.AppendErrorWithFormat ("failed to create a value object for: (%s) %s\n",
822 view_as_type_cstr,
823 name_strm.GetString().c_str());
824 result.SetStatus(eReturnStatusFailed);
825 return false;
826 }
827 }
828 return true;
829 }
830
831 result.SetStatus(eReturnStatusSuccessFinishResult);
832 DataExtractor data (data_sp,
Greg Clayton567e7f32011-09-22 04:58:26 +0000833 target->GetArchitecture().GetByteOrder(),
834 target->GetArchitecture().GetAddressByteSize());
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000835
836
Greg Claytone9f5fbd2010-10-10 20:52:20 +0000837 assert (output_stream);
Greg Clayton36da2aa2013-01-25 18:06:21 +0000838 size_t bytes_dumped = data.Dump (output_stream,
839 0,
840 m_format_options.GetFormat(),
841 item_byte_size,
842 item_count,
843 num_per_line,
844 addr,
845 0,
846 0,
847 exe_scope);
Greg Clayton746979d2011-10-28 23:44:55 +0000848 m_next_addr = addr + bytes_dumped;
Greg Claytone9f5fbd2010-10-10 20:52:20 +0000849 output_stream->EOL();
Chris Lattner24943d22010-06-08 16:52:24 +0000850 return true;
851 }
852
Greg Clayton57b3c6b2011-04-27 22:04:39 +0000853 OptionGroupOptions m_option_group;
854 OptionGroupFormat m_format_options;
855 OptionGroupReadMemory m_memory_options;
856 OptionGroupOutputFile m_outfile_options;
Greg Clayton56bbdaf2011-04-28 20:55:26 +0000857 OptionGroupValueObjectDisplay m_varobj_options;
Greg Clayton902b5be2011-10-26 04:32:38 +0000858 lldb::addr_t m_next_addr;
859 lldb::addr_t m_prev_byte_size;
860 OptionGroupFormat m_prev_format_options;
861 OptionGroupReadMemory m_prev_memory_options;
862 OptionGroupOutputFile m_prev_outfile_options;
863 OptionGroupValueObjectDisplay m_prev_varobj_options;
Greg Claytonbad1c9e2012-12-15 02:08:17 +0000864 ClangASTType m_prev_clang_ast_type;
Chris Lattner24943d22010-06-08 16:52:24 +0000865};
866
Greg Claytona42880a2011-10-25 06:44:01 +0000867
868OptionDefinition
869g_memory_write_option_table[] =
870{
871{ LLDB_OPT_SET_1, true, "infile", 'i', required_argument, NULL, 0, eArgTypeFilename, "Write memory using the contents of a file."},
872{ LLDB_OPT_SET_1, false, "offset", 'o', required_argument, NULL, 0, eArgTypeOffset, "Start writng bytes from an offset within the input file."},
873};
874
875
Chris Lattner24943d22010-06-08 16:52:24 +0000876//----------------------------------------------------------------------
877// Write memory to the inferior process
878//----------------------------------------------------------------------
Jim Inghamda26bd22012-06-08 21:56:10 +0000879class CommandObjectMemoryWrite : public CommandObjectParsed
Chris Lattner24943d22010-06-08 16:52:24 +0000880{
881public:
882
Greg Claytona42880a2011-10-25 06:44:01 +0000883 class OptionGroupWriteMemory : public OptionGroup
Chris Lattner24943d22010-06-08 16:52:24 +0000884 {
885 public:
Greg Claytona42880a2011-10-25 06:44:01 +0000886 OptionGroupWriteMemory () :
887 OptionGroup()
Chris Lattner24943d22010-06-08 16:52:24 +0000888 {
Chris Lattner24943d22010-06-08 16:52:24 +0000889 }
890
891 virtual
Greg Claytona42880a2011-10-25 06:44:01 +0000892 ~OptionGroupWriteMemory ()
Chris Lattner24943d22010-06-08 16:52:24 +0000893 {
894 }
895
Greg Claytona42880a2011-10-25 06:44:01 +0000896 virtual uint32_t
897 GetNumDefinitions ()
898 {
899 return sizeof (g_memory_write_option_table) / sizeof (OptionDefinition);
900 }
901
902 virtual const OptionDefinition*
903 GetDefinitions ()
904 {
905 return g_memory_write_option_table;
906 }
907
Chris Lattner24943d22010-06-08 16:52:24 +0000908 virtual Error
Greg Claytona42880a2011-10-25 06:44:01 +0000909 SetOptionValue (CommandInterpreter &interpreter,
910 uint32_t option_idx,
911 const char *option_arg)
Chris Lattner24943d22010-06-08 16:52:24 +0000912 {
913 Error error;
Greg Clayton6475c422012-12-04 00:32:51 +0000914 const int short_option = g_memory_write_option_table[option_idx].short_option;
Greg Claytona42880a2011-10-25 06:44:01 +0000915
Chris Lattner24943d22010-06-08 16:52:24 +0000916 switch (short_option)
917 {
Greg Claytona42880a2011-10-25 06:44:01 +0000918 case 'i':
919 m_infile.SetFile (option_arg, true);
920 if (!m_infile.Exists())
Greg Claytone9f5fbd2010-10-10 20:52:20 +0000921 {
Greg Claytona42880a2011-10-25 06:44:01 +0000922 m_infile.Clear();
Greg Clayton9c236732011-10-26 00:56:27 +0000923 error.SetErrorStringWithFormat("input file does not exist: '%s'", option_arg);
Greg Claytone9f5fbd2010-10-10 20:52:20 +0000924 }
Greg Claytona42880a2011-10-25 06:44:01 +0000925 break;
926
927 case 'o':
928 {
929 bool success;
930 m_infile_offset = Args::StringToUInt64(option_arg, 0, 0, &success);
931 if (!success)
932 {
Greg Clayton9c236732011-10-26 00:56:27 +0000933 error.SetErrorStringWithFormat("invalid offset string '%s'", option_arg);
Greg Claytona42880a2011-10-25 06:44:01 +0000934 }
935 }
936 break;
937
938 default:
Greg Clayton9c236732011-10-26 00:56:27 +0000939 error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option);
Greg Claytona42880a2011-10-25 06:44:01 +0000940 break;
Chris Lattner24943d22010-06-08 16:52:24 +0000941 }
942 return error;
943 }
Greg Claytona42880a2011-10-25 06:44:01 +0000944
945 virtual void
946 OptionParsingStarting (CommandInterpreter &interpreter)
Chris Lattner24943d22010-06-08 16:52:24 +0000947 {
Greg Claytone9f5fbd2010-10-10 20:52:20 +0000948 m_infile.Clear();
949 m_infile_offset = 0;
Chris Lattner24943d22010-06-08 16:52:24 +0000950 }
951
Greg Claytone9f5fbd2010-10-10 20:52:20 +0000952 FileSpec m_infile;
953 off_t m_infile_offset;
Chris Lattner24943d22010-06-08 16:52:24 +0000954 };
955
Greg Clayton238c0a12010-09-18 01:14:36 +0000956 CommandObjectMemoryWrite (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000957 CommandObjectParsed (interpreter,
958 "memory write",
959 "Write to the memory of the process being debugged.",
960 NULL,
Greg Claytonea0bb4d2013-01-09 19:44:40 +0000961 eFlagRequiresProcess | eFlagProcessMustBeLaunched),
Greg Claytona42880a2011-10-25 06:44:01 +0000962 m_option_group (interpreter),
963 m_format_options (eFormatBytes, 1, UINT64_MAX),
964 m_memory_options ()
Chris Lattner24943d22010-06-08 16:52:24 +0000965 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000966 CommandArgumentEntry arg1;
967 CommandArgumentEntry arg2;
968 CommandArgumentData addr_arg;
969 CommandArgumentData value_arg;
970
971 // Define the first (and only) variant of this arg.
972 addr_arg.arg_type = eArgTypeAddress;
973 addr_arg.arg_repetition = eArgRepeatPlain;
974
975 // There is only one variant this argument could be; put it into the argument entry.
976 arg1.push_back (addr_arg);
977
978 // Define the first (and only) variant of this arg.
979 value_arg.arg_type = eArgTypeValue;
980 value_arg.arg_repetition = eArgRepeatPlus;
981
982 // There is only one variant this argument could be; put it into the argument entry.
983 arg2.push_back (value_arg);
984
985 // Push the data for the first argument into the m_arguments vector.
986 m_arguments.push_back (arg1);
987 m_arguments.push_back (arg2);
Greg Claytona42880a2011-10-25 06:44:01 +0000988
989 m_option_group.Append (&m_format_options, OptionGroupFormat::OPTION_GROUP_FORMAT, LLDB_OPT_SET_1);
990 m_option_group.Append (&m_format_options, OptionGroupFormat::OPTION_GROUP_SIZE , LLDB_OPT_SET_1|LLDB_OPT_SET_2);
991 m_option_group.Append (&m_memory_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_2);
992 m_option_group.Finalize();
993
Chris Lattner24943d22010-06-08 16:52:24 +0000994 }
995
996 virtual
997 ~CommandObjectMemoryWrite ()
998 {
999 }
1000
1001 Options *
1002 GetOptions ()
1003 {
Greg Claytona42880a2011-10-25 06:44:01 +00001004 return &m_option_group;
Chris Lattner24943d22010-06-08 16:52:24 +00001005 }
1006
1007 bool
1008 UIntValueIsValidForSize (uint64_t uval64, size_t total_byte_size)
1009 {
1010 if (total_byte_size > 8)
1011 return false;
1012
1013 if (total_byte_size == 8)
1014 return true;
1015
1016 const uint64_t max = ((uint64_t)1 << (uint64_t)(total_byte_size * 8)) - 1;
1017 return uval64 <= max;
1018 }
1019
1020 bool
1021 SIntValueIsValidForSize (int64_t sval64, size_t total_byte_size)
1022 {
1023 if (total_byte_size > 8)
1024 return false;
1025
1026 if (total_byte_size == 8)
1027 return true;
1028
1029 const int64_t max = ((int64_t)1 << (uint64_t)(total_byte_size * 8 - 1)) - 1;
1030 const int64_t min = ~(max);
1031 return min <= sval64 && sval64 <= max;
1032 }
1033
Jim Inghamda26bd22012-06-08 21:56:10 +00001034protected:
Chris Lattner24943d22010-06-08 16:52:24 +00001035 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +00001036 DoExecute (Args& command, CommandReturnObject &result)
Chris Lattner24943d22010-06-08 16:52:24 +00001037 {
Greg Claytonea0bb4d2013-01-09 19:44:40 +00001038 // No need to check "process" for validity as eFlagRequiresProcess ensures it is valid
1039 Process *process = m_exe_ctx.GetProcessPtr();
Chris Lattner24943d22010-06-08 16:52:24 +00001040
1041 const size_t argc = command.GetArgumentCount();
1042
Greg Claytona42880a2011-10-25 06:44:01 +00001043 if (m_memory_options.m_infile)
Chris Lattner24943d22010-06-08 16:52:24 +00001044 {
Greg Claytone9f5fbd2010-10-10 20:52:20 +00001045 if (argc < 1)
1046 {
1047 result.AppendErrorWithFormat ("%s takes a destination address when writing file contents.\n", m_cmd_name.c_str());
1048 result.SetStatus(eReturnStatusFailed);
1049 return false;
1050 }
1051 }
1052 else if (argc < 2)
1053 {
1054 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 +00001055 result.SetStatus(eReturnStatusFailed);
1056 return false;
1057 }
1058
Chris Lattner24943d22010-06-08 16:52:24 +00001059 StreamString buffer (Stream::eBinary,
Greg Clayton395fc332011-02-15 21:59:32 +00001060 process->GetTarget().GetArchitecture().GetAddressByteSize(),
1061 process->GetTarget().GetArchitecture().GetByteOrder());
Chris Lattner24943d22010-06-08 16:52:24 +00001062
Greg Claytona42880a2011-10-25 06:44:01 +00001063 OptionValueUInt64 &byte_size_value = m_format_options.GetByteSizeValue();
1064 size_t item_byte_size = byte_size_value.GetCurrentValue();
Greg Clayton54e7afa2010-07-09 20:39:50 +00001065
Greg Clayton49d888d2012-12-06 22:49:16 +00001066 Error error;
Greg Claytonea0bb4d2013-01-09 19:44:40 +00001067 lldb::addr_t addr = Args::StringToAddress (&m_exe_ctx,
Greg Clayton49d888d2012-12-06 22:49:16 +00001068 command.GetArgumentAtIndex(0),
1069 LLDB_INVALID_ADDRESS,
1070 &error);
Chris Lattner24943d22010-06-08 16:52:24 +00001071
1072 if (addr == LLDB_INVALID_ADDRESS)
1073 {
Greg Clayton49d888d2012-12-06 22:49:16 +00001074 result.AppendError("invalid address expression\n");
1075 result.AppendError(error.AsCString());
Chris Lattner24943d22010-06-08 16:52:24 +00001076 result.SetStatus(eReturnStatusFailed);
1077 return false;
1078 }
Greg Claytone9f5fbd2010-10-10 20:52:20 +00001079
Greg Claytona42880a2011-10-25 06:44:01 +00001080 if (m_memory_options.m_infile)
Greg Claytone9f5fbd2010-10-10 20:52:20 +00001081 {
1082 size_t length = SIZE_MAX;
Greg Claytona42880a2011-10-25 06:44:01 +00001083 if (item_byte_size > 0)
1084 length = item_byte_size;
1085 lldb::DataBufferSP data_sp (m_memory_options.m_infile.ReadFileContents (m_memory_options.m_infile_offset, length));
Greg Claytone9f5fbd2010-10-10 20:52:20 +00001086 if (data_sp)
1087 {
1088 length = data_sp->GetByteSize();
1089 if (length > 0)
1090 {
1091 Error error;
1092 size_t bytes_written = process->WriteMemory (addr, data_sp->GetBytes(), length, error);
1093
1094 if (bytes_written == length)
1095 {
1096 // All bytes written
Daniel Malea5f35a4b2012-11-29 21:49:15 +00001097 result.GetOutputStream().Printf("%" PRIu64 " bytes were written to 0x%" PRIx64 "\n", (uint64_t)bytes_written, addr);
Greg Claytone9f5fbd2010-10-10 20:52:20 +00001098 result.SetStatus(eReturnStatusSuccessFinishResult);
1099 }
1100 else if (bytes_written > 0)
1101 {
1102 // Some byte written
Daniel Malea5f35a4b2012-11-29 21:49:15 +00001103 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 +00001104 result.SetStatus(eReturnStatusSuccessFinishResult);
1105 }
1106 else
1107 {
Daniel Malea5f35a4b2012-11-29 21:49:15 +00001108 result.AppendErrorWithFormat ("Memory write to 0x%" PRIx64 " failed: %s.\n", addr, error.AsCString());
Greg Claytone9f5fbd2010-10-10 20:52:20 +00001109 result.SetStatus(eReturnStatusFailed);
1110 }
1111 }
1112 }
1113 else
1114 {
1115 result.AppendErrorWithFormat ("Unable to read contents of file.\n");
1116 result.SetStatus(eReturnStatusFailed);
1117 }
1118 return result.Succeeded();
1119 }
Greg Claytona42880a2011-10-25 06:44:01 +00001120 else if (item_byte_size == 0)
Greg Claytone9f5fbd2010-10-10 20:52:20 +00001121 {
Greg Claytona42880a2011-10-25 06:44:01 +00001122 if (m_format_options.GetFormat() == eFormatPointer)
Greg Claytone9f5fbd2010-10-10 20:52:20 +00001123 item_byte_size = buffer.GetAddressByteSize();
1124 else
1125 item_byte_size = 1;
1126 }
1127
Chris Lattner24943d22010-06-08 16:52:24 +00001128 command.Shift(); // shift off the address argument
1129 uint64_t uval64;
1130 int64_t sval64;
1131 bool success = false;
Greg Clayton36da2aa2013-01-25 18:06:21 +00001132 const size_t num_value_args = command.GetArgumentCount();
1133 for (size_t i=0; i<num_value_args; ++i)
Chris Lattner24943d22010-06-08 16:52:24 +00001134 {
1135 const char *value_str = command.GetArgumentAtIndex(i);
1136
Greg Claytona42880a2011-10-25 06:44:01 +00001137 switch (m_format_options.GetFormat())
Chris Lattner24943d22010-06-08 16:52:24 +00001138 {
Greg Clayton3182eff2011-06-23 21:22:24 +00001139 case kNumFormats:
Chris Lattner24943d22010-06-08 16:52:24 +00001140 case eFormatFloat: // TODO: add support for floats soon
1141 case eFormatCharPrintable:
1142 case eFormatBytesWithASCII:
1143 case eFormatComplex:
1144 case eFormatEnum:
1145 case eFormatUnicode16:
1146 case eFormatUnicode32:
1147 case eFormatVectorOfChar:
1148 case eFormatVectorOfSInt8:
1149 case eFormatVectorOfUInt8:
1150 case eFormatVectorOfSInt16:
1151 case eFormatVectorOfUInt16:
1152 case eFormatVectorOfSInt32:
1153 case eFormatVectorOfUInt32:
1154 case eFormatVectorOfSInt64:
1155 case eFormatVectorOfUInt64:
1156 case eFormatVectorOfFloat32:
1157 case eFormatVectorOfFloat64:
1158 case eFormatVectorOfUInt128:
Greg Clayton4fdf7602011-03-20 04:57:14 +00001159 case eFormatOSType:
1160 case eFormatComplexInteger:
Greg Clayton24a6bd92011-10-27 17:55:14 +00001161 case eFormatAddressInfo:
1162 case eFormatHexFloat:
1163 case eFormatInstruction:
Sean Callanan96abc622012-08-08 17:35:10 +00001164 case eFormatVoid:
Chris Lattner24943d22010-06-08 16:52:24 +00001165 result.AppendError("unsupported format for writing memory");
1166 result.SetStatus(eReturnStatusFailed);
1167 return false;
1168
1169 case eFormatDefault:
1170 case eFormatBytes:
1171 case eFormatHex:
Enrico Granata535543d2012-08-09 19:33:34 +00001172 case eFormatHexUppercase:
Greg Clayton54e7afa2010-07-09 20:39:50 +00001173 case eFormatPointer:
1174
Chris Lattner24943d22010-06-08 16:52:24 +00001175 // Decode hex bytes
1176 uval64 = Args::StringToUInt64(value_str, UINT64_MAX, 16, &success);
1177 if (!success)
1178 {
1179 result.AppendErrorWithFormat ("'%s' is not a valid hex string value.\n", value_str);
1180 result.SetStatus(eReturnStatusFailed);
1181 return false;
1182 }
1183 else if (!UIntValueIsValidForSize (uval64, item_byte_size))
1184 {
Daniel Malea5f35a4b2012-11-29 21:49:15 +00001185 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 +00001186 result.SetStatus(eReturnStatusFailed);
1187 return false;
1188 }
1189 buffer.PutMaxHex64 (uval64, item_byte_size);
1190 break;
1191
1192 case eFormatBoolean:
1193 uval64 = Args::StringToBoolean(value_str, false, &success);
1194 if (!success)
1195 {
1196 result.AppendErrorWithFormat ("'%s' is not a valid boolean string value.\n", value_str);
1197 result.SetStatus(eReturnStatusFailed);
1198 return false;
1199 }
1200 buffer.PutMaxHex64 (uval64, item_byte_size);
1201 break;
1202
1203 case eFormatBinary:
1204 uval64 = Args::StringToUInt64(value_str, UINT64_MAX, 2, &success);
1205 if (!success)
1206 {
1207 result.AppendErrorWithFormat ("'%s' is not a valid binary string value.\n", value_str);
1208 result.SetStatus(eReturnStatusFailed);
1209 return false;
1210 }
1211 else if (!UIntValueIsValidForSize (uval64, item_byte_size))
1212 {
Daniel Malea5f35a4b2012-11-29 21:49:15 +00001213 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 +00001214 result.SetStatus(eReturnStatusFailed);
1215 return false;
1216 }
1217 buffer.PutMaxHex64 (uval64, item_byte_size);
1218 break;
1219
Greg Clayton307fa072011-06-17 23:50:44 +00001220 case eFormatCharArray:
Chris Lattner24943d22010-06-08 16:52:24 +00001221 case eFormatChar:
1222 case eFormatCString:
1223 if (value_str[0])
1224 {
1225 size_t len = strlen (value_str);
1226 // Include the NULL for C strings...
Greg Claytona42880a2011-10-25 06:44:01 +00001227 if (m_format_options.GetFormat() == eFormatCString)
Chris Lattner24943d22010-06-08 16:52:24 +00001228 ++len;
1229 Error error;
1230 if (process->WriteMemory (addr, value_str, len, error) == len)
1231 {
1232 addr += len;
1233 }
1234 else
1235 {
Daniel Malea5f35a4b2012-11-29 21:49:15 +00001236 result.AppendErrorWithFormat ("Memory write to 0x%" PRIx64 " failed: %s.\n", addr, error.AsCString());
Chris Lattner24943d22010-06-08 16:52:24 +00001237 result.SetStatus(eReturnStatusFailed);
1238 return false;
1239 }
1240 }
1241 break;
1242
1243 case eFormatDecimal:
1244 sval64 = Args::StringToSInt64(value_str, INT64_MAX, 0, &success);
1245 if (!success)
1246 {
1247 result.AppendErrorWithFormat ("'%s' is not a valid signed decimal value.\n", value_str);
1248 result.SetStatus(eReturnStatusFailed);
1249 return false;
1250 }
1251 else if (!SIntValueIsValidForSize (sval64, item_byte_size))
1252 {
Daniel Malea5f35a4b2012-11-29 21:49:15 +00001253 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 +00001254 result.SetStatus(eReturnStatusFailed);
1255 return false;
1256 }
1257 buffer.PutMaxHex64 (sval64, item_byte_size);
1258 break;
1259
1260 case eFormatUnsigned:
1261 uval64 = Args::StringToUInt64(value_str, UINT64_MAX, 0, &success);
1262 if (!success)
1263 {
1264 result.AppendErrorWithFormat ("'%s' is not a valid unsigned decimal string value.\n", value_str);
1265 result.SetStatus(eReturnStatusFailed);
1266 return false;
1267 }
1268 else if (!UIntValueIsValidForSize (uval64, item_byte_size))
1269 {
Daniel Malea5f35a4b2012-11-29 21:49:15 +00001270 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 +00001271 result.SetStatus(eReturnStatusFailed);
1272 return false;
1273 }
1274 buffer.PutMaxHex64 (uval64, item_byte_size);
1275 break;
1276
1277 case eFormatOctal:
1278 uval64 = Args::StringToUInt64(value_str, UINT64_MAX, 8, &success);
1279 if (!success)
1280 {
1281 result.AppendErrorWithFormat ("'%s' is not a valid octal string value.\n", value_str);
1282 result.SetStatus(eReturnStatusFailed);
1283 return false;
1284 }
1285 else if (!UIntValueIsValidForSize (uval64, item_byte_size))
1286 {
Daniel Malea5f35a4b2012-11-29 21:49:15 +00001287 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 +00001288 result.SetStatus(eReturnStatusFailed);
1289 return false;
1290 }
1291 buffer.PutMaxHex64 (uval64, item_byte_size);
1292 break;
1293 }
1294 }
1295
1296 if (!buffer.GetString().empty())
1297 {
1298 Error error;
Greg Clayton53d68e72010-07-20 22:52:08 +00001299 if (process->WriteMemory (addr, buffer.GetString().c_str(), buffer.GetString().size(), error) == buffer.GetString().size())
Chris Lattner24943d22010-06-08 16:52:24 +00001300 return true;
1301 else
1302 {
Daniel Malea5f35a4b2012-11-29 21:49:15 +00001303 result.AppendErrorWithFormat ("Memory write to 0x%" PRIx64 " failed: %s.\n", addr, error.AsCString());
Chris Lattner24943d22010-06-08 16:52:24 +00001304 result.SetStatus(eReturnStatusFailed);
1305 return false;
1306 }
1307 }
1308 return true;
1309 }
1310
Greg Claytona42880a2011-10-25 06:44:01 +00001311 OptionGroupOptions m_option_group;
1312 OptionGroupFormat m_format_options;
1313 OptionGroupWriteMemory m_memory_options;
Chris Lattner24943d22010-06-08 16:52:24 +00001314};
1315
Chris Lattner24943d22010-06-08 16:52:24 +00001316
1317//-------------------------------------------------------------------------
1318// CommandObjectMemory
1319//-------------------------------------------------------------------------
1320
Greg Clayton63094e02010-06-23 01:19:29 +00001321CommandObjectMemory::CommandObjectMemory (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +00001322 CommandObjectMultiword (interpreter,
1323 "memory",
Caroline Ticec1ad82e2010-09-07 22:38:08 +00001324 "A set of commands for operating on memory.",
Chris Lattner24943d22010-06-08 16:52:24 +00001325 "memory <subcommand> [<subcommand-options>]")
1326{
Greg Clayton238c0a12010-09-18 01:14:36 +00001327 LoadSubCommand ("read", CommandObjectSP (new CommandObjectMemoryRead (interpreter)));
1328 LoadSubCommand ("write", CommandObjectSP (new CommandObjectMemoryWrite (interpreter)));
Chris Lattner24943d22010-06-08 16:52:24 +00001329}
1330
1331CommandObjectMemory::~CommandObjectMemory ()
1332{
1333}