blob: 4f41d9beeb0dd557687e90f3af3ebb71d21fe5e8 [file] [log] [blame]
Chris Lattner30fdc8d2010-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 Malea93a64302012-12-05 00:20:57 +000010#include "lldb/lldb-python.h"
11
Chris Lattner30fdc8d2010-06-08 16:52:24 +000012#include "CommandObjectMemory.h"
13
14// C Includes
Virgile Bellobdae3782013-08-28 12:14:27 +000015#include <inttypes.h>
16
Chris Lattner30fdc8d2010-06-08 16:52:24 +000017// C++ Includes
18// Other libraries and framework includes
Zachary Turnera78bd7f2015-03-03 23:11:11 +000019#include "clang/AST/Decl.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000020// Project includes
Chris Lattner30fdc8d2010-06-08 16:52:24 +000021#include "lldb/Core/DataBufferHeap.h"
22#include "lldb/Core/DataExtractor.h"
Greg Clayton66111032010-06-23 01:19:29 +000023#include "lldb/Core/Debugger.h"
Greg Clayton1f746072012-08-29 21:13:06 +000024#include "lldb/Core/Module.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000025#include "lldb/Core/StreamString.h"
Greg Clayton84c39662011-04-27 22:04:39 +000026#include "lldb/Core/ValueObjectMemory.h"
Enrico Granata4d93b8c2013-09-30 19:11:51 +000027#include "lldb/DataFormatters/ValueObjectPrinter.h"
Zachary Turneraf0f45f2015-03-03 21:05:17 +000028#include "lldb/Expression/ClangPersistentVariables.h"
Vince Harron5275aaa2015-01-15 20:08:35 +000029#include "lldb/Host/StringConvert.h"
Greg Clayton66111032010-06-23 01:19:29 +000030#include "lldb/Interpreter/Args.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000031#include "lldb/Interpreter/CommandReturnObject.h"
Greg Clayton66111032010-06-23 01:19:29 +000032#include "lldb/Interpreter/CommandInterpreter.h"
33#include "lldb/Interpreter/Options.h"
Greg Clayton84c39662011-04-27 22:04:39 +000034#include "lldb/Interpreter/OptionGroupFormat.h"
35#include "lldb/Interpreter/OptionGroupOutputFile.h"
Greg Clayton68ebae62011-04-28 20:55:26 +000036#include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
Greg Clayton67cc0632012-08-22 17:17:09 +000037#include "lldb/Interpreter/OptionValueString.h"
Greg Clayton1f746072012-08-29 21:13:06 +000038#include "lldb/Symbol/TypeList.h"
Kuba Breckabeed8212014-09-04 01:03:18 +000039#include "lldb/Target/MemoryHistory.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000040#include "lldb/Target/Process.h"
Jason Molendab57e4a12013-11-04 09:33:30 +000041#include "lldb/Target/StackFrame.h"
Kuba Breckabeed8212014-09-04 01:03:18 +000042#include "lldb/Target/Thread.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000043
44using namespace lldb;
45using namespace lldb_private;
46
Greg Clayton68ebae62011-04-28 20:55:26 +000047static OptionDefinition
Greg Clayton84c39662011-04-27 22:04:39 +000048g_option_table[] =
49{
Zachary Turnerd37221d2014-07-09 16:31:49 +000050 { LLDB_OPT_SET_1, false, "num-per-line" ,'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeNumberPerLine ,"The number of items per line to display."},
51 { LLDB_OPT_SET_2, false, "binary" ,'b', OptionParser::eNoArgument , NULL, 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."},
52 { LLDB_OPT_SET_3, true , "type" ,'t', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeNone ,"The name of a type to view memory as."},
Greg Clayton2346fcf2012-11-02 21:14:58 +000053 { LLDB_OPT_SET_1|
54 LLDB_OPT_SET_2|
Zachary Turnerd37221d2014-07-09 16:31:49 +000055 LLDB_OPT_SET_3, false, "force" ,'r', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone ,"Necessary if reading over target.max-memory-read-size bytes."},
Greg Clayton84c39662011-04-27 22:04:39 +000056};
57
58
59
60class OptionGroupReadMemory : public OptionGroup
61{
62public:
63
64 OptionGroupReadMemory () :
Greg Clayton68ebae62011-04-28 20:55:26 +000065 m_num_per_line (1,1),
Greg Clayton84c39662011-04-27 22:04:39 +000066 m_output_as_binary (false),
67 m_view_as_type()
68 {
69 }
70
71 virtual
72 ~OptionGroupReadMemory ()
73 {
74 }
75
76
77 virtual uint32_t
78 GetNumDefinitions ()
79 {
80 return sizeof (g_option_table) / sizeof (OptionDefinition);
81 }
82
83 virtual const OptionDefinition*
84 GetDefinitions ()
85 {
86 return g_option_table;
87 }
88
89 virtual Error
90 SetOptionValue (CommandInterpreter &interpreter,
91 uint32_t option_idx,
92 const char *option_arg)
93 {
94 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +000095 const int short_option = g_option_table[option_idx].short_option;
Greg Clayton84c39662011-04-27 22:04:39 +000096
97 switch (short_option)
98 {
99 case 'l':
Pavel Labathc95f7e22015-02-20 11:14:59 +0000100 error = m_num_per_line.SetValueFromString (option_arg);
Greg Clayton84c39662011-04-27 22:04:39 +0000101 if (m_num_per_line.GetCurrentValue() == 0)
Greg Clayton86edbf42011-10-26 00:56:27 +0000102 error.SetErrorStringWithFormat("invalid value for --num-per-line option '%s'", option_arg);
Greg Clayton84c39662011-04-27 22:04:39 +0000103 break;
Greg Clayton1deb7962011-10-25 06:44:01 +0000104
Greg Clayton84c39662011-04-27 22:04:39 +0000105 case 'b':
106 m_output_as_binary = true;
107 break;
108
109 case 't':
Pavel Labathc95f7e22015-02-20 11:14:59 +0000110 error = m_view_as_type.SetValueFromString (option_arg);
Greg Clayton84c39662011-04-27 22:04:39 +0000111 break;
Sean Callanan1276c332012-04-28 01:27:38 +0000112
113 case 'r':
114 m_force = true;
115 break;
Greg Clayton84c39662011-04-27 22:04:39 +0000116
117 default:
Greg Clayton86edbf42011-10-26 00:56:27 +0000118 error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option);
Greg Clayton84c39662011-04-27 22:04:39 +0000119 break;
120 }
121 return error;
122 }
123
124 virtual void
125 OptionParsingStarting (CommandInterpreter &interpreter)
126 {
Greg Clayton84c39662011-04-27 22:04:39 +0000127 m_num_per_line.Clear();
128 m_output_as_binary = false;
129 m_view_as_type.Clear();
Enrico Granatad325bf92013-06-04 22:54:16 +0000130 m_force = false;
Greg Clayton84c39662011-04-27 22:04:39 +0000131 }
132
Greg Clayton68ebae62011-04-28 20:55:26 +0000133 Error
Greg Clayton1deb7962011-10-25 06:44:01 +0000134 FinalizeSettings (Target *target, OptionGroupFormat& format_options)
Greg Clayton84c39662011-04-27 22:04:39 +0000135 {
Greg Clayton68ebae62011-04-28 20:55:26 +0000136 Error error;
Greg Clayton1deb7962011-10-25 06:44:01 +0000137 OptionValueUInt64 &byte_size_value = format_options.GetByteSizeValue();
138 OptionValueUInt64 &count_value = format_options.GetCountValue();
Greg Clayton86edbf42011-10-26 00:56:27 +0000139 const bool byte_size_option_set = byte_size_value.OptionWasSet();
Greg Clayton68ebae62011-04-28 20:55:26 +0000140 const bool num_per_line_option_set = m_num_per_line.OptionWasSet();
Greg Clayton1deb7962011-10-25 06:44:01 +0000141 const bool count_option_set = format_options.GetCountValue().OptionWasSet();
Greg Clayton68ebae62011-04-28 20:55:26 +0000142
Greg Clayton68ebae62011-04-28 20:55:26 +0000143 switch (format_options.GetFormat())
Greg Clayton84c39662011-04-27 22:04:39 +0000144 {
145 default:
146 break;
147
148 case eFormatBoolean:
Greg Clayton68ebae62011-04-28 20:55:26 +0000149 if (!byte_size_option_set)
Greg Clayton1deb7962011-10-25 06:44:01 +0000150 byte_size_value = 1;
Greg Clayton68ebae62011-04-28 20:55:26 +0000151 if (!num_per_line_option_set)
152 m_num_per_line = 1;
153 if (!count_option_set)
Greg Clayton1deb7962011-10-25 06:44:01 +0000154 format_options.GetCountValue() = 8;
Greg Clayton84c39662011-04-27 22:04:39 +0000155 break;
156
157 case eFormatCString:
158 break;
Greg Clayton5009f9d2011-10-27 17:55:14 +0000159
160 case eFormatInstruction:
161 if (count_option_set)
Jim Inghamd073fe42012-11-07 01:52:04 +0000162 byte_size_value = target->GetArchitecture().GetMaximumOpcodeByteSize();
Greg Clayton5009f9d2011-10-27 17:55:14 +0000163 m_num_per_line = 1;
164 break;
165
166 case eFormatAddressInfo:
167 if (!byte_size_option_set)
168 byte_size_value = target->GetArchitecture().GetAddressByteSize();
169 m_num_per_line = 1;
170 if (!count_option_set)
171 format_options.GetCountValue() = 8;
172 break;
173
Greg Clayton84c39662011-04-27 22:04:39 +0000174 case eFormatPointer:
Greg Clayton1deb7962011-10-25 06:44:01 +0000175 byte_size_value = target->GetArchitecture().GetAddressByteSize();
Greg Clayton68ebae62011-04-28 20:55:26 +0000176 if (!num_per_line_option_set)
177 m_num_per_line = 4;
178 if (!count_option_set)
Greg Clayton1deb7962011-10-25 06:44:01 +0000179 format_options.GetCountValue() = 8;
Greg Clayton84c39662011-04-27 22:04:39 +0000180 break;
181
182 case eFormatBinary:
183 case eFormatFloat:
184 case eFormatOctal:
185 case eFormatDecimal:
186 case eFormatEnum:
187 case eFormatUnicode16:
188 case eFormatUnicode32:
189 case eFormatUnsigned:
Greg Clayton5009f9d2011-10-27 17:55:14 +0000190 case eFormatHexFloat:
Greg Clayton68ebae62011-04-28 20:55:26 +0000191 if (!byte_size_option_set)
Greg Clayton1deb7962011-10-25 06:44:01 +0000192 byte_size_value = 4;
Greg Clayton68ebae62011-04-28 20:55:26 +0000193 if (!num_per_line_option_set)
194 m_num_per_line = 1;
195 if (!count_option_set)
Greg Clayton1deb7962011-10-25 06:44:01 +0000196 format_options.GetCountValue() = 8;
Greg Clayton84c39662011-04-27 22:04:39 +0000197 break;
Greg Clayton5009f9d2011-10-27 17:55:14 +0000198
Greg Clayton84c39662011-04-27 22:04:39 +0000199 case eFormatBytes:
200 case eFormatBytesWithASCII:
Greg Clayton86edbf42011-10-26 00:56:27 +0000201 if (byte_size_option_set)
Greg Clayton68ebae62011-04-28 20:55:26 +0000202 {
Greg Clayton1deb7962011-10-25 06:44:01 +0000203 if (byte_size_value > 1)
Daniel Malead01b2952012-11-29 21:49:15 +0000204 error.SetErrorStringWithFormat ("display format (bytes/bytes with ascii) conflicts with the specified byte size %" PRIu64 "\n"
Johnny Chenda324de2012-03-06 01:17:59 +0000205 "\tconsider using a different display format or don't specify the byte size",
206 byte_size_value.GetCurrentValue());
Greg Clayton68ebae62011-04-28 20:55:26 +0000207 }
208 else
Greg Clayton1deb7962011-10-25 06:44:01 +0000209 byte_size_value = 1;
Greg Clayton68ebae62011-04-28 20:55:26 +0000210 if (!num_per_line_option_set)
211 m_num_per_line = 16;
212 if (!count_option_set)
Greg Clayton1deb7962011-10-25 06:44:01 +0000213 format_options.GetCountValue() = 32;
Greg Clayton84c39662011-04-27 22:04:39 +0000214 break;
Greg Clayton4e4294b2011-06-17 23:50:44 +0000215 case eFormatCharArray:
Greg Clayton84c39662011-04-27 22:04:39 +0000216 case eFormatChar:
217 case eFormatCharPrintable:
Greg Clayton68ebae62011-04-28 20:55:26 +0000218 if (!byte_size_option_set)
Greg Clayton1deb7962011-10-25 06:44:01 +0000219 byte_size_value = 1;
Greg Clayton68ebae62011-04-28 20:55:26 +0000220 if (!num_per_line_option_set)
221 m_num_per_line = 32;
222 if (!count_option_set)
Greg Clayton1deb7962011-10-25 06:44:01 +0000223 format_options.GetCountValue() = 64;
Greg Clayton84c39662011-04-27 22:04:39 +0000224 break;
225 case eFormatComplex:
Greg Clayton68ebae62011-04-28 20:55:26 +0000226 if (!byte_size_option_set)
Greg Clayton1deb7962011-10-25 06:44:01 +0000227 byte_size_value = 8;
Greg Clayton68ebae62011-04-28 20:55:26 +0000228 if (!num_per_line_option_set)
229 m_num_per_line = 1;
230 if (!count_option_set)
Greg Clayton1deb7962011-10-25 06:44:01 +0000231 format_options.GetCountValue() = 8;
Greg Clayton84c39662011-04-27 22:04:39 +0000232 break;
Jason Molendafc306d32013-03-23 05:16:54 +0000233 case eFormatComplexInteger:
234 if (!byte_size_option_set)
235 byte_size_value = 8;
236 if (!num_per_line_option_set)
237 m_num_per_line = 1;
238 if (!count_option_set)
239 format_options.GetCountValue() = 8;
240 break;
Greg Clayton84c39662011-04-27 22:04:39 +0000241 case eFormatHex:
Greg Clayton68ebae62011-04-28 20:55:26 +0000242 if (!byte_size_option_set)
Greg Clayton1deb7962011-10-25 06:44:01 +0000243 byte_size_value = 4;
Greg Clayton68ebae62011-04-28 20:55:26 +0000244 if (!num_per_line_option_set)
245 {
Greg Clayton1deb7962011-10-25 06:44:01 +0000246 switch (byte_size_value)
Greg Clayton68ebae62011-04-28 20:55:26 +0000247 {
248 case 1:
249 case 2:
250 m_num_per_line = 8;
251 break;
252 case 4:
253 m_num_per_line = 4;
254 break;
255 case 8:
256 m_num_per_line = 2;
257 break;
258 default:
259 m_num_per_line = 1;
260 break;
261 }
262 }
263 if (!count_option_set)
Greg Clayton1deb7962011-10-25 06:44:01 +0000264 count_value = 8;
Greg Clayton84c39662011-04-27 22:04:39 +0000265 break;
266
267 case eFormatVectorOfChar:
268 case eFormatVectorOfSInt8:
269 case eFormatVectorOfUInt8:
270 case eFormatVectorOfSInt16:
271 case eFormatVectorOfUInt16:
272 case eFormatVectorOfSInt32:
273 case eFormatVectorOfUInt32:
274 case eFormatVectorOfSInt64:
275 case eFormatVectorOfUInt64:
276 case eFormatVectorOfFloat32:
277 case eFormatVectorOfFloat64:
278 case eFormatVectorOfUInt128:
Greg Clayton68ebae62011-04-28 20:55:26 +0000279 if (!byte_size_option_set)
Greg Clayton1deb7962011-10-25 06:44:01 +0000280 byte_size_value = 128;
Greg Clayton68ebae62011-04-28 20:55:26 +0000281 if (!num_per_line_option_set)
282 m_num_per_line = 1;
283 if (!count_option_set)
Greg Clayton1deb7962011-10-25 06:44:01 +0000284 count_value = 4;
Greg Clayton84c39662011-04-27 22:04:39 +0000285 break;
286 }
Greg Clayton68ebae62011-04-28 20:55:26 +0000287 return error;
Greg Clayton84c39662011-04-27 22:04:39 +0000288 }
289
Greg Clayton82f4cf42011-10-26 04:32:38 +0000290 bool
291 AnyOptionWasSet () const
292 {
293 return m_num_per_line.OptionWasSet() ||
294 m_output_as_binary ||
295 m_view_as_type.OptionWasSet();
296 }
297
Greg Clayton84c39662011-04-27 22:04:39 +0000298 OptionValueUInt64 m_num_per_line;
299 bool m_output_as_binary;
300 OptionValueString m_view_as_type;
Sean Callanan1276c332012-04-28 01:27:38 +0000301 bool m_force;
Greg Clayton84c39662011-04-27 22:04:39 +0000302};
303
304
305
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000306//----------------------------------------------------------------------
307// Read memory from the inferior process
308//----------------------------------------------------------------------
Jim Ingham5a988412012-06-08 21:56:10 +0000309class CommandObjectMemoryRead : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000310{
311public:
312
Greg Claytona7015092010-09-18 01:14:36 +0000313 CommandObjectMemoryRead (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +0000314 CommandObjectParsed (interpreter,
315 "memory read",
316 "Read from the memory of the process being debugged.",
317 NULL,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000318 eFlagRequiresTarget | eFlagProcessMustBePaused),
Greg Clayton84c39662011-04-27 22:04:39 +0000319 m_option_group (interpreter),
Greg Clayton1deb7962011-10-25 06:44:01 +0000320 m_format_options (eFormatBytesWithASCII, 1, 8),
Greg Clayton84c39662011-04-27 22:04:39 +0000321 m_memory_options (),
Greg Clayton68ebae62011-04-28 20:55:26 +0000322 m_outfile_options (),
Greg Clayton82f4cf42011-10-26 04:32:38 +0000323 m_varobj_options(),
324 m_next_addr(LLDB_INVALID_ADDRESS),
325 m_prev_byte_size(0),
326 m_prev_format_options (eFormatBytesWithASCII, 1, 8),
327 m_prev_memory_options (),
328 m_prev_outfile_options (),
329 m_prev_varobj_options()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000330 {
Caroline Tice405fe672010-10-04 22:28:36 +0000331 CommandArgumentEntry arg1;
332 CommandArgumentEntry arg2;
333 CommandArgumentData start_addr_arg;
334 CommandArgumentData end_addr_arg;
335
336 // Define the first (and only) variant of this arg.
Enrico Granatab84a9db2013-01-29 01:48:30 +0000337 start_addr_arg.arg_type = eArgTypeAddressOrExpression;
Caroline Tice405fe672010-10-04 22:28:36 +0000338 start_addr_arg.arg_repetition = eArgRepeatPlain;
339
340 // There is only one variant this argument could be; put it into the argument entry.
341 arg1.push_back (start_addr_arg);
342
343 // Define the first (and only) variant of this arg.
Enrico Granatab84a9db2013-01-29 01:48:30 +0000344 end_addr_arg.arg_type = eArgTypeAddressOrExpression;
Caroline Tice405fe672010-10-04 22:28:36 +0000345 end_addr_arg.arg_repetition = eArgRepeatOptional;
346
347 // There is only one variant this argument could be; put it into the argument entry.
348 arg2.push_back (end_addr_arg);
349
350 // Push the data for the first argument into the m_arguments vector.
351 m_arguments.push_back (arg1);
352 m_arguments.push_back (arg2);
Greg Clayton84c39662011-04-27 22:04:39 +0000353
Greg Clayton1deb7962011-10-25 06:44:01 +0000354 // Add the "--format" and "--count" options to group 1 and 3
355 m_option_group.Append (&m_format_options,
356 OptionGroupFormat::OPTION_GROUP_FORMAT | OptionGroupFormat::OPTION_GROUP_COUNT,
Greg Clayton83889552011-11-22 18:07:35 +0000357 LLDB_OPT_SET_1 | LLDB_OPT_SET_2 | LLDB_OPT_SET_3);
Greg Clayton5009f9d2011-10-27 17:55:14 +0000358 m_option_group.Append (&m_format_options,
359 OptionGroupFormat::OPTION_GROUP_GDB_FMT,
Greg Clayton83889552011-11-22 18:07:35 +0000360 LLDB_OPT_SET_1 | LLDB_OPT_SET_3);
Greg Clayton1deb7962011-10-25 06:44:01 +0000361 // Add the "--size" option to group 1 and 2
362 m_option_group.Append (&m_format_options,
363 OptionGroupFormat::OPTION_GROUP_SIZE,
364 LLDB_OPT_SET_1 | LLDB_OPT_SET_2);
Greg Clayton84c39662011-04-27 22:04:39 +0000365 m_option_group.Append (&m_memory_options);
366 m_option_group.Append (&m_outfile_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1 | LLDB_OPT_SET_2 | LLDB_OPT_SET_3);
Greg Clayton68ebae62011-04-28 20:55:26 +0000367 m_option_group.Append (&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_3);
Greg Clayton84c39662011-04-27 22:04:39 +0000368 m_option_group.Finalize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000369 }
370
371 virtual
372 ~CommandObjectMemoryRead ()
373 {
374 }
375
376 Options *
377 GetOptions ()
378 {
Greg Clayton84c39662011-04-27 22:04:39 +0000379 return &m_option_group;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000380 }
381
Greg Clayton82f4cf42011-10-26 04:32:38 +0000382 virtual const char *GetRepeatCommand (Args &current_command_args, uint32_t index)
383 {
384 return m_cmd_name.c_str();
385 }
386
Jim Ingham5a988412012-06-08 21:56:10 +0000387protected:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000388 virtual bool
Greg Claytonb9d5df52012-12-06 22:49:16 +0000389 DoExecute (Args& command, CommandReturnObject &result)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000390 {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000391 // No need to check "target" for validity as eFlagRequiresTarget ensures it is valid
392 Target *target = m_exe_ctx.GetTargetPtr();
393
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000394 const size_t argc = command.GetArgumentCount();
395
Greg Clayton82f4cf42011-10-26 04:32:38 +0000396 if ((argc == 0 && m_next_addr == LLDB_INVALID_ADDRESS) || argc > 2)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000397 {
Greg Claytonb9d5df52012-12-06 22:49:16 +0000398 result.AppendErrorWithFormat ("%s takes a start address expression with an optional end address expression.\n", m_cmd_name.c_str());
Greg Clayton2e1f7452012-12-15 02:08:17 +0000399 result.AppendRawWarning("Expressions should be quoted if they contain spaces or other special characters.\n");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000400 result.SetStatus(eReturnStatusFailed);
401 return false;
402 }
403
Greg Clayton68ebae62011-04-28 20:55:26 +0000404 ClangASTType clang_ast_type;
405 Error error;
406
Greg Clayton84c39662011-04-27 22:04:39 +0000407 const char *view_as_type_cstr = m_memory_options.m_view_as_type.GetCurrentValue();
408 if (view_as_type_cstr && view_as_type_cstr[0])
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000409 {
Greg Clayton84c39662011-04-27 22:04:39 +0000410 // We are viewing memory as a type
Greg Clayton2e1f7452012-12-15 02:08:17 +0000411
Greg Clayton84c39662011-04-27 22:04:39 +0000412 SymbolContext sc;
Greg Clayton84db9102012-03-26 23:03:23 +0000413 const bool exact_match = false;
Greg Clayton84c39662011-04-27 22:04:39 +0000414 TypeList type_list;
415 uint32_t reference_count = 0;
416 uint32_t pointer_count = 0;
417 size_t idx;
Sean Callanan17cf1132012-07-10 21:24:26 +0000418
419#define ALL_KEYWORDS \
420 KEYWORD("const") \
421 KEYWORD("volatile") \
422 KEYWORD("restrict") \
423 KEYWORD("struct") \
424 KEYWORD("class") \
425 KEYWORD("union")
426
427#define KEYWORD(s) s,
428 static const char *g_keywords[] =
429 {
430 ALL_KEYWORDS
431 };
432#undef KEYWORD
433
434#define KEYWORD(s) (sizeof(s) - 1),
435 static const int g_keyword_lengths[] =
436 {
437 ALL_KEYWORDS
438 };
439#undef KEYWORD
440
441#undef ALL_KEYWORDS
442
443 static size_t g_num_keywords = sizeof(g_keywords) / sizeof(const char *);
Greg Clayton84c39662011-04-27 22:04:39 +0000444 std::string type_str(view_as_type_cstr);
445
446 // Remove all instances of g_keywords that are followed by spaces
447 for (size_t i = 0; i < g_num_keywords; ++i)
448 {
449 const char *keyword = g_keywords[i];
Sean Callanan17cf1132012-07-10 21:24:26 +0000450 int keyword_len = g_keyword_lengths[i];
451
452 idx = 0;
453 while ((idx = type_str.find (keyword, idx)) != std::string::npos)
Greg Clayton84c39662011-04-27 22:04:39 +0000454 {
455 if (type_str[idx + keyword_len] == ' ' || type_str[idx + keyword_len] == '\t')
Sean Callanan17cf1132012-07-10 21:24:26 +0000456 {
Greg Clayton84c39662011-04-27 22:04:39 +0000457 type_str.erase(idx, keyword_len+1);
Sean Callanan17cf1132012-07-10 21:24:26 +0000458 idx = 0;
459 }
460 else
461 {
462 idx += keyword_len;
463 }
Greg Clayton84c39662011-04-27 22:04:39 +0000464 }
465 }
466 bool done = type_str.empty();
467 //
468 idx = type_str.find_first_not_of (" \t");
469 if (idx > 0 && idx != std::string::npos)
470 type_str.erase (0, idx);
471 while (!done)
472 {
473 // Strip trailing spaces
474 if (type_str.empty())
475 done = true;
476 else
477 {
478 switch (type_str[type_str.size()-1])
479 {
480 case '*':
481 ++pointer_count;
482 // fall through...
483 case ' ':
484 case '\t':
485 type_str.erase(type_str.size()-1);
486 break;
487
488 case '&':
489 if (reference_count == 0)
490 {
491 reference_count = 1;
492 type_str.erase(type_str.size()-1);
493 }
494 else
495 {
496 result.AppendErrorWithFormat ("invalid type string: '%s'\n", view_as_type_cstr);
497 result.SetStatus(eReturnStatusFailed);
498 return false;
499 }
500 break;
501
502 default:
503 done = true;
504 break;
505 }
506 }
507 }
508
509 ConstString lookup_type_name(type_str.c_str());
Jason Molendab57e4a12013-11-04 09:33:30 +0000510 StackFrame *frame = m_exe_ctx.GetFramePtr();
Greg Claytonc14ee322011-09-22 04:58:26 +0000511 if (frame)
Greg Clayton84c39662011-04-27 22:04:39 +0000512 {
Greg Claytonc14ee322011-09-22 04:58:26 +0000513 sc = frame->GetSymbolContext (eSymbolContextModule);
Greg Clayton84c39662011-04-27 22:04:39 +0000514 if (sc.module_sp)
515 {
Sean Callananb6d70eb2011-10-12 02:08:07 +0000516 sc.module_sp->FindTypes (sc,
517 lookup_type_name,
Greg Clayton84db9102012-03-26 23:03:23 +0000518 exact_match,
Greg Clayton84c39662011-04-27 22:04:39 +0000519 1,
520 type_list);
521 }
522 }
523 if (type_list.GetSize() == 0)
524 {
Greg Clayton29399a22012-04-06 17:41:13 +0000525 target->GetImages().FindTypes (sc,
Greg Claytonc14ee322011-09-22 04:58:26 +0000526 lookup_type_name,
Greg Clayton84db9102012-03-26 23:03:23 +0000527 exact_match,
Greg Claytonc14ee322011-09-22 04:58:26 +0000528 1,
529 type_list);
Greg Clayton84c39662011-04-27 22:04:39 +0000530 }
531
Enrico Granata7bd2bbb2013-06-11 18:47:55 +0000532 if (type_list.GetSize() == 0 && lookup_type_name.GetCString() && *lookup_type_name.GetCString() == '$')
Greg Clayton84c39662011-04-27 22:04:39 +0000533 {
Enrico Granata7bd2bbb2013-06-11 18:47:55 +0000534 clang::TypeDecl *tdecl = target->GetPersistentVariables().GetPersistentType(ConstString(lookup_type_name));
535 if (tdecl)
536 {
537 clang_ast_type.SetClangType(&tdecl->getASTContext(),(lldb::clang_type_t)tdecl->getTypeForDecl());
538 }
Greg Clayton84c39662011-04-27 22:04:39 +0000539 }
540
Enrico Granata7bd2bbb2013-06-11 18:47:55 +0000541 if (clang_ast_type.IsValid() == false)
542 {
543 if (type_list.GetSize() == 0)
544 {
545 result.AppendErrorWithFormat ("unable to find any types that match the raw type '%s' for full type '%s'\n",
546 lookup_type_name.GetCString(),
547 view_as_type_cstr);
548 result.SetStatus(eReturnStatusFailed);
549 return false;
550 }
551 else
552 {
553 TypeSP type_sp (type_list.GetTypeAtIndex(0));
Greg Clayton57ee3062013-07-11 22:46:58 +0000554 clang_ast_type = type_sp->GetClangFullType();
Enrico Granata7bd2bbb2013-06-11 18:47:55 +0000555 }
556 }
Greg Clayton84c39662011-04-27 22:04:39 +0000557
558 while (pointer_count > 0)
559 {
Greg Clayton57ee3062013-07-11 22:46:58 +0000560 ClangASTType pointer_type = clang_ast_type.GetPointerType();
561 if (pointer_type.IsValid())
562 clang_ast_type = pointer_type;
Greg Clayton84c39662011-04-27 22:04:39 +0000563 else
564 {
565 result.AppendError ("unable make a pointer type\n");
566 result.SetStatus(eReturnStatusFailed);
567 return false;
568 }
569 --pointer_count;
570 }
571
Enrico Granata1cd5e922015-01-28 00:07:51 +0000572 m_format_options.GetByteSizeValue() = clang_ast_type.GetByteSize(nullptr);
Greg Clayton84c39662011-04-27 22:04:39 +0000573
Greg Clayton1deb7962011-10-25 06:44:01 +0000574 if (m_format_options.GetByteSizeValue() == 0)
Greg Clayton84c39662011-04-27 22:04:39 +0000575 {
576 result.AppendErrorWithFormat ("unable to get the byte size of the type '%s'\n",
577 view_as_type_cstr);
578 result.SetStatus(eReturnStatusFailed);
579 return false;
580 }
Greg Clayton68ebae62011-04-28 20:55:26 +0000581
Greg Clayton1deb7962011-10-25 06:44:01 +0000582 if (!m_format_options.GetCountValue().OptionWasSet())
583 m_format_options.GetCountValue() = 1;
Greg Clayton84c39662011-04-27 22:04:39 +0000584 }
585 else
586 {
Greg Claytonc14ee322011-09-22 04:58:26 +0000587 error = m_memory_options.FinalizeSettings (target, m_format_options);
Greg Clayton68ebae62011-04-28 20:55:26 +0000588 }
589
590 // Look for invalid combinations of settings
591 if (error.Fail())
592 {
Greg Claytonb9d5df52012-12-06 22:49:16 +0000593 result.AppendError(error.AsCString());
Greg Clayton68ebae62011-04-28 20:55:26 +0000594 result.SetStatus(eReturnStatusFailed);
595 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000596 }
597
Greg Clayton82f4cf42011-10-26 04:32:38 +0000598 lldb::addr_t addr;
599 size_t total_byte_size = 0;
600 if (argc == 0)
601 {
602 // Use the last address and byte size and all options as they were
603 // if no options have been set
604 addr = m_next_addr;
605 total_byte_size = m_prev_byte_size;
Greg Clayton2e1f7452012-12-15 02:08:17 +0000606 clang_ast_type = m_prev_clang_ast_type;
607 if (!m_format_options.AnyOptionWasSet() &&
Greg Clayton82f4cf42011-10-26 04:32:38 +0000608 !m_memory_options.AnyOptionWasSet() &&
609 !m_outfile_options.AnyOptionWasSet() &&
610 !m_varobj_options.AnyOptionWasSet())
611 {
612 m_format_options = m_prev_format_options;
613 m_memory_options = m_prev_memory_options;
614 m_outfile_options = m_prev_outfile_options;
615 m_varobj_options = m_prev_varobj_options;
616 }
617 }
618
Greg Clayton1deb7962011-10-25 06:44:01 +0000619 size_t item_count = m_format_options.GetCountValue().GetCurrentValue();
Matthew Gardinerf03e6d842014-09-29 08:02:24 +0000620
621 // TODO For non-8-bit byte addressable architectures this needs to be
622 // revisited to fully support all lldb's range of formatting options.
623 // Furthermore code memory reads (for those architectures) will not
624 // be correctly formatted even w/o formatting options.
625 size_t item_byte_size =
626 target->GetArchitecture().GetDataByteSize() > 1 ?
627 target->GetArchitecture().GetDataByteSize() :
628 m_format_options.GetByteSizeValue().GetCurrentValue();
629
Greg Clayton68ebae62011-04-28 20:55:26 +0000630 const size_t num_per_line = m_memory_options.m_num_per_line.GetCurrentValue();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000631
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000632 if (total_byte_size == 0)
Greg Clayton82f4cf42011-10-26 04:32:38 +0000633 {
634 total_byte_size = item_count * item_byte_size;
635 if (total_byte_size == 0)
636 total_byte_size = 32;
637 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000638
Greg Clayton82f4cf42011-10-26 04:32:38 +0000639 if (argc > 0)
Greg Claytonf9fc6092013-01-09 19:44:40 +0000640 addr = Args::StringToAddress(&m_exe_ctx, command.GetArgumentAtIndex(0), LLDB_INVALID_ADDRESS, &error);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000641
642 if (addr == LLDB_INVALID_ADDRESS)
643 {
Greg Claytonb9d5df52012-12-06 22:49:16 +0000644 result.AppendError("invalid start address expression.");
645 result.AppendError(error.AsCString());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000646 result.SetStatus(eReturnStatusFailed);
647 return false;
648 }
649
650 if (argc == 2)
651 {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000652 lldb::addr_t end_addr = Args::StringToAddress(&m_exe_ctx, command.GetArgumentAtIndex(1), LLDB_INVALID_ADDRESS, 0);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000653 if (end_addr == LLDB_INVALID_ADDRESS)
654 {
Greg Claytonb9d5df52012-12-06 22:49:16 +0000655 result.AppendError("invalid end address expression.");
656 result.AppendError(error.AsCString());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000657 result.SetStatus(eReturnStatusFailed);
658 return false;
659 }
660 else if (end_addr <= addr)
661 {
Daniel Malead01b2952012-11-29 21:49:15 +0000662 result.AppendErrorWithFormat("end address (0x%" PRIx64 ") must be greater that the start address (0x%" PRIx64 ").\n", end_addr, addr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000663 result.SetStatus(eReturnStatusFailed);
664 return false;
665 }
Greg Clayton1deb7962011-10-25 06:44:01 +0000666 else if (m_format_options.GetCountValue().OptionWasSet())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000667 {
Greg Clayton6fea17e2014-03-03 19:15:20 +0000668 result.AppendErrorWithFormat("specify either the end address (0x%" PRIx64 ") or the count (--count %" PRIu64 "), not both.\n", end_addr, (uint64_t)item_count);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000669 result.SetStatus(eReturnStatusFailed);
670 return false;
671 }
672
673 total_byte_size = end_addr - addr;
674 item_count = total_byte_size / item_byte_size;
675 }
Matthew Gardinerf03e6d842014-09-29 08:02:24 +0000676
Enrico Granatad325bf92013-06-04 22:54:16 +0000677 uint32_t max_unforced_size = target->GetMaximumMemReadSize();
678
679 if (total_byte_size > max_unforced_size && !m_memory_options.m_force)
Sean Callanan1276c332012-04-28 01:27:38 +0000680 {
Enrico Granatad325bf92013-06-04 22:54:16 +0000681 result.AppendErrorWithFormat("Normally, \'memory read\' will not read over %" PRIu32 " bytes of data.\n",max_unforced_size);
682 result.AppendErrorWithFormat("Please use --force to override this restriction just once.\n");
683 result.AppendErrorWithFormat("or set target.max-memory-read-size if you will often need a larger limit.\n");
Sean Callanan1276c332012-04-28 01:27:38 +0000684 return false;
685 }
686
Greg Clayton84c39662011-04-27 22:04:39 +0000687 DataBufferSP data_sp;
Greg Clayton84c39662011-04-27 22:04:39 +0000688 size_t bytes_read = 0;
Greg Clayton2e1f7452012-12-15 02:08:17 +0000689 if (clang_ast_type.GetOpaqueQualType())
690 {
691 // Make sure we don't display our type as ASCII bytes like the default memory read
692 if (m_format_options.GetFormatValue().OptionWasSet() == false)
693 m_format_options.GetFormatValue().SetCurrentValue(eFormatDefault);
694
Enrico Granata1cd5e922015-01-28 00:07:51 +0000695 bytes_read = clang_ast_type.GetByteSize(nullptr) * m_format_options.GetCountValue().GetCurrentValue();
Greg Clayton2e1f7452012-12-15 02:08:17 +0000696 }
Enrico Granata6b4ddc62013-01-21 19:20:50 +0000697 else if (m_format_options.GetFormatValue().GetCurrentValue() != eFormatCString)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000698 {
Greg Clayton84c39662011-04-27 22:04:39 +0000699 data_sp.reset (new DataBufferHeap (total_byte_size, '\0'));
Greg Clayton46a44262013-07-24 18:17:35 +0000700 if (data_sp->GetBytes() == NULL)
701 {
Virgile Belloffeba252014-03-08 17:15:35 +0000702 result.AppendErrorWithFormat ("can't allocate 0x%" PRIx32 " bytes for the memory read buffer, specify a smaller size to read", (uint32_t)total_byte_size);
Greg Clayton46a44262013-07-24 18:17:35 +0000703 result.SetStatus(eReturnStatusFailed);
704 return false;
705 }
706
Greg Claytone72dfb32012-02-24 01:59:29 +0000707 Address address(addr, NULL);
Greg Claytonc14ee322011-09-22 04:58:26 +0000708 bytes_read = target->ReadMemory(address, false, data_sp->GetBytes (), data_sp->GetByteSize(), error);
Greg Clayton84c39662011-04-27 22:04:39 +0000709 if (bytes_read == 0)
710 {
Greg Clayton57f06302012-05-25 17:05:55 +0000711 const char *error_cstr = error.AsCString();
712 if (error_cstr && error_cstr[0])
713 {
714 result.AppendError(error_cstr);
715 }
716 else
717 {
Daniel Malead01b2952012-11-29 21:49:15 +0000718 result.AppendErrorWithFormat("failed to read memory from 0x%" PRIx64 ".\n", addr);
Greg Clayton57f06302012-05-25 17:05:55 +0000719 }
Greg Clayton84c39662011-04-27 22:04:39 +0000720 result.SetStatus(eReturnStatusFailed);
721 return false;
722 }
723
724 if (bytes_read < total_byte_size)
Greg Clayton6fea17e2014-03-03 19:15:20 +0000725 result.AppendWarningWithFormat("Not all bytes (%" PRIu64 "/%" PRIu64 ") were able to be read from 0x%" PRIx64 ".\n", (uint64_t)bytes_read, (uint64_t)total_byte_size, addr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000726 }
Enrico Granata6b4ddc62013-01-21 19:20:50 +0000727 else
728 {
729 // we treat c-strings as a special case because they do not have a fixed size
730 if (m_format_options.GetByteSizeValue().OptionWasSet() && !m_format_options.HasGDBFormat())
731 item_byte_size = m_format_options.GetByteSizeValue().GetCurrentValue();
732 else
733 item_byte_size = target->GetMaximumSizeOfStringSummary();
734 if (!m_format_options.GetCountValue().OptionWasSet())
735 item_count = 1;
736 data_sp.reset (new DataBufferHeap ((item_byte_size+1) * item_count, '\0')); // account for NULLs as necessary
Greg Clayton46a44262013-07-24 18:17:35 +0000737 if (data_sp->GetBytes() == NULL)
738 {
739 result.AppendErrorWithFormat ("can't allocate 0x%" PRIx64 " bytes for the memory read buffer, specify a smaller size to read", (uint64_t)((item_byte_size+1) * item_count));
740 result.SetStatus(eReturnStatusFailed);
741 return false;
742 }
Enrico Granata6b4ddc62013-01-21 19:20:50 +0000743 uint8_t *data_ptr = data_sp->GetBytes();
744 auto data_addr = addr;
745 auto count = item_count;
746 item_count = 0;
747 while (item_count < count)
748 {
749 std::string buffer;
750 buffer.resize(item_byte_size+1,0);
751 Error error;
752 size_t read = target->ReadCStringFromMemory(data_addr, &buffer[0], item_byte_size+1, error);
753 if (error.Fail())
754 {
755 result.AppendErrorWithFormat("failed to read memory from 0x%" PRIx64 ".\n", addr);
756 result.SetStatus(eReturnStatusFailed);
757 return false;
758 }
759 if (item_byte_size == read)
760 {
761 result.AppendWarningWithFormat("unable to find a NULL terminated string at 0x%" PRIx64 ".Consider increasing the maximum read length.\n", data_addr);
762 break;
763 }
764 read+=1; // account for final NULL byte
765 memcpy(data_ptr, &buffer[0], read);
766 data_ptr += read;
767 data_addr += read;
768 bytes_read += read;
769 item_count++; // if we break early we know we only read item_count strings
770 }
771 data_sp.reset(new DataBufferHeap(data_sp->GetBytes(),bytes_read+1));
772 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000773
Greg Clayton2e1f7452012-12-15 02:08:17 +0000774 m_next_addr = addr + bytes_read;
775 m_prev_byte_size = bytes_read;
776 m_prev_format_options = m_format_options;
777 m_prev_memory_options = m_memory_options;
778 m_prev_outfile_options = m_outfile_options;
779 m_prev_varobj_options = m_varobj_options;
780 m_prev_clang_ast_type = clang_ast_type;
781
Greg Clayton6d7e77b2010-10-10 20:52:20 +0000782 StreamFile outfile_stream;
783 Stream *output_stream = NULL;
Greg Clayton84c39662011-04-27 22:04:39 +0000784 const FileSpec &outfile_spec = m_outfile_options.GetFile().GetCurrentValue();
785 if (outfile_spec)
Greg Clayton6d7e77b2010-10-10 20:52:20 +0000786 {
787 char path[PATH_MAX];
Greg Clayton84c39662011-04-27 22:04:39 +0000788 outfile_spec.GetPath (path, sizeof(path));
789
790 uint32_t open_options = File::eOpenOptionWrite | File::eOpenOptionCanCreate;
791 const bool append = m_outfile_options.GetAppend().GetCurrentValue();
792 if (append)
793 open_options |= File::eOpenOptionAppend;
794
795 if (outfile_stream.GetFile ().Open (path, open_options).Success())
Greg Clayton6d7e77b2010-10-10 20:52:20 +0000796 {
Greg Clayton84c39662011-04-27 22:04:39 +0000797 if (m_memory_options.m_output_as_binary)
Greg Clayton6d7e77b2010-10-10 20:52:20 +0000798 {
Greg Claytonc7bece562013-01-25 18:06:21 +0000799 const size_t bytes_written = outfile_stream.Write (data_sp->GetBytes(), bytes_read);
Greg Clayton6d7e77b2010-10-10 20:52:20 +0000800 if (bytes_written > 0)
801 {
Greg Claytonc7bece562013-01-25 18:06:21 +0000802 result.GetOutputStream().Printf ("%zi bytes %s to '%s'\n",
Greg Clayton6d7e77b2010-10-10 20:52:20 +0000803 bytes_written,
Greg Clayton84c39662011-04-27 22:04:39 +0000804 append ? "appended" : "written",
Greg Clayton6d7e77b2010-10-10 20:52:20 +0000805 path);
806 return true;
807 }
808 else
809 {
Daniel Malead01b2952012-11-29 21:49:15 +0000810 result.AppendErrorWithFormat("Failed to write %" PRIu64 " bytes to '%s'.\n", (uint64_t)bytes_read, path);
Greg Clayton6d7e77b2010-10-10 20:52:20 +0000811 result.SetStatus(eReturnStatusFailed);
812 return false;
813 }
814 }
815 else
816 {
817 // We are going to write ASCII to the file just point the
818 // output_stream to our outfile_stream...
819 output_stream = &outfile_stream;
820 }
821 }
822 else
823 {
Greg Clayton84c39662011-04-27 22:04:39 +0000824 result.AppendErrorWithFormat("Failed to open file '%s' for %s.\n", path, append ? "append" : "write");
Greg Clayton6d7e77b2010-10-10 20:52:20 +0000825 result.SetStatus(eReturnStatusFailed);
826 return false;
827 }
828 }
829 else
830 {
831 output_stream = &result.GetOutputStream();
832 }
833
Greg Clayton84c39662011-04-27 22:04:39 +0000834
Greg Claytonf9fc6092013-01-09 19:44:40 +0000835 ExecutionContextScope *exe_scope = m_exe_ctx.GetBestExecutionContextScope();
Greg Clayton84c39662011-04-27 22:04:39 +0000836 if (clang_ast_type.GetOpaqueQualType())
837 {
838 for (uint32_t i = 0; i<item_count; ++i)
839 {
840 addr_t item_addr = addr + (i * item_byte_size);
Greg Claytone72dfb32012-02-24 01:59:29 +0000841 Address address (item_addr);
Greg Clayton84c39662011-04-27 22:04:39 +0000842 StreamString name_strm;
Daniel Malead01b2952012-11-29 21:49:15 +0000843 name_strm.Printf ("0x%" PRIx64, item_addr);
Greg Clayton5009f9d2011-10-27 17:55:14 +0000844 ValueObjectSP valobj_sp (ValueObjectMemory::Create (exe_scope,
Greg Clayton84c39662011-04-27 22:04:39 +0000845 name_strm.GetString().c_str(),
846 address,
847 clang_ast_type));
848 if (valobj_sp)
849 {
Greg Clayton2e1f7452012-12-15 02:08:17 +0000850 Format format = m_format_options.GetFormat();
Greg Clayton68ebae62011-04-28 20:55:26 +0000851 if (format != eFormatDefault)
852 valobj_sp->SetFormat (format);
853
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000854 DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions(eLanguageRuntimeDescriptionDisplayVerbosityFull,format));
Enrico Granata9fb5ab52013-03-26 18:04:53 +0000855
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000856 valobj_sp->Dump(*output_stream,options);
Greg Clayton84c39662011-04-27 22:04:39 +0000857 }
858 else
859 {
860 result.AppendErrorWithFormat ("failed to create a value object for: (%s) %s\n",
861 view_as_type_cstr,
862 name_strm.GetString().c_str());
863 result.SetStatus(eReturnStatusFailed);
864 return false;
865 }
866 }
867 return true;
868 }
869
870 result.SetStatus(eReturnStatusSuccessFinishResult);
871 DataExtractor data (data_sp,
Greg Claytonc14ee322011-09-22 04:58:26 +0000872 target->GetArchitecture().GetByteOrder(),
Matthew Gardinerf03e6d842014-09-29 08:02:24 +0000873 target->GetArchitecture().GetAddressByteSize(),
874 target->GetArchitecture().GetDataByteSize());
Enrico Granata31898912013-05-21 17:39:04 +0000875
876 Format format = m_format_options.GetFormat();
877 if ( ( (format == eFormatChar) || (format == eFormatCharPrintable) )
Enrico Granata0947a6e2013-10-29 23:04:29 +0000878 && (item_byte_size != 1))
Enrico Granata31898912013-05-21 17:39:04 +0000879 {
Enrico Granata0947a6e2013-10-29 23:04:29 +0000880 // if a count was not passed, or it is 1
881 if (m_format_options.GetCountValue().OptionWasSet() == false || item_count == 1)
882 {
883 // this turns requests such as
884 // memory read -fc -s10 -c1 *charPtrPtr
885 // which make no sense (what is a char of size 10?)
886 // into a request for fetching 10 chars of size 1 from the same memory location
887 format = eFormatCharArray;
888 item_count = item_byte_size;
889 item_byte_size = 1;
890 }
891 else
892 {
893 // here we passed a count, and it was not 1
894 // so we have a byte_size and a count
895 // we could well multiply those, but instead let's just fail
Greg Clayton6fea17e2014-03-03 19:15:20 +0000896 result.AppendErrorWithFormat("reading memory as characters of size %" PRIu64 " is not supported", (uint64_t)item_byte_size);
Enrico Granata0947a6e2013-10-29 23:04:29 +0000897 result.SetStatus(eReturnStatusFailed);
898 return false;
899 }
Enrico Granata31898912013-05-21 17:39:04 +0000900 }
Greg Clayton84c39662011-04-27 22:04:39 +0000901
Greg Clayton6d7e77b2010-10-10 20:52:20 +0000902 assert (output_stream);
Greg Claytonc7bece562013-01-25 18:06:21 +0000903 size_t bytes_dumped = data.Dump (output_stream,
904 0,
Enrico Granata31898912013-05-21 17:39:04 +0000905 format,
Greg Claytonc7bece562013-01-25 18:06:21 +0000906 item_byte_size,
907 item_count,
Matthew Gardinerf03e6d842014-09-29 08:02:24 +0000908 num_per_line / target->GetArchitecture().GetDataByteSize(),
Greg Claytonc7bece562013-01-25 18:06:21 +0000909 addr,
910 0,
911 0,
912 exe_scope);
Greg Clayton1848afb2011-10-28 23:44:55 +0000913 m_next_addr = addr + bytes_dumped;
Greg Clayton6d7e77b2010-10-10 20:52:20 +0000914 output_stream->EOL();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000915 return true;
916 }
917
Greg Clayton84c39662011-04-27 22:04:39 +0000918 OptionGroupOptions m_option_group;
919 OptionGroupFormat m_format_options;
920 OptionGroupReadMemory m_memory_options;
921 OptionGroupOutputFile m_outfile_options;
Greg Clayton68ebae62011-04-28 20:55:26 +0000922 OptionGroupValueObjectDisplay m_varobj_options;
Greg Clayton82f4cf42011-10-26 04:32:38 +0000923 lldb::addr_t m_next_addr;
924 lldb::addr_t m_prev_byte_size;
925 OptionGroupFormat m_prev_format_options;
926 OptionGroupReadMemory m_prev_memory_options;
927 OptionGroupOutputFile m_prev_outfile_options;
928 OptionGroupValueObjectDisplay m_prev_varobj_options;
Greg Clayton2e1f7452012-12-15 02:08:17 +0000929 ClangASTType m_prev_clang_ast_type;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000930};
931
Enrico Granata53468432013-11-13 02:18:44 +0000932OptionDefinition
933g_memory_find_option_table[] =
934{
Zachary Turnerd37221d2014-07-09 16:31:49 +0000935 { LLDB_OPT_SET_1, false, "expression", 'e', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeExpression, "Evaluate an expression to obtain a byte pattern."},
936 { LLDB_OPT_SET_2, false, "string", 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName, "Use text to find a byte pattern."},
937 { LLDB_OPT_SET_1|LLDB_OPT_SET_2, false, "count", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeCount, "How many times to perform the search."},
938 { LLDB_OPT_SET_1|LLDB_OPT_SET_2, false, "dump-offset", 'o', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeOffset, "When dumping memory for a match, an offset from the match location to start dumping from."},
Enrico Granata53468432013-11-13 02:18:44 +0000939};
940
Enrico Granata53468432013-11-13 02:18:44 +0000941//----------------------------------------------------------------------
942// Find the specified data in memory
943//----------------------------------------------------------------------
944class CommandObjectMemoryFind : public CommandObjectParsed
945{
946public:
947
948 class OptionGroupFindMemory : public OptionGroup
949 {
950 public:
951 OptionGroupFindMemory () :
952 OptionGroup(),
953 m_count(1),
Enrico Granata8d81a842013-11-13 20:08:30 +0000954 m_offset(0)
Enrico Granata53468432013-11-13 02:18:44 +0000955 {
956 }
957
958 virtual
959 ~OptionGroupFindMemory ()
960 {
961 }
962
963 virtual uint32_t
964 GetNumDefinitions ()
965 {
966 return sizeof (g_memory_find_option_table) / sizeof (OptionDefinition);
967 }
968
969 virtual const OptionDefinition*
970 GetDefinitions ()
971 {
972 return g_memory_find_option_table;
973 }
974
975 virtual Error
976 SetOptionValue (CommandInterpreter &interpreter,
977 uint32_t option_idx,
978 const char *option_arg)
979 {
980 Error error;
981 const int short_option = g_memory_find_option_table[option_idx].short_option;
982
983 switch (short_option)
984 {
985 case 'e':
Pavel Labathc95f7e22015-02-20 11:14:59 +0000986 m_expr.SetValueFromString(option_arg);
Enrico Granata53468432013-11-13 02:18:44 +0000987 break;
988
989 case 's':
Pavel Labathc95f7e22015-02-20 11:14:59 +0000990 m_string.SetValueFromString(option_arg);
Enrico Granata53468432013-11-13 02:18:44 +0000991 break;
992
993 case 'c':
Pavel Labathc95f7e22015-02-20 11:14:59 +0000994 if (m_count.SetValueFromString(option_arg).Fail())
Enrico Granata53468432013-11-13 02:18:44 +0000995 error.SetErrorString("unrecognized value for count");
996 break;
997
Enrico Granata8d81a842013-11-13 20:08:30 +0000998 case 'o':
Pavel Labathc95f7e22015-02-20 11:14:59 +0000999 if (m_offset.SetValueFromString(option_arg).Fail())
Enrico Granata8d81a842013-11-13 20:08:30 +00001000 error.SetErrorString("unrecognized value for dump-offset");
1001 break;
1002
Enrico Granata53468432013-11-13 02:18:44 +00001003 default:
1004 error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option);
1005 break;
1006 }
1007 return error;
1008 }
1009
1010 virtual void
1011 OptionParsingStarting (CommandInterpreter &interpreter)
1012 {
1013 m_expr.Clear();
1014 m_string.Clear();
1015 m_count.Clear();
Enrico Granata53468432013-11-13 02:18:44 +00001016 }
1017
1018 OptionValueString m_expr;
1019 OptionValueString m_string;
1020 OptionValueUInt64 m_count;
Enrico Granata8d81a842013-11-13 20:08:30 +00001021 OptionValueUInt64 m_offset;
Enrico Granata53468432013-11-13 02:18:44 +00001022 };
1023
1024 CommandObjectMemoryFind (CommandInterpreter &interpreter) :
1025 CommandObjectParsed (interpreter,
1026 "memory find",
1027 "Find a value in the memory of the process being debugged.",
1028 NULL,
1029 eFlagRequiresProcess | eFlagProcessMustBeLaunched),
1030 m_option_group (interpreter),
1031 m_memory_options ()
1032 {
1033 CommandArgumentEntry arg1;
1034 CommandArgumentEntry arg2;
1035 CommandArgumentData addr_arg;
1036 CommandArgumentData value_arg;
1037
1038 // Define the first (and only) variant of this arg.
1039 addr_arg.arg_type = eArgTypeAddress;
1040 addr_arg.arg_repetition = eArgRepeatPlain;
1041
1042 // There is only one variant this argument could be; put it into the argument entry.
1043 arg1.push_back (addr_arg);
1044
1045 // Define the first (and only) variant of this arg.
1046 value_arg.arg_type = eArgTypeValue;
1047 value_arg.arg_repetition = eArgRepeatPlus;
1048
1049 // There is only one variant this argument could be; put it into the argument entry.
1050 arg2.push_back (value_arg);
1051
1052 // Push the data for the first argument into the m_arguments vector.
1053 m_arguments.push_back (arg1);
1054 m_arguments.push_back (arg2);
1055
1056 m_option_group.Append (&m_memory_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_2);
1057 m_option_group.Finalize();
1058 }
1059
1060 virtual
1061 ~CommandObjectMemoryFind ()
1062 {
1063 }
1064
1065 Options *
1066 GetOptions ()
1067 {
1068 return &m_option_group;
1069 }
1070
1071protected:
1072 virtual bool
1073 DoExecute (Args& command, CommandReturnObject &result)
1074 {
1075 // No need to check "process" for validity as eFlagRequiresProcess ensures it is valid
1076 Process *process = m_exe_ctx.GetProcessPtr();
1077
1078 const size_t argc = command.GetArgumentCount();
1079
1080 if (argc != 2)
1081 {
Enrico Granata6e49c482013-11-13 02:22:24 +00001082 result.AppendError("two addresses needed for memory find");
Enrico Granata53468432013-11-13 02:18:44 +00001083 return false;
1084 }
1085
1086 Error error;
1087 lldb::addr_t low_addr = Args::StringToAddress(&m_exe_ctx, command.GetArgumentAtIndex(0),LLDB_INVALID_ADDRESS,&error);
1088 if (low_addr == LLDB_INVALID_ADDRESS || error.Fail())
1089 {
1090 result.AppendError("invalid low address");
1091 return false;
1092 }
1093 lldb::addr_t high_addr = Args::StringToAddress(&m_exe_ctx, command.GetArgumentAtIndex(1),LLDB_INVALID_ADDRESS,&error);
1094 if (high_addr == LLDB_INVALID_ADDRESS || error.Fail())
1095 {
Ed Maste47a8a5e2014-09-06 11:29:08 +00001096 result.AppendError("invalid high address");
Enrico Granata53468432013-11-13 02:18:44 +00001097 return false;
1098 }
1099
1100 if (high_addr <= low_addr)
1101 {
1102 result.AppendError("starting address must be smaller than ending address");
1103 return false;
1104 }
1105
1106 lldb::addr_t found_location = LLDB_INVALID_ADDRESS;
1107
1108 DataBufferHeap buffer;
1109
1110 if (m_memory_options.m_string.OptionWasSet())
1111 buffer.CopyData(m_memory_options.m_string.GetStringValue(), strlen(m_memory_options.m_string.GetStringValue()));
1112 else if (m_memory_options.m_expr.OptionWasSet())
1113 {
1114 StackFrame* frame = m_exe_ctx.GetFramePtr();
1115 ValueObjectSP result_sp;
1116 if (process->GetTarget().EvaluateExpression(m_memory_options.m_expr.GetStringValue(), frame, result_sp) && result_sp.get())
1117 {
1118 uint64_t value = result_sp->GetValueAsUnsigned(0);
Enrico Granata1cd5e922015-01-28 00:07:51 +00001119 switch (result_sp->GetClangType().GetByteSize(nullptr))
Enrico Granata53468432013-11-13 02:18:44 +00001120 {
1121 case 1: {
1122 uint8_t byte = (uint8_t)value;
1123 buffer.CopyData(&byte,1);
1124 }
1125 break;
1126 case 2: {
1127 uint16_t word = (uint16_t)value;
1128 buffer.CopyData(&word,2);
1129 }
1130 break;
1131 case 4: {
1132 uint32_t lword = (uint32_t)value;
1133 buffer.CopyData(&lword,4);
1134 }
1135 break;
1136 case 8: {
1137 buffer.CopyData(&value, 8);
1138 }
1139 break;
1140 case 3:
1141 case 5:
1142 case 6:
1143 case 7:
1144 result.AppendError("unknown type. pass a string instead");
1145 return false;
1146 default:
1147 result.AppendError("do not know how to deal with larger than 8 byte result types. pass a string instead");
1148 return false;
1149 }
1150 }
1151 else
1152 {
1153 result.AppendError("expression evaluation failed. pass a string instead?");
1154 return false;
1155 }
1156 }
1157 else
1158 {
1159 result.AppendError("please pass either a block of text, or an expression to evaluate.");
1160 return false;
1161 }
1162
1163 size_t count = m_memory_options.m_count.GetCurrentValue();
1164 found_location = low_addr;
1165 bool ever_found = false;
1166 while (count)
1167 {
1168 found_location = Search(found_location, high_addr, buffer.GetBytes(), buffer.GetByteSize());
1169 if (found_location == LLDB_INVALID_ADDRESS)
1170 {
1171 if (!ever_found)
1172 {
1173 result.AppendMessage("Your data was not found within the range.\n");
1174 result.SetStatus(lldb::eReturnStatusSuccessFinishNoResult);
1175 }
1176 else
1177 result.AppendMessage("No more matches found within the range.\n");
1178 break;
1179 }
1180 result.AppendMessageWithFormat("Your data was found at location: 0x%" PRIx64 "\n", found_location);
Enrico Granata8d81a842013-11-13 20:08:30 +00001181
1182 DataBufferHeap dumpbuffer(32,0);
1183 process->ReadMemory(found_location+m_memory_options.m_offset.GetCurrentValue(), dumpbuffer.GetBytes(), dumpbuffer.GetByteSize(), error);
1184 if (!error.Fail())
Enrico Granata53468432013-11-13 02:18:44 +00001185 {
Enrico Granata8d81a842013-11-13 20:08:30 +00001186 DataExtractor data(dumpbuffer.GetBytes(), dumpbuffer.GetByteSize(), process->GetByteOrder(), process->GetAddressByteSize());
1187 data.Dump(&result.GetOutputStream(), 0, lldb::eFormatBytesWithASCII, 1, dumpbuffer.GetByteSize(), 16, found_location+m_memory_options.m_offset.GetCurrentValue(), 0, 0);
1188 result.GetOutputStream().EOL();
Enrico Granata53468432013-11-13 02:18:44 +00001189 }
Enrico Granata8d81a842013-11-13 20:08:30 +00001190
Enrico Granata53468432013-11-13 02:18:44 +00001191 --count;
1192 found_location++;
1193 ever_found = true;
1194 }
1195
1196 result.SetStatus(lldb::eReturnStatusSuccessFinishResult);
1197 return true;
1198 }
1199
1200 lldb::addr_t
1201 Search (lldb::addr_t low,
1202 lldb::addr_t high,
1203 uint8_t* buffer,
1204 size_t buffer_size)
1205 {
1206 Process *process = m_exe_ctx.GetProcessPtr();
1207 DataBufferHeap heap(buffer_size, 0);
1208 lldb::addr_t fictional_ptr = low;
1209 for (auto ptr = low;
1210 low < high;
1211 fictional_ptr++)
1212 {
1213 Error error;
1214 if (ptr == low || buffer_size == 1)
1215 process->ReadMemory(ptr, heap.GetBytes(), buffer_size, error);
1216 else
1217 {
1218 memmove(heap.GetBytes(), heap.GetBytes()+1, buffer_size-1);
1219 process->ReadMemory(ptr, heap.GetBytes()+buffer_size-1, 1, error);
1220 }
1221 if (error.Fail())
1222 return LLDB_INVALID_ADDRESS;
1223 if (memcmp(heap.GetBytes(), buffer, buffer_size) == 0)
1224 return fictional_ptr;
1225 if (ptr == low)
1226 ptr += buffer_size;
1227 else
1228 ptr += 1;
1229 }
1230 return LLDB_INVALID_ADDRESS;
1231 }
1232
1233 OptionGroupOptions m_option_group;
1234 OptionGroupFindMemory m_memory_options;
1235};
1236
Greg Clayton1deb7962011-10-25 06:44:01 +00001237
1238OptionDefinition
1239g_memory_write_option_table[] =
1240{
Zachary Turnerd37221d2014-07-09 16:31:49 +00001241{ LLDB_OPT_SET_1, true, "infile", 'i', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFilename, "Write memory using the contents of a file."},
Bruce Mitchener350b78e2014-07-10 14:45:57 +00001242{ LLDB_OPT_SET_1, false, "offset", 'o', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeOffset, "Start writing bytes from an offset within the input file."},
Greg Clayton1deb7962011-10-25 06:44:01 +00001243};
1244
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001245//----------------------------------------------------------------------
1246// Write memory to the inferior process
1247//----------------------------------------------------------------------
Jim Ingham5a988412012-06-08 21:56:10 +00001248class CommandObjectMemoryWrite : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001249{
1250public:
1251
Greg Clayton1deb7962011-10-25 06:44:01 +00001252 class OptionGroupWriteMemory : public OptionGroup
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001253 {
1254 public:
Greg Clayton1deb7962011-10-25 06:44:01 +00001255 OptionGroupWriteMemory () :
1256 OptionGroup()
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001257 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001258 }
1259
1260 virtual
Greg Clayton1deb7962011-10-25 06:44:01 +00001261 ~OptionGroupWriteMemory ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001262 {
1263 }
1264
Greg Clayton1deb7962011-10-25 06:44:01 +00001265 virtual uint32_t
1266 GetNumDefinitions ()
1267 {
1268 return sizeof (g_memory_write_option_table) / sizeof (OptionDefinition);
1269 }
Enrico Granata53468432013-11-13 02:18:44 +00001270
Greg Clayton1deb7962011-10-25 06:44:01 +00001271 virtual const OptionDefinition*
1272 GetDefinitions ()
1273 {
1274 return g_memory_write_option_table;
1275 }
Enrico Granata53468432013-11-13 02:18:44 +00001276
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001277 virtual Error
Greg Clayton1deb7962011-10-25 06:44:01 +00001278 SetOptionValue (CommandInterpreter &interpreter,
1279 uint32_t option_idx,
1280 const char *option_arg)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001281 {
1282 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +00001283 const int short_option = g_memory_write_option_table[option_idx].short_option;
Enrico Granata53468432013-11-13 02:18:44 +00001284
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001285 switch (short_option)
1286 {
Greg Clayton1deb7962011-10-25 06:44:01 +00001287 case 'i':
1288 m_infile.SetFile (option_arg, true);
1289 if (!m_infile.Exists())
Greg Clayton6d7e77b2010-10-10 20:52:20 +00001290 {
Greg Clayton1deb7962011-10-25 06:44:01 +00001291 m_infile.Clear();
Greg Clayton86edbf42011-10-26 00:56:27 +00001292 error.SetErrorStringWithFormat("input file does not exist: '%s'", option_arg);
Greg Clayton6d7e77b2010-10-10 20:52:20 +00001293 }
Greg Clayton1deb7962011-10-25 06:44:01 +00001294 break;
Enrico Granata53468432013-11-13 02:18:44 +00001295
Greg Clayton1deb7962011-10-25 06:44:01 +00001296 case 'o':
1297 {
1298 bool success;
Vince Harron5275aaa2015-01-15 20:08:35 +00001299 m_infile_offset = StringConvert::ToUInt64(option_arg, 0, 0, &success);
Greg Clayton1deb7962011-10-25 06:44:01 +00001300 if (!success)
1301 {
Greg Clayton86edbf42011-10-26 00:56:27 +00001302 error.SetErrorStringWithFormat("invalid offset string '%s'", option_arg);
Greg Clayton1deb7962011-10-25 06:44:01 +00001303 }
1304 }
1305 break;
1306
1307 default:
Greg Clayton86edbf42011-10-26 00:56:27 +00001308 error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option);
Greg Clayton1deb7962011-10-25 06:44:01 +00001309 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001310 }
1311 return error;
1312 }
Greg Clayton1deb7962011-10-25 06:44:01 +00001313
1314 virtual void
1315 OptionParsingStarting (CommandInterpreter &interpreter)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001316 {
Greg Clayton6d7e77b2010-10-10 20:52:20 +00001317 m_infile.Clear();
1318 m_infile_offset = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001319 }
1320
Greg Clayton6d7e77b2010-10-10 20:52:20 +00001321 FileSpec m_infile;
1322 off_t m_infile_offset;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001323 };
1324
Greg Claytona7015092010-09-18 01:14:36 +00001325 CommandObjectMemoryWrite (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +00001326 CommandObjectParsed (interpreter,
1327 "memory write",
1328 "Write to the memory of the process being debugged.",
1329 NULL,
Greg Claytonf9fc6092013-01-09 19:44:40 +00001330 eFlagRequiresProcess | eFlagProcessMustBeLaunched),
Greg Clayton1deb7962011-10-25 06:44:01 +00001331 m_option_group (interpreter),
1332 m_format_options (eFormatBytes, 1, UINT64_MAX),
1333 m_memory_options ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001334 {
Caroline Tice405fe672010-10-04 22:28:36 +00001335 CommandArgumentEntry arg1;
1336 CommandArgumentEntry arg2;
1337 CommandArgumentData addr_arg;
1338 CommandArgumentData value_arg;
1339
1340 // Define the first (and only) variant of this arg.
1341 addr_arg.arg_type = eArgTypeAddress;
1342 addr_arg.arg_repetition = eArgRepeatPlain;
1343
1344 // There is only one variant this argument could be; put it into the argument entry.
1345 arg1.push_back (addr_arg);
1346
1347 // Define the first (and only) variant of this arg.
1348 value_arg.arg_type = eArgTypeValue;
1349 value_arg.arg_repetition = eArgRepeatPlus;
1350
1351 // There is only one variant this argument could be; put it into the argument entry.
1352 arg2.push_back (value_arg);
1353
1354 // Push the data for the first argument into the m_arguments vector.
1355 m_arguments.push_back (arg1);
1356 m_arguments.push_back (arg2);
Greg Clayton1deb7962011-10-25 06:44:01 +00001357
1358 m_option_group.Append (&m_format_options, OptionGroupFormat::OPTION_GROUP_FORMAT, LLDB_OPT_SET_1);
1359 m_option_group.Append (&m_format_options, OptionGroupFormat::OPTION_GROUP_SIZE , LLDB_OPT_SET_1|LLDB_OPT_SET_2);
1360 m_option_group.Append (&m_memory_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_2);
1361 m_option_group.Finalize();
1362
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001363 }
1364
1365 virtual
1366 ~CommandObjectMemoryWrite ()
1367 {
1368 }
1369
1370 Options *
1371 GetOptions ()
1372 {
Greg Clayton1deb7962011-10-25 06:44:01 +00001373 return &m_option_group;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001374 }
1375
1376 bool
1377 UIntValueIsValidForSize (uint64_t uval64, size_t total_byte_size)
1378 {
1379 if (total_byte_size > 8)
1380 return false;
1381
1382 if (total_byte_size == 8)
1383 return true;
1384
1385 const uint64_t max = ((uint64_t)1 << (uint64_t)(total_byte_size * 8)) - 1;
1386 return uval64 <= max;
1387 }
1388
1389 bool
1390 SIntValueIsValidForSize (int64_t sval64, size_t total_byte_size)
1391 {
1392 if (total_byte_size > 8)
1393 return false;
1394
1395 if (total_byte_size == 8)
1396 return true;
1397
1398 const int64_t max = ((int64_t)1 << (uint64_t)(total_byte_size * 8 - 1)) - 1;
1399 const int64_t min = ~(max);
1400 return min <= sval64 && sval64 <= max;
1401 }
1402
Jim Ingham5a988412012-06-08 21:56:10 +00001403protected:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001404 virtual bool
Jim Ingham5a988412012-06-08 21:56:10 +00001405 DoExecute (Args& command, CommandReturnObject &result)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001406 {
Greg Claytonf9fc6092013-01-09 19:44:40 +00001407 // No need to check "process" for validity as eFlagRequiresProcess ensures it is valid
1408 Process *process = m_exe_ctx.GetProcessPtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001409
1410 const size_t argc = command.GetArgumentCount();
1411
Greg Clayton1deb7962011-10-25 06:44:01 +00001412 if (m_memory_options.m_infile)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001413 {
Greg Clayton6d7e77b2010-10-10 20:52:20 +00001414 if (argc < 1)
1415 {
1416 result.AppendErrorWithFormat ("%s takes a destination address when writing file contents.\n", m_cmd_name.c_str());
1417 result.SetStatus(eReturnStatusFailed);
1418 return false;
1419 }
1420 }
1421 else if (argc < 2)
1422 {
1423 result.AppendErrorWithFormat ("%s takes a destination address and at least one value.\n", m_cmd_name.c_str());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001424 result.SetStatus(eReturnStatusFailed);
1425 return false;
1426 }
1427
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001428 StreamString buffer (Stream::eBinary,
Greg Clayton514487e2011-02-15 21:59:32 +00001429 process->GetTarget().GetArchitecture().GetAddressByteSize(),
1430 process->GetTarget().GetArchitecture().GetByteOrder());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001431
Greg Clayton1deb7962011-10-25 06:44:01 +00001432 OptionValueUInt64 &byte_size_value = m_format_options.GetByteSizeValue();
1433 size_t item_byte_size = byte_size_value.GetCurrentValue();
Greg Claytonc982c762010-07-09 20:39:50 +00001434
Greg Claytonb9d5df52012-12-06 22:49:16 +00001435 Error error;
Greg Claytonf9fc6092013-01-09 19:44:40 +00001436 lldb::addr_t addr = Args::StringToAddress (&m_exe_ctx,
Greg Claytonb9d5df52012-12-06 22:49:16 +00001437 command.GetArgumentAtIndex(0),
1438 LLDB_INVALID_ADDRESS,
1439 &error);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001440
1441 if (addr == LLDB_INVALID_ADDRESS)
1442 {
Greg Claytonb9d5df52012-12-06 22:49:16 +00001443 result.AppendError("invalid address expression\n");
1444 result.AppendError(error.AsCString());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001445 result.SetStatus(eReturnStatusFailed);
1446 return false;
1447 }
Greg Clayton6d7e77b2010-10-10 20:52:20 +00001448
Greg Clayton1deb7962011-10-25 06:44:01 +00001449 if (m_memory_options.m_infile)
Greg Clayton6d7e77b2010-10-10 20:52:20 +00001450 {
1451 size_t length = SIZE_MAX;
Jason Molenda250b1b892015-02-03 23:39:47 +00001452 if (item_byte_size > 1)
Greg Clayton1deb7962011-10-25 06:44:01 +00001453 length = item_byte_size;
1454 lldb::DataBufferSP data_sp (m_memory_options.m_infile.ReadFileContents (m_memory_options.m_infile_offset, length));
Greg Clayton6d7e77b2010-10-10 20:52:20 +00001455 if (data_sp)
1456 {
1457 length = data_sp->GetByteSize();
1458 if (length > 0)
1459 {
1460 Error error;
1461 size_t bytes_written = process->WriteMemory (addr, data_sp->GetBytes(), length, error);
1462
1463 if (bytes_written == length)
1464 {
1465 // All bytes written
Daniel Malead01b2952012-11-29 21:49:15 +00001466 result.GetOutputStream().Printf("%" PRIu64 " bytes were written to 0x%" PRIx64 "\n", (uint64_t)bytes_written, addr);
Greg Clayton6d7e77b2010-10-10 20:52:20 +00001467 result.SetStatus(eReturnStatusSuccessFinishResult);
1468 }
1469 else if (bytes_written > 0)
1470 {
1471 // Some byte written
Daniel Malead01b2952012-11-29 21:49:15 +00001472 result.GetOutputStream().Printf("%" PRIu64 " bytes of %" PRIu64 " requested were written to 0x%" PRIx64 "\n", (uint64_t)bytes_written, (uint64_t)length, addr);
Greg Clayton6d7e77b2010-10-10 20:52:20 +00001473 result.SetStatus(eReturnStatusSuccessFinishResult);
1474 }
1475 else
1476 {
Daniel Malead01b2952012-11-29 21:49:15 +00001477 result.AppendErrorWithFormat ("Memory write to 0x%" PRIx64 " failed: %s.\n", addr, error.AsCString());
Greg Clayton6d7e77b2010-10-10 20:52:20 +00001478 result.SetStatus(eReturnStatusFailed);
1479 }
1480 }
1481 }
1482 else
1483 {
1484 result.AppendErrorWithFormat ("Unable to read contents of file.\n");
1485 result.SetStatus(eReturnStatusFailed);
1486 }
1487 return result.Succeeded();
1488 }
Greg Clayton1deb7962011-10-25 06:44:01 +00001489 else if (item_byte_size == 0)
Greg Clayton6d7e77b2010-10-10 20:52:20 +00001490 {
Greg Clayton1deb7962011-10-25 06:44:01 +00001491 if (m_format_options.GetFormat() == eFormatPointer)
Greg Clayton6d7e77b2010-10-10 20:52:20 +00001492 item_byte_size = buffer.GetAddressByteSize();
1493 else
1494 item_byte_size = 1;
1495 }
1496
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001497 command.Shift(); // shift off the address argument
1498 uint64_t uval64;
1499 int64_t sval64;
1500 bool success = false;
Greg Claytonc7bece562013-01-25 18:06:21 +00001501 const size_t num_value_args = command.GetArgumentCount();
1502 for (size_t i=0; i<num_value_args; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001503 {
1504 const char *value_str = command.GetArgumentAtIndex(i);
1505
Greg Clayton1deb7962011-10-25 06:44:01 +00001506 switch (m_format_options.GetFormat())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001507 {
Greg Claytonbb7f31f2011-06-23 21:22:24 +00001508 case kNumFormats:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001509 case eFormatFloat: // TODO: add support for floats soon
1510 case eFormatCharPrintable:
1511 case eFormatBytesWithASCII:
1512 case eFormatComplex:
1513 case eFormatEnum:
1514 case eFormatUnicode16:
1515 case eFormatUnicode32:
1516 case eFormatVectorOfChar:
1517 case eFormatVectorOfSInt8:
1518 case eFormatVectorOfUInt8:
1519 case eFormatVectorOfSInt16:
1520 case eFormatVectorOfUInt16:
1521 case eFormatVectorOfSInt32:
1522 case eFormatVectorOfUInt32:
1523 case eFormatVectorOfSInt64:
1524 case eFormatVectorOfUInt64:
1525 case eFormatVectorOfFloat32:
1526 case eFormatVectorOfFloat64:
1527 case eFormatVectorOfUInt128:
Greg Clayton7a5388b2011-03-20 04:57:14 +00001528 case eFormatOSType:
1529 case eFormatComplexInteger:
Greg Clayton5009f9d2011-10-27 17:55:14 +00001530 case eFormatAddressInfo:
1531 case eFormatHexFloat:
1532 case eFormatInstruction:
Sean Callananbf154da2012-08-08 17:35:10 +00001533 case eFormatVoid:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001534 result.AppendError("unsupported format for writing memory");
1535 result.SetStatus(eReturnStatusFailed);
1536 return false;
1537
1538 case eFormatDefault:
1539 case eFormatBytes:
1540 case eFormatHex:
Enrico Granata7ec18e32012-08-09 19:33:34 +00001541 case eFormatHexUppercase:
Greg Claytonc982c762010-07-09 20:39:50 +00001542 case eFormatPointer:
1543
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001544 // Decode hex bytes
Vince Harron5275aaa2015-01-15 20:08:35 +00001545 uval64 = StringConvert::ToUInt64(value_str, UINT64_MAX, 16, &success);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001546 if (!success)
1547 {
1548 result.AppendErrorWithFormat ("'%s' is not a valid hex string value.\n", value_str);
1549 result.SetStatus(eReturnStatusFailed);
1550 return false;
1551 }
1552 else if (!UIntValueIsValidForSize (uval64, item_byte_size))
1553 {
Greg Clayton6fea17e2014-03-03 19:15:20 +00001554 result.AppendErrorWithFormat("Value 0x%" PRIx64 " is too large to fit in a %" PRIu64 " byte unsigned integer value.\n", uval64, (uint64_t)item_byte_size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001555 result.SetStatus(eReturnStatusFailed);
1556 return false;
1557 }
1558 buffer.PutMaxHex64 (uval64, item_byte_size);
1559 break;
1560
1561 case eFormatBoolean:
1562 uval64 = Args::StringToBoolean(value_str, false, &success);
1563 if (!success)
1564 {
1565 result.AppendErrorWithFormat ("'%s' is not a valid boolean string value.\n", value_str);
1566 result.SetStatus(eReturnStatusFailed);
1567 return false;
1568 }
1569 buffer.PutMaxHex64 (uval64, item_byte_size);
1570 break;
1571
1572 case eFormatBinary:
Vince Harron5275aaa2015-01-15 20:08:35 +00001573 uval64 = StringConvert::ToUInt64(value_str, UINT64_MAX, 2, &success);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001574 if (!success)
1575 {
1576 result.AppendErrorWithFormat ("'%s' is not a valid binary string value.\n", value_str);
1577 result.SetStatus(eReturnStatusFailed);
1578 return false;
1579 }
1580 else if (!UIntValueIsValidForSize (uval64, item_byte_size))
1581 {
Greg Clayton6fea17e2014-03-03 19:15:20 +00001582 result.AppendErrorWithFormat("Value 0x%" PRIx64 " is too large to fit in a %" PRIu64 " byte unsigned integer value.\n", uval64, (uint64_t)item_byte_size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001583 result.SetStatus(eReturnStatusFailed);
1584 return false;
1585 }
1586 buffer.PutMaxHex64 (uval64, item_byte_size);
1587 break;
1588
Greg Clayton4e4294b2011-06-17 23:50:44 +00001589 case eFormatCharArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001590 case eFormatChar:
1591 case eFormatCString:
1592 if (value_str[0])
1593 {
1594 size_t len = strlen (value_str);
1595 // Include the NULL for C strings...
Greg Clayton1deb7962011-10-25 06:44:01 +00001596 if (m_format_options.GetFormat() == eFormatCString)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001597 ++len;
1598 Error error;
1599 if (process->WriteMemory (addr, value_str, len, error) == len)
1600 {
1601 addr += len;
1602 }
1603 else
1604 {
Daniel Malead01b2952012-11-29 21:49:15 +00001605 result.AppendErrorWithFormat ("Memory write to 0x%" PRIx64 " failed: %s.\n", addr, error.AsCString());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001606 result.SetStatus(eReturnStatusFailed);
1607 return false;
1608 }
1609 }
1610 break;
1611
1612 case eFormatDecimal:
Vince Harron5275aaa2015-01-15 20:08:35 +00001613 sval64 = StringConvert::ToSInt64(value_str, INT64_MAX, 0, &success);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001614 if (!success)
1615 {
1616 result.AppendErrorWithFormat ("'%s' is not a valid signed decimal value.\n", value_str);
1617 result.SetStatus(eReturnStatusFailed);
1618 return false;
1619 }
1620 else if (!SIntValueIsValidForSize (sval64, item_byte_size))
1621 {
Greg Clayton6fea17e2014-03-03 19:15:20 +00001622 result.AppendErrorWithFormat ("Value %" PRIi64 " is too large or small to fit in a %" PRIu64 " byte signed integer value.\n", sval64, (uint64_t)item_byte_size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001623 result.SetStatus(eReturnStatusFailed);
1624 return false;
1625 }
1626 buffer.PutMaxHex64 (sval64, item_byte_size);
1627 break;
1628
1629 case eFormatUnsigned:
Vince Harron5275aaa2015-01-15 20:08:35 +00001630 uval64 = StringConvert::ToUInt64(value_str, UINT64_MAX, 0, &success);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001631 if (!success)
1632 {
1633 result.AppendErrorWithFormat ("'%s' is not a valid unsigned decimal string value.\n", value_str);
1634 result.SetStatus(eReturnStatusFailed);
1635 return false;
1636 }
1637 else if (!UIntValueIsValidForSize (uval64, item_byte_size))
1638 {
Greg Clayton6fea17e2014-03-03 19:15:20 +00001639 result.AppendErrorWithFormat ("Value %" PRIu64 " is too large to fit in a %" PRIu64 " byte unsigned integer value.\n", uval64, (uint64_t)item_byte_size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001640 result.SetStatus(eReturnStatusFailed);
1641 return false;
1642 }
1643 buffer.PutMaxHex64 (uval64, item_byte_size);
1644 break;
1645
1646 case eFormatOctal:
Vince Harron5275aaa2015-01-15 20:08:35 +00001647 uval64 = StringConvert::ToUInt64(value_str, UINT64_MAX, 8, &success);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001648 if (!success)
1649 {
1650 result.AppendErrorWithFormat ("'%s' is not a valid octal string value.\n", value_str);
1651 result.SetStatus(eReturnStatusFailed);
1652 return false;
1653 }
1654 else if (!UIntValueIsValidForSize (uval64, item_byte_size))
1655 {
Greg Clayton6fea17e2014-03-03 19:15:20 +00001656 result.AppendErrorWithFormat ("Value %" PRIo64 " is too large to fit in a %" PRIu64 " byte unsigned integer value.\n", uval64, (uint64_t)item_byte_size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001657 result.SetStatus(eReturnStatusFailed);
1658 return false;
1659 }
1660 buffer.PutMaxHex64 (uval64, item_byte_size);
1661 break;
1662 }
1663 }
1664
1665 if (!buffer.GetString().empty())
1666 {
1667 Error error;
Greg Clayton471b31c2010-07-20 22:52:08 +00001668 if (process->WriteMemory (addr, buffer.GetString().c_str(), buffer.GetString().size(), error) == buffer.GetString().size())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001669 return true;
1670 else
1671 {
Daniel Malead01b2952012-11-29 21:49:15 +00001672 result.AppendErrorWithFormat ("Memory write to 0x%" PRIx64 " failed: %s.\n", addr, error.AsCString());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001673 result.SetStatus(eReturnStatusFailed);
1674 return false;
1675 }
1676 }
1677 return true;
1678 }
1679
Greg Clayton1deb7962011-10-25 06:44:01 +00001680 OptionGroupOptions m_option_group;
1681 OptionGroupFormat m_format_options;
1682 OptionGroupWriteMemory m_memory_options;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001683};
1684
Kuba Breckabeed8212014-09-04 01:03:18 +00001685//----------------------------------------------------------------------
1686// Get malloc/free history of a memory address.
1687//----------------------------------------------------------------------
1688class CommandObjectMemoryHistory : public CommandObjectParsed
1689{
1690public:
1691
1692 CommandObjectMemoryHistory (CommandInterpreter &interpreter) :
1693 CommandObjectParsed (interpreter,
1694 "memory history",
1695 "Prints out the recorded stack traces for allocation/deallocation of a memory address.",
1696 NULL,
1697 eFlagRequiresTarget | eFlagRequiresProcess | eFlagProcessMustBePaused | eFlagProcessMustBeLaunched)
1698 {
1699 CommandArgumentEntry arg1;
1700 CommandArgumentData addr_arg;
1701
1702 // Define the first (and only) variant of this arg.
1703 addr_arg.arg_type = eArgTypeAddress;
1704 addr_arg.arg_repetition = eArgRepeatPlain;
1705
1706 // There is only one variant this argument could be; put it into the argument entry.
1707 arg1.push_back (addr_arg);
1708
1709 // Push the data for the first argument into the m_arguments vector.
1710 m_arguments.push_back (arg1);
1711 }
1712
1713 virtual
1714 ~CommandObjectMemoryHistory ()
1715 {
1716 }
1717
1718 virtual const char *GetRepeatCommand (Args &current_command_args, uint32_t index)
1719 {
1720 return m_cmd_name.c_str();
1721 }
1722
1723protected:
1724 virtual bool
1725 DoExecute (Args& command, CommandReturnObject &result)
1726 {
1727 const size_t argc = command.GetArgumentCount();
1728
1729 if (argc == 0 || argc > 1)
1730 {
1731 result.AppendErrorWithFormat ("%s takes an address expression", m_cmd_name.c_str());
1732 result.SetStatus(eReturnStatusFailed);
1733 return false;
1734 }
1735
1736 Error error;
1737 lldb::addr_t addr = Args::StringToAddress (&m_exe_ctx,
1738 command.GetArgumentAtIndex(0),
1739 LLDB_INVALID_ADDRESS,
1740 &error);
1741
1742 if (addr == LLDB_INVALID_ADDRESS)
1743 {
1744 result.AppendError("invalid address expression");
1745 result.AppendError(error.AsCString());
1746 result.SetStatus(eReturnStatusFailed);
1747 return false;
1748 }
1749
1750 Stream *output_stream = &result.GetOutputStream();
1751
1752 const ProcessSP &process_sp = m_exe_ctx.GetProcessSP();
1753 const MemoryHistorySP &memory_history = MemoryHistory::FindPlugin(process_sp);
1754
1755 if (! memory_history.get())
1756 {
1757 result.AppendError("no available memory history provider");
1758 result.SetStatus(eReturnStatusFailed);
1759 return false;
1760 }
1761
1762 HistoryThreads thread_list = memory_history->GetHistoryThreads(addr);
1763
1764 for (auto thread : thread_list) {
1765 thread->GetStatus(*output_stream, 0, UINT32_MAX, 0);
1766 }
1767
1768 result.SetStatus(eReturnStatusSuccessFinishResult);
1769
1770 return true;
1771 }
1772
1773};
1774
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001775
1776//-------------------------------------------------------------------------
1777// CommandObjectMemory
1778//-------------------------------------------------------------------------
1779
Greg Clayton66111032010-06-23 01:19:29 +00001780CommandObjectMemory::CommandObjectMemory (CommandInterpreter &interpreter) :
Greg Claytona7015092010-09-18 01:14:36 +00001781 CommandObjectMultiword (interpreter,
1782 "memory",
Caroline Tice3f4c09c2010-09-07 22:38:08 +00001783 "A set of commands for operating on memory.",
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001784 "memory <subcommand> [<subcommand-options>]")
1785{
Enrico Granata53468432013-11-13 02:18:44 +00001786 LoadSubCommand ("find", CommandObjectSP (new CommandObjectMemoryFind (interpreter)));
Greg Claytona7015092010-09-18 01:14:36 +00001787 LoadSubCommand ("read", CommandObjectSP (new CommandObjectMemoryRead (interpreter)));
1788 LoadSubCommand ("write", CommandObjectSP (new CommandObjectMemoryWrite (interpreter)));
Kuba Breckabeed8212014-09-04 01:03:18 +00001789 LoadSubCommand ("history", CommandObjectSP (new CommandObjectMemoryHistory (interpreter)));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001790}
1791
1792CommandObjectMemory::~CommandObjectMemory ()
1793{
1794}