1// Copyright 2013 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 "a64/debugger-a64.h"
30
31namespace vixl {
32
33// List of commands supported by the debugger.
34#define DEBUG_COMMAND_LIST(C)  \
35C(HelpCommand)                 \
36C(ContinueCommand)             \
37C(StepCommand)                 \
38C(DisasmCommand)               \
39C(PrintCommand)                \
40C(ExamineCommand)
41
42// Debugger command lines are broken up in token of different type to make
43// processing easier later on.
44class Token {
45 public:
46  virtual ~Token() {}
47
48  // Token type.
49  virtual bool IsRegister() const { return false; }
50  virtual bool IsFPRegister() const { return false; }
51  virtual bool IsIdentifier() const { return false; }
52  virtual bool IsAddress() const { return false; }
53  virtual bool IsInteger() const { return false; }
54  virtual bool IsFormat() const { return false; }
55  virtual bool IsUnknown() const { return false; }
56  // Token properties.
57  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.
65template<typename T> class ValueToken : public Token {
66 public:
67  explicit ValueToken(T value) : value_(value) {}
68  ValueToken() {}
69
70  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.
78class RegisterToken : public ValueToken<const Register> {
79 public:
80  explicit RegisterToken(const Register reg)
81      : ValueToken<const Register>(reg) {}
82
83  virtual bool IsRegister() const { return true; }
84  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);
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.
103class FPRegisterToken : public ValueToken<const FPRegister> {
104 public:
105  explicit FPRegisterToken(const FPRegister fpreg)
106      : ValueToken<const FPRegister>(fpreg) {}
107
108  virtual bool IsFPRegister() const { return true; }
109  virtual void Print(FILE* out = stdout) const ;
110
111  static Token* Tokenize(const char* arg);
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.
121class IdentifierToken : public ValueToken<char*> {
122 public:
123  explicit IdentifierToken(const char* name) {
124    int size = strlen(name) + 1;
125    value_ = new char[size];
126    strncpy(value_, name, size);
127  }
128  virtual ~IdentifierToken() { delete[] value_; }
129
130  virtual bool IsIdentifier() const { return true; }
131  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);
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.
144class AddressToken : public ValueToken<uint8_t*> {
145 public:
146  explicit AddressToken(uint8_t* address) : ValueToken<uint8_t*>(address) {}
147
148  virtual bool IsAddress() const { return true; }
149  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);
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.
163class IntegerToken : public ValueToken<int64_t> {
164 public:
165  explicit IntegerToken(int value) : ValueToken<int64_t>(value) {}
166
167  virtual bool IsInteger() const { return true; }
168  virtual void Print(FILE* out = stdout) const;
169
170  static Token* Tokenize(const char* arg);
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.
187class FormatToken : public Token {
188 public:
189  FormatToken() {}
190
191  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);
198  static FormatToken* Cast(Token* tok) {
199    VIXL_ASSERT(tok->IsFormat());
200    return reinterpret_cast<FormatToken*>(tok);
201  }
202};
203
204
205template<typename T> class Format : public FormatToken {
206 public:
207  Format(const char* fmt, char type_code) : fmt_(fmt), type_code_(type_code) {}
208
209  virtual int SizeOf() const { return sizeof(T); }
210  virtual char type_code() const { return type_code_; }
211  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.
224class UnknownToken : public Token {
225 public:
226  explicit UnknownToken(const char* arg) {
227    int size = strlen(arg) + 1;
228    unknown_ = new char[size];
229    strncpy(unknown_, arg, size);
230  }
231  virtual ~UnknownToken() { delete[] unknown_; }
232
233  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.
243class DebugCommand {
244 public:
245  explicit DebugCommand(Token* name) : name_(IdentifierToken::Cast(name)) {}
246  DebugCommand() : name_(NULL) {}
247  virtual ~DebugCommand() { delete name_; }
248
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
267class HelpCommand : public DebugCommand {
268 public:
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
281class ContinueCommand : public DebugCommand {
282 public:
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
295class StepCommand : public DebugCommand {
296 public:
297  StepCommand(Token* name, IntegerToken* count)
298      : DebugCommand(name), count_(count) {}
299  virtual ~StepCommand() { delete count_; }
300
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
315class 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
325class PrintCommand : public DebugCommand {
326 public:
327  PrintCommand(Token* name, Token* target, FormatToken* format)
328      : DebugCommand(name), target_(target), format_(format) {}
329  virtual ~PrintCommand() {
330    delete target_;
331    delete format_;
332  }
333
334  Token* target() { return target_; }
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
350class ExamineCommand : public DebugCommand {
351 public:
352  ExamineCommand(Token* name,
353                 Token* target,
354                 FormatToken* format,
355                 IntegerToken* count)
356      : DebugCommand(name), target_(target), format_(format), count_(count) {}
357  virtual ~ExamineCommand() {
358    delete target_;
359    delete format_;
360    delete count_;
361  }
362
363  Token* target() { return target_; }
364  FormatToken* format() { return format_; }
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.
382class UnknownCommand : public DebugCommand {
383 public:
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.
394class InvalidCommand : public DebugCommand {
395 public:
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
408const char* HelpCommand::kAliases[] = { "help", NULL };
409const char* HelpCommand::kArguments = NULL;
410const char* HelpCommand::kHelp = "  Print this help.";
411
412const char* ContinueCommand::kAliases[] = { "continue", "c", NULL };
413const char* ContinueCommand::kArguments = NULL;
414const char* ContinueCommand::kHelp = "  Resume execution.";
415
416const char* StepCommand::kAliases[] = { "stepi", "si", NULL };
417const char* StepCommand::kArguments = "[n = 1]";
418const char* StepCommand::kHelp = "  Execute n next instruction(s).";
419
420const char* DisasmCommand::kAliases[] = { "disasm", "di", NULL };
421const char* DisasmCommand::kArguments = "[n = 10]";
422const char* DisasmCommand::kHelp =
423  "  Disassemble n instruction(s) at pc.\n"
424  "  This command is equivalent to x pc.i [n = 10]."
425;
426
427const char* PrintCommand::kAliases[] = { "print", "p", NULL };
428const char* PrintCommand::kArguments =  "<entity>[.format]";
429const 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
441const char* ExamineCommand::kAliases[] = { "m", "mem", "x", NULL };
442const char* ExamineCommand::kArguments = "<addr>[.format] [n = 10]";
443const 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
454const 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
489const 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
525Debugger::Debugger(Decoder* decoder, FILE* stream)
526    : Simulator(decoder, stream),
527      log_parameters_(0),
528      debug_parameters_(0),
529      pending_request_(false),
530      steps_(0),
531      last_command_(NULL) {
532  disasm_ = new PrintDisassembler(stdout);
533  printer_ = new Decoder();
534  printer_->AppendVisitor(disasm_);
535}
536
537
538void Debugger::Run() {
539  pc_modified_ = false;
540  while (pc_ != kEndOfSimAddress) {
541    if (pending_request()) {
542      LogProcessorState();
543      RunDebuggerShell();
544    }
545
546    ExecuteInstruction();
547  }
548}
549
550
551void Debugger::PrintInstructions(void* address, int64_t count) {
552  if (count == 0) {
553    return;
554  }
555
556  Instruction* from = Instruction::Cast(address);
557  if (count < 0) {
558    count = -count;
559    from -= (count - 1) * kInstructionSize;
560  }
561  Instruction* to = from + count * kInstructionSize;
562
563  for (Instruction* current = from;
564       current < to;
565       current = current->NextInstruction()) {
566    printer_->Decode(current);
567  }
568}
569
570
571void Debugger::PrintMemory(const uint8_t* address,
572                           const FormatToken* format,
573                           int64_t count) {
574  if (count == 0) {
575    return;
576  }
577
578  const uint8_t* from = address;
579  int size = format->SizeOf();
580  if (count < 0) {
581    count = -count;
582    from -= (count - 1) * size;
583  }
584  const uint8_t* to = from + count * size;
585
586  for (const uint8_t* current = from; current < to; current += size) {
587    if (((current - from) % 8) == 0) {
588      printf("\n%p: ", current);
589    }
590
591    uint64_t data = MemoryRead(current, size);
592    format->PrintData(&data);
593    printf(" ");
594  }
595  printf("\n\n");
596}
597
598
599void Debugger::PrintRegister(const Register& target_reg,
600                             const char* name,
601                             const FormatToken* format) {
602  const uint64_t reg_size = target_reg.SizeInBits();
603  const uint64_t format_size = format->SizeOf() * 8;
604  const uint64_t count = reg_size / format_size;
605  const uint64_t mask = UINT64_C(0xffffffffffffffff) >> (64 - format_size);
606  const uint64_t reg_value = reg<uint64_t>(reg_size,
607                                           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
622void Debugger::PrintFPRegister(const FPRegister& target_fpreg,
623                               const FormatToken* format) {
624  const uint64_t fpreg_size = target_fpreg.SizeInBits();
625  const uint64_t format_size = format->SizeOf() * 8;
626  const uint64_t count = fpreg_size / format_size;
627  const uint64_t mask = UINT64_C(0xffffffffffffffff) >> (64 - format_size);
628  const uint64_t fpreg_value = fpreg<uint64_t>(fpreg_size,
629                                               target_fpreg.code());
630  VIXL_ASSERT(count > 0);
631
632  if (target_fpreg.Is32Bits()) {
633    printf("s%u = ", target_fpreg.code());
634  } else {
635    printf("d%u = ", target_fpreg.code());
636  }
637  for (uint64_t i = 1; i <= count; i++) {
638    uint64_t data = fpreg_value >> (fpreg_size - (i * format_size));
639    data &= mask;
640    format->PrintData(&data);
641    printf(" ");
642  }
643  printf("\n");
644}
645
646
647void Debugger::VisitException(Instruction* instr) {
648  switch (instr->Mask(ExceptionMask)) {
649    case BRK:
650      DoBreakpoint(instr);
651      return;
652    case HLT:
653      switch (instr->ImmException()) {
654        case kUnreachableOpcode:
655          DoUnreachable(instr);
656          return;
657        case kTraceOpcode:
658          DoTrace(instr);
659          return;
660        case kLogOpcode:
661          DoLog(instr);
662          return;
663      }
664      // Fall through
665    default: Simulator::VisitException(instr);
666  }
667}
668
669
670void Debugger::LogSystemRegisters() {
671  if (log_parameters_ & LOG_SYS_REGS) PrintSystemRegisters();
672}
673
674
675void Debugger::LogRegisters() {
676  if (log_parameters_ & LOG_REGS) PrintRegisters();
677}
678
679
680void Debugger::LogFPRegisters() {
681  if (log_parameters_ & LOG_FP_REGS) PrintFPRegisters();
682}
683
684
685void Debugger::LogProcessorState() {
686  LogSystemRegisters();
687  LogRegisters();
688  LogFPRegisters();
689}
690
691
692// Read a command. A command will be at most kMaxDebugShellLine char long and
693// ends with '\n\0'.
694// TODO: Should this be a utility function?
695char* Debugger::ReadCommandLine(const char* prompt, char* buffer, int length) {
696  int fgets_calls = 0;
697  char* end = NULL;
698
699  printf("%s", prompt);
700  fflush(stdout);
701
702  do {
703    if (fgets(buffer, length, stdin) == NULL) {
704      printf(" ** Error while reading command. **\n");
705      return NULL;
706    }
707
708    fgets_calls++;
709    end = strchr(buffer, '\n');
710  } while (end == NULL);
711
712  if (fgets_calls != 1) {
713    printf(" ** Command too long. **\n");
714    return NULL;
715  }
716
717  // Remove the newline from the end of the command.
718  VIXL_ASSERT(end[1] == '\0');
719  VIXL_ASSERT((end - buffer) < (length - 1));
720  end[0] = '\0';
721
722  return buffer;
723}
724
725
726void Debugger::RunDebuggerShell() {
727  if (IsDebuggerRunning()) {
728    if (steps_ > 0) {
729      // Finish stepping first.
730      --steps_;
731      return;
732    }
733
734    printf("Next: ");
735    PrintInstructions(pc());
736    bool done = false;
737    while (!done) {
738      char buffer[kMaxDebugShellLine];
739      char* line = ReadCommandLine("vixl> ", buffer, kMaxDebugShellLine);
740
741      if (line == NULL) continue;  // An error occurred.
742
743      DebugCommand* command = DebugCommand::Parse(line);
744      if (command != NULL) {
745        last_command_ = command;
746      }
747
748      if (last_command_ != NULL) {
749        done = last_command_->Run(this);
750      } else {
751        printf("No previous command to run!\n");
752      }
753    }
754
755    if ((debug_parameters_ & DBG_BREAK) != 0) {
756      // The break request has now been handled, move to next instruction.
757      debug_parameters_ &= ~DBG_BREAK;
758      increment_pc();
759    }
760  }
761}
762
763
764void Debugger::DoBreakpoint(Instruction* instr) {
765  VIXL_ASSERT(instr->Mask(ExceptionMask) == BRK);
766
767  printf("Hit breakpoint at pc=%p.\n", reinterpret_cast<void*>(instr));
768  set_debug_parameters(debug_parameters() | DBG_BREAK | DBG_ACTIVE);
769  // Make the shell point to the brk instruction.
770  set_pc(instr);
771}
772
773
774void Debugger::DoUnreachable(Instruction* instr) {
775  VIXL_ASSERT((instr->Mask(ExceptionMask) == HLT) &&
776              (instr->ImmException() == kUnreachableOpcode));
777
778  fprintf(stream_, "Hit UNREACHABLE marker at pc=%p.\n",
779          reinterpret_cast<void*>(instr));
780  abort();
781}
782
783
784void Debugger::DoTrace(Instruction* instr) {
785  VIXL_ASSERT((instr->Mask(ExceptionMask) == HLT) &&
786              (instr->ImmException() == kTraceOpcode));
787
788  // Read the arguments encoded inline in the instruction stream.
789  uint32_t parameters;
790  uint32_t command;
791
792  VIXL_STATIC_ASSERT(sizeof(*instr) == 1);
793  memcpy(&parameters, instr + kTraceParamsOffset, sizeof(parameters));
794  memcpy(&command, instr + kTraceCommandOffset, sizeof(command));
795
796  switch (command) {
797    case TRACE_ENABLE:
798      set_log_parameters(log_parameters() | parameters);
799      break;
800    case TRACE_DISABLE:
801      set_log_parameters(log_parameters() & ~parameters);
802      break;
803    default:
804      VIXL_UNREACHABLE();
805  }
806
807  set_pc(instr->InstructionAtOffset(kTraceLength));
808}
809
810
811void Debugger::DoLog(Instruction* instr) {
812  VIXL_ASSERT((instr->Mask(ExceptionMask) == HLT) &&
813              (instr->ImmException() == kLogOpcode));
814
815  // Read the arguments encoded inline in the instruction stream.
816  uint32_t parameters;
817
818  VIXL_STATIC_ASSERT(sizeof(*instr) == 1);
819  memcpy(&parameters, instr + kTraceParamsOffset, sizeof(parameters));
820
821  // We don't support a one-shot LOG_DISASM.
822  VIXL_ASSERT((parameters & LOG_DISASM) == 0);
823  // Print the requested information.
824  if (parameters & LOG_SYS_REGS) PrintSystemRegisters(true);
825  if (parameters & LOG_REGS) PrintRegisters(true);
826  if (parameters & LOG_FP_REGS) PrintFPRegisters(true);
827
828  set_pc(instr->InstructionAtOffset(kLogLength));
829}
830
831
832static bool StringToUInt64(uint64_t* value, const char* line, int base = 10) {
833  char* endptr = NULL;
834  errno = 0;  // Reset errors.
835  uint64_t parsed = strtoul(line, &endptr, base);
836
837  if (errno == ERANGE) {
838    // Overflow.
839    return false;
840  }
841
842  if (endptr == line) {
843    // No digits were parsed.
844    return false;
845  }
846
847  if (*endptr != '\0') {
848    // Non-digit characters present at the end.
849    return false;
850  }
851
852  *value = parsed;
853  return true;
854}
855
856
857static bool StringToInt64(int64_t* value, const char* line, int base = 10) {
858  char* endptr = NULL;
859  errno = 0;  // Reset errors.
860  int64_t parsed = strtol(line, &endptr, base);
861
862  if (errno == ERANGE) {
863    // Overflow, undeflow.
864    return false;
865  }
866
867  if (endptr == line) {
868    // No digits were parsed.
869    return false;
870  }
871
872  if (*endptr != '\0') {
873    // Non-digit characters present at the end.
874    return false;
875  }
876
877  *value = parsed;
878  return true;
879}
880
881
882uint8_t* Token::ToAddress(Debugger* debugger) const {
883  USE(debugger);
884  VIXL_UNREACHABLE();
885  return NULL;
886}
887
888
889Token* Token::Tokenize(const char* arg) {
890  if ((arg == NULL) || (*arg == '\0')) {
891    return NULL;
892  }
893
894  // The order is important. For example Identifier::Tokenize would consider
895  // any register to be a valid identifier.
896
897  Token* token = RegisterToken::Tokenize(arg);
898  if (token != NULL) {
899    return token;
900  }
901
902  token = FPRegisterToken::Tokenize(arg);
903  if (token != NULL) {
904    return token;
905  }
906
907  token = IdentifierToken::Tokenize(arg);
908  if (token != NULL) {
909    return token;
910  }
911
912  token = AddressToken::Tokenize(arg);
913  if (token != NULL) {
914    return token;
915  }
916
917  token = IntegerToken::Tokenize(arg);
918  if (token != NULL) {
919    return token;
920  }
921
922  return new UnknownToken(arg);
923}
924
925
926uint8_t* RegisterToken::ToAddress(Debugger* debugger) const {
927  VIXL_ASSERT(CanAddressMemory());
928  uint64_t reg_value = debugger->xreg(value().code(), Reg31IsStackPointer);
929  uint8_t* address = NULL;
930  memcpy(&address, &reg_value, sizeof(address));
931  return address;
932}
933
934
935void RegisterToken::Print(FILE* out) const {
936  VIXL_ASSERT(value().IsValid());
937  fprintf(out, "[Register %s]", Name());
938}
939
940
941const char* RegisterToken::Name() const {
942  if (value().Is32Bits()) {
943    return kWAliases[value().code()][0];
944  } else {
945    return kXAliases[value().code()][0];
946  }
947}
948
949
950Token* RegisterToken::Tokenize(const char* arg) {
951  for (unsigned i = 0; i < kNumberOfRegisters; i++) {
952    // Is it a X register or alias?
953    for (const char** current = kXAliases[i]; *current != NULL; current++) {
954      if (strcmp(arg, *current) == 0) {
955        return new RegisterToken(Register::XRegFromCode(i));
956      }
957    }
958
959    // Is it a W register or alias?
960    for (const char** current = kWAliases[i]; *current != NULL; current++) {
961      if (strcmp(arg, *current) == 0) {
962        return new RegisterToken(Register::WRegFromCode(i));
963      }
964    }
965  }
966
967  return NULL;
968}
969
970
971void FPRegisterToken::Print(FILE* out) const {
972  VIXL_ASSERT(value().IsValid());
973  char prefix = value().Is32Bits() ? 's' : 'd';
974  fprintf(out, "[FPRegister %c%" PRIu32 "]", prefix, value().code());
975}
976
977
978Token* FPRegisterToken::Tokenize(const char* arg) {
979  if (strlen(arg) < 2) {
980    return NULL;
981  }
982
983  switch (*arg) {
984    case 's':
985    case 'd':
986      const char* cursor = arg + 1;
987      uint64_t code = 0;
988      if (!StringToUInt64(&code, cursor)) {
989        return NULL;
990      }
991
992      if (code > kNumberOfFPRegisters) {
993        return NULL;
994      }
995
996      FPRegister fpreg = NoFPReg;
997      switch (*arg) {
998        case 's': fpreg = FPRegister::SRegFromCode(code); break;
999        case 'd': fpreg = FPRegister::DRegFromCode(code); break;
1000        default: VIXL_UNREACHABLE();
1001      }
1002
1003      return new FPRegisterToken(fpreg);
1004  }
1005
1006  return NULL;
1007}
1008
1009
1010uint8_t* IdentifierToken::ToAddress(Debugger* debugger) const {
1011  VIXL_ASSERT(CanAddressMemory());
1012  Instruction* pc_value = debugger->pc();
1013  uint8_t* address = NULL;
1014  memcpy(&address, &pc_value, sizeof(address));
1015  return address;
1016}
1017
1018void IdentifierToken::Print(FILE* out) const {
1019  fprintf(out, "[Identifier %s]", value());
1020}
1021
1022
1023Token* IdentifierToken::Tokenize(const char* arg) {
1024  if (!isalpha(arg[0])) {
1025    return NULL;
1026  }
1027
1028  const char* cursor = arg + 1;
1029  while ((*cursor != '\0') && isalnum(*cursor)) {
1030    ++cursor;
1031  }
1032
1033  if (*cursor == '\0') {
1034    return new IdentifierToken(arg);
1035  }
1036
1037  return NULL;
1038}
1039
1040
1041uint8_t* AddressToken::ToAddress(Debugger* debugger) const {
1042  USE(debugger);
1043  return value();
1044}
1045
1046
1047void AddressToken::Print(FILE* out) const {
1048  fprintf(out, "[Address %p]", value());
1049}
1050
1051
1052Token* AddressToken::Tokenize(const char* arg) {
1053  if ((strlen(arg) < 3) || (arg[0] != '0') || (arg[1] != 'x')) {
1054    return NULL;
1055  }
1056
1057  uint64_t ptr = 0;
1058  if (!StringToUInt64(&ptr, arg, 16)) {
1059    return NULL;
1060  }
1061
1062  uint8_t* address = reinterpret_cast<uint8_t*>(ptr);
1063  return new AddressToken(address);
1064}
1065
1066
1067void IntegerToken::Print(FILE* out) const {
1068  fprintf(out, "[Integer %" PRId64 "]", value());
1069}
1070
1071
1072Token* IntegerToken::Tokenize(const char* arg) {
1073  int64_t value = 0;
1074  if (!StringToInt64(&value, arg)) {
1075    return NULL;
1076  }
1077
1078  return new IntegerToken(value);
1079}
1080
1081
1082Token* FormatToken::Tokenize(const char* arg) {
1083  int length = strlen(arg);
1084  switch (arg[0]) {
1085    case 'x':
1086    case 's':
1087    case 'u':
1088    case 'f':
1089      if (length == 1) return NULL;
1090      break;
1091    case 'i':
1092      if (length == 1) return new Format<uint32_t>("%08" PRIx32, 'i');
1093    default: return NULL;
1094  }
1095
1096  char* endptr = NULL;
1097  errno = 0;  // Reset errors.
1098  uint64_t count = strtoul(arg + 1, &endptr, 10);
1099
1100  if (errno != 0) {
1101    // Overflow, etc.
1102    return NULL;
1103  }
1104
1105  if (endptr == arg) {
1106    // No digits were parsed.
1107    return NULL;
1108  }
1109
1110  if (*endptr != '\0') {
1111    // There are unexpected (non-digit) characters after the number.
1112    return NULL;
1113  }
1114
1115  switch (arg[0]) {
1116    case 'x':
1117      switch (count) {
1118        case 8: return new Format<uint8_t>("%02" PRIx8, 'x');
1119        case 16: return new Format<uint16_t>("%04" PRIx16, 'x');
1120        case 32: return new Format<uint32_t>("%08" PRIx32, 'x');
1121        case 64: return new Format<uint64_t>("%016" PRIx64, 'x');
1122        default: return NULL;
1123      }
1124    case 's':
1125      switch (count) {
1126        case 8: return new Format<int8_t>("%4" PRId8, 's');
1127        case 16: return new Format<int16_t>("%6" PRId16, 's');
1128        case 32: return new Format<int32_t>("%11" PRId32, 's');
1129        case 64: return new Format<int64_t>("%20" PRId64, 's');
1130        default: return NULL;
1131      }
1132    case 'u':
1133      switch (count) {
1134        case 8: return new Format<uint8_t>("%3" PRIu8, 'u');
1135        case 16: return new Format<uint16_t>("%5" PRIu16, 'u');
1136        case 32: return new Format<uint32_t>("%10" PRIu32, 'u');
1137        case 64: return new Format<uint64_t>("%20" PRIu64, 'u');
1138        default: return NULL;
1139      }
1140    case 'f':
1141      switch (count) {
1142        case 32: return new Format<float>("%13g", 'f');
1143        case 64: return new Format<double>("%13g", 'f');
1144        default: return NULL;
1145      }
1146    default:
1147      VIXL_UNREACHABLE();
1148      return NULL;
1149  }
1150}
1151
1152
1153template<typename T>
1154void Format<T>::Print(FILE* out) const {
1155  unsigned size = sizeof(T) * 8;
1156  fprintf(out, "[Format %c%u - %s]", type_code_, size, fmt_);
1157}
1158
1159
1160void UnknownToken::Print(FILE* out) const {
1161  fprintf(out, "[Unknown %s]", unknown_);
1162}
1163
1164
1165void DebugCommand::Print(FILE* out) {
1166  fprintf(out, "%s", name());
1167}
1168
1169
1170bool DebugCommand::Match(const char* name, const char** aliases) {
1171  for (const char** current = aliases; *current != NULL; current++) {
1172    if (strcmp(name, *current) == 0) {
1173       return true;
1174    }
1175  }
1176
1177  return false;
1178}
1179
1180
1181DebugCommand* DebugCommand::Parse(char* line) {
1182  std::vector<Token*> args;
1183
1184  for (char* chunk = strtok(line, " \t");
1185       chunk != NULL;
1186       chunk = strtok(NULL, " \t")) {
1187    char* dot = strchr(chunk, '.');
1188    if (dot != NULL) {
1189      // 'Token.format'.
1190      Token* format = FormatToken::Tokenize(dot + 1);
1191      if (format != NULL) {
1192        *dot = '\0';
1193        args.push_back(Token::Tokenize(chunk));
1194        args.push_back(format);
1195      } else {
1196        // Error while parsing the format, push the UnknownToken so an error
1197        // can be accurately reported.
1198        args.push_back(Token::Tokenize(chunk));
1199      }
1200    } else {
1201      args.push_back(Token::Tokenize(chunk));
1202    }
1203  }
1204
1205  if (args.size() == 0) {
1206    return NULL;
1207  }
1208
1209  if (!args[0]->IsIdentifier()) {
1210    return new InvalidCommand(args, 0, "command name is not valid");
1211  }
1212
1213  const char* name = IdentifierToken::Cast(args[0])->value();
1214  #define RETURN_IF_MATCH(Command)       \
1215  if (Match(name, Command::kAliases)) {  \
1216    return Command::Build(args);         \
1217  }
1218  DEBUG_COMMAND_LIST(RETURN_IF_MATCH);
1219  #undef RETURN_IF_MATCH
1220
1221  return new UnknownCommand(args);
1222}
1223
1224
1225void DebugCommand::PrintHelp(const char** aliases,
1226                             const char* args,
1227                             const char* help) {
1228  VIXL_ASSERT(aliases[0] != NULL);
1229  VIXL_ASSERT(help != NULL);
1230
1231  printf("\n----\n\n");
1232  for (const char** current = aliases; *current != NULL; current++) {
1233    if (args != NULL) {
1234      printf("%s %s\n", *current, args);
1235    } else {
1236      printf("%s\n", *current);
1237    }
1238  }
1239  printf("\n%s\n", help);
1240}
1241
1242
1243bool HelpCommand::Run(Debugger* debugger) {
1244  VIXL_ASSERT(debugger->IsDebuggerRunning());
1245  USE(debugger);
1246
1247  #define PRINT_HELP(Command)                     \
1248    DebugCommand::PrintHelp(Command::kAliases,    \
1249                            Command::kArguments,  \
1250                            Command::kHelp);
1251  DEBUG_COMMAND_LIST(PRINT_HELP);
1252  #undef PRINT_HELP
1253  printf("\n----\n\n");
1254
1255  return false;
1256}
1257
1258
1259DebugCommand* HelpCommand::Build(std::vector<Token*> args) {
1260  if (args.size() != 1) {
1261    return new InvalidCommand(args, -1, "too many arguments");
1262  }
1263
1264  return new HelpCommand(args[0]);
1265}
1266
1267
1268bool ContinueCommand::Run(Debugger* debugger) {
1269  VIXL_ASSERT(debugger->IsDebuggerRunning());
1270
1271  debugger->set_debug_parameters(debugger->debug_parameters() & ~DBG_ACTIVE);
1272  return true;
1273}
1274
1275
1276DebugCommand* ContinueCommand::Build(std::vector<Token*> args) {
1277  if (args.size() != 1) {
1278    return new InvalidCommand(args, -1, "too many arguments");
1279  }
1280
1281  return new ContinueCommand(args[0]);
1282}
1283
1284
1285bool StepCommand::Run(Debugger* debugger) {
1286  VIXL_ASSERT(debugger->IsDebuggerRunning());
1287
1288  int64_t steps = count();
1289  if (steps < 0) {
1290    printf(" ** invalid value for steps: %" PRId64 " (<0) **\n", steps);
1291  } else if (steps > 1) {
1292    debugger->set_steps(steps - 1);
1293  }
1294
1295  return true;
1296}
1297
1298
1299void StepCommand::Print(FILE* out) {
1300  fprintf(out, "%s %" PRId64 "", name(), count());
1301}
1302
1303
1304DebugCommand* StepCommand::Build(std::vector<Token*> args) {
1305  IntegerToken* count = NULL;
1306  switch (args.size()) {
1307    case 1: {  // step [1]
1308      count = new IntegerToken(1);
1309      break;
1310    }
1311    case 2: {  // step n
1312      Token* first = args[1];
1313      if (!first->IsInteger()) {
1314        return new InvalidCommand(args, 1, "expects int");
1315      }
1316      count = IntegerToken::Cast(first);
1317      break;
1318    }
1319    default:
1320      return new InvalidCommand(args, -1, "too many arguments");
1321  }
1322
1323  return new StepCommand(args[0], count);
1324}
1325
1326
1327DebugCommand* DisasmCommand::Build(std::vector<Token*> args) {
1328  IntegerToken* count = NULL;
1329  switch (args.size()) {
1330    case 1: {  // disasm [10]
1331      count = new IntegerToken(10);
1332      break;
1333    }
1334    case 2: {  // disasm n
1335      Token* first = args[1];
1336      if (!first->IsInteger()) {
1337        return new InvalidCommand(args, 1, "expects int");
1338      }
1339
1340      count = IntegerToken::Cast(first);
1341      break;
1342    }
1343    default:
1344      return new InvalidCommand(args, -1, "too many arguments");
1345  }
1346
1347  Token* target = new IdentifierToken("pc");
1348  FormatToken* format = new Format<uint32_t>("%08" PRIx32, 'i');
1349  return new ExamineCommand(args[0], target, format, count);
1350}
1351
1352
1353void PrintCommand::Print(FILE* out) {
1354  fprintf(out, "%s ", name());
1355  target()->Print(out);
1356  if (format() != NULL) format()->Print(out);
1357}
1358
1359
1360bool PrintCommand::Run(Debugger* debugger) {
1361  VIXL_ASSERT(debugger->IsDebuggerRunning());
1362
1363  Token* tok = target();
1364  if (tok->IsIdentifier()) {
1365    char* identifier = IdentifierToken::Cast(tok)->value();
1366    if (strcmp(identifier, "regs") == 0) {
1367      debugger->PrintRegisters(true);
1368    } else if (strcmp(identifier, "fpregs") == 0) {
1369      debugger->PrintFPRegisters(true);
1370    } else if (strcmp(identifier, "sysregs") == 0) {
1371      debugger->PrintSystemRegisters(true);
1372    } else if (strcmp(identifier, "pc") == 0) {
1373      printf("pc = %16p\n", reinterpret_cast<void*>(debugger->pc()));
1374    } else {
1375      printf(" ** Unknown identifier to print: %s **\n", identifier);
1376    }
1377
1378    return false;
1379  }
1380
1381  FormatToken* format_tok = format();
1382  VIXL_ASSERT(format_tok != NULL);
1383  if (format_tok->type_code() == 'i') {
1384    // TODO(all): Add support for instruction disassembly.
1385    printf(" ** unsupported format: instructions **\n");
1386    return false;
1387  }
1388
1389  if (tok->IsRegister()) {
1390    RegisterToken* reg_tok = RegisterToken::Cast(tok);
1391    Register reg = reg_tok->value();
1392    debugger->PrintRegister(reg, reg_tok->Name(), format_tok);
1393    return false;
1394  }
1395
1396  if (tok->IsFPRegister()) {
1397    FPRegister fpreg = FPRegisterToken::Cast(tok)->value();
1398    debugger->PrintFPRegister(fpreg, format_tok);
1399    return false;
1400  }
1401
1402  VIXL_UNREACHABLE();
1403  return false;
1404}
1405
1406
1407DebugCommand* PrintCommand::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->IsRegister() &&
1414      !target->IsFPRegister() &&
1415      !target->IsIdentifier()) {
1416    return new InvalidCommand(args, 1, "expects reg or identifier");
1417  }
1418
1419  FormatToken* format = NULL;
1420  int target_size = 0;
1421  if (target->IsRegister()) {
1422    Register reg = RegisterToken::Cast(target)->value();
1423    target_size = reg.SizeInBytes();
1424  } else if (target->IsFPRegister()) {
1425    FPRegister fpreg = FPRegisterToken::Cast(target)->value();
1426    target_size = fpreg.SizeInBytes();
1427  }
1428  // If the target is an identifier there must be no format. This is checked
1429  // in the switch statement below.
1430
1431  switch (args.size()) {
1432    case 2: {
1433      if (target->IsRegister()) {
1434        switch (target_size) {
1435          case 4: format = new Format<uint32_t>("%08" PRIx32, 'x'); break;
1436          case 8: format = new Format<uint64_t>("%016" PRIx64, 'x'); break;
1437          default: VIXL_UNREACHABLE();
1438        }
1439      } else if (target->IsFPRegister()) {
1440        switch (target_size) {
1441          case 4: format = new Format<float>("%8g", 'f'); break;
1442          case 8: format = new Format<double>("%8g", 'f'); break;
1443          default: VIXL_UNREACHABLE();
1444        }
1445      }
1446      break;
1447    }
1448    case 3: {
1449      if (target->IsIdentifier()) {
1450        return new InvalidCommand(args, 2,
1451            "format is only allowed with registers");
1452      }
1453
1454      Token* second = args[2];
1455      if (!second->IsFormat()) {
1456        return new InvalidCommand(args, 2, "expects format");
1457      }
1458      format = FormatToken::Cast(second);
1459
1460      if (format->SizeOf() > target_size) {
1461        return new InvalidCommand(args, 2, "format too wide");
1462      }
1463
1464      break;
1465    }
1466    default:
1467      return new InvalidCommand(args, -1, "too many arguments");
1468  }
1469
1470  return new PrintCommand(args[0], target, format);
1471}
1472
1473
1474bool ExamineCommand::Run(Debugger* debugger) {
1475  VIXL_ASSERT(debugger->IsDebuggerRunning());
1476
1477  uint8_t* address = target()->ToAddress(debugger);
1478  int64_t  amount = count()->value();
1479  if (format()->type_code() == 'i') {
1480    debugger->PrintInstructions(address, amount);
1481  } else {
1482    debugger->PrintMemory(address, format(), amount);
1483  }
1484
1485  return false;
1486}
1487
1488
1489void ExamineCommand::Print(FILE* out) {
1490  fprintf(out, "%s ", name());
1491  format()->Print(out);
1492  target()->Print(out);
1493}
1494
1495
1496DebugCommand* ExamineCommand::Build(std::vector<Token*> args) {
1497  if (args.size() < 2) {
1498    return new InvalidCommand(args, -1, "too few arguments");
1499  }
1500
1501  Token* target = args[1];
1502  if (!target->CanAddressMemory()) {
1503    return new InvalidCommand(args, 1, "expects address");
1504  }
1505
1506  FormatToken* format = NULL;
1507  IntegerToken* count = NULL;
1508
1509  switch (args.size()) {
1510    case 2: {  // mem addr[.x64] [10]
1511      format = new Format<uint64_t>("%016" PRIx64, 'x');
1512      count = new IntegerToken(10);
1513      break;
1514    }
1515    case 3: {  // mem addr.format [10]
1516               // mem addr[.x64] n
1517      Token* second = args[2];
1518      if (second->IsFormat()) {
1519        format = FormatToken::Cast(second);
1520        count = new IntegerToken(10);
1521        break;
1522      } else if (second->IsInteger()) {
1523        format = new Format<uint64_t>("%016" PRIx64, 'x');
1524        count = IntegerToken::Cast(second);
1525      } else {
1526        return new InvalidCommand(args, 2, "expects format or integer");
1527      }
1528      VIXL_UNREACHABLE();
1529      break;
1530    }
1531    case 4: {  // mem addr.format n
1532      Token* second = args[2];
1533      Token* third = args[3];
1534      if (!second->IsFormat() || !third->IsInteger()) {
1535        return new InvalidCommand(args, -1, "expects addr[.format] [n]");
1536      }
1537      format = FormatToken::Cast(second);
1538      count = IntegerToken::Cast(third);
1539      break;
1540    }
1541    default:
1542      return new InvalidCommand(args, -1, "too many arguments");
1543  }
1544
1545  return new ExamineCommand(args[0], target, format, count);
1546}
1547
1548
1549UnknownCommand::~UnknownCommand() {
1550  const int size = args_.size();
1551  for (int i = 0; i < size; ++i) {
1552    delete args_[i];
1553  }
1554}
1555
1556
1557bool UnknownCommand::Run(Debugger* debugger) {
1558  VIXL_ASSERT(debugger->IsDebuggerRunning());
1559  USE(debugger);
1560
1561  printf(" ** Unknown Command:");
1562  const int size = args_.size();
1563  for (int i = 0; i < size; ++i) {
1564    printf(" ");
1565    args_[i]->Print(stdout);
1566  }
1567  printf(" **\n");
1568
1569  return false;
1570}
1571
1572
1573InvalidCommand::~InvalidCommand() {
1574  const int size = args_.size();
1575  for (int i = 0; i < size; ++i) {
1576    delete args_[i];
1577  }
1578}
1579
1580
1581bool InvalidCommand::Run(Debugger* debugger) {
1582  VIXL_ASSERT(debugger->IsDebuggerRunning());
1583  USE(debugger);
1584
1585  printf(" ** Invalid Command:");
1586  const int size = args_.size();
1587  for (int i = 0; i < size; ++i) {
1588    printf(" ");
1589    if (i == index_) {
1590      printf(">>");
1591      args_[i]->Print(stdout);
1592      printf("<<");
1593    } else {
1594      args_[i]->Print(stdout);
1595    }
1596  }
1597  printf(" **\n");
1598  printf(" ** %s\n", cause_);
1599
1600  return false;
1601}
1602
1603}  // namespace vixl
1604
1605#endif  // USE_SIMULATOR
1606