1 //===-- CommandObjectRegister.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 "lldb/lldb-python.h"
11
12 #include "CommandObjectRegister.h"
13
14 // C Includes
15 // C++ Includes
16 // Other libraries and framework includes
17 // Project includes
18 #include "lldb/Core/DataExtractor.h"
19 #include "lldb/Core/RegisterValue.h"
20 #include "lldb/Core/Scalar.h"
21 #include "lldb/Core/Debugger.h"
22 #include "lldb/Interpreter/Args.h"
23 #include "lldb/Interpreter/CommandInterpreter.h"
24 #include "lldb/Interpreter/CommandReturnObject.h"
25 #include "lldb/Interpreter/Options.h"
26 #include "lldb/Interpreter/OptionGroupFormat.h"
27 #include "lldb/Interpreter/OptionValueArray.h"
28 #include "lldb/Interpreter/OptionValueUInt64.h"
29 #include "lldb/Target/ExecutionContext.h"
30 #include "lldb/Target/Process.h"
31 #include "lldb/Target/RegisterContext.h"
32 #include "lldb/Target/Thread.h"
33
34 using namespace lldb;
35 using namespace lldb_private;
36
37 //----------------------------------------------------------------------
38 // "register read"
39 //----------------------------------------------------------------------
40 class CommandObjectRegisterRead : public CommandObjectParsed
41 {
42 public:
CommandObjectRegisterRead(CommandInterpreter & interpreter)43 CommandObjectRegisterRead (CommandInterpreter &interpreter) :
44 CommandObjectParsed (interpreter,
45 "register read",
46 "Dump the contents of one or more register values from the current frame. If no register is specified, dumps them all.",
47 NULL,
48 eFlagRequiresFrame |
49 eFlagRequiresRegContext |
50 eFlagProcessMustBeLaunched |
51 eFlagProcessMustBePaused ),
52 m_option_group (interpreter),
53 m_format_options (eFormatDefault),
54 m_command_options ()
55 {
56 CommandArgumentEntry arg;
57 CommandArgumentData register_arg;
58
59 // Define the first (and only) variant of this arg.
60 register_arg.arg_type = eArgTypeRegisterName;
61 register_arg.arg_repetition = eArgRepeatStar;
62
63 // There is only one variant this argument could be; put it into the argument entry.
64 arg.push_back (register_arg);
65
66 // Push the data for the first argument into the m_arguments vector.
67 m_arguments.push_back (arg);
68
69 // Add the "--format"
70 m_option_group.Append (&m_format_options, OptionGroupFormat::OPTION_GROUP_FORMAT | OptionGroupFormat::OPTION_GROUP_GDB_FMT, LLDB_OPT_SET_ALL);
71 m_option_group.Append (&m_command_options);
72 m_option_group.Finalize();
73
74 }
75
76 virtual
~CommandObjectRegisterRead()77 ~CommandObjectRegisterRead ()
78 {
79 }
80
81 Options *
GetOptions()82 GetOptions ()
83 {
84 return &m_option_group;
85 }
86
87 bool
DumpRegister(const ExecutionContext & exe_ctx,Stream & strm,RegisterContext * reg_ctx,const RegisterInfo * reg_info)88 DumpRegister (const ExecutionContext &exe_ctx,
89 Stream &strm,
90 RegisterContext *reg_ctx,
91 const RegisterInfo *reg_info)
92 {
93 if (reg_info)
94 {
95 RegisterValue reg_value;
96
97 if (reg_ctx->ReadRegister (reg_info, reg_value))
98 {
99 strm.Indent ();
100
101 bool prefix_with_altname = m_command_options.alternate_name;
102 bool prefix_with_name = !prefix_with_altname;
103 reg_value.Dump(&strm, reg_info, prefix_with_name, prefix_with_altname, m_format_options.GetFormat(), 8);
104 if ((reg_info->encoding == eEncodingUint) || (reg_info->encoding == eEncodingSint))
105 {
106 Process *process = exe_ctx.GetProcessPtr();
107 if (process && reg_info->byte_size == process->GetAddressByteSize())
108 {
109 addr_t reg_addr = reg_value.GetAsUInt64(LLDB_INVALID_ADDRESS);
110 if (reg_addr != LLDB_INVALID_ADDRESS)
111 {
112 Address so_reg_addr;
113 if (exe_ctx.GetTargetRef().GetSectionLoadList().ResolveLoadAddress(reg_addr, so_reg_addr))
114 {
115 strm.PutCString (" ");
116 so_reg_addr.Dump(&strm, exe_ctx.GetBestExecutionContextScope(), Address::DumpStyleResolvedDescription);
117 }
118 }
119 }
120 }
121 strm.EOL();
122 return true;
123 }
124 }
125 return false;
126 }
127
128 bool
DumpRegisterSet(const ExecutionContext & exe_ctx,Stream & strm,RegisterContext * reg_ctx,size_t set_idx,bool primitive_only=false)129 DumpRegisterSet (const ExecutionContext &exe_ctx,
130 Stream &strm,
131 RegisterContext *reg_ctx,
132 size_t set_idx,
133 bool primitive_only=false)
134 {
135 uint32_t unavailable_count = 0;
136 uint32_t available_count = 0;
137
138 if (!reg_ctx)
139 return false; // thread has no registers (i.e. core files are corrupt, incomplete crash logs...)
140
141 const RegisterSet * const reg_set = reg_ctx->GetRegisterSet(set_idx);
142 if (reg_set)
143 {
144 strm.Printf ("%s:\n", reg_set->name);
145 strm.IndentMore ();
146 const size_t num_registers = reg_set->num_registers;
147 for (size_t reg_idx = 0; reg_idx < num_registers; ++reg_idx)
148 {
149 const uint32_t reg = reg_set->registers[reg_idx];
150 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex(reg);
151 // Skip the dumping of derived register if primitive_only is true.
152 if (primitive_only && reg_info && reg_info->value_regs)
153 continue;
154
155 if (DumpRegister (exe_ctx, strm, reg_ctx, reg_info))
156 ++available_count;
157 else
158 ++unavailable_count;
159 }
160 strm.IndentLess ();
161 if (unavailable_count)
162 {
163 strm.Indent ();
164 strm.Printf("%u registers were unavailable.\n", unavailable_count);
165 }
166 strm.EOL();
167 }
168 return available_count > 0;
169 }
170
171 protected:
172 virtual bool
DoExecute(Args & command,CommandReturnObject & result)173 DoExecute (Args& command, CommandReturnObject &result)
174 {
175 Stream &strm = result.GetOutputStream();
176 RegisterContext *reg_ctx = m_exe_ctx.GetRegisterContext ();
177
178 const RegisterInfo *reg_info = NULL;
179 if (command.GetArgumentCount() == 0)
180 {
181 size_t set_idx;
182
183 size_t num_register_sets = 1;
184 const size_t set_array_size = m_command_options.set_indexes.GetSize();
185 if (set_array_size > 0)
186 {
187 for (size_t i=0; i<set_array_size; ++i)
188 {
189 set_idx = m_command_options.set_indexes[i]->GetUInt64Value (UINT32_MAX, NULL);
190 if (set_idx < reg_ctx->GetRegisterSetCount())
191 {
192 if (!DumpRegisterSet (m_exe_ctx, strm, reg_ctx, set_idx))
193 {
194 if (errno)
195 result.AppendErrorWithFormat ("register read failed with errno: %d\n", errno);
196 else
197 result.AppendError ("unknown error while reading registers.\n");
198 result.SetStatus (eReturnStatusFailed);
199 break;
200 }
201 }
202 else
203 {
204 result.AppendErrorWithFormat ("invalid register set index: %zu\n", set_idx);
205 result.SetStatus (eReturnStatusFailed);
206 break;
207 }
208 }
209 }
210 else
211 {
212 if (m_command_options.dump_all_sets)
213 num_register_sets = reg_ctx->GetRegisterSetCount();
214
215 for (set_idx = 0; set_idx < num_register_sets; ++set_idx)
216 {
217 // When dump_all_sets option is set, dump primitive as well as derived registers.
218 DumpRegisterSet (m_exe_ctx, strm, reg_ctx, set_idx, !m_command_options.dump_all_sets.GetCurrentValue());
219 }
220 }
221 }
222 else
223 {
224 if (m_command_options.dump_all_sets)
225 {
226 result.AppendError ("the --all option can't be used when registers names are supplied as arguments\n");
227 result.SetStatus (eReturnStatusFailed);
228 }
229 else if (m_command_options.set_indexes.GetSize() > 0)
230 {
231 result.AppendError ("the --set <set> option can't be used when registers names are supplied as arguments\n");
232 result.SetStatus (eReturnStatusFailed);
233 }
234 else
235 {
236 const char *arg_cstr;
237 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
238 {
239 // in most LLDB commands we accept $rbx as the name for register RBX - and here we would
240 // reject it and non-existant. we should be more consistent towards the user and allow them
241 // to say reg read $rbx - internally, however, we should be strict and not allow ourselves
242 // to call our registers $rbx in our own API
243 if (*arg_cstr == '$')
244 arg_cstr = arg_cstr+1;
245 reg_info = reg_ctx->GetRegisterInfoByName(arg_cstr);
246
247 if (reg_info)
248 {
249 if (!DumpRegister (m_exe_ctx, strm, reg_ctx, reg_info))
250 strm.Printf("%-12s = error: unavailable\n", reg_info->name);
251 }
252 else
253 {
254 result.AppendErrorWithFormat ("Invalid register name '%s'.\n", arg_cstr);
255 }
256 }
257 }
258 }
259 return result.Succeeded();
260 }
261
262 class CommandOptions : public OptionGroup
263 {
264 public:
CommandOptions()265 CommandOptions () :
266 OptionGroup(),
267 set_indexes (OptionValue::ConvertTypeToMask (OptionValue::eTypeUInt64)),
268 dump_all_sets (false, false), // Initial and default values are false
269 alternate_name (false, false)
270 {
271 }
272
273 virtual
~CommandOptions()274 ~CommandOptions ()
275 {
276 }
277
278
279 virtual uint32_t
280 GetNumDefinitions ();
281
282 virtual const OptionDefinition*
GetDefinitions()283 GetDefinitions ()
284 {
285 return g_option_table;
286 }
287
288 virtual void
OptionParsingStarting(CommandInterpreter & interpreter)289 OptionParsingStarting (CommandInterpreter &interpreter)
290 {
291 set_indexes.Clear();
292 dump_all_sets.Clear();
293 alternate_name.Clear();
294 }
295
296 virtual Error
SetOptionValue(CommandInterpreter & interpreter,uint32_t option_idx,const char * option_value)297 SetOptionValue (CommandInterpreter &interpreter,
298 uint32_t option_idx,
299 const char *option_value)
300 {
301 Error error;
302 const int short_option = g_option_table[option_idx].short_option;
303 switch (short_option)
304 {
305 case 's':
306 {
307 OptionValueSP value_sp (OptionValueUInt64::Create (option_value, error));
308 if (value_sp)
309 set_indexes.AppendValue (value_sp);
310 }
311 break;
312
313 case 'a':
314 // When we don't use OptionValue::SetValueFromCString(const char *) to
315 // set an option value, it won't be marked as being set in the options
316 // so we make a call to let users know the value was set via option
317 dump_all_sets.SetCurrentValue (true);
318 dump_all_sets.SetOptionWasSet ();
319 break;
320
321 case 'A':
322 // When we don't use OptionValue::SetValueFromCString(const char *) to
323 // set an option value, it won't be marked as being set in the options
324 // so we make a call to let users know the value was set via option
325 alternate_name.SetCurrentValue (true);
326 dump_all_sets.SetOptionWasSet ();
327 break;
328
329 default:
330 error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option);
331 break;
332 }
333 return error;
334 }
335
336 // Options table: Required for subclasses of Options.
337
338 static const OptionDefinition g_option_table[];
339
340 // Instance variables to hold the values for command options.
341 OptionValueArray set_indexes;
342 OptionValueBoolean dump_all_sets;
343 OptionValueBoolean alternate_name;
344 };
345
346 OptionGroupOptions m_option_group;
347 OptionGroupFormat m_format_options;
348 CommandOptions m_command_options;
349 };
350
351 const OptionDefinition
352 CommandObjectRegisterRead::CommandOptions::g_option_table[] =
353 {
354 { LLDB_OPT_SET_ALL, false, "alternate", 'A', no_argument , NULL, 0, eArgTypeNone , "Display register names using the alternate register name if there is one."},
355 { LLDB_OPT_SET_1 , false, "set" , 's', required_argument, NULL, 0, eArgTypeIndex , "Specify which register sets to dump by index."},
356 { LLDB_OPT_SET_2 , false, "all" , 'a', no_argument , NULL, 0, eArgTypeNone , "Show all register sets."},
357 };
358
359 uint32_t
GetNumDefinitions()360 CommandObjectRegisterRead::CommandOptions::GetNumDefinitions ()
361 {
362 return sizeof(g_option_table)/sizeof(OptionDefinition);
363 }
364
365
366 //----------------------------------------------------------------------
367 // "register write"
368 //----------------------------------------------------------------------
369 class CommandObjectRegisterWrite : public CommandObjectParsed
370 {
371 public:
CommandObjectRegisterWrite(CommandInterpreter & interpreter)372 CommandObjectRegisterWrite (CommandInterpreter &interpreter) :
373 CommandObjectParsed (interpreter,
374 "register write",
375 "Modify a single register value.",
376 NULL,
377 eFlagRequiresFrame |
378 eFlagRequiresRegContext |
379 eFlagProcessMustBeLaunched |
380 eFlagProcessMustBePaused)
381 {
382 CommandArgumentEntry arg1;
383 CommandArgumentEntry arg2;
384 CommandArgumentData register_arg;
385 CommandArgumentData value_arg;
386
387 // Define the first (and only) variant of this arg.
388 register_arg.arg_type = eArgTypeRegisterName;
389 register_arg.arg_repetition = eArgRepeatPlain;
390
391 // There is only one variant this argument could be; put it into the argument entry.
392 arg1.push_back (register_arg);
393
394 // Define the first (and only) variant of this arg.
395 value_arg.arg_type = eArgTypeValue;
396 value_arg.arg_repetition = eArgRepeatPlain;
397
398 // There is only one variant this argument could be; put it into the argument entry.
399 arg2.push_back (value_arg);
400
401 // Push the data for the first argument into the m_arguments vector.
402 m_arguments.push_back (arg1);
403 m_arguments.push_back (arg2);
404 }
405
406 virtual
~CommandObjectRegisterWrite()407 ~CommandObjectRegisterWrite ()
408 {
409 }
410
411 protected:
412 virtual bool
DoExecute(Args & command,CommandReturnObject & result)413 DoExecute(Args& command, CommandReturnObject &result)
414 {
415 DataExtractor reg_data;
416 RegisterContext *reg_ctx = m_exe_ctx.GetRegisterContext ();
417
418 if (command.GetArgumentCount() != 2)
419 {
420 result.AppendError ("register write takes exactly 2 arguments: <reg-name> <value>");
421 result.SetStatus (eReturnStatusFailed);
422 }
423 else
424 {
425 const char *reg_name = command.GetArgumentAtIndex(0);
426 const char *value_str = command.GetArgumentAtIndex(1);
427
428
429 // in most LLDB commands we accept $rbx as the name for register RBX - and here we would
430 // reject it and non-existant. we should be more consistent towards the user and allow them
431 // to say reg write $rbx - internally, however, we should be strict and not allow ourselves
432 // to call our registers $rbx in our own API
433 if (reg_name && *reg_name == '$')
434 reg_name = reg_name+1;
435
436 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(reg_name);
437
438 if (reg_info)
439 {
440 RegisterValue reg_value;
441
442 Error error (reg_value.SetValueFromCString (reg_info, value_str));
443 if (error.Success())
444 {
445 if (reg_ctx->WriteRegister (reg_info, reg_value))
446 {
447 // Toss all frames and anything else in the thread
448 // after a register has been written.
449 m_exe_ctx.GetThreadRef().Flush();
450 result.SetStatus (eReturnStatusSuccessFinishNoResult);
451 return true;
452 }
453 }
454 if (error.AsCString())
455 {
456 result.AppendErrorWithFormat ("Failed to write register '%s' with value '%s': %s\n",
457 reg_name,
458 value_str,
459 error.AsCString());
460 }
461 else
462 {
463 result.AppendErrorWithFormat ("Failed to write register '%s' with value '%s'",
464 reg_name,
465 value_str);
466 }
467 result.SetStatus (eReturnStatusFailed);
468 }
469 else
470 {
471 result.AppendErrorWithFormat ("Register not found for '%s'.\n", reg_name);
472 result.SetStatus (eReturnStatusFailed);
473 }
474 }
475 return result.Succeeded();
476 }
477 };
478
479
480 //----------------------------------------------------------------------
481 // CommandObjectRegister constructor
482 //----------------------------------------------------------------------
CommandObjectRegister(CommandInterpreter & interpreter)483 CommandObjectRegister::CommandObjectRegister(CommandInterpreter &interpreter) :
484 CommandObjectMultiword (interpreter,
485 "register",
486 "A set of commands to access thread registers.",
487 "register [read|write] ...")
488 {
489 LoadSubCommand ("read", CommandObjectSP (new CommandObjectRegisterRead (interpreter)));
490 LoadSubCommand ("write", CommandObjectSP (new CommandObjectRegisterWrite (interpreter)));
491 }
492
493
494 //----------------------------------------------------------------------
495 // Destructor
496 //----------------------------------------------------------------------
~CommandObjectRegister()497 CommandObjectRegister::~CommandObjectRegister()
498 {
499 }
500