]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - contrib/llvm/tools/lldb/source/Commands/CommandObjectRegister.cpp
Copy head (r256279) to stable/10 as part of the 10.0-RELEASE cycle.
[FreeBSD/stable/10.git] / contrib / llvm / tools / lldb / source / Commands / CommandObjectRegister.cpp
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:
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
77     ~CommandObjectRegisterRead ()
78     {
79     }
80
81     Options *
82     GetOptions ()
83     {
84         return &m_option_group;
85     }
86
87     bool
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
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
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:
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
274         ~CommandOptions ()
275         {
276         }
277         
278         
279         virtual uint32_t
280         GetNumDefinitions ();
281
282         virtual const OptionDefinition*
283         GetDefinitions ()
284         {
285             return g_option_table;
286         }
287         
288         virtual void
289         OptionParsingStarting (CommandInterpreter &interpreter)
290         {
291             set_indexes.Clear();
292             dump_all_sets.Clear();
293             alternate_name.Clear();
294         }
295
296         virtual Error
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
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:
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
407     ~CommandObjectRegisterWrite ()
408     {
409     }
410
411 protected:
412     virtual bool
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 //----------------------------------------------------------------------
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 //----------------------------------------------------------------------
497 CommandObjectRegister::~CommandObjectRegister()
498 {
499 }