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