blob: d589800299a3104368149cace9a7aef1121a3a02 [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
10#include "CommandObjectMemory.h"
11
12// C Includes
Virgile Bellobdae3782013-08-28 12:14:27 +000013#include <inttypes.h>
14
Chris Lattner30fdc8d2010-06-08 16:52:24 +000015// C++ Includes
16// Other libraries and framework includes
Zachary Turnera78bd7f2015-03-03 23:11:11 +000017#include "clang/AST/Decl.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000018// Project includes
Chris Lattner30fdc8d2010-06-08 16:52:24 +000019#include "lldb/Core/DataBufferHeap.h"
20#include "lldb/Core/DataExtractor.h"
Greg Clayton66111032010-06-23 01:19:29 +000021#include "lldb/Core/Debugger.h"
Greg Clayton1f746072012-08-29 21:13:06 +000022#include "lldb/Core/Module.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000023#include "lldb/Core/StreamString.h"
Greg Clayton84c39662011-04-27 22:04:39 +000024#include "lldb/Core/ValueObjectMemory.h"
Enrico Granata4d93b8c2013-09-30 19:11:51 +000025#include "lldb/DataFormatters/ValueObjectPrinter.h"
Zachary Turneraf0f45f2015-03-03 21:05:17 +000026#include "lldb/Expression/ClangPersistentVariables.h"
Vince Harron5275aaa2015-01-15 20:08:35 +000027#include "lldb/Host/StringConvert.h"
Greg Clayton66111032010-06-23 01:19:29 +000028#include "lldb/Interpreter/Args.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000029#include "lldb/Interpreter/CommandReturnObject.h"
Greg Clayton66111032010-06-23 01:19:29 +000030#include "lldb/Interpreter/CommandInterpreter.h"
31#include "lldb/Interpreter/Options.h"
Greg Clayton84c39662011-04-27 22:04:39 +000032#include "lldb/Interpreter/OptionGroupFormat.h"
33#include "lldb/Interpreter/OptionGroupOutputFile.h"
Greg Clayton68ebae62011-04-28 20:55:26 +000034#include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
Greg Clayton67cc0632012-08-22 17:17:09 +000035#include "lldb/Interpreter/OptionValueString.h"
Greg Clayton1f746072012-08-29 21:13:06 +000036#include "lldb/Symbol/TypeList.h"
Kuba Breckabeed8212014-09-04 01:03:18 +000037#include "lldb/Target/MemoryHistory.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000038#include "lldb/Target/Process.h"
Jason Molendab57e4a12013-11-04 09:33:30 +000039#include "lldb/Target/StackFrame.h"
Kuba Breckabeed8212014-09-04 01:03:18 +000040#include "lldb/Target/Thread.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000041
42using namespace lldb;
43using namespace lldb_private;
44
Greg Clayton68ebae62011-04-28 20:55:26 +000045static OptionDefinition
Greg Clayton84c39662011-04-27 22:04:39 +000046g_option_table[] =
47{
Zachary Turnerd37221d2014-07-09 16:31:49 +000048 { LLDB_OPT_SET_1, false, "num-per-line" ,'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeNumberPerLine ,"The number of items per line to display."},
49 { 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."},
50 { 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 +000051 { LLDB_OPT_SET_1|
52 LLDB_OPT_SET_2|
Zachary Turnerd37221d2014-07-09 16:31:49 +000053 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 +000054};
55
56
57
58class OptionGroupReadMemory : public OptionGroup
59{
60public:
61
62 OptionGroupReadMemory () :
Greg Clayton68ebae62011-04-28 20:55:26 +000063 m_num_per_line (1,1),
Greg Clayton84c39662011-04-27 22:04:39 +000064 m_output_as_binary (false),
65 m_view_as_type()
66 {
67 }
68
69 virtual
70 ~OptionGroupReadMemory ()
71 {
72 }
73
74
75 virtual uint32_t
76 GetNumDefinitions ()
77 {
78 return sizeof (g_option_table) / sizeof (OptionDefinition);
79 }
80
81 virtual const OptionDefinition*
82 GetDefinitions ()
83 {
84 return g_option_table;
85 }
86
87 virtual Error
88 SetOptionValue (CommandInterpreter &interpreter,
89 uint32_t option_idx,
90 const char *option_arg)
91 {
92 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +000093 const int short_option = g_option_table[option_idx].short_option;
Greg Clayton84c39662011-04-27 22:04:39 +000094
95 switch (short_option)
96 {
97 case 'l':
Pavel Labathc95f7e22015-02-20 11:14:59 +000098 error = m_num_per_line.SetValueFromString (option_arg);
Greg Clayton84c39662011-04-27 22:04:39 +000099 if (m_num_per_line.GetCurrentValue() == 0)
Greg Clayton86edbf42011-10-26 00:56:27 +0000100 error.SetErrorStringWithFormat("invalid value for --num-per-line option '%s'", option_arg);
Greg Clayton84c39662011-04-27 22:04:39 +0000101 break;
Greg Clayton1deb7962011-10-25 06:44:01 +0000102
Greg Clayton84c39662011-04-27 22:04:39 +0000103 case 'b':
104 m_output_as_binary = true;
105 break;
106
107 case 't':
Pavel Labathc95f7e22015-02-20 11:14:59 +0000108 error = m_view_as_type.SetValueFromString (option_arg);
Greg Clayton84c39662011-04-27 22:04:39 +0000109 break;
Sean Callanan1276c332012-04-28 01:27:38 +0000110
111 case 'r':
112 m_force = true;
113 break;
Greg Clayton84c39662011-04-27 22:04:39 +0000114
115 default:
Greg Clayton86edbf42011-10-26 00:56:27 +0000116 error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option);
Greg Clayton84c39662011-04-27 22:04:39 +0000117 break;
118 }
119 return error;
120 }
121
122 virtual void
123 OptionParsingStarting (CommandInterpreter &interpreter)
124 {
Greg Clayton84c39662011-04-27 22:04:39 +0000125 m_num_per_line.Clear();
126 m_output_as_binary = false;
127 m_view_as_type.Clear();
Enrico Granatad325bf92013-06-04 22:54:16 +0000128 m_force = false;
Greg Clayton84c39662011-04-27 22:04:39 +0000129 }
130
Greg Clayton68ebae62011-04-28 20:55:26 +0000131 Error
Greg Clayton1deb7962011-10-25 06:44:01 +0000132 FinalizeSettings (Target *target, OptionGroupFormat& format_options)
Greg Clayton84c39662011-04-27 22:04:39 +0000133 {
Greg Clayton68ebae62011-04-28 20:55:26 +0000134 Error error;
Greg Clayton1deb7962011-10-25 06:44:01 +0000135 OptionValueUInt64 &byte_size_value = format_options.GetByteSizeValue();
136 OptionValueUInt64 &count_value = format_options.GetCountValue();
Greg Clayton86edbf42011-10-26 00:56:27 +0000137 const bool byte_size_option_set = byte_size_value.OptionWasSet();
Greg Clayton68ebae62011-04-28 20:55:26 +0000138 const bool num_per_line_option_set = m_num_per_line.OptionWasSet();
Greg Clayton1deb7962011-10-25 06:44:01 +0000139 const bool count_option_set = format_options.GetCountValue().OptionWasSet();
Greg Clayton68ebae62011-04-28 20:55:26 +0000140
Greg Clayton68ebae62011-04-28 20:55:26 +0000141 switch (format_options.GetFormat())
Greg Clayton84c39662011-04-27 22:04:39 +0000142 {
143 default:
144 break;
145
146 case eFormatBoolean:
Greg Clayton68ebae62011-04-28 20:55:26 +0000147 if (!byte_size_option_set)
Greg Clayton1deb7962011-10-25 06:44:01 +0000148 byte_size_value = 1;
Greg Clayton68ebae62011-04-28 20:55:26 +0000149 if (!num_per_line_option_set)
150 m_num_per_line = 1;
151 if (!count_option_set)
Greg Clayton1deb7962011-10-25 06:44:01 +0000152 format_options.GetCountValue() = 8;
Greg Clayton84c39662011-04-27 22:04:39 +0000153 break;
154
155 case eFormatCString:
156 break;
Greg Clayton5009f9d2011-10-27 17:55:14 +0000157
158 case eFormatInstruction:
159 if (count_option_set)
Jim Inghamd073fe42012-11-07 01:52:04 +0000160 byte_size_value = target->GetArchitecture().GetMaximumOpcodeByteSize();
Greg Clayton5009f9d2011-10-27 17:55:14 +0000161 m_num_per_line = 1;
162 break;
163
164 case eFormatAddressInfo:
165 if (!byte_size_option_set)
166 byte_size_value = target->GetArchitecture().GetAddressByteSize();
167 m_num_per_line = 1;
168 if (!count_option_set)
169 format_options.GetCountValue() = 8;
170 break;
171
Greg Clayton84c39662011-04-27 22:04:39 +0000172 case eFormatPointer:
Greg Clayton1deb7962011-10-25 06:44:01 +0000173 byte_size_value = target->GetArchitecture().GetAddressByteSize();
Greg Clayton68ebae62011-04-28 20:55:26 +0000174 if (!num_per_line_option_set)
175 m_num_per_line = 4;
176 if (!count_option_set)
Greg Clayton1deb7962011-10-25 06:44:01 +0000177 format_options.GetCountValue() = 8;
Greg Clayton84c39662011-04-27 22:04:39 +0000178 break;
179
180 case eFormatBinary:
181 case eFormatFloat:
182 case eFormatOctal:
183 case eFormatDecimal:
184 case eFormatEnum:
185 case eFormatUnicode16:
186 case eFormatUnicode32:
187 case eFormatUnsigned:
Greg Clayton5009f9d2011-10-27 17:55:14 +0000188 case eFormatHexFloat:
Greg Clayton68ebae62011-04-28 20:55:26 +0000189 if (!byte_size_option_set)
Greg Clayton1deb7962011-10-25 06:44:01 +0000190 byte_size_value = 4;
Greg Clayton68ebae62011-04-28 20:55:26 +0000191 if (!num_per_line_option_set)
192 m_num_per_line = 1;
193 if (!count_option_set)
Greg Clayton1deb7962011-10-25 06:44:01 +0000194 format_options.GetCountValue() = 8;
Greg Clayton84c39662011-04-27 22:04:39 +0000195 break;
Greg Clayton5009f9d2011-10-27 17:55:14 +0000196
Greg Clayton84c39662011-04-27 22:04:39 +0000197 case eFormatBytes:
198 case eFormatBytesWithASCII:
Greg Clayton86edbf42011-10-26 00:56:27 +0000199 if (byte_size_option_set)
Greg Clayton68ebae62011-04-28 20:55:26 +0000200 {
Greg Clayton1deb7962011-10-25 06:44:01 +0000201 if (byte_size_value > 1)
Daniel Malead01b2952012-11-29 21:49:15 +0000202 error.SetErrorStringWithFormat ("display format (bytes/bytes with ascii) conflicts with the specified byte size %" PRIu64 "\n"
Johnny Chenda324de2012-03-06 01:17:59 +0000203 "\tconsider using a different display format or don't specify the byte size",
204 byte_size_value.GetCurrentValue());
Greg Clayton68ebae62011-04-28 20:55:26 +0000205 }
206 else
Greg Clayton1deb7962011-10-25 06:44:01 +0000207 byte_size_value = 1;
Greg Clayton68ebae62011-04-28 20:55:26 +0000208 if (!num_per_line_option_set)
209 m_num_per_line = 16;
210 if (!count_option_set)
Greg Clayton1deb7962011-10-25 06:44:01 +0000211 format_options.GetCountValue() = 32;
Greg Clayton84c39662011-04-27 22:04:39 +0000212 break;
Greg Clayton4e4294b2011-06-17 23:50:44 +0000213 case eFormatCharArray:
Greg Clayton84c39662011-04-27 22:04:39 +0000214 case eFormatChar:
215 case eFormatCharPrintable:
Greg Clayton68ebae62011-04-28 20:55:26 +0000216 if (!byte_size_option_set)
Greg Clayton1deb7962011-10-25 06:44:01 +0000217 byte_size_value = 1;
Greg Clayton68ebae62011-04-28 20:55:26 +0000218 if (!num_per_line_option_set)
219 m_num_per_line = 32;
220 if (!count_option_set)
Greg Clayton1deb7962011-10-25 06:44:01 +0000221 format_options.GetCountValue() = 64;
Greg Clayton84c39662011-04-27 22:04:39 +0000222 break;
223 case eFormatComplex:
Greg Clayton68ebae62011-04-28 20:55:26 +0000224 if (!byte_size_option_set)
Greg Clayton1deb7962011-10-25 06:44:01 +0000225 byte_size_value = 8;
Greg Clayton68ebae62011-04-28 20:55:26 +0000226 if (!num_per_line_option_set)
227 m_num_per_line = 1;
228 if (!count_option_set)
Greg Clayton1deb7962011-10-25 06:44:01 +0000229 format_options.GetCountValue() = 8;
Greg Clayton84c39662011-04-27 22:04:39 +0000230 break;
Jason Molendafc306d32013-03-23 05:16:54 +0000231 case eFormatComplexInteger:
232 if (!byte_size_option_set)
233 byte_size_value = 8;
234 if (!num_per_line_option_set)
235 m_num_per_line = 1;
236 if (!count_option_set)
237 format_options.GetCountValue() = 8;
238 break;
Greg Clayton84c39662011-04-27 22:04:39 +0000239 case eFormatHex:
Greg Clayton68ebae62011-04-28 20:55:26 +0000240 if (!byte_size_option_set)
Greg Clayton1deb7962011-10-25 06:44:01 +0000241 byte_size_value = 4;
Greg Clayton68ebae62011-04-28 20:55:26 +0000242 if (!num_per_line_option_set)
243 {
Greg Clayton1deb7962011-10-25 06:44:01 +0000244 switch (byte_size_value)
Greg Clayton68ebae62011-04-28 20:55:26 +0000245 {
246 case 1:
247 case 2:
248 m_num_per_line = 8;
249 break;
250 case 4:
251 m_num_per_line = 4;
252 break;
253 case 8:
254 m_num_per_line = 2;
255 break;
256 default:
257 m_num_per_line = 1;
258 break;
259 }
260 }
261 if (!count_option_set)
Greg Clayton1deb7962011-10-25 06:44:01 +0000262 count_value = 8;
Greg Clayton84c39662011-04-27 22:04:39 +0000263 break;
264
265 case eFormatVectorOfChar:
266 case eFormatVectorOfSInt8:
267 case eFormatVectorOfUInt8:
268 case eFormatVectorOfSInt16:
269 case eFormatVectorOfUInt16:
270 case eFormatVectorOfSInt32:
271 case eFormatVectorOfUInt32:
272 case eFormatVectorOfSInt64:
273 case eFormatVectorOfUInt64:
274 case eFormatVectorOfFloat32:
275 case eFormatVectorOfFloat64:
276 case eFormatVectorOfUInt128:
Greg Clayton68ebae62011-04-28 20:55:26 +0000277 if (!byte_size_option_set)
Greg Clayton1deb7962011-10-25 06:44:01 +0000278 byte_size_value = 128;
Greg Clayton68ebae62011-04-28 20:55:26 +0000279 if (!num_per_line_option_set)
280 m_num_per_line = 1;
281 if (!count_option_set)
Greg Clayton1deb7962011-10-25 06:44:01 +0000282 count_value = 4;
Greg Clayton84c39662011-04-27 22:04:39 +0000283 break;
284 }
Greg Clayton68ebae62011-04-28 20:55:26 +0000285 return error;
Greg Clayton84c39662011-04-27 22:04:39 +0000286 }
287
Greg Clayton82f4cf42011-10-26 04:32:38 +0000288 bool
289 AnyOptionWasSet () const
290 {
291 return m_num_per_line.OptionWasSet() ||
292 m_output_as_binary ||
293 m_view_as_type.OptionWasSet();
294 }
295
Greg Clayton84c39662011-04-27 22:04:39 +0000296 OptionValueUInt64 m_num_per_line;
297 bool m_output_as_binary;
298 OptionValueString m_view_as_type;
Sean Callanan1276c332012-04-28 01:27:38 +0000299 bool m_force;
Greg Clayton84c39662011-04-27 22:04:39 +0000300};
301
302
303
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000304//----------------------------------------------------------------------
305// Read memory from the inferior process
306//----------------------------------------------------------------------
Jim Ingham5a988412012-06-08 21:56:10 +0000307class CommandObjectMemoryRead : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000308{
309public:
310
Greg Claytona7015092010-09-18 01:14:36 +0000311 CommandObjectMemoryRead (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +0000312 CommandObjectParsed (interpreter,
313 "memory read",
314 "Read from the memory of the process being debugged.",
315 NULL,
Enrico Granatae87764f2015-05-27 05:04:35 +0000316 eCommandRequiresTarget | eCommandProcessMustBePaused),
Greg Clayton84c39662011-04-27 22:04:39 +0000317 m_option_group (interpreter),
Greg Clayton1deb7962011-10-25 06:44:01 +0000318 m_format_options (eFormatBytesWithASCII, 1, 8),
Greg Clayton84c39662011-04-27 22:04:39 +0000319 m_memory_options (),
Greg Clayton68ebae62011-04-28 20:55:26 +0000320 m_outfile_options (),
Greg Clayton82f4cf42011-10-26 04:32:38 +0000321 m_varobj_options(),
322 m_next_addr(LLDB_INVALID_ADDRESS),
323 m_prev_byte_size(0),
324 m_prev_format_options (eFormatBytesWithASCII, 1, 8),
325 m_prev_memory_options (),
326 m_prev_outfile_options (),
327 m_prev_varobj_options()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000328 {
Caroline Tice405fe672010-10-04 22:28:36 +0000329 CommandArgumentEntry arg1;
330 CommandArgumentEntry arg2;
331 CommandArgumentData start_addr_arg;
332 CommandArgumentData end_addr_arg;
333
334 // Define the first (and only) variant of this arg.
Enrico Granatab84a9db2013-01-29 01:48:30 +0000335 start_addr_arg.arg_type = eArgTypeAddressOrExpression;
Caroline Tice405fe672010-10-04 22:28:36 +0000336 start_addr_arg.arg_repetition = eArgRepeatPlain;
337
338 // There is only one variant this argument could be; put it into the argument entry.
339 arg1.push_back (start_addr_arg);
340
341 // Define the first (and only) variant of this arg.
Enrico Granatab84a9db2013-01-29 01:48:30 +0000342 end_addr_arg.arg_type = eArgTypeAddressOrExpression;
Caroline Tice405fe672010-10-04 22:28:36 +0000343 end_addr_arg.arg_repetition = eArgRepeatOptional;
344
345 // There is only one variant this argument could be; put it into the argument entry.
346 arg2.push_back (end_addr_arg);
347
348 // Push the data for the first argument into the m_arguments vector.
349 m_arguments.push_back (arg1);
350 m_arguments.push_back (arg2);
Greg Clayton84c39662011-04-27 22:04:39 +0000351
Greg Clayton1deb7962011-10-25 06:44:01 +0000352 // Add the "--format" and "--count" options to group 1 and 3
353 m_option_group.Append (&m_format_options,
354 OptionGroupFormat::OPTION_GROUP_FORMAT | OptionGroupFormat::OPTION_GROUP_COUNT,
Greg Clayton83889552011-11-22 18:07:35 +0000355 LLDB_OPT_SET_1 | LLDB_OPT_SET_2 | LLDB_OPT_SET_3);
Greg Clayton5009f9d2011-10-27 17:55:14 +0000356 m_option_group.Append (&m_format_options,
357 OptionGroupFormat::OPTION_GROUP_GDB_FMT,
Greg Clayton83889552011-11-22 18:07:35 +0000358 LLDB_OPT_SET_1 | LLDB_OPT_SET_3);
Greg Clayton1deb7962011-10-25 06:44:01 +0000359 // Add the "--size" option to group 1 and 2
360 m_option_group.Append (&m_format_options,
361 OptionGroupFormat::OPTION_GROUP_SIZE,
362 LLDB_OPT_SET_1 | LLDB_OPT_SET_2);
Greg Clayton84c39662011-04-27 22:04:39 +0000363 m_option_group.Append (&m_memory_options);
364 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 +0000365 m_option_group.Append (&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_3);
Greg Clayton84c39662011-04-27 22:04:39 +0000366 m_option_group.Finalize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000367 }
368
369 virtual
370 ~CommandObjectMemoryRead ()
371 {
372 }
373
374 Options *
375 GetOptions ()
376 {
Greg Clayton84c39662011-04-27 22:04:39 +0000377 return &m_option_group;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000378 }
379
Greg Clayton82f4cf42011-10-26 04:32:38 +0000380 virtual const char *GetRepeatCommand (Args &current_command_args, uint32_t index)
381 {
382 return m_cmd_name.c_str();
383 }
384
Jim Ingham5a988412012-06-08 21:56:10 +0000385protected:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000386 virtual bool
Greg Claytonb9d5df52012-12-06 22:49:16 +0000387 DoExecute (Args& command, CommandReturnObject &result)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000388 {
Enrico Granatae87764f2015-05-27 05:04:35 +0000389 // No need to check "target" for validity as eCommandRequiresTarget ensures it is valid
Greg Claytonf9fc6092013-01-09 19:44:40 +0000390 Target *target = m_exe_ctx.GetTargetPtr();
391
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000392 const size_t argc = command.GetArgumentCount();
393
Greg Clayton82f4cf42011-10-26 04:32:38 +0000394 if ((argc == 0 && m_next_addr == LLDB_INVALID_ADDRESS) || argc > 2)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000395 {
Greg Claytonb9d5df52012-12-06 22:49:16 +0000396 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 +0000397 result.AppendRawWarning("Expressions should be quoted if they contain spaces or other special characters.\n");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000398 result.SetStatus(eReturnStatusFailed);
399 return false;
400 }
401
Greg Clayton68ebae62011-04-28 20:55:26 +0000402 ClangASTType clang_ast_type;
403 Error error;
404
Greg Clayton84c39662011-04-27 22:04:39 +0000405 const char *view_as_type_cstr = m_memory_options.m_view_as_type.GetCurrentValue();
406 if (view_as_type_cstr && view_as_type_cstr[0])
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000407 {
Greg Clayton84c39662011-04-27 22:04:39 +0000408 // We are viewing memory as a type
Greg Clayton2e1f7452012-12-15 02:08:17 +0000409
Greg Clayton84c39662011-04-27 22:04:39 +0000410 SymbolContext sc;
Greg Clayton84db9102012-03-26 23:03:23 +0000411 const bool exact_match = false;
Greg Clayton84c39662011-04-27 22:04:39 +0000412 TypeList type_list;
413 uint32_t reference_count = 0;
414 uint32_t pointer_count = 0;
415 size_t idx;
Sean Callanan17cf1132012-07-10 21:24:26 +0000416
417#define ALL_KEYWORDS \
418 KEYWORD("const") \
419 KEYWORD("volatile") \
420 KEYWORD("restrict") \
421 KEYWORD("struct") \
422 KEYWORD("class") \
423 KEYWORD("union")
424
425#define KEYWORD(s) s,
426 static const char *g_keywords[] =
427 {
428 ALL_KEYWORDS
429 };
430#undef KEYWORD
431
432#define KEYWORD(s) (sizeof(s) - 1),
433 static const int g_keyword_lengths[] =
434 {
435 ALL_KEYWORDS
436 };
437#undef KEYWORD
438
439#undef ALL_KEYWORDS
440
441 static size_t g_num_keywords = sizeof(g_keywords) / sizeof(const char *);
Greg Clayton84c39662011-04-27 22:04:39 +0000442 std::string type_str(view_as_type_cstr);
443
444 // Remove all instances of g_keywords that are followed by spaces
445 for (size_t i = 0; i < g_num_keywords; ++i)
446 {
447 const char *keyword = g_keywords[i];
Sean Callanan17cf1132012-07-10 21:24:26 +0000448 int keyword_len = g_keyword_lengths[i];
449
450 idx = 0;
451 while ((idx = type_str.find (keyword, idx)) != std::string::npos)
Greg Clayton84c39662011-04-27 22:04:39 +0000452 {
453 if (type_str[idx + keyword_len] == ' ' || type_str[idx + keyword_len] == '\t')
Sean Callanan17cf1132012-07-10 21:24:26 +0000454 {
Greg Clayton84c39662011-04-27 22:04:39 +0000455 type_str.erase(idx, keyword_len+1);
Sean Callanan17cf1132012-07-10 21:24:26 +0000456 idx = 0;
457 }
458 else
459 {
460 idx += keyword_len;
461 }
Greg Clayton84c39662011-04-27 22:04:39 +0000462 }
463 }
464 bool done = type_str.empty();
465 //
466 idx = type_str.find_first_not_of (" \t");
467 if (idx > 0 && idx != std::string::npos)
468 type_str.erase (0, idx);
469 while (!done)
470 {
471 // Strip trailing spaces
472 if (type_str.empty())
473 done = true;
474 else
475 {
476 switch (type_str[type_str.size()-1])
477 {
478 case '*':
479 ++pointer_count;
480 // fall through...
481 case ' ':
482 case '\t':
483 type_str.erase(type_str.size()-1);
484 break;
485
486 case '&':
487 if (reference_count == 0)
488 {
489 reference_count = 1;
490 type_str.erase(type_str.size()-1);
491 }
492 else
493 {
494 result.AppendErrorWithFormat ("invalid type string: '%s'\n", view_as_type_cstr);
495 result.SetStatus(eReturnStatusFailed);
496 return false;
497 }
498 break;
499
500 default:
501 done = true;
502 break;
503 }
504 }
505 }
506
507 ConstString lookup_type_name(type_str.c_str());
Jason Molendab57e4a12013-11-04 09:33:30 +0000508 StackFrame *frame = m_exe_ctx.GetFramePtr();
Greg Claytonc14ee322011-09-22 04:58:26 +0000509 if (frame)
Greg Clayton84c39662011-04-27 22:04:39 +0000510 {
Greg Claytonc14ee322011-09-22 04:58:26 +0000511 sc = frame->GetSymbolContext (eSymbolContextModule);
Greg Clayton84c39662011-04-27 22:04:39 +0000512 if (sc.module_sp)
513 {
Sean Callananb6d70eb2011-10-12 02:08:07 +0000514 sc.module_sp->FindTypes (sc,
515 lookup_type_name,
Greg Clayton84db9102012-03-26 23:03:23 +0000516 exact_match,
Greg Clayton84c39662011-04-27 22:04:39 +0000517 1,
518 type_list);
519 }
520 }
521 if (type_list.GetSize() == 0)
522 {
Greg Clayton29399a22012-04-06 17:41:13 +0000523 target->GetImages().FindTypes (sc,
Greg Claytonc14ee322011-09-22 04:58:26 +0000524 lookup_type_name,
Greg Clayton84db9102012-03-26 23:03:23 +0000525 exact_match,
Greg Claytonc14ee322011-09-22 04:58:26 +0000526 1,
527 type_list);
Greg Clayton84c39662011-04-27 22:04:39 +0000528 }
529
Enrico Granata7bd2bbb2013-06-11 18:47:55 +0000530 if (type_list.GetSize() == 0 && lookup_type_name.GetCString() && *lookup_type_name.GetCString() == '$')
Greg Clayton84c39662011-04-27 22:04:39 +0000531 {
Enrico Granata7bd2bbb2013-06-11 18:47:55 +0000532 clang::TypeDecl *tdecl = target->GetPersistentVariables().GetPersistentType(ConstString(lookup_type_name));
533 if (tdecl)
534 {
Pavel Labathc7c30eb2015-06-08 23:38:06 +0000535 clang_ast_type.SetClangType(&tdecl->getASTContext(),(const lldb::clang_type_t)tdecl->getTypeForDecl());
Enrico Granata7bd2bbb2013-06-11 18:47:55 +0000536 }
Greg Clayton84c39662011-04-27 22:04:39 +0000537 }
538
Enrico Granata7bd2bbb2013-06-11 18:47:55 +0000539 if (clang_ast_type.IsValid() == false)
540 {
541 if (type_list.GetSize() == 0)
542 {
543 result.AppendErrorWithFormat ("unable to find any types that match the raw type '%s' for full type '%s'\n",
544 lookup_type_name.GetCString(),
545 view_as_type_cstr);
546 result.SetStatus(eReturnStatusFailed);
547 return false;
548 }
549 else
550 {
551 TypeSP type_sp (type_list.GetTypeAtIndex(0));
Greg Clayton57ee3062013-07-11 22:46:58 +0000552 clang_ast_type = type_sp->GetClangFullType();
Enrico Granata7bd2bbb2013-06-11 18:47:55 +0000553 }
554 }
Greg Clayton84c39662011-04-27 22:04:39 +0000555
556 while (pointer_count > 0)
557 {
Greg Clayton57ee3062013-07-11 22:46:58 +0000558 ClangASTType pointer_type = clang_ast_type.GetPointerType();
559 if (pointer_type.IsValid())
560 clang_ast_type = pointer_type;
Greg Clayton84c39662011-04-27 22:04:39 +0000561 else
562 {
563 result.AppendError ("unable make a pointer type\n");
564 result.SetStatus(eReturnStatusFailed);
565 return false;
566 }
567 --pointer_count;
568 }
569
Enrico Granata1cd5e922015-01-28 00:07:51 +0000570 m_format_options.GetByteSizeValue() = clang_ast_type.GetByteSize(nullptr);
Greg Clayton84c39662011-04-27 22:04:39 +0000571
Greg Clayton1deb7962011-10-25 06:44:01 +0000572 if (m_format_options.GetByteSizeValue() == 0)
Greg Clayton84c39662011-04-27 22:04:39 +0000573 {
574 result.AppendErrorWithFormat ("unable to get the byte size of the type '%s'\n",
575 view_as_type_cstr);
576 result.SetStatus(eReturnStatusFailed);
577 return false;
578 }
Greg Clayton68ebae62011-04-28 20:55:26 +0000579
Greg Clayton1deb7962011-10-25 06:44:01 +0000580 if (!m_format_options.GetCountValue().OptionWasSet())
581 m_format_options.GetCountValue() = 1;
Greg Clayton84c39662011-04-27 22:04:39 +0000582 }
583 else
584 {
Greg Claytonc14ee322011-09-22 04:58:26 +0000585 error = m_memory_options.FinalizeSettings (target, m_format_options);
Greg Clayton68ebae62011-04-28 20:55:26 +0000586 }
587
588 // Look for invalid combinations of settings
589 if (error.Fail())
590 {
Greg Claytonb9d5df52012-12-06 22:49:16 +0000591 result.AppendError(error.AsCString());
Greg Clayton68ebae62011-04-28 20:55:26 +0000592 result.SetStatus(eReturnStatusFailed);
593 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000594 }
595
Greg Clayton82f4cf42011-10-26 04:32:38 +0000596 lldb::addr_t addr;
597 size_t total_byte_size = 0;
598 if (argc == 0)
599 {
600 // Use the last address and byte size and all options as they were
601 // if no options have been set
602 addr = m_next_addr;
603 total_byte_size = m_prev_byte_size;
Greg Clayton2e1f7452012-12-15 02:08:17 +0000604 clang_ast_type = m_prev_clang_ast_type;
605 if (!m_format_options.AnyOptionWasSet() &&
Greg Clayton82f4cf42011-10-26 04:32:38 +0000606 !m_memory_options.AnyOptionWasSet() &&
607 !m_outfile_options.AnyOptionWasSet() &&
608 !m_varobj_options.AnyOptionWasSet())
609 {
610 m_format_options = m_prev_format_options;
611 m_memory_options = m_prev_memory_options;
612 m_outfile_options = m_prev_outfile_options;
613 m_varobj_options = m_prev_varobj_options;
614 }
615 }
616
Greg Clayton1deb7962011-10-25 06:44:01 +0000617 size_t item_count = m_format_options.GetCountValue().GetCurrentValue();
Matthew Gardinerf03e6d842014-09-29 08:02:24 +0000618
619 // TODO For non-8-bit byte addressable architectures this needs to be
620 // revisited to fully support all lldb's range of formatting options.
621 // Furthermore code memory reads (for those architectures) will not
622 // be correctly formatted even w/o formatting options.
623 size_t item_byte_size =
624 target->GetArchitecture().GetDataByteSize() > 1 ?
625 target->GetArchitecture().GetDataByteSize() :
626 m_format_options.GetByteSizeValue().GetCurrentValue();
627
Greg Clayton68ebae62011-04-28 20:55:26 +0000628 const size_t num_per_line = m_memory_options.m_num_per_line.GetCurrentValue();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000629
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000630 if (total_byte_size == 0)
Greg Clayton82f4cf42011-10-26 04:32:38 +0000631 {
632 total_byte_size = item_count * item_byte_size;
633 if (total_byte_size == 0)
634 total_byte_size = 32;
635 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000636
Greg Clayton82f4cf42011-10-26 04:32:38 +0000637 if (argc > 0)
Greg Claytonf9fc6092013-01-09 19:44:40 +0000638 addr = Args::StringToAddress(&m_exe_ctx, command.GetArgumentAtIndex(0), LLDB_INVALID_ADDRESS, &error);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000639
640 if (addr == LLDB_INVALID_ADDRESS)
641 {
Greg Claytonb9d5df52012-12-06 22:49:16 +0000642 result.AppendError("invalid start address expression.");
643 result.AppendError(error.AsCString());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000644 result.SetStatus(eReturnStatusFailed);
645 return false;
646 }
647
648 if (argc == 2)
649 {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000650 lldb::addr_t end_addr = Args::StringToAddress(&m_exe_ctx, command.GetArgumentAtIndex(1), LLDB_INVALID_ADDRESS, 0);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000651 if (end_addr == LLDB_INVALID_ADDRESS)
652 {
Greg Claytonb9d5df52012-12-06 22:49:16 +0000653 result.AppendError("invalid end address expression.");
654 result.AppendError(error.AsCString());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000655 result.SetStatus(eReturnStatusFailed);
656 return false;
657 }
658 else if (end_addr <= addr)
659 {
Daniel Malead01b2952012-11-29 21:49:15 +0000660 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 +0000661 result.SetStatus(eReturnStatusFailed);
662 return false;
663 }
Greg Clayton1deb7962011-10-25 06:44:01 +0000664 else if (m_format_options.GetCountValue().OptionWasSet())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000665 {
Greg Clayton6fea17e2014-03-03 19:15:20 +0000666 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 +0000667 result.SetStatus(eReturnStatusFailed);
668 return false;
669 }
670
671 total_byte_size = end_addr - addr;
672 item_count = total_byte_size / item_byte_size;
673 }
Matthew Gardinerf03e6d842014-09-29 08:02:24 +0000674
Enrico Granatad325bf92013-06-04 22:54:16 +0000675 uint32_t max_unforced_size = target->GetMaximumMemReadSize();
676
677 if (total_byte_size > max_unforced_size && !m_memory_options.m_force)
Sean Callanan1276c332012-04-28 01:27:38 +0000678 {
Enrico Granatad325bf92013-06-04 22:54:16 +0000679 result.AppendErrorWithFormat("Normally, \'memory read\' will not read over %" PRIu32 " bytes of data.\n",max_unforced_size);
680 result.AppendErrorWithFormat("Please use --force to override this restriction just once.\n");
681 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 +0000682 return false;
683 }
684
Greg Clayton84c39662011-04-27 22:04:39 +0000685 DataBufferSP data_sp;
Greg Clayton84c39662011-04-27 22:04:39 +0000686 size_t bytes_read = 0;
Greg Clayton2e1f7452012-12-15 02:08:17 +0000687 if (clang_ast_type.GetOpaqueQualType())
688 {
689 // Make sure we don't display our type as ASCII bytes like the default memory read
690 if (m_format_options.GetFormatValue().OptionWasSet() == false)
691 m_format_options.GetFormatValue().SetCurrentValue(eFormatDefault);
692
Enrico Granata1cd5e922015-01-28 00:07:51 +0000693 bytes_read = clang_ast_type.GetByteSize(nullptr) * m_format_options.GetCountValue().GetCurrentValue();
Greg Clayton2e1f7452012-12-15 02:08:17 +0000694 }
Enrico Granata6b4ddc62013-01-21 19:20:50 +0000695 else if (m_format_options.GetFormatValue().GetCurrentValue() != eFormatCString)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000696 {
Greg Clayton84c39662011-04-27 22:04:39 +0000697 data_sp.reset (new DataBufferHeap (total_byte_size, '\0'));
Greg Clayton46a44262013-07-24 18:17:35 +0000698 if (data_sp->GetBytes() == NULL)
699 {
Virgile Belloffeba252014-03-08 17:15:35 +0000700 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 +0000701 result.SetStatus(eReturnStatusFailed);
702 return false;
703 }
704
Greg Claytone72dfb32012-02-24 01:59:29 +0000705 Address address(addr, NULL);
Greg Claytonc14ee322011-09-22 04:58:26 +0000706 bytes_read = target->ReadMemory(address, false, data_sp->GetBytes (), data_sp->GetByteSize(), error);
Greg Clayton84c39662011-04-27 22:04:39 +0000707 if (bytes_read == 0)
708 {
Greg Clayton57f06302012-05-25 17:05:55 +0000709 const char *error_cstr = error.AsCString();
710 if (error_cstr && error_cstr[0])
711 {
712 result.AppendError(error_cstr);
713 }
714 else
715 {
Daniel Malead01b2952012-11-29 21:49:15 +0000716 result.AppendErrorWithFormat("failed to read memory from 0x%" PRIx64 ".\n", addr);
Greg Clayton57f06302012-05-25 17:05:55 +0000717 }
Greg Clayton84c39662011-04-27 22:04:39 +0000718 result.SetStatus(eReturnStatusFailed);
719 return false;
720 }
721
722 if (bytes_read < total_byte_size)
Greg Clayton6fea17e2014-03-03 19:15:20 +0000723 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 +0000724 }
Enrico Granata6b4ddc62013-01-21 19:20:50 +0000725 else
726 {
727 // we treat c-strings as a special case because they do not have a fixed size
728 if (m_format_options.GetByteSizeValue().OptionWasSet() && !m_format_options.HasGDBFormat())
729 item_byte_size = m_format_options.GetByteSizeValue().GetCurrentValue();
730 else
731 item_byte_size = target->GetMaximumSizeOfStringSummary();
732 if (!m_format_options.GetCountValue().OptionWasSet())
733 item_count = 1;
734 data_sp.reset (new DataBufferHeap ((item_byte_size+1) * item_count, '\0')); // account for NULLs as necessary
Greg Clayton46a44262013-07-24 18:17:35 +0000735 if (data_sp->GetBytes() == NULL)
736 {
737 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));
738 result.SetStatus(eReturnStatusFailed);
739 return false;
740 }
Enrico Granata6b4ddc62013-01-21 19:20:50 +0000741 uint8_t *data_ptr = data_sp->GetBytes();
742 auto data_addr = addr;
743 auto count = item_count;
744 item_count = 0;
Enrico Granatadc3c3ee2015-04-06 18:41:17 +0000745 bool break_on_no_NULL = false;
Enrico Granata6b4ddc62013-01-21 19:20:50 +0000746 while (item_count < count)
747 {
748 std::string buffer;
749 buffer.resize(item_byte_size+1,0);
750 Error error;
751 size_t read = target->ReadCStringFromMemory(data_addr, &buffer[0], item_byte_size+1, error);
752 if (error.Fail())
753 {
754 result.AppendErrorWithFormat("failed to read memory from 0x%" PRIx64 ".\n", addr);
755 result.SetStatus(eReturnStatusFailed);
756 return false;
757 }
Enrico Granatadc3c3ee2015-04-06 18:41:17 +0000758
Enrico Granata6b4ddc62013-01-21 19:20:50 +0000759 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);
Enrico Granatadc3c3ee2015-04-06 18:41:17 +0000762 --read;
763 break_on_no_NULL = true;
Enrico Granata6b4ddc62013-01-21 19:20:50 +0000764 }
Enrico Granatadc3c3ee2015-04-06 18:41:17 +0000765 else
766 ++read; // account for final NULL byte
767
Enrico Granata6b4ddc62013-01-21 19:20:50 +0000768 memcpy(data_ptr, &buffer[0], read);
769 data_ptr += read;
770 data_addr += read;
771 bytes_read += read;
772 item_count++; // if we break early we know we only read item_count strings
Enrico Granatadc3c3ee2015-04-06 18:41:17 +0000773
774 if (break_on_no_NULL)
775 break;
Enrico Granata6b4ddc62013-01-21 19:20:50 +0000776 }
777 data_sp.reset(new DataBufferHeap(data_sp->GetBytes(),bytes_read+1));
778 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000779
Greg Clayton2e1f7452012-12-15 02:08:17 +0000780 m_next_addr = addr + bytes_read;
781 m_prev_byte_size = bytes_read;
782 m_prev_format_options = m_format_options;
783 m_prev_memory_options = m_memory_options;
784 m_prev_outfile_options = m_outfile_options;
785 m_prev_varobj_options = m_varobj_options;
786 m_prev_clang_ast_type = clang_ast_type;
787
Greg Clayton6d7e77b2010-10-10 20:52:20 +0000788 StreamFile outfile_stream;
789 Stream *output_stream = NULL;
Greg Clayton84c39662011-04-27 22:04:39 +0000790 const FileSpec &outfile_spec = m_outfile_options.GetFile().GetCurrentValue();
791 if (outfile_spec)
Greg Clayton6d7e77b2010-10-10 20:52:20 +0000792 {
793 char path[PATH_MAX];
Greg Clayton84c39662011-04-27 22:04:39 +0000794 outfile_spec.GetPath (path, sizeof(path));
795
796 uint32_t open_options = File::eOpenOptionWrite | File::eOpenOptionCanCreate;
797 const bool append = m_outfile_options.GetAppend().GetCurrentValue();
798 if (append)
799 open_options |= File::eOpenOptionAppend;
800
801 if (outfile_stream.GetFile ().Open (path, open_options).Success())
Greg Clayton6d7e77b2010-10-10 20:52:20 +0000802 {
Greg Clayton84c39662011-04-27 22:04:39 +0000803 if (m_memory_options.m_output_as_binary)
Greg Clayton6d7e77b2010-10-10 20:52:20 +0000804 {
Greg Claytonc7bece562013-01-25 18:06:21 +0000805 const size_t bytes_written = outfile_stream.Write (data_sp->GetBytes(), bytes_read);
Greg Clayton6d7e77b2010-10-10 20:52:20 +0000806 if (bytes_written > 0)
807 {
Greg Claytonc7bece562013-01-25 18:06:21 +0000808 result.GetOutputStream().Printf ("%zi bytes %s to '%s'\n",
Greg Clayton6d7e77b2010-10-10 20:52:20 +0000809 bytes_written,
Greg Clayton84c39662011-04-27 22:04:39 +0000810 append ? "appended" : "written",
Greg Clayton6d7e77b2010-10-10 20:52:20 +0000811 path);
812 return true;
813 }
814 else
815 {
Daniel Malead01b2952012-11-29 21:49:15 +0000816 result.AppendErrorWithFormat("Failed to write %" PRIu64 " bytes to '%s'.\n", (uint64_t)bytes_read, path);
Greg Clayton6d7e77b2010-10-10 20:52:20 +0000817 result.SetStatus(eReturnStatusFailed);
818 return false;
819 }
820 }
821 else
822 {
823 // We are going to write ASCII to the file just point the
824 // output_stream to our outfile_stream...
825 output_stream = &outfile_stream;
826 }
827 }
828 else
829 {
Greg Clayton84c39662011-04-27 22:04:39 +0000830 result.AppendErrorWithFormat("Failed to open file '%s' for %s.\n", path, append ? "append" : "write");
Greg Clayton6d7e77b2010-10-10 20:52:20 +0000831 result.SetStatus(eReturnStatusFailed);
832 return false;
833 }
834 }
835 else
836 {
837 output_stream = &result.GetOutputStream();
838 }
839
Greg Clayton84c39662011-04-27 22:04:39 +0000840
Greg Claytonf9fc6092013-01-09 19:44:40 +0000841 ExecutionContextScope *exe_scope = m_exe_ctx.GetBestExecutionContextScope();
Greg Clayton84c39662011-04-27 22:04:39 +0000842 if (clang_ast_type.GetOpaqueQualType())
843 {
844 for (uint32_t i = 0; i<item_count; ++i)
845 {
846 addr_t item_addr = addr + (i * item_byte_size);
Greg Claytone72dfb32012-02-24 01:59:29 +0000847 Address address (item_addr);
Greg Clayton84c39662011-04-27 22:04:39 +0000848 StreamString name_strm;
Daniel Malead01b2952012-11-29 21:49:15 +0000849 name_strm.Printf ("0x%" PRIx64, item_addr);
Greg Clayton5009f9d2011-10-27 17:55:14 +0000850 ValueObjectSP valobj_sp (ValueObjectMemory::Create (exe_scope,
Greg Clayton84c39662011-04-27 22:04:39 +0000851 name_strm.GetString().c_str(),
852 address,
853 clang_ast_type));
854 if (valobj_sp)
855 {
Greg Clayton2e1f7452012-12-15 02:08:17 +0000856 Format format = m_format_options.GetFormat();
Greg Clayton68ebae62011-04-28 20:55:26 +0000857 if (format != eFormatDefault)
858 valobj_sp->SetFormat (format);
859
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000860 DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions(eLanguageRuntimeDescriptionDisplayVerbosityFull,format));
Enrico Granata9fb5ab52013-03-26 18:04:53 +0000861
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000862 valobj_sp->Dump(*output_stream,options);
Greg Clayton84c39662011-04-27 22:04:39 +0000863 }
864 else
865 {
866 result.AppendErrorWithFormat ("failed to create a value object for: (%s) %s\n",
867 view_as_type_cstr,
868 name_strm.GetString().c_str());
869 result.SetStatus(eReturnStatusFailed);
870 return false;
871 }
872 }
873 return true;
874 }
875
876 result.SetStatus(eReturnStatusSuccessFinishResult);
877 DataExtractor data (data_sp,
Greg Claytonc14ee322011-09-22 04:58:26 +0000878 target->GetArchitecture().GetByteOrder(),
Matthew Gardinerf03e6d842014-09-29 08:02:24 +0000879 target->GetArchitecture().GetAddressByteSize(),
880 target->GetArchitecture().GetDataByteSize());
Enrico Granata31898912013-05-21 17:39:04 +0000881
882 Format format = m_format_options.GetFormat();
883 if ( ( (format == eFormatChar) || (format == eFormatCharPrintable) )
Enrico Granata0947a6e2013-10-29 23:04:29 +0000884 && (item_byte_size != 1))
Enrico Granata31898912013-05-21 17:39:04 +0000885 {
Enrico Granata0947a6e2013-10-29 23:04:29 +0000886 // if a count was not passed, or it is 1
887 if (m_format_options.GetCountValue().OptionWasSet() == false || item_count == 1)
888 {
889 // this turns requests such as
890 // memory read -fc -s10 -c1 *charPtrPtr
891 // which make no sense (what is a char of size 10?)
892 // into a request for fetching 10 chars of size 1 from the same memory location
893 format = eFormatCharArray;
894 item_count = item_byte_size;
895 item_byte_size = 1;
896 }
897 else
898 {
899 // here we passed a count, and it was not 1
900 // so we have a byte_size and a count
901 // we could well multiply those, but instead let's just fail
Greg Clayton6fea17e2014-03-03 19:15:20 +0000902 result.AppendErrorWithFormat("reading memory as characters of size %" PRIu64 " is not supported", (uint64_t)item_byte_size);
Enrico Granata0947a6e2013-10-29 23:04:29 +0000903 result.SetStatus(eReturnStatusFailed);
904 return false;
905 }
Enrico Granata31898912013-05-21 17:39:04 +0000906 }
Greg Clayton84c39662011-04-27 22:04:39 +0000907
Greg Clayton6d7e77b2010-10-10 20:52:20 +0000908 assert (output_stream);
Greg Claytonc7bece562013-01-25 18:06:21 +0000909 size_t bytes_dumped = data.Dump (output_stream,
910 0,
Enrico Granata31898912013-05-21 17:39:04 +0000911 format,
Greg Claytonc7bece562013-01-25 18:06:21 +0000912 item_byte_size,
913 item_count,
Matthew Gardinerf03e6d842014-09-29 08:02:24 +0000914 num_per_line / target->GetArchitecture().GetDataByteSize(),
Greg Claytonc7bece562013-01-25 18:06:21 +0000915 addr,
916 0,
917 0,
918 exe_scope);
Greg Clayton1848afb2011-10-28 23:44:55 +0000919 m_next_addr = addr + bytes_dumped;
Greg Clayton6d7e77b2010-10-10 20:52:20 +0000920 output_stream->EOL();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000921 return true;
922 }
923
Greg Clayton84c39662011-04-27 22:04:39 +0000924 OptionGroupOptions m_option_group;
925 OptionGroupFormat m_format_options;
926 OptionGroupReadMemory m_memory_options;
927 OptionGroupOutputFile m_outfile_options;
Greg Clayton68ebae62011-04-28 20:55:26 +0000928 OptionGroupValueObjectDisplay m_varobj_options;
Greg Clayton82f4cf42011-10-26 04:32:38 +0000929 lldb::addr_t m_next_addr;
930 lldb::addr_t m_prev_byte_size;
931 OptionGroupFormat m_prev_format_options;
932 OptionGroupReadMemory m_prev_memory_options;
933 OptionGroupOutputFile m_prev_outfile_options;
934 OptionGroupValueObjectDisplay m_prev_varobj_options;
Greg Clayton2e1f7452012-12-15 02:08:17 +0000935 ClangASTType m_prev_clang_ast_type;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000936};
937
Enrico Granata53468432013-11-13 02:18:44 +0000938OptionDefinition
939g_memory_find_option_table[] =
940{
Zachary Turnerd37221d2014-07-09 16:31:49 +0000941 { LLDB_OPT_SET_1, false, "expression", 'e', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeExpression, "Evaluate an expression to obtain a byte pattern."},
942 { LLDB_OPT_SET_2, false, "string", 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName, "Use text to find a byte pattern."},
943 { LLDB_OPT_SET_1|LLDB_OPT_SET_2, false, "count", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeCount, "How many times to perform the search."},
944 { 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 +0000945};
946
Enrico Granata53468432013-11-13 02:18:44 +0000947//----------------------------------------------------------------------
948// Find the specified data in memory
949//----------------------------------------------------------------------
950class CommandObjectMemoryFind : public CommandObjectParsed
951{
952public:
953
954 class OptionGroupFindMemory : public OptionGroup
955 {
956 public:
957 OptionGroupFindMemory () :
958 OptionGroup(),
959 m_count(1),
Enrico Granata8d81a842013-11-13 20:08:30 +0000960 m_offset(0)
Enrico Granata53468432013-11-13 02:18:44 +0000961 {
962 }
963
964 virtual
965 ~OptionGroupFindMemory ()
966 {
967 }
968
969 virtual uint32_t
970 GetNumDefinitions ()
971 {
972 return sizeof (g_memory_find_option_table) / sizeof (OptionDefinition);
973 }
974
975 virtual const OptionDefinition*
976 GetDefinitions ()
977 {
978 return g_memory_find_option_table;
979 }
980
981 virtual Error
982 SetOptionValue (CommandInterpreter &interpreter,
983 uint32_t option_idx,
984 const char *option_arg)
985 {
986 Error error;
987 const int short_option = g_memory_find_option_table[option_idx].short_option;
988
989 switch (short_option)
990 {
991 case 'e':
Pavel Labathc95f7e22015-02-20 11:14:59 +0000992 m_expr.SetValueFromString(option_arg);
Enrico Granata53468432013-11-13 02:18:44 +0000993 break;
994
995 case 's':
Pavel Labathc95f7e22015-02-20 11:14:59 +0000996 m_string.SetValueFromString(option_arg);
Enrico Granata53468432013-11-13 02:18:44 +0000997 break;
998
999 case 'c':
Pavel Labathc95f7e22015-02-20 11:14:59 +00001000 if (m_count.SetValueFromString(option_arg).Fail())
Enrico Granata53468432013-11-13 02:18:44 +00001001 error.SetErrorString("unrecognized value for count");
1002 break;
1003
Enrico Granata8d81a842013-11-13 20:08:30 +00001004 case 'o':
Pavel Labathc95f7e22015-02-20 11:14:59 +00001005 if (m_offset.SetValueFromString(option_arg).Fail())
Enrico Granata8d81a842013-11-13 20:08:30 +00001006 error.SetErrorString("unrecognized value for dump-offset");
1007 break;
1008
Enrico Granata53468432013-11-13 02:18:44 +00001009 default:
1010 error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option);
1011 break;
1012 }
1013 return error;
1014 }
1015
1016 virtual void
1017 OptionParsingStarting (CommandInterpreter &interpreter)
1018 {
1019 m_expr.Clear();
1020 m_string.Clear();
1021 m_count.Clear();
Enrico Granata53468432013-11-13 02:18:44 +00001022 }
1023
1024 OptionValueString m_expr;
1025 OptionValueString m_string;
1026 OptionValueUInt64 m_count;
Enrico Granata8d81a842013-11-13 20:08:30 +00001027 OptionValueUInt64 m_offset;
Enrico Granata53468432013-11-13 02:18:44 +00001028 };
1029
1030 CommandObjectMemoryFind (CommandInterpreter &interpreter) :
1031 CommandObjectParsed (interpreter,
1032 "memory find",
1033 "Find a value in the memory of the process being debugged.",
1034 NULL,
Enrico Granatae87764f2015-05-27 05:04:35 +00001035 eCommandRequiresProcess | eCommandProcessMustBeLaunched),
Enrico Granata53468432013-11-13 02:18:44 +00001036 m_option_group (interpreter),
1037 m_memory_options ()
1038 {
1039 CommandArgumentEntry arg1;
1040 CommandArgumentEntry arg2;
1041 CommandArgumentData addr_arg;
1042 CommandArgumentData value_arg;
1043
1044 // Define the first (and only) variant of this arg.
1045 addr_arg.arg_type = eArgTypeAddress;
1046 addr_arg.arg_repetition = eArgRepeatPlain;
1047
1048 // There is only one variant this argument could be; put it into the argument entry.
1049 arg1.push_back (addr_arg);
1050
1051 // Define the first (and only) variant of this arg.
1052 value_arg.arg_type = eArgTypeValue;
1053 value_arg.arg_repetition = eArgRepeatPlus;
1054
1055 // There is only one variant this argument could be; put it into the argument entry.
1056 arg2.push_back (value_arg);
1057
1058 // Push the data for the first argument into the m_arguments vector.
1059 m_arguments.push_back (arg1);
1060 m_arguments.push_back (arg2);
1061
1062 m_option_group.Append (&m_memory_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_2);
1063 m_option_group.Finalize();
1064 }
1065
1066 virtual
1067 ~CommandObjectMemoryFind ()
1068 {
1069 }
1070
1071 Options *
1072 GetOptions ()
1073 {
1074 return &m_option_group;
1075 }
1076
1077protected:
1078 virtual bool
1079 DoExecute (Args& command, CommandReturnObject &result)
1080 {
Enrico Granatae87764f2015-05-27 05:04:35 +00001081 // No need to check "process" for validity as eCommandRequiresProcess ensures it is valid
Enrico Granata53468432013-11-13 02:18:44 +00001082 Process *process = m_exe_ctx.GetProcessPtr();
1083
1084 const size_t argc = command.GetArgumentCount();
1085
1086 if (argc != 2)
1087 {
Enrico Granata6e49c482013-11-13 02:22:24 +00001088 result.AppendError("two addresses needed for memory find");
Enrico Granata53468432013-11-13 02:18:44 +00001089 return false;
1090 }
1091
1092 Error error;
1093 lldb::addr_t low_addr = Args::StringToAddress(&m_exe_ctx, command.GetArgumentAtIndex(0),LLDB_INVALID_ADDRESS,&error);
1094 if (low_addr == LLDB_INVALID_ADDRESS || error.Fail())
1095 {
1096 result.AppendError("invalid low address");
1097 return false;
1098 }
1099 lldb::addr_t high_addr = Args::StringToAddress(&m_exe_ctx, command.GetArgumentAtIndex(1),LLDB_INVALID_ADDRESS,&error);
1100 if (high_addr == LLDB_INVALID_ADDRESS || error.Fail())
1101 {
Ed Maste47a8a5e2014-09-06 11:29:08 +00001102 result.AppendError("invalid high address");
Enrico Granata53468432013-11-13 02:18:44 +00001103 return false;
1104 }
1105
1106 if (high_addr <= low_addr)
1107 {
1108 result.AppendError("starting address must be smaller than ending address");
1109 return false;
1110 }
1111
1112 lldb::addr_t found_location = LLDB_INVALID_ADDRESS;
1113
1114 DataBufferHeap buffer;
1115
1116 if (m_memory_options.m_string.OptionWasSet())
1117 buffer.CopyData(m_memory_options.m_string.GetStringValue(), strlen(m_memory_options.m_string.GetStringValue()));
1118 else if (m_memory_options.m_expr.OptionWasSet())
1119 {
1120 StackFrame* frame = m_exe_ctx.GetFramePtr();
1121 ValueObjectSP result_sp;
1122 if (process->GetTarget().EvaluateExpression(m_memory_options.m_expr.GetStringValue(), frame, result_sp) && result_sp.get())
1123 {
1124 uint64_t value = result_sp->GetValueAsUnsigned(0);
Enrico Granata1cd5e922015-01-28 00:07:51 +00001125 switch (result_sp->GetClangType().GetByteSize(nullptr))
Enrico Granata53468432013-11-13 02:18:44 +00001126 {
1127 case 1: {
1128 uint8_t byte = (uint8_t)value;
1129 buffer.CopyData(&byte,1);
1130 }
1131 break;
1132 case 2: {
1133 uint16_t word = (uint16_t)value;
1134 buffer.CopyData(&word,2);
1135 }
1136 break;
1137 case 4: {
1138 uint32_t lword = (uint32_t)value;
1139 buffer.CopyData(&lword,4);
1140 }
1141 break;
1142 case 8: {
1143 buffer.CopyData(&value, 8);
1144 }
1145 break;
1146 case 3:
1147 case 5:
1148 case 6:
1149 case 7:
1150 result.AppendError("unknown type. pass a string instead");
1151 return false;
1152 default:
1153 result.AppendError("do not know how to deal with larger than 8 byte result types. pass a string instead");
1154 return false;
1155 }
1156 }
1157 else
1158 {
1159 result.AppendError("expression evaluation failed. pass a string instead?");
1160 return false;
1161 }
1162 }
1163 else
1164 {
1165 result.AppendError("please pass either a block of text, or an expression to evaluate.");
1166 return false;
1167 }
1168
1169 size_t count = m_memory_options.m_count.GetCurrentValue();
1170 found_location = low_addr;
1171 bool ever_found = false;
1172 while (count)
1173 {
1174 found_location = Search(found_location, high_addr, buffer.GetBytes(), buffer.GetByteSize());
1175 if (found_location == LLDB_INVALID_ADDRESS)
1176 {
1177 if (!ever_found)
1178 {
1179 result.AppendMessage("Your data was not found within the range.\n");
1180 result.SetStatus(lldb::eReturnStatusSuccessFinishNoResult);
1181 }
1182 else
1183 result.AppendMessage("No more matches found within the range.\n");
1184 break;
1185 }
1186 result.AppendMessageWithFormat("Your data was found at location: 0x%" PRIx64 "\n", found_location);
Enrico Granata8d81a842013-11-13 20:08:30 +00001187
1188 DataBufferHeap dumpbuffer(32,0);
1189 process->ReadMemory(found_location+m_memory_options.m_offset.GetCurrentValue(), dumpbuffer.GetBytes(), dumpbuffer.GetByteSize(), error);
1190 if (!error.Fail())
Enrico Granata53468432013-11-13 02:18:44 +00001191 {
Enrico Granata8d81a842013-11-13 20:08:30 +00001192 DataExtractor data(dumpbuffer.GetBytes(), dumpbuffer.GetByteSize(), process->GetByteOrder(), process->GetAddressByteSize());
1193 data.Dump(&result.GetOutputStream(), 0, lldb::eFormatBytesWithASCII, 1, dumpbuffer.GetByteSize(), 16, found_location+m_memory_options.m_offset.GetCurrentValue(), 0, 0);
1194 result.GetOutputStream().EOL();
Enrico Granata53468432013-11-13 02:18:44 +00001195 }
Enrico Granata8d81a842013-11-13 20:08:30 +00001196
Enrico Granata53468432013-11-13 02:18:44 +00001197 --count;
1198 found_location++;
1199 ever_found = true;
1200 }
1201
1202 result.SetStatus(lldb::eReturnStatusSuccessFinishResult);
1203 return true;
1204 }
1205
1206 lldb::addr_t
1207 Search (lldb::addr_t low,
1208 lldb::addr_t high,
1209 uint8_t* buffer,
1210 size_t buffer_size)
1211 {
1212 Process *process = m_exe_ctx.GetProcessPtr();
1213 DataBufferHeap heap(buffer_size, 0);
1214 lldb::addr_t fictional_ptr = low;
1215 for (auto ptr = low;
1216 low < high;
1217 fictional_ptr++)
1218 {
1219 Error error;
1220 if (ptr == low || buffer_size == 1)
1221 process->ReadMemory(ptr, heap.GetBytes(), buffer_size, error);
1222 else
1223 {
1224 memmove(heap.GetBytes(), heap.GetBytes()+1, buffer_size-1);
1225 process->ReadMemory(ptr, heap.GetBytes()+buffer_size-1, 1, error);
1226 }
1227 if (error.Fail())
1228 return LLDB_INVALID_ADDRESS;
1229 if (memcmp(heap.GetBytes(), buffer, buffer_size) == 0)
1230 return fictional_ptr;
1231 if (ptr == low)
1232 ptr += buffer_size;
1233 else
1234 ptr += 1;
1235 }
1236 return LLDB_INVALID_ADDRESS;
1237 }
1238
1239 OptionGroupOptions m_option_group;
1240 OptionGroupFindMemory m_memory_options;
1241};
1242
Greg Clayton1deb7962011-10-25 06:44:01 +00001243
1244OptionDefinition
1245g_memory_write_option_table[] =
1246{
Zachary Turnerd37221d2014-07-09 16:31:49 +00001247{ 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 +00001248{ 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 +00001249};
1250
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001251//----------------------------------------------------------------------
1252// Write memory to the inferior process
1253//----------------------------------------------------------------------
Jim Ingham5a988412012-06-08 21:56:10 +00001254class CommandObjectMemoryWrite : public CommandObjectParsed
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001255{
1256public:
1257
Greg Clayton1deb7962011-10-25 06:44:01 +00001258 class OptionGroupWriteMemory : public OptionGroup
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001259 {
1260 public:
Greg Clayton1deb7962011-10-25 06:44:01 +00001261 OptionGroupWriteMemory () :
1262 OptionGroup()
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001263 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001264 }
1265
1266 virtual
Greg Clayton1deb7962011-10-25 06:44:01 +00001267 ~OptionGroupWriteMemory ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001268 {
1269 }
1270
Greg Clayton1deb7962011-10-25 06:44:01 +00001271 virtual uint32_t
1272 GetNumDefinitions ()
1273 {
1274 return sizeof (g_memory_write_option_table) / sizeof (OptionDefinition);
1275 }
Enrico Granata53468432013-11-13 02:18:44 +00001276
Greg Clayton1deb7962011-10-25 06:44:01 +00001277 virtual const OptionDefinition*
1278 GetDefinitions ()
1279 {
1280 return g_memory_write_option_table;
1281 }
Enrico Granata53468432013-11-13 02:18:44 +00001282
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001283 virtual Error
Greg Clayton1deb7962011-10-25 06:44:01 +00001284 SetOptionValue (CommandInterpreter &interpreter,
1285 uint32_t option_idx,
1286 const char *option_arg)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001287 {
1288 Error error;
Greg Clayton3bcdfc02012-12-04 00:32:51 +00001289 const int short_option = g_memory_write_option_table[option_idx].short_option;
Enrico Granata53468432013-11-13 02:18:44 +00001290
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001291 switch (short_option)
1292 {
Greg Clayton1deb7962011-10-25 06:44:01 +00001293 case 'i':
1294 m_infile.SetFile (option_arg, true);
1295 if (!m_infile.Exists())
Greg Clayton6d7e77b2010-10-10 20:52:20 +00001296 {
Greg Clayton1deb7962011-10-25 06:44:01 +00001297 m_infile.Clear();
Greg Clayton86edbf42011-10-26 00:56:27 +00001298 error.SetErrorStringWithFormat("input file does not exist: '%s'", option_arg);
Greg Clayton6d7e77b2010-10-10 20:52:20 +00001299 }
Greg Clayton1deb7962011-10-25 06:44:01 +00001300 break;
Enrico Granata53468432013-11-13 02:18:44 +00001301
Greg Clayton1deb7962011-10-25 06:44:01 +00001302 case 'o':
1303 {
1304 bool success;
Vince Harron5275aaa2015-01-15 20:08:35 +00001305 m_infile_offset = StringConvert::ToUInt64(option_arg, 0, 0, &success);
Greg Clayton1deb7962011-10-25 06:44:01 +00001306 if (!success)
1307 {
Greg Clayton86edbf42011-10-26 00:56:27 +00001308 error.SetErrorStringWithFormat("invalid offset string '%s'", option_arg);
Greg Clayton1deb7962011-10-25 06:44:01 +00001309 }
1310 }
1311 break;
1312
1313 default:
Greg Clayton86edbf42011-10-26 00:56:27 +00001314 error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option);
Greg Clayton1deb7962011-10-25 06:44:01 +00001315 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001316 }
1317 return error;
1318 }
Greg Clayton1deb7962011-10-25 06:44:01 +00001319
1320 virtual void
1321 OptionParsingStarting (CommandInterpreter &interpreter)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001322 {
Greg Clayton6d7e77b2010-10-10 20:52:20 +00001323 m_infile.Clear();
1324 m_infile_offset = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001325 }
1326
Greg Clayton6d7e77b2010-10-10 20:52:20 +00001327 FileSpec m_infile;
1328 off_t m_infile_offset;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001329 };
1330
Greg Claytona7015092010-09-18 01:14:36 +00001331 CommandObjectMemoryWrite (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +00001332 CommandObjectParsed (interpreter,
1333 "memory write",
1334 "Write to the memory of the process being debugged.",
1335 NULL,
Enrico Granatae87764f2015-05-27 05:04:35 +00001336 eCommandRequiresProcess | eCommandProcessMustBeLaunched),
Greg Clayton1deb7962011-10-25 06:44:01 +00001337 m_option_group (interpreter),
1338 m_format_options (eFormatBytes, 1, UINT64_MAX),
1339 m_memory_options ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001340 {
Caroline Tice405fe672010-10-04 22:28:36 +00001341 CommandArgumentEntry arg1;
1342 CommandArgumentEntry arg2;
1343 CommandArgumentData addr_arg;
1344 CommandArgumentData value_arg;
1345
1346 // Define the first (and only) variant of this arg.
1347 addr_arg.arg_type = eArgTypeAddress;
1348 addr_arg.arg_repetition = eArgRepeatPlain;
1349
1350 // There is only one variant this argument could be; put it into the argument entry.
1351 arg1.push_back (addr_arg);
1352
1353 // Define the first (and only) variant of this arg.
1354 value_arg.arg_type = eArgTypeValue;
1355 value_arg.arg_repetition = eArgRepeatPlus;
1356
1357 // There is only one variant this argument could be; put it into the argument entry.
1358 arg2.push_back (value_arg);
1359
1360 // Push the data for the first argument into the m_arguments vector.
1361 m_arguments.push_back (arg1);
1362 m_arguments.push_back (arg2);
Greg Clayton1deb7962011-10-25 06:44:01 +00001363
1364 m_option_group.Append (&m_format_options, OptionGroupFormat::OPTION_GROUP_FORMAT, LLDB_OPT_SET_1);
1365 m_option_group.Append (&m_format_options, OptionGroupFormat::OPTION_GROUP_SIZE , LLDB_OPT_SET_1|LLDB_OPT_SET_2);
1366 m_option_group.Append (&m_memory_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_2);
1367 m_option_group.Finalize();
1368
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001369 }
1370
1371 virtual
1372 ~CommandObjectMemoryWrite ()
1373 {
1374 }
1375
1376 Options *
1377 GetOptions ()
1378 {
Greg Clayton1deb7962011-10-25 06:44:01 +00001379 return &m_option_group;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001380 }
1381
1382 bool
1383 UIntValueIsValidForSize (uint64_t uval64, size_t total_byte_size)
1384 {
1385 if (total_byte_size > 8)
1386 return false;
1387
1388 if (total_byte_size == 8)
1389 return true;
1390
1391 const uint64_t max = ((uint64_t)1 << (uint64_t)(total_byte_size * 8)) - 1;
1392 return uval64 <= max;
1393 }
1394
1395 bool
1396 SIntValueIsValidForSize (int64_t sval64, size_t total_byte_size)
1397 {
1398 if (total_byte_size > 8)
1399 return false;
1400
1401 if (total_byte_size == 8)
1402 return true;
1403
1404 const int64_t max = ((int64_t)1 << (uint64_t)(total_byte_size * 8 - 1)) - 1;
1405 const int64_t min = ~(max);
1406 return min <= sval64 && sval64 <= max;
1407 }
1408
Jim Ingham5a988412012-06-08 21:56:10 +00001409protected:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001410 virtual bool
Jim Ingham5a988412012-06-08 21:56:10 +00001411 DoExecute (Args& command, CommandReturnObject &result)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001412 {
Enrico Granatae87764f2015-05-27 05:04:35 +00001413 // No need to check "process" for validity as eCommandRequiresProcess ensures it is valid
Greg Claytonf9fc6092013-01-09 19:44:40 +00001414 Process *process = m_exe_ctx.GetProcessPtr();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001415
1416 const size_t argc = command.GetArgumentCount();
1417
Greg Clayton1deb7962011-10-25 06:44:01 +00001418 if (m_memory_options.m_infile)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001419 {
Greg Clayton6d7e77b2010-10-10 20:52:20 +00001420 if (argc < 1)
1421 {
1422 result.AppendErrorWithFormat ("%s takes a destination address when writing file contents.\n", m_cmd_name.c_str());
1423 result.SetStatus(eReturnStatusFailed);
1424 return false;
1425 }
1426 }
1427 else if (argc < 2)
1428 {
1429 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 +00001430 result.SetStatus(eReturnStatusFailed);
1431 return false;
1432 }
1433
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001434 StreamString buffer (Stream::eBinary,
Greg Clayton514487e2011-02-15 21:59:32 +00001435 process->GetTarget().GetArchitecture().GetAddressByteSize(),
1436 process->GetTarget().GetArchitecture().GetByteOrder());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001437
Greg Clayton1deb7962011-10-25 06:44:01 +00001438 OptionValueUInt64 &byte_size_value = m_format_options.GetByteSizeValue();
1439 size_t item_byte_size = byte_size_value.GetCurrentValue();
Greg Claytonc982c762010-07-09 20:39:50 +00001440
Greg Claytonb9d5df52012-12-06 22:49:16 +00001441 Error error;
Greg Claytonf9fc6092013-01-09 19:44:40 +00001442 lldb::addr_t addr = Args::StringToAddress (&m_exe_ctx,
Greg Claytonb9d5df52012-12-06 22:49:16 +00001443 command.GetArgumentAtIndex(0),
1444 LLDB_INVALID_ADDRESS,
1445 &error);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001446
1447 if (addr == LLDB_INVALID_ADDRESS)
1448 {
Greg Claytonb9d5df52012-12-06 22:49:16 +00001449 result.AppendError("invalid address expression\n");
1450 result.AppendError(error.AsCString());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001451 result.SetStatus(eReturnStatusFailed);
1452 return false;
1453 }
Greg Clayton6d7e77b2010-10-10 20:52:20 +00001454
Greg Clayton1deb7962011-10-25 06:44:01 +00001455 if (m_memory_options.m_infile)
Greg Clayton6d7e77b2010-10-10 20:52:20 +00001456 {
1457 size_t length = SIZE_MAX;
Jason Molenda250b1b892015-02-03 23:39:47 +00001458 if (item_byte_size > 1)
Greg Clayton1deb7962011-10-25 06:44:01 +00001459 length = item_byte_size;
1460 lldb::DataBufferSP data_sp (m_memory_options.m_infile.ReadFileContents (m_memory_options.m_infile_offset, length));
Greg Clayton6d7e77b2010-10-10 20:52:20 +00001461 if (data_sp)
1462 {
1463 length = data_sp->GetByteSize();
1464 if (length > 0)
1465 {
1466 Error error;
1467 size_t bytes_written = process->WriteMemory (addr, data_sp->GetBytes(), length, error);
1468
1469 if (bytes_written == length)
1470 {
1471 // All bytes written
Daniel Malead01b2952012-11-29 21:49:15 +00001472 result.GetOutputStream().Printf("%" PRIu64 " bytes were written to 0x%" PRIx64 "\n", (uint64_t)bytes_written, addr);
Greg Clayton6d7e77b2010-10-10 20:52:20 +00001473 result.SetStatus(eReturnStatusSuccessFinishResult);
1474 }
1475 else if (bytes_written > 0)
1476 {
1477 // Some byte written
Daniel Malead01b2952012-11-29 21:49:15 +00001478 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 +00001479 result.SetStatus(eReturnStatusSuccessFinishResult);
1480 }
1481 else
1482 {
Daniel Malead01b2952012-11-29 21:49:15 +00001483 result.AppendErrorWithFormat ("Memory write to 0x%" PRIx64 " failed: %s.\n", addr, error.AsCString());
Greg Clayton6d7e77b2010-10-10 20:52:20 +00001484 result.SetStatus(eReturnStatusFailed);
1485 }
1486 }
1487 }
1488 else
1489 {
1490 result.AppendErrorWithFormat ("Unable to read contents of file.\n");
1491 result.SetStatus(eReturnStatusFailed);
1492 }
1493 return result.Succeeded();
1494 }
Greg Clayton1deb7962011-10-25 06:44:01 +00001495 else if (item_byte_size == 0)
Greg Clayton6d7e77b2010-10-10 20:52:20 +00001496 {
Greg Clayton1deb7962011-10-25 06:44:01 +00001497 if (m_format_options.GetFormat() == eFormatPointer)
Greg Clayton6d7e77b2010-10-10 20:52:20 +00001498 item_byte_size = buffer.GetAddressByteSize();
1499 else
1500 item_byte_size = 1;
1501 }
1502
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001503 command.Shift(); // shift off the address argument
1504 uint64_t uval64;
1505 int64_t sval64;
1506 bool success = false;
Greg Claytonc7bece562013-01-25 18:06:21 +00001507 const size_t num_value_args = command.GetArgumentCount();
1508 for (size_t i=0; i<num_value_args; ++i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001509 {
1510 const char *value_str = command.GetArgumentAtIndex(i);
1511
Greg Clayton1deb7962011-10-25 06:44:01 +00001512 switch (m_format_options.GetFormat())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001513 {
Greg Claytonbb7f31f2011-06-23 21:22:24 +00001514 case kNumFormats:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001515 case eFormatFloat: // TODO: add support for floats soon
1516 case eFormatCharPrintable:
1517 case eFormatBytesWithASCII:
1518 case eFormatComplex:
1519 case eFormatEnum:
1520 case eFormatUnicode16:
1521 case eFormatUnicode32:
1522 case eFormatVectorOfChar:
1523 case eFormatVectorOfSInt8:
1524 case eFormatVectorOfUInt8:
1525 case eFormatVectorOfSInt16:
1526 case eFormatVectorOfUInt16:
1527 case eFormatVectorOfSInt32:
1528 case eFormatVectorOfUInt32:
1529 case eFormatVectorOfSInt64:
1530 case eFormatVectorOfUInt64:
1531 case eFormatVectorOfFloat32:
1532 case eFormatVectorOfFloat64:
1533 case eFormatVectorOfUInt128:
Greg Clayton7a5388b2011-03-20 04:57:14 +00001534 case eFormatOSType:
1535 case eFormatComplexInteger:
Greg Clayton5009f9d2011-10-27 17:55:14 +00001536 case eFormatAddressInfo:
1537 case eFormatHexFloat:
1538 case eFormatInstruction:
Sean Callananbf154da2012-08-08 17:35:10 +00001539 case eFormatVoid:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001540 result.AppendError("unsupported format for writing memory");
1541 result.SetStatus(eReturnStatusFailed);
1542 return false;
1543
1544 case eFormatDefault:
1545 case eFormatBytes:
1546 case eFormatHex:
Enrico Granata7ec18e32012-08-09 19:33:34 +00001547 case eFormatHexUppercase:
Greg Claytonc982c762010-07-09 20:39:50 +00001548 case eFormatPointer:
1549
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001550 // Decode hex bytes
Vince Harron5275aaa2015-01-15 20:08:35 +00001551 uval64 = StringConvert::ToUInt64(value_str, UINT64_MAX, 16, &success);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001552 if (!success)
1553 {
1554 result.AppendErrorWithFormat ("'%s' is not a valid hex string value.\n", value_str);
1555 result.SetStatus(eReturnStatusFailed);
1556 return false;
1557 }
1558 else if (!UIntValueIsValidForSize (uval64, item_byte_size))
1559 {
Greg Clayton6fea17e2014-03-03 19:15:20 +00001560 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 +00001561 result.SetStatus(eReturnStatusFailed);
1562 return false;
1563 }
1564 buffer.PutMaxHex64 (uval64, item_byte_size);
1565 break;
1566
1567 case eFormatBoolean:
1568 uval64 = Args::StringToBoolean(value_str, false, &success);
1569 if (!success)
1570 {
1571 result.AppendErrorWithFormat ("'%s' is not a valid boolean string value.\n", value_str);
1572 result.SetStatus(eReturnStatusFailed);
1573 return false;
1574 }
1575 buffer.PutMaxHex64 (uval64, item_byte_size);
1576 break;
1577
1578 case eFormatBinary:
Vince Harron5275aaa2015-01-15 20:08:35 +00001579 uval64 = StringConvert::ToUInt64(value_str, UINT64_MAX, 2, &success);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001580 if (!success)
1581 {
1582 result.AppendErrorWithFormat ("'%s' is not a valid binary string value.\n", value_str);
1583 result.SetStatus(eReturnStatusFailed);
1584 return false;
1585 }
1586 else if (!UIntValueIsValidForSize (uval64, item_byte_size))
1587 {
Greg Clayton6fea17e2014-03-03 19:15:20 +00001588 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 +00001589 result.SetStatus(eReturnStatusFailed);
1590 return false;
1591 }
1592 buffer.PutMaxHex64 (uval64, item_byte_size);
1593 break;
1594
Greg Clayton4e4294b2011-06-17 23:50:44 +00001595 case eFormatCharArray:
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001596 case eFormatChar:
1597 case eFormatCString:
1598 if (value_str[0])
1599 {
1600 size_t len = strlen (value_str);
1601 // Include the NULL for C strings...
Greg Clayton1deb7962011-10-25 06:44:01 +00001602 if (m_format_options.GetFormat() == eFormatCString)
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001603 ++len;
1604 Error error;
1605 if (process->WriteMemory (addr, value_str, len, error) == len)
1606 {
1607 addr += len;
1608 }
1609 else
1610 {
Daniel Malead01b2952012-11-29 21:49:15 +00001611 result.AppendErrorWithFormat ("Memory write to 0x%" PRIx64 " failed: %s.\n", addr, error.AsCString());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001612 result.SetStatus(eReturnStatusFailed);
1613 return false;
1614 }
1615 }
1616 break;
1617
1618 case eFormatDecimal:
Vince Harron5275aaa2015-01-15 20:08:35 +00001619 sval64 = StringConvert::ToSInt64(value_str, INT64_MAX, 0, &success);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001620 if (!success)
1621 {
1622 result.AppendErrorWithFormat ("'%s' is not a valid signed decimal value.\n", value_str);
1623 result.SetStatus(eReturnStatusFailed);
1624 return false;
1625 }
1626 else if (!SIntValueIsValidForSize (sval64, item_byte_size))
1627 {
Greg Clayton6fea17e2014-03-03 19:15:20 +00001628 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 +00001629 result.SetStatus(eReturnStatusFailed);
1630 return false;
1631 }
1632 buffer.PutMaxHex64 (sval64, item_byte_size);
1633 break;
1634
1635 case eFormatUnsigned:
Vince Harron5275aaa2015-01-15 20:08:35 +00001636 uval64 = StringConvert::ToUInt64(value_str, UINT64_MAX, 0, &success);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001637 if (!success)
1638 {
1639 result.AppendErrorWithFormat ("'%s' is not a valid unsigned decimal string value.\n", value_str);
1640 result.SetStatus(eReturnStatusFailed);
1641 return false;
1642 }
1643 else if (!UIntValueIsValidForSize (uval64, item_byte_size))
1644 {
Greg Clayton6fea17e2014-03-03 19:15:20 +00001645 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 +00001646 result.SetStatus(eReturnStatusFailed);
1647 return false;
1648 }
1649 buffer.PutMaxHex64 (uval64, item_byte_size);
1650 break;
1651
1652 case eFormatOctal:
Vince Harron5275aaa2015-01-15 20:08:35 +00001653 uval64 = StringConvert::ToUInt64(value_str, UINT64_MAX, 8, &success);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001654 if (!success)
1655 {
1656 result.AppendErrorWithFormat ("'%s' is not a valid octal string value.\n", value_str);
1657 result.SetStatus(eReturnStatusFailed);
1658 return false;
1659 }
1660 else if (!UIntValueIsValidForSize (uval64, item_byte_size))
1661 {
Greg Clayton6fea17e2014-03-03 19:15:20 +00001662 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 +00001663 result.SetStatus(eReturnStatusFailed);
1664 return false;
1665 }
1666 buffer.PutMaxHex64 (uval64, item_byte_size);
1667 break;
1668 }
1669 }
1670
1671 if (!buffer.GetString().empty())
1672 {
1673 Error error;
Greg Clayton471b31c2010-07-20 22:52:08 +00001674 if (process->WriteMemory (addr, buffer.GetString().c_str(), buffer.GetString().size(), error) == buffer.GetString().size())
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001675 return true;
1676 else
1677 {
Daniel Malead01b2952012-11-29 21:49:15 +00001678 result.AppendErrorWithFormat ("Memory write to 0x%" PRIx64 " failed: %s.\n", addr, error.AsCString());
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001679 result.SetStatus(eReturnStatusFailed);
1680 return false;
1681 }
1682 }
1683 return true;
1684 }
1685
Greg Clayton1deb7962011-10-25 06:44:01 +00001686 OptionGroupOptions m_option_group;
1687 OptionGroupFormat m_format_options;
1688 OptionGroupWriteMemory m_memory_options;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001689};
1690
Kuba Breckabeed8212014-09-04 01:03:18 +00001691//----------------------------------------------------------------------
1692// Get malloc/free history of a memory address.
1693//----------------------------------------------------------------------
1694class CommandObjectMemoryHistory : public CommandObjectParsed
1695{
1696public:
1697
1698 CommandObjectMemoryHistory (CommandInterpreter &interpreter) :
1699 CommandObjectParsed (interpreter,
1700 "memory history",
1701 "Prints out the recorded stack traces for allocation/deallocation of a memory address.",
1702 NULL,
Enrico Granatae87764f2015-05-27 05:04:35 +00001703 eCommandRequiresTarget | eCommandRequiresProcess | eCommandProcessMustBePaused | eCommandProcessMustBeLaunched)
Kuba Breckabeed8212014-09-04 01:03:18 +00001704 {
1705 CommandArgumentEntry arg1;
1706 CommandArgumentData addr_arg;
1707
1708 // Define the first (and only) variant of this arg.
1709 addr_arg.arg_type = eArgTypeAddress;
1710 addr_arg.arg_repetition = eArgRepeatPlain;
1711
1712 // There is only one variant this argument could be; put it into the argument entry.
1713 arg1.push_back (addr_arg);
1714
1715 // Push the data for the first argument into the m_arguments vector.
1716 m_arguments.push_back (arg1);
1717 }
1718
1719 virtual
1720 ~CommandObjectMemoryHistory ()
1721 {
1722 }
1723
1724 virtual const char *GetRepeatCommand (Args &current_command_args, uint32_t index)
1725 {
1726 return m_cmd_name.c_str();
1727 }
1728
1729protected:
1730 virtual bool
1731 DoExecute (Args& command, CommandReturnObject &result)
1732 {
1733 const size_t argc = command.GetArgumentCount();
1734
1735 if (argc == 0 || argc > 1)
1736 {
1737 result.AppendErrorWithFormat ("%s takes an address expression", m_cmd_name.c_str());
1738 result.SetStatus(eReturnStatusFailed);
1739 return false;
1740 }
1741
1742 Error error;
1743 lldb::addr_t addr = Args::StringToAddress (&m_exe_ctx,
1744 command.GetArgumentAtIndex(0),
1745 LLDB_INVALID_ADDRESS,
1746 &error);
1747
1748 if (addr == LLDB_INVALID_ADDRESS)
1749 {
1750 result.AppendError("invalid address expression");
1751 result.AppendError(error.AsCString());
1752 result.SetStatus(eReturnStatusFailed);
1753 return false;
1754 }
1755
1756 Stream *output_stream = &result.GetOutputStream();
1757
1758 const ProcessSP &process_sp = m_exe_ctx.GetProcessSP();
1759 const MemoryHistorySP &memory_history = MemoryHistory::FindPlugin(process_sp);
1760
1761 if (! memory_history.get())
1762 {
1763 result.AppendError("no available memory history provider");
1764 result.SetStatus(eReturnStatusFailed);
1765 return false;
1766 }
1767
1768 HistoryThreads thread_list = memory_history->GetHistoryThreads(addr);
1769
1770 for (auto thread : thread_list) {
1771 thread->GetStatus(*output_stream, 0, UINT32_MAX, 0);
1772 }
1773
1774 result.SetStatus(eReturnStatusSuccessFinishResult);
1775
1776 return true;
1777 }
1778
1779};
1780
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001781
1782//-------------------------------------------------------------------------
1783// CommandObjectMemory
1784//-------------------------------------------------------------------------
1785
Greg Clayton66111032010-06-23 01:19:29 +00001786CommandObjectMemory::CommandObjectMemory (CommandInterpreter &interpreter) :
Greg Claytona7015092010-09-18 01:14:36 +00001787 CommandObjectMultiword (interpreter,
1788 "memory",
Caroline Tice3f4c09c2010-09-07 22:38:08 +00001789 "A set of commands for operating on memory.",
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001790 "memory <subcommand> [<subcommand-options>]")
1791{
Enrico Granata53468432013-11-13 02:18:44 +00001792 LoadSubCommand ("find", CommandObjectSP (new CommandObjectMemoryFind (interpreter)));
Greg Claytona7015092010-09-18 01:14:36 +00001793 LoadSubCommand ("read", CommandObjectSP (new CommandObjectMemoryRead (interpreter)));
1794 LoadSubCommand ("write", CommandObjectSP (new CommandObjectMemoryWrite (interpreter)));
Kuba Breckabeed8212014-09-04 01:03:18 +00001795 LoadSubCommand ("history", CommandObjectSP (new CommandObjectMemoryHistory (interpreter)));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001796}
1797
1798CommandObjectMemory::~CommandObjectMemory ()
1799{
1800}