1 // Copyright 2014, ARM Limited
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are met:
6 //
7 //   * Redistributions of source code must retain the above copyright notice,
8 //     this list of conditions and the following disclaimer.
9 //   * Redistributions in binary form must reproduce the above copyright notice,
10 //     this list of conditions and the following disclaimer in the documentation
11 //     and/or other materials provided with the distribution.
12 //   * Neither the name of ARM Limited nor the names of its contributors may be
13 //     used to endorse or promote products derived from this software without
14 //     specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY ARM LIMITED AND CONTRIBUTORS "AS IS" AND ANY
17 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 // DISCLAIMED. IN NO EVENT SHALL ARM LIMITED BE LIABLE FOR ANY DIRECT, INDIRECT,
20 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
22 // OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
25 // EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 
27 #ifdef USE_SIMULATOR
28 
29 #include "vixl/a64/debugger-a64.h"
30 
31 namespace vixl {
32 
33 // List of commands supported by the debugger.
34 #define DEBUG_COMMAND_LIST(C)  \
35 C(HelpCommand)                 \
36 C(ContinueCommand)             \
37 C(StepCommand)                 \
38 C(DisasmCommand)               \
39 C(PrintCommand)                \
40 C(ExamineCommand)
41 
42 // Debugger command lines are broken up in token of different type to make
43 // processing easier later on.
44 class Token {
45  public:
~Token()46   virtual ~Token() {}
47 
48   // Token type.
IsRegister() const49   virtual bool IsRegister() const { return false; }
IsFPRegister() const50   virtual bool IsFPRegister() const { return false; }
IsIdentifier() const51   virtual bool IsIdentifier() const { return false; }
IsAddress() const52   virtual bool IsAddress() const { return false; }
IsInteger() const53   virtual bool IsInteger() const { return false; }
IsFormat() const54   virtual bool IsFormat() const { return false; }
IsUnknown() const55   virtual bool IsUnknown() const { return false; }
56   // Token properties.
CanAddressMemory() const57   virtual bool CanAddressMemory() const { return false; }
58   virtual uint8_t* ToAddress(Debugger* debugger) const;
59   virtual void Print(FILE* out = stdout) const = 0;
60 
61   static Token* Tokenize(const char* arg);
62 };
63 
64 // Tokens often hold one value.
65 template<typename T> class ValueToken : public Token {
66  public:
ValueToken(T value)67   explicit ValueToken(T value) : value_(value) {}
ValueToken()68   ValueToken() {}
69 
value() const70   T value() const { return value_; }
71 
72  protected:
73   T value_;
74 };
75 
76 // Integer registers (X or W) and their aliases.
77 // Format: wn or xn with 0 <= n < 32 or a name in the aliases list.
78 class RegisterToken : public ValueToken<const Register> {
79  public:
RegisterToken(const Register reg)80   explicit RegisterToken(const Register reg)
81       : ValueToken<const Register>(reg) {}
82 
IsRegister() const83   virtual bool IsRegister() const { return true; }
CanAddressMemory() const84   virtual bool CanAddressMemory() const { return value().Is64Bits(); }
85   virtual uint8_t* ToAddress(Debugger* debugger) const;
86   virtual void Print(FILE* out = stdout) const ;
87   const char* Name() const;
88 
89   static Token* Tokenize(const char* arg);
Cast(Token * tok)90   static RegisterToken* Cast(Token* tok) {
91     VIXL_ASSERT(tok->IsRegister());
92     return reinterpret_cast<RegisterToken*>(tok);
93   }
94 
95  private:
96   static const int kMaxAliasNumber = 4;
97   static const char* kXAliases[kNumberOfRegisters][kMaxAliasNumber];
98   static const char* kWAliases[kNumberOfRegisters][kMaxAliasNumber];
99 };
100 
101 // Floating point registers (D or S).
102 // Format: sn or dn with 0 <= n < 32.
103 class FPRegisterToken : public ValueToken<const FPRegister> {
104  public:
FPRegisterToken(const FPRegister fpreg)105   explicit FPRegisterToken(const FPRegister fpreg)
106       : ValueToken<const FPRegister>(fpreg) {}
107 
IsFPRegister() const108   virtual bool IsFPRegister() const { return true; }
109   virtual void Print(FILE* out = stdout) const ;
110 
111   static Token* Tokenize(const char* arg);
Cast(Token * tok)112   static FPRegisterToken* Cast(Token* tok) {
113     VIXL_ASSERT(tok->IsFPRegister());
114     return reinterpret_cast<FPRegisterToken*>(tok);
115   }
116 };
117 
118 
119 // Non-register identifiers.
120 // Format: Alphanumeric string starting with a letter.
121 class IdentifierToken : public ValueToken<char*> {
122  public:
IdentifierToken(const char * name)123   explicit IdentifierToken(const char* name) {
124     int size = strlen(name) + 1;
125     value_ = new char[size];
126     strncpy(value_, name, size);
127   }
~IdentifierToken()128   virtual ~IdentifierToken() { delete[] value_; }
129 
IsIdentifier() const130   virtual bool IsIdentifier() const { return true; }
CanAddressMemory() const131   virtual bool CanAddressMemory() const { return strcmp(value(), "pc") == 0; }
132   virtual uint8_t* ToAddress(Debugger* debugger) const;
133   virtual void Print(FILE* out = stdout) const;
134 
135   static Token* Tokenize(const char* arg);
Cast(Token * tok)136   static IdentifierToken* Cast(Token* tok) {
137     VIXL_ASSERT(tok->IsIdentifier());
138     return reinterpret_cast<IdentifierToken*>(tok);
139   }
140 };
141 
142 // 64-bit address literal.
143 // Format: 0x... with up to 16 hexadecimal digits.
144 class AddressToken : public ValueToken<uint8_t*> {
145  public:
AddressToken(uint8_t * address)146   explicit AddressToken(uint8_t* address) : ValueToken<uint8_t*>(address) {}
147 
IsAddress() const148   virtual bool IsAddress() const { return true; }
CanAddressMemory() const149   virtual bool CanAddressMemory() const { return true; }
150   virtual uint8_t* ToAddress(Debugger* debugger) const;
151   virtual void Print(FILE* out = stdout) const ;
152 
153   static Token* Tokenize(const char* arg);
Cast(Token * tok)154   static AddressToken* Cast(Token* tok) {
155     VIXL_ASSERT(tok->IsAddress());
156     return reinterpret_cast<AddressToken*>(tok);
157   }
158 };
159 
160 
161 // 64-bit decimal integer literal.
162 // Format: n.
163 class IntegerToken : public ValueToken<int64_t> {
164  public:
IntegerToken(int value)165   explicit IntegerToken(int value) : ValueToken<int64_t>(value) {}
166 
IsInteger() const167   virtual bool IsInteger() const { return true; }
168   virtual void Print(FILE* out = stdout) const;
169 
170   static Token* Tokenize(const char* arg);
Cast(Token * tok)171   static IntegerToken* Cast(Token* tok) {
172     VIXL_ASSERT(tok->IsInteger());
173     return reinterpret_cast<IntegerToken*>(tok);
174   }
175 };
176 
177 // Literal describing how to print a chunk of data (up to 64 bits).
178 // Format: .ln
179 // where l (letter) is one of
180 //  * x: hexadecimal
181 //  * s: signed integer
182 //  * u: unsigned integer
183 //  * f: floating point
184 //  * i: instruction
185 // and n (size) is one of 8, 16, 32 and 64. n should be omitted for
186 // instructions.
187 class FormatToken : public Token {
188  public:
FormatToken()189   FormatToken() {}
190 
IsFormat() const191   virtual bool IsFormat() const { return true; }
192   virtual int SizeOf() const = 0;
193   virtual char type_code() const = 0;
194   virtual void PrintData(void* data, FILE* out = stdout) const = 0;
195   virtual void Print(FILE* out = stdout) const = 0;
196 
197   static Token* Tokenize(const char* arg);
Cast(Token * tok)198   static FormatToken* Cast(Token* tok) {
199     VIXL_ASSERT(tok->IsFormat());
200     return reinterpret_cast<FormatToken*>(tok);
201   }
202 };
203 
204 
205 template<typename T> class Format : public FormatToken {
206  public:
Format(const char * fmt,char type_code)207   Format(const char* fmt, char type_code) : fmt_(fmt), type_code_(type_code) {}
208 
SizeOf() const209   virtual int SizeOf() const { return sizeof(T); }
type_code() const210   virtual char type_code() const { return type_code_; }
PrintData(void * data,FILE * out=stdout) const211   virtual void PrintData(void* data, FILE* out = stdout) const {
212     T value;
213     memcpy(&value, data, sizeof(value));
214     fprintf(out, fmt_, value);
215   }
216   virtual void Print(FILE* out = stdout) const;
217 
218  private:
219   const char* fmt_;
220   char type_code_;
221 };
222 
223 // Tokens which don't fit any of the above.
224 class UnknownToken : public Token {
225  public:
UnknownToken(const char * arg)226   explicit UnknownToken(const char* arg) {
227     int size = strlen(arg) + 1;
228     unknown_ = new char[size];
229     strncpy(unknown_, arg, size);
230   }
~UnknownToken()231   virtual ~UnknownToken() { delete[] unknown_; }
232 
IsUnknown() const233   virtual bool IsUnknown() const { return true; }
234   virtual void Print(FILE* out = stdout) const;
235 
236  private:
237   char* unknown_;
238 };
239 
240 
241 // All debugger commands must subclass DebugCommand and implement Run, Print
242 // and Build. Commands must also define kHelp and kAliases.
243 class DebugCommand {
244  public:
DebugCommand(Token * name)245   explicit DebugCommand(Token* name) : name_(IdentifierToken::Cast(name)) {}
DebugCommand()246   DebugCommand() : name_(NULL) {}
~DebugCommand()247   virtual ~DebugCommand() { delete name_; }
248 
name()249   const char* name() { return name_->value(); }
250   // Run the command on the given debugger. The command returns true if
251   // execution should move to the next instruction.
252   virtual bool Run(Debugger * debugger) = 0;
253   virtual void Print(FILE* out = stdout);
254 
255   static bool Match(const char* name, const char** aliases);
256   static DebugCommand* Parse(char* line);
257   static void PrintHelp(const char** aliases,
258                         const char* args,
259                         const char* help);
260 
261  private:
262   IdentifierToken* name_;
263 };
264 
265 // For all commands below see their respective kHelp and kAliases in
266 // debugger-a64.cc
267 class HelpCommand : public DebugCommand {
268  public:
HelpCommand(Token * name)269   explicit HelpCommand(Token* name) : DebugCommand(name) {}
270 
271   virtual bool Run(Debugger* debugger);
272 
273   static DebugCommand* Build(std::vector<Token*> args);
274 
275   static const char* kHelp;
276   static const char* kAliases[];
277   static const char* kArguments;
278 };
279 
280 
281 class ContinueCommand : public DebugCommand {
282  public:
ContinueCommand(Token * name)283   explicit ContinueCommand(Token* name) : DebugCommand(name) {}
284 
285   virtual bool Run(Debugger* debugger);
286 
287   static DebugCommand* Build(std::vector<Token*> args);
288 
289   static const char* kHelp;
290   static const char* kAliases[];
291   static const char* kArguments;
292 };
293 
294 
295 class StepCommand : public DebugCommand {
296  public:
StepCommand(Token * name,IntegerToken * count)297   StepCommand(Token* name, IntegerToken* count)
298       : DebugCommand(name), count_(count) {}
~StepCommand()299   virtual ~StepCommand() { delete count_; }
300 
count()301   int64_t count() { return count_->value(); }
302   virtual bool Run(Debugger* debugger);
303   virtual void Print(FILE* out = stdout);
304 
305   static DebugCommand* Build(std::vector<Token*> args);
306 
307   static const char* kHelp;
308   static const char* kAliases[];
309   static const char* kArguments;
310 
311  private:
312   IntegerToken* count_;
313 };
314 
315 class DisasmCommand : public DebugCommand {
316  public:
317   static DebugCommand* Build(std::vector<Token*> args);
318 
319   static const char* kHelp;
320   static const char* kAliases[];
321   static const char* kArguments;
322 };
323 
324 
325 class PrintCommand : public DebugCommand {
326  public:
PrintCommand(Token * name,Token * target,FormatToken * format)327   PrintCommand(Token* name, Token* target, FormatToken* format)
328       : DebugCommand(name), target_(target), format_(format) {}
~PrintCommand()329   virtual ~PrintCommand() {
330     delete target_;
331     delete format_;
332   }
333 
target()334   Token* target() { return target_; }
format()335   FormatToken* format() { return format_; }
336   virtual bool Run(Debugger* debugger);
337   virtual void Print(FILE* out = stdout);
338 
339   static DebugCommand* Build(std::vector<Token*> args);
340 
341   static const char* kHelp;
342   static const char* kAliases[];
343   static const char* kArguments;
344 
345  private:
346   Token* target_;
347   FormatToken* format_;
348 };
349 
350 class ExamineCommand : public DebugCommand {
351  public:
ExamineCommand(Token * name,Token * target,FormatToken * format,IntegerToken * count)352   ExamineCommand(Token* name,
353                  Token* target,
354                  FormatToken* format,
355                  IntegerToken* count)
356       : DebugCommand(name), target_(target), format_(format), count_(count) {}
~ExamineCommand()357   virtual ~ExamineCommand() {
358     delete target_;
359     delete format_;
360     delete count_;
361   }
362 
target()363   Token* target() { return target_; }
format()364   FormatToken* format() { return format_; }
count()365   IntegerToken* count() { return count_; }
366   virtual bool Run(Debugger* debugger);
367   virtual void Print(FILE* out = stdout);
368 
369   static DebugCommand* Build(std::vector<Token*> args);
370 
371   static const char* kHelp;
372   static const char* kAliases[];
373   static const char* kArguments;
374 
375  private:
376   Token* target_;
377   FormatToken* format_;
378   IntegerToken* count_;
379 };
380 
381 // Commands which name does not match any of the known commnand.
382 class UnknownCommand : public DebugCommand {
383  public:
UnknownCommand(std::vector<Token * > args)384   explicit UnknownCommand(std::vector<Token*> args) : args_(args) {}
385   virtual ~UnknownCommand();
386 
387   virtual bool Run(Debugger* debugger);
388 
389  private:
390   std::vector<Token*> args_;
391 };
392 
393 // Commands which name match a known command but the syntax is invalid.
394 class InvalidCommand : public DebugCommand {
395  public:
InvalidCommand(std::vector<Token * > args,int index,const char * cause)396   InvalidCommand(std::vector<Token*> args, int index, const char* cause)
397       : args_(args), index_(index), cause_(cause) {}
398   virtual ~InvalidCommand();
399 
400   virtual bool Run(Debugger* debugger);
401 
402  private:
403   std::vector<Token*> args_;
404   int index_;
405   const char* cause_;
406 };
407 
408 const char* HelpCommand::kAliases[] = { "help", NULL };
409 const char* HelpCommand::kArguments = NULL;
410 const char* HelpCommand::kHelp = "  Print this help.";
411 
412 const char* ContinueCommand::kAliases[] = { "continue", "c", NULL };
413 const char* ContinueCommand::kArguments = NULL;
414 const char* ContinueCommand::kHelp = "  Resume execution.";
415 
416 const char* StepCommand::kAliases[] = { "stepi", "si", NULL };
417 const char* StepCommand::kArguments = "[n = 1]";
418 const char* StepCommand::kHelp = "  Execute n next instruction(s).";
419 
420 const char* DisasmCommand::kAliases[] = { "disasm", "di", NULL };
421 const char* DisasmCommand::kArguments = "[n = 10]";
422 const char* DisasmCommand::kHelp =
423   "  Disassemble n instruction(s) at pc.\n"
424   "  This command is equivalent to x pc.i [n = 10]."
425 ;
426 
427 const char* PrintCommand::kAliases[] = { "print", "p", NULL };
428 const char* PrintCommand::kArguments =  "<entity>[.format]";
429 const char* PrintCommand::kHelp =
430   "  Print the given entity according to the given format.\n"
431   "  The format parameter only affects individual registers; it is ignored\n"
432   "  for other entities.\n"
433   "  <entity> can be one of the following:\n"
434   "   * A register name (such as x0, s1, ...).\n"
435   "   * 'regs', to print all integer (W and X) registers.\n"
436   "   * 'fpregs' to print all floating-point (S and D) registers.\n"
437   "   * 'sysregs' to print all system registers (including NZCV).\n"
438   "   * 'pc' to print the current program counter.\n"
439 ;
440 
441 const char* ExamineCommand::kAliases[] = { "m", "mem", "x", NULL };
442 const char* ExamineCommand::kArguments = "<addr>[.format] [n = 10]";
443 const char* ExamineCommand::kHelp =
444   "  Examine memory. Print n items of memory at address <addr> according to\n"
445   "  the given [.format].\n"
446   "  Addr can be an immediate address, a register name or pc.\n"
447   "  Format is made of a type letter: 'x' (hexadecimal), 's' (signed), 'u'\n"
448   "  (unsigned), 'f' (floating point), i (instruction) and a size in bits\n"
449   "  when appropriate (8, 16, 32, 64)\n"
450   "  E.g 'x sp.x64' will print 10 64-bit words from the stack in\n"
451   "  hexadecimal format."
452 ;
453 
454 const char* RegisterToken::kXAliases[kNumberOfRegisters][kMaxAliasNumber] = {
455   { "x0", NULL },
456   { "x1", NULL },
457   { "x2", NULL },
458   { "x3", NULL },
459   { "x4", NULL },
460   { "x5", NULL },
461   { "x6", NULL },
462   { "x7", NULL },
463   { "x8", NULL },
464   { "x9", NULL },
465   { "x10", NULL },
466   { "x11", NULL },
467   { "x12", NULL },
468   { "x13", NULL },
469   { "x14", NULL },
470   { "x15", NULL },
471   { "ip0", "x16", NULL },
472   { "ip1", "x17", NULL },
473   { "x18", "pr", NULL },
474   { "x19", NULL },
475   { "x20", NULL },
476   { "x21", NULL },
477   { "x22", NULL },
478   { "x23", NULL },
479   { "x24", NULL },
480   { "x25", NULL },
481   { "x26", NULL },
482   { "x27", NULL },
483   { "x28", NULL },
484   { "fp", "x29", NULL },
485   { "lr", "x30", NULL },
486   { "sp", NULL}
487 };
488 
489 const char* RegisterToken::kWAliases[kNumberOfRegisters][kMaxAliasNumber] = {
490   { "w0", NULL },
491   { "w1", NULL },
492   { "w2", NULL },
493   { "w3", NULL },
494   { "w4", NULL },
495   { "w5", NULL },
496   { "w6", NULL },
497   { "w7", NULL },
498   { "w8", NULL },
499   { "w9", NULL },
500   { "w10", NULL },
501   { "w11", NULL },
502   { "w12", NULL },
503   { "w13", NULL },
504   { "w14", NULL },
505   { "w15", NULL },
506   { "w16", NULL },
507   { "w17", NULL },
508   { "w18", NULL },
509   { "w19", NULL },
510   { "w20", NULL },
511   { "w21", NULL },
512   { "w22", NULL },
513   { "w23", NULL },
514   { "w24", NULL },
515   { "w25", NULL },
516   { "w26", NULL },
517   { "w27", NULL },
518   { "w28", NULL },
519   { "w29", NULL },
520   { "w30", NULL },
521   { "wsp", NULL }
522 };
523 
524 
Debugger(Decoder * decoder,FILE * stream)525 Debugger::Debugger(Decoder* decoder, FILE* stream)
526     : Simulator(decoder, stream),
527       debug_parameters_(DBG_INACTIVE),
528       pending_request_(false),
529       steps_(0),
530       last_command_(NULL) {
531   disasm_ = new PrintDisassembler(stdout);
532   printer_ = new Decoder();
533   printer_->AppendVisitor(disasm_);
534 }
535 
~Debugger()536 Debugger::~Debugger() {
537   delete disasm_;
538   delete printer_;
539 }
540 
541 
Run()542 void Debugger::Run() {
543   pc_modified_ = false;
544   while (pc_ != kEndOfSimAddress) {
545     if (pending_request()) RunDebuggerShell();
546     ExecuteInstruction();
547     LogAllWrittenRegisters();
548   }
549 }
550 
551 
PrintInstructions(const void * address,int64_t count)552 void Debugger::PrintInstructions(const void* address, int64_t count) {
553   if (count == 0) {
554     return;
555   }
556 
557   const Instruction* from = Instruction::CastConst(address);
558   if (count < 0) {
559     count = -count;
560     from -= (count - 1) * kInstructionSize;
561   }
562   const Instruction* to = from + count * kInstructionSize;
563 
564   for (const Instruction* current = from;
565        current < to;
566        current = current->NextInstruction()) {
567     printer_->Decode(current);
568   }
569 }
570 
571 
PrintMemory(const uint8_t * address,const FormatToken * format,int64_t count)572 void Debugger::PrintMemory(const uint8_t* address,
573                            const FormatToken* format,
574                            int64_t count) {
575   if (count == 0) {
576     return;
577   }
578 
579   const uint8_t* from = address;
580   int size = format->SizeOf();
581   if (count < 0) {
582     count = -count;
583     from -= (count - 1) * size;
584   }
585   const uint8_t* to = from + count * size;
586 
587   for (const uint8_t* current = from; current < to; current += size) {
588     if (((current - from) % 8) == 0) {
589       printf("\n%p: ", current);
590     }
591 
592     uint64_t data = Memory::Read<uint64_t>(current);
593     format->PrintData(&data);
594     printf(" ");
595   }
596   printf("\n\n");
597 }
598 
599 
PrintRegister(const Register & target_reg,const char * name,const FormatToken * format)600 void Debugger::PrintRegister(const Register& target_reg,
601                              const char* name,
602                              const FormatToken* format) {
603   const uint64_t reg_size = target_reg.size();
604   const uint64_t format_size = format->SizeOf() * 8;
605   const uint64_t count = reg_size / format_size;
606   const uint64_t mask = 0xffffffffffffffff >> (64 - format_size);
607   const uint64_t reg_value = reg<uint64_t>(target_reg.code(),
608                                            Reg31IsStackPointer);
609   VIXL_ASSERT(count > 0);
610 
611   printf("%s = ", name);
612   for (uint64_t i = 1; i <= count; i++) {
613     uint64_t data = reg_value >> (reg_size - (i * format_size));
614     data &= mask;
615     format->PrintData(&data);
616     printf(" ");
617   }
618   printf("\n");
619 }
620 
621 
622 // TODO(all): fix this for vector registers.
PrintFPRegister(const FPRegister & target_fpreg,const FormatToken * format)623 void Debugger::PrintFPRegister(const FPRegister& target_fpreg,
624                                const FormatToken* format) {
625   const uint64_t fpreg_size = target_fpreg.size();
626   const uint64_t format_size = format->SizeOf() * 8;
627   const uint64_t count = fpreg_size / format_size;
628   const uint64_t mask = 0xffffffffffffffff >> (64 - format_size);
629   const uint64_t fpreg_value = vreg<uint64_t>(fpreg_size,
630                                               target_fpreg.code());
631   VIXL_ASSERT(count > 0);
632 
633   if (target_fpreg.Is32Bits()) {
634     printf("s%u = ", target_fpreg.code());
635   } else {
636     printf("d%u = ", target_fpreg.code());
637   }
638   for (uint64_t i = 1; i <= count; i++) {
639     uint64_t data = fpreg_value >> (fpreg_size - (i * format_size));
640     data &= mask;
641     format->PrintData(&data);
642     printf(" ");
643   }
644   printf("\n");
645 }
646 
647 
VisitException(const Instruction * instr)648 void Debugger::VisitException(const Instruction* instr) {
649   switch (instr->Mask(ExceptionMask)) {
650     case BRK:
651       DoBreakpoint(instr);
652       return;
653     case HLT:
654       VIXL_FALLTHROUGH();
655     default: Simulator::VisitException(instr);
656   }
657 }
658 
659 
660 // Read a command. A command will be at most kMaxDebugShellLine char long and
661 // ends with '\n\0'.
662 // TODO: Should this be a utility function?
ReadCommandLine(const char * prompt,char * buffer,int length)663 char* Debugger::ReadCommandLine(const char* prompt, char* buffer, int length) {
664   int fgets_calls = 0;
665   char* end = NULL;
666 
667   printf("%s", prompt);
668   fflush(stdout);
669 
670   do {
671     if (fgets(buffer, length, stdin) == NULL) {
672       printf(" ** Error while reading command. **\n");
673       return NULL;
674     }
675 
676     fgets_calls++;
677     end = strchr(buffer, '\n');
678   } while (end == NULL);
679 
680   if (fgets_calls != 1) {
681     printf(" ** Command too long. **\n");
682     return NULL;
683   }
684 
685   // Remove the newline from the end of the command.
686   VIXL_ASSERT(end[1] == '\0');
687   VIXL_ASSERT((end - buffer) < (length - 1));
688   end[0] = '\0';
689 
690   return buffer;
691 }
692 
693 
RunDebuggerShell()694 void Debugger::RunDebuggerShell() {
695   if (IsDebuggerRunning()) {
696     if (steps_ > 0) {
697       // Finish stepping first.
698       --steps_;
699       return;
700     }
701 
702     printf("Next: ");
703     PrintInstructions(pc());
704     bool done = false;
705     while (!done) {
706       char buffer[kMaxDebugShellLine];
707       char* line = ReadCommandLine("vixl> ", buffer, kMaxDebugShellLine);
708 
709       if (line == NULL) continue;  // An error occurred.
710 
711       DebugCommand* command = DebugCommand::Parse(line);
712       if (command != NULL) {
713         last_command_ = command;
714       }
715 
716       if (last_command_ != NULL) {
717         done = last_command_->Run(this);
718       } else {
719         printf("No previous command to run!\n");
720       }
721     }
722 
723     if ((debug_parameters_ & DBG_BREAK) != 0) {
724       // The break request has now been handled, move to next instruction.
725       debug_parameters_ &= ~DBG_BREAK;
726       increment_pc();
727     }
728   }
729 }
730 
731 
DoBreakpoint(const Instruction * instr)732 void Debugger::DoBreakpoint(const Instruction* instr) {
733   VIXL_ASSERT(instr->Mask(ExceptionMask) == BRK);
734 
735   printf("Hit breakpoint at pc=%p.\n", reinterpret_cast<const void*>(instr));
736   set_debug_parameters(debug_parameters() | DBG_BREAK | DBG_ACTIVE);
737   // Make the shell point to the brk instruction.
738   set_pc(instr);
739 }
740 
741 
StringToUInt64(uint64_t * value,const char * line,int base=10)742 static bool StringToUInt64(uint64_t* value, const char* line, int base = 10) {
743   char* endptr = NULL;
744   errno = 0;  // Reset errors.
745   uint64_t parsed = strtoul(line, &endptr, base);
746 
747   if (errno == ERANGE) {
748     // Overflow.
749     return false;
750   }
751 
752   if (endptr == line) {
753     // No digits were parsed.
754     return false;
755   }
756 
757   if (*endptr != '\0') {
758     // Non-digit characters present at the end.
759     return false;
760   }
761 
762   *value = parsed;
763   return true;
764 }
765 
766 
StringToInt64(int64_t * value,const char * line,int base=10)767 static bool StringToInt64(int64_t* value, const char* line, int base = 10) {
768   char* endptr = NULL;
769   errno = 0;  // Reset errors.
770   int64_t parsed = strtol(line, &endptr, base);
771 
772   if (errno == ERANGE) {
773     // Overflow, undeflow.
774     return false;
775   }
776 
777   if (endptr == line) {
778     // No digits were parsed.
779     return false;
780   }
781 
782   if (*endptr != '\0') {
783     // Non-digit characters present at the end.
784     return false;
785   }
786 
787   *value = parsed;
788   return true;
789 }
790 
791 
ToAddress(Debugger * debugger) const792 uint8_t* Token::ToAddress(Debugger* debugger) const {
793   USE(debugger);
794   VIXL_UNREACHABLE();
795   return NULL;
796 }
797 
798 
Tokenize(const char * arg)799 Token* Token::Tokenize(const char* arg) {
800   if ((arg == NULL) || (*arg == '\0')) {
801     return NULL;
802   }
803 
804   // The order is important. For example Identifier::Tokenize would consider
805   // any register to be a valid identifier.
806 
807   Token* token = RegisterToken::Tokenize(arg);
808   if (token != NULL) {
809     return token;
810   }
811 
812   token = FPRegisterToken::Tokenize(arg);
813   if (token != NULL) {
814     return token;
815   }
816 
817   token = IdentifierToken::Tokenize(arg);
818   if (token != NULL) {
819     return token;
820   }
821 
822   token = AddressToken::Tokenize(arg);
823   if (token != NULL) {
824     return token;
825   }
826 
827   token = IntegerToken::Tokenize(arg);
828   if (token != NULL) {
829     return token;
830   }
831 
832   return new UnknownToken(arg);
833 }
834 
835 
ToAddress(Debugger * debugger) const836 uint8_t* RegisterToken::ToAddress(Debugger* debugger) const {
837   VIXL_ASSERT(CanAddressMemory());
838   uint64_t reg_value = debugger->xreg(value().code(), Reg31IsStackPointer);
839   uint8_t* address = NULL;
840   memcpy(&address, &reg_value, sizeof(address));
841   return address;
842 }
843 
844 
Print(FILE * out) const845 void RegisterToken::Print(FILE* out) const {
846   VIXL_ASSERT(value().IsValid());
847   fprintf(out, "[Register %s]", Name());
848 }
849 
850 
Name() const851 const char* RegisterToken::Name() const {
852   if (value().Is32Bits()) {
853     return kWAliases[value().code()][0];
854   } else {
855     return kXAliases[value().code()][0];
856   }
857 }
858 
859 
Tokenize(const char * arg)860 Token* RegisterToken::Tokenize(const char* arg) {
861   for (unsigned i = 0; i < kNumberOfRegisters; i++) {
862     // Is it a X register or alias?
863     for (const char** current = kXAliases[i]; *current != NULL; current++) {
864       if (strcmp(arg, *current) == 0) {
865         return new RegisterToken(Register::XRegFromCode(i));
866       }
867     }
868 
869     // Is it a W register or alias?
870     for (const char** current = kWAliases[i]; *current != NULL; current++) {
871       if (strcmp(arg, *current) == 0) {
872         return new RegisterToken(Register::WRegFromCode(i));
873       }
874     }
875   }
876 
877   return NULL;
878 }
879 
880 
Print(FILE * out) const881 void FPRegisterToken::Print(FILE* out) const {
882   VIXL_ASSERT(value().IsValid());
883   char prefix = value().Is32Bits() ? 's' : 'd';
884   fprintf(out, "[FPRegister %c%" PRIu32 "]", prefix, value().code());
885 }
886 
887 
Tokenize(const char * arg)888 Token* FPRegisterToken::Tokenize(const char* arg) {
889   if (strlen(arg) < 2) {
890     return NULL;
891   }
892 
893   switch (*arg) {
894     case 's':
895     case 'd':
896       const char* cursor = arg + 1;
897       uint64_t code = 0;
898       if (!StringToUInt64(&code, cursor)) {
899         return NULL;
900       }
901 
902       if (code > kNumberOfFPRegisters) {
903         return NULL;
904       }
905 
906       VRegister fpreg = NoVReg;
907       switch (*arg) {
908         case 's': fpreg = VRegister::SRegFromCode(code); break;
909         case 'd': fpreg = VRegister::DRegFromCode(code); break;
910         default: VIXL_UNREACHABLE();
911       }
912 
913       return new FPRegisterToken(fpreg);
914   }
915 
916   return NULL;
917 }
918 
919 
ToAddress(Debugger * debugger) const920 uint8_t* IdentifierToken::ToAddress(Debugger* debugger) const {
921   VIXL_ASSERT(CanAddressMemory());
922   const Instruction* pc_value = debugger->pc();
923   uint8_t* address = NULL;
924   memcpy(&address, &pc_value, sizeof(address));
925   return address;
926 }
927 
Print(FILE * out) const928 void IdentifierToken::Print(FILE* out) const {
929   fprintf(out, "[Identifier %s]", value());
930 }
931 
932 
Tokenize(const char * arg)933 Token* IdentifierToken::Tokenize(const char* arg) {
934   if (!isalpha(arg[0])) {
935     return NULL;
936   }
937 
938   const char* cursor = arg + 1;
939   while ((*cursor != '\0') && isalnum(*cursor)) {
940     ++cursor;
941   }
942 
943   if (*cursor == '\0') {
944     return new IdentifierToken(arg);
945   }
946 
947   return NULL;
948 }
949 
950 
ToAddress(Debugger * debugger) const951 uint8_t* AddressToken::ToAddress(Debugger* debugger) const {
952   USE(debugger);
953   return value();
954 }
955 
956 
Print(FILE * out) const957 void AddressToken::Print(FILE* out) const {
958   fprintf(out, "[Address %p]", value());
959 }
960 
961 
Tokenize(const char * arg)962 Token* AddressToken::Tokenize(const char* arg) {
963   if ((strlen(arg) < 3) || (arg[0] != '0') || (arg[1] != 'x')) {
964     return NULL;
965   }
966 
967   uint64_t ptr = 0;
968   if (!StringToUInt64(&ptr, arg, 16)) {
969     return NULL;
970   }
971 
972   uint8_t* address = reinterpret_cast<uint8_t*>(ptr);
973   return new AddressToken(address);
974 }
975 
976 
Print(FILE * out) const977 void IntegerToken::Print(FILE* out) const {
978   fprintf(out, "[Integer %" PRId64 "]", value());
979 }
980 
981 
Tokenize(const char * arg)982 Token* IntegerToken::Tokenize(const char* arg) {
983   int64_t value = 0;
984   if (!StringToInt64(&value, arg)) {
985     return NULL;
986   }
987 
988   return new IntegerToken(value);
989 }
990 
991 
Tokenize(const char * arg)992 Token* FormatToken::Tokenize(const char* arg) {
993   int length = strlen(arg);
994   switch (arg[0]) {
995     case 'x':
996     case 's':
997     case 'u':
998     case 'f':
999       if (length == 1) return NULL;
1000       break;
1001     case 'i':
1002       if (length == 1) return new Format<uint32_t>("%08" PRIx32, 'i');
1003       VIXL_FALLTHROUGH();
1004     default: return NULL;
1005   }
1006 
1007   char* endptr = NULL;
1008   errno = 0;  // Reset errors.
1009   uint64_t count = strtoul(arg + 1, &endptr, 10);
1010 
1011   if (errno != 0) {
1012     // Overflow, etc.
1013     return NULL;
1014   }
1015 
1016   if (endptr == arg) {
1017     // No digits were parsed.
1018     return NULL;
1019   }
1020 
1021   if (*endptr != '\0') {
1022     // There are unexpected (non-digit) characters after the number.
1023     return NULL;
1024   }
1025 
1026   switch (arg[0]) {
1027     case 'x':
1028       switch (count) {
1029         case 8: return new Format<uint8_t>("%02" PRIx8, 'x');
1030         case 16: return new Format<uint16_t>("%04" PRIx16, 'x');
1031         case 32: return new Format<uint32_t>("%08" PRIx32, 'x');
1032         case 64: return new Format<uint64_t>("%016" PRIx64, 'x');
1033         default: return NULL;
1034       }
1035     case 's':
1036       switch (count) {
1037         case 8: return new Format<int8_t>("%4" PRId8, 's');
1038         case 16: return new Format<int16_t>("%6" PRId16, 's');
1039         case 32: return new Format<int32_t>("%11" PRId32, 's');
1040         case 64: return new Format<int64_t>("%20" PRId64, 's');
1041         default: return NULL;
1042       }
1043     case 'u':
1044       switch (count) {
1045         case 8: return new Format<uint8_t>("%3" PRIu8, 'u');
1046         case 16: return new Format<uint16_t>("%5" PRIu16, 'u');
1047         case 32: return new Format<uint32_t>("%10" PRIu32, 'u');
1048         case 64: return new Format<uint64_t>("%20" PRIu64, 'u');
1049         default: return NULL;
1050       }
1051     case 'f':
1052       switch (count) {
1053         case 32: return new Format<float>("%13g", 'f');
1054         case 64: return new Format<double>("%13g", 'f');
1055         default: return NULL;
1056       }
1057     default:
1058       VIXL_UNREACHABLE();
1059       return NULL;
1060   }
1061 }
1062 
1063 
1064 template<typename T>
Print(FILE * out) const1065 void Format<T>::Print(FILE* out) const {
1066   unsigned size = sizeof(T) * 8;
1067   fprintf(out, "[Format %c%u - %s]", type_code_, size, fmt_);
1068 }
1069 
1070 
Print(FILE * out) const1071 void UnknownToken::Print(FILE* out) const {
1072   fprintf(out, "[Unknown %s]", unknown_);
1073 }
1074 
1075 
Print(FILE * out)1076 void DebugCommand::Print(FILE* out) {
1077   fprintf(out, "%s", name());
1078 }
1079 
1080 
Match(const char * name,const char ** aliases)1081 bool DebugCommand::Match(const char* name, const char** aliases) {
1082   for (const char** current = aliases; *current != NULL; current++) {
1083     if (strcmp(name, *current) == 0) {
1084        return true;
1085     }
1086   }
1087 
1088   return false;
1089 }
1090 
1091 
Parse(char * line)1092 DebugCommand* DebugCommand::Parse(char* line) {
1093   std::vector<Token*> args;
1094 
1095   for (char* chunk = strtok(line, " \t");
1096        chunk != NULL;
1097        chunk = strtok(NULL, " \t")) {
1098     char* dot = strchr(chunk, '.');
1099     if (dot != NULL) {
1100       // 'Token.format'.
1101       Token* format = FormatToken::Tokenize(dot + 1);
1102       if (format != NULL) {
1103         *dot = '\0';
1104         args.push_back(Token::Tokenize(chunk));
1105         args.push_back(format);
1106       } else {
1107         // Error while parsing the format, push the UnknownToken so an error
1108         // can be accurately reported.
1109         args.push_back(Token::Tokenize(chunk));
1110       }
1111     } else {
1112       args.push_back(Token::Tokenize(chunk));
1113     }
1114   }
1115 
1116   if (args.size() == 0) {
1117     return NULL;
1118   }
1119 
1120   if (!args[0]->IsIdentifier()) {
1121     return new InvalidCommand(args, 0, "command name is not valid");
1122   }
1123 
1124   const char* name = IdentifierToken::Cast(args[0])->value();
1125   #define RETURN_IF_MATCH(Command)       \
1126   if (Match(name, Command::kAliases)) {  \
1127     return Command::Build(args);         \
1128   }
1129   DEBUG_COMMAND_LIST(RETURN_IF_MATCH);
1130   #undef RETURN_IF_MATCH
1131 
1132   return new UnknownCommand(args);
1133 }
1134 
1135 
PrintHelp(const char ** aliases,const char * args,const char * help)1136 void DebugCommand::PrintHelp(const char** aliases,
1137                              const char* args,
1138                              const char* help) {
1139   VIXL_ASSERT(aliases[0] != NULL);
1140   VIXL_ASSERT(help != NULL);
1141 
1142   printf("\n----\n\n");
1143   for (const char** current = aliases; *current != NULL; current++) {
1144     if (args != NULL) {
1145       printf("%s %s\n", *current, args);
1146     } else {
1147       printf("%s\n", *current);
1148     }
1149   }
1150   printf("\n%s\n", help);
1151 }
1152 
1153 
Run(Debugger * debugger)1154 bool HelpCommand::Run(Debugger* debugger) {
1155   VIXL_ASSERT(debugger->IsDebuggerRunning());
1156   USE(debugger);
1157 
1158   #define PRINT_HELP(Command)                     \
1159     DebugCommand::PrintHelp(Command::kAliases,    \
1160                             Command::kArguments,  \
1161                             Command::kHelp);
1162   DEBUG_COMMAND_LIST(PRINT_HELP);
1163   #undef PRINT_HELP
1164   printf("\n----\n\n");
1165 
1166   return false;
1167 }
1168 
1169 
Build(std::vector<Token * > args)1170 DebugCommand* HelpCommand::Build(std::vector<Token*> args) {
1171   if (args.size() != 1) {
1172     return new InvalidCommand(args, -1, "too many arguments");
1173   }
1174 
1175   return new HelpCommand(args[0]);
1176 }
1177 
1178 
Run(Debugger * debugger)1179 bool ContinueCommand::Run(Debugger* debugger) {
1180   VIXL_ASSERT(debugger->IsDebuggerRunning());
1181 
1182   debugger->set_debug_parameters(debugger->debug_parameters() & ~DBG_ACTIVE);
1183   return true;
1184 }
1185 
1186 
Build(std::vector<Token * > args)1187 DebugCommand* ContinueCommand::Build(std::vector<Token*> args) {
1188   if (args.size() != 1) {
1189     return new InvalidCommand(args, -1, "too many arguments");
1190   }
1191 
1192   return new ContinueCommand(args[0]);
1193 }
1194 
1195 
Run(Debugger * debugger)1196 bool StepCommand::Run(Debugger* debugger) {
1197   VIXL_ASSERT(debugger->IsDebuggerRunning());
1198 
1199   int64_t steps = count();
1200   if (steps < 0) {
1201     printf(" ** invalid value for steps: %" PRId64 " (<0) **\n", steps);
1202   } else if (steps > 1) {
1203     debugger->set_steps(steps - 1);
1204   }
1205 
1206   return true;
1207 }
1208 
1209 
Print(FILE * out)1210 void StepCommand::Print(FILE* out) {
1211   fprintf(out, "%s %" PRId64 "", name(), count());
1212 }
1213 
1214 
Build(std::vector<Token * > args)1215 DebugCommand* StepCommand::Build(std::vector<Token*> args) {
1216   IntegerToken* count = NULL;
1217   switch (args.size()) {
1218     case 1: {  // step [1]
1219       count = new IntegerToken(1);
1220       break;
1221     }
1222     case 2: {  // step n
1223       Token* first = args[1];
1224       if (!first->IsInteger()) {
1225         return new InvalidCommand(args, 1, "expects int");
1226       }
1227       count = IntegerToken::Cast(first);
1228       break;
1229     }
1230     default:
1231       return new InvalidCommand(args, -1, "too many arguments");
1232   }
1233 
1234   return new StepCommand(args[0], count);
1235 }
1236 
1237 
Build(std::vector<Token * > args)1238 DebugCommand* DisasmCommand::Build(std::vector<Token*> args) {
1239   IntegerToken* count = NULL;
1240   switch (args.size()) {
1241     case 1: {  // disasm [10]
1242       count = new IntegerToken(10);
1243       break;
1244     }
1245     case 2: {  // disasm n
1246       Token* first = args[1];
1247       if (!first->IsInteger()) {
1248         return new InvalidCommand(args, 1, "expects int");
1249       }
1250 
1251       count = IntegerToken::Cast(first);
1252       break;
1253     }
1254     default:
1255       return new InvalidCommand(args, -1, "too many arguments");
1256   }
1257 
1258   Token* target = new IdentifierToken("pc");
1259   FormatToken* format = new Format<uint32_t>("%08" PRIx32, 'i');
1260   return new ExamineCommand(args[0], target, format, count);
1261 }
1262 
1263 
Print(FILE * out)1264 void PrintCommand::Print(FILE* out) {
1265   fprintf(out, "%s ", name());
1266   target()->Print(out);
1267   if (format() != NULL) format()->Print(out);
1268 }
1269 
1270 
Run(Debugger * debugger)1271 bool PrintCommand::Run(Debugger* debugger) {
1272   VIXL_ASSERT(debugger->IsDebuggerRunning());
1273 
1274   Token* tok = target();
1275   if (tok->IsIdentifier()) {
1276     char* identifier = IdentifierToken::Cast(tok)->value();
1277     if (strcmp(identifier, "regs") == 0) {
1278       debugger->PrintRegisters();
1279     } else if (strcmp(identifier, "fpregs") == 0) {
1280       debugger->PrintVRegisters();
1281     } else if (strcmp(identifier, "sysregs") == 0) {
1282       debugger->PrintSystemRegisters();
1283     } else if (strcmp(identifier, "pc") == 0) {
1284       printf("pc = %16p\n", reinterpret_cast<const void*>(debugger->pc()));
1285     } else {
1286       printf(" ** Unknown identifier to print: %s **\n", identifier);
1287     }
1288 
1289     return false;
1290   }
1291 
1292   FormatToken* format_tok = format();
1293   VIXL_ASSERT(format_tok != NULL);
1294   if (format_tok->type_code() == 'i') {
1295     // TODO(all): Add support for instruction disassembly.
1296     printf(" ** unsupported format: instructions **\n");
1297     return false;
1298   }
1299 
1300   if (tok->IsRegister()) {
1301     RegisterToken* reg_tok = RegisterToken::Cast(tok);
1302     Register reg = reg_tok->value();
1303     debugger->PrintRegister(reg, reg_tok->Name(), format_tok);
1304     return false;
1305   }
1306 
1307   if (tok->IsFPRegister()) {
1308     FPRegister fpreg = FPRegisterToken::Cast(tok)->value();
1309     debugger->PrintFPRegister(fpreg, format_tok);
1310     return false;
1311   }
1312 
1313   VIXL_UNREACHABLE();
1314   return false;
1315 }
1316 
1317 
Build(std::vector<Token * > args)1318 DebugCommand* PrintCommand::Build(std::vector<Token*> args) {
1319   if (args.size() < 2) {
1320     return new InvalidCommand(args, -1, "too few arguments");
1321   }
1322 
1323   Token* target = args[1];
1324   if (!target->IsRegister() &&
1325       !target->IsFPRegister() &&
1326       !target->IsIdentifier()) {
1327     return new InvalidCommand(args, 1, "expects reg or identifier");
1328   }
1329 
1330   FormatToken* format = NULL;
1331   int target_size = 0;
1332   if (target->IsRegister()) {
1333     Register reg = RegisterToken::Cast(target)->value();
1334     target_size = reg.SizeInBytes();
1335   } else if (target->IsFPRegister()) {
1336     FPRegister fpreg = FPRegisterToken::Cast(target)->value();
1337     target_size = fpreg.SizeInBytes();
1338   }
1339   // If the target is an identifier there must be no format. This is checked
1340   // in the switch statement below.
1341 
1342   switch (args.size()) {
1343     case 2: {
1344       if (target->IsRegister()) {
1345         switch (target_size) {
1346           case 4: format = new Format<uint32_t>("%08" PRIx32, 'x'); break;
1347           case 8: format = new Format<uint64_t>("%016" PRIx64, 'x'); break;
1348           default: VIXL_UNREACHABLE();
1349         }
1350       } else if (target->IsFPRegister()) {
1351         switch (target_size) {
1352           case 4: format = new Format<float>("%8g", 'f'); break;
1353           case 8: format = new Format<double>("%8g", 'f'); break;
1354           default: VIXL_UNREACHABLE();
1355         }
1356       }
1357       break;
1358     }
1359     case 3: {
1360       if (target->IsIdentifier()) {
1361         return new InvalidCommand(args, 2,
1362             "format is only allowed with registers");
1363       }
1364 
1365       Token* second = args[2];
1366       if (!second->IsFormat()) {
1367         return new InvalidCommand(args, 2, "expects format");
1368       }
1369       format = FormatToken::Cast(second);
1370 
1371       if (format->SizeOf() > target_size) {
1372         return new InvalidCommand(args, 2, "format too wide");
1373       }
1374 
1375       break;
1376     }
1377     default:
1378       return new InvalidCommand(args, -1, "too many arguments");
1379   }
1380 
1381   return new PrintCommand(args[0], target, format);
1382 }
1383 
1384 
Run(Debugger * debugger)1385 bool ExamineCommand::Run(Debugger* debugger) {
1386   VIXL_ASSERT(debugger->IsDebuggerRunning());
1387 
1388   uint8_t* address = target()->ToAddress(debugger);
1389   int64_t  amount = count()->value();
1390   if (format()->type_code() == 'i') {
1391     debugger->PrintInstructions(address, amount);
1392   } else {
1393     debugger->PrintMemory(address, format(), amount);
1394   }
1395 
1396   return false;
1397 }
1398 
1399 
Print(FILE * out)1400 void ExamineCommand::Print(FILE* out) {
1401   fprintf(out, "%s ", name());
1402   format()->Print(out);
1403   target()->Print(out);
1404 }
1405 
1406 
Build(std::vector<Token * > args)1407 DebugCommand* ExamineCommand::Build(std::vector<Token*> args) {
1408   if (args.size() < 2) {
1409     return new InvalidCommand(args, -1, "too few arguments");
1410   }
1411 
1412   Token* target = args[1];
1413   if (!target->CanAddressMemory()) {
1414     return new InvalidCommand(args, 1, "expects address");
1415   }
1416 
1417   FormatToken* format = NULL;
1418   IntegerToken* count = NULL;
1419 
1420   switch (args.size()) {
1421     case 2: {  // mem addr[.x64] [10]
1422       format = new Format<uint64_t>("%016" PRIx64, 'x');
1423       count = new IntegerToken(10);
1424       break;
1425     }
1426     case 3: {  // mem addr.format [10]
1427                // mem addr[.x64] n
1428       Token* second = args[2];
1429       if (second->IsFormat()) {
1430         format = FormatToken::Cast(second);
1431         count = new IntegerToken(10);
1432         break;
1433       } else if (second->IsInteger()) {
1434         format = new Format<uint64_t>("%016" PRIx64, 'x');
1435         count = IntegerToken::Cast(second);
1436       } else {
1437         return new InvalidCommand(args, 2, "expects format or integer");
1438       }
1439       VIXL_UNREACHABLE();
1440       break;
1441     }
1442     case 4: {  // mem addr.format n
1443       Token* second = args[2];
1444       Token* third = args[3];
1445       if (!second->IsFormat() || !third->IsInteger()) {
1446         return new InvalidCommand(args, -1, "expects addr[.format] [n]");
1447       }
1448       format = FormatToken::Cast(second);
1449       count = IntegerToken::Cast(third);
1450       break;
1451     }
1452     default:
1453       return new InvalidCommand(args, -1, "too many arguments");
1454   }
1455 
1456   return new ExamineCommand(args[0], target, format, count);
1457 }
1458 
1459 
~UnknownCommand()1460 UnknownCommand::~UnknownCommand() {
1461   const int size = args_.size();
1462   for (int i = 0; i < size; ++i) {
1463     delete args_[i];
1464   }
1465 }
1466 
1467 
Run(Debugger * debugger)1468 bool UnknownCommand::Run(Debugger* debugger) {
1469   VIXL_ASSERT(debugger->IsDebuggerRunning());
1470   USE(debugger);
1471 
1472   printf(" ** Unknown Command:");
1473   const int size = args_.size();
1474   for (int i = 0; i < size; ++i) {
1475     printf(" ");
1476     args_[i]->Print(stdout);
1477   }
1478   printf(" **\n");
1479 
1480   return false;
1481 }
1482 
1483 
~InvalidCommand()1484 InvalidCommand::~InvalidCommand() {
1485   const int size = args_.size();
1486   for (int i = 0; i < size; ++i) {
1487     delete args_[i];
1488   }
1489 }
1490 
1491 
Run(Debugger * debugger)1492 bool InvalidCommand::Run(Debugger* debugger) {
1493   VIXL_ASSERT(debugger->IsDebuggerRunning());
1494   USE(debugger);
1495 
1496   printf(" ** Invalid Command:");
1497   const int size = args_.size();
1498   for (int i = 0; i < size; ++i) {
1499     printf(" ");
1500     if (i == index_) {
1501       printf(">>");
1502       args_[i]->Print(stdout);
1503       printf("<<");
1504     } else {
1505       args_[i]->Print(stdout);
1506     }
1507   }
1508   printf(" **\n");
1509   printf(" ** %s\n", cause_);
1510 
1511   return false;
1512 }
1513 
1514 }  // namespace vixl
1515 
1516 #endif  // USE_SIMULATOR
1517