Home | History | Annotate | Download | only in a64
      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 
     31 namespace vixl {
     32 
     33 // List of commands supported by the debugger.
     34 #define DEBUG_COMMAND_LIST(C)  \
     35 C(HelpCommand)                 \
     36 C(ContinueCommand)             \
     37 C(StepCommand)                 \
     38 C(DisasmCommand)               \
     39 C(PrintCommand)                \
     40 C(ExamineCommand)
     41 
     42 // Debugger command lines are broken up in token of different type to make
     43 // processing easier later on.
     44 class Token {
     45  public:
     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.
     65 template<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.
     78 class 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.
    103 class 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.
    121 class 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.
    144 class 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.
    163 class 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.
    187 class 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 
    205 template<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.
    224 class 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.
    243 class 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
    267 class 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 
    281 class 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 
    295 class 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 
    315 class DisasmCommand : public DebugCommand {
    316  public:
    317   static DebugCommand* Build(std::vector<Token*> args);
    318 
    319   static const char* kHelp;
    320   static const char* kAliases[];
    321   static const char* kArguments;
    322 };
    323 
    324 
    325 class PrintCommand : public DebugCommand {
    326  public:
    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 
    350 class 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.
    382 class 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.
    394 class 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 
    408 const char* HelpCommand::kAliases[] = { "help", NULL };
    409 const char* HelpCommand::kArguments = NULL;
    410 const char* HelpCommand::kHelp = "  Print this help.";
    411 
    412 const char* ContinueCommand::kAliases[] = { "continue", "c", NULL };
    413 const char* ContinueCommand::kArguments = NULL;
    414 const char* ContinueCommand::kHelp = "  Resume execution.";
    415 
    416 const char* StepCommand::kAliases[] = { "stepi", "si", NULL };
    417 const char* StepCommand::kArguments = "[n = 1]";
    418 const char* StepCommand::kHelp = "  Execute n next instruction(s).";
    419 
    420 const char* DisasmCommand::kAliases[] = { "disasm", "di", NULL };
    421 const char* DisasmCommand::kArguments = "[n = 10]";
    422 const char* DisasmCommand::kHelp =
    423   "  Disassemble n instruction(s) at pc.\n"
    424   "  This command is equivalent to x pc.i [n = 10]."
    425 ;
    426 
    427 const char* PrintCommand::kAliases[] = { "print", "p", NULL };
    428 const char* PrintCommand::kArguments =  "<entity>[.format]";
    429 const char* PrintCommand::kHelp =
    430   "  Print the given entity according to the given format.\n"
    431   "  The format parameter only affects individual registers; it is ignored\n"
    432   "  for other entities.\n"
    433   "  <entity> can be one of the following:\n"
    434   "   * A register name (such as x0, s1, ...).\n"
    435   "   * 'regs', to print all integer (W and X) registers.\n"
    436   "   * 'fpregs' to print all floating-point (S and D) registers.\n"
    437   "   * 'sysregs' to print all system registers (including NZCV).\n"
    438   "   * 'pc' to print the current program counter.\n"
    439 ;
    440 
    441 const char* ExamineCommand::kAliases[] = { "m", "mem", "x", NULL };
    442 const char* ExamineCommand::kArguments = "<addr>[.format] [n = 10]";
    443 const char* ExamineCommand::kHelp =
    444   "  Examine memory. Print n items of memory at address <addr> according to\n"
    445   "  the given [.format].\n"
    446   "  Addr can be an immediate address, a register name or pc.\n"
    447   "  Format is made of a type letter: 'x' (hexadecimal), 's' (signed), 'u'\n"
    448   "  (unsigned), 'f' (floating point), i (instruction) and a size in bits\n"
    449   "  when appropriate (8, 16, 32, 64)\n"
    450   "  E.g 'x sp.x64' will print 10 64-bit words from the stack in\n"
    451   "  hexadecimal format."
    452 ;
    453 
    454 const char* RegisterToken::kXAliases[kNumberOfRegisters][kMaxAliasNumber] = {
    455   { "x0", NULL },
    456   { "x1", NULL },
    457   { "x2", NULL },
    458   { "x3", NULL },
    459   { "x4", NULL },
    460   { "x5", NULL },
    461   { "x6", NULL },
    462   { "x7", NULL },
    463   { "x8", NULL },
    464   { "x9", NULL },
    465   { "x10", NULL },
    466   { "x11", NULL },
    467   { "x12", NULL },
    468   { "x13", NULL },
    469   { "x14", NULL },
    470   { "x15", NULL },
    471   { "ip0", "x16", NULL },
    472   { "ip1", "x17", NULL },
    473   { "x18", "pr", NULL },
    474   { "x19", NULL },
    475   { "x20", NULL },
    476   { "x21", NULL },
    477   { "x22", NULL },
    478   { "x23", NULL },
    479   { "x24", NULL },
    480   { "x25", NULL },
    481   { "x26", NULL },
    482   { "x27", NULL },
    483   { "x28", NULL },
    484   { "fp", "x29", NULL },
    485   { "lr", "x30", NULL },
    486   { "sp", NULL}
    487 };
    488 
    489 const char* RegisterToken::kWAliases[kNumberOfRegisters][kMaxAliasNumber] = {
    490   { "w0", NULL },
    491   { "w1", NULL },
    492   { "w2", NULL },
    493   { "w3", NULL },
    494   { "w4", NULL },
    495   { "w5", NULL },
    496   { "w6", NULL },
    497   { "w7", NULL },
    498   { "w8", NULL },
    499   { "w9", NULL },
    500   { "w10", NULL },
    501   { "w11", NULL },
    502   { "w12", NULL },
    503   { "w13", NULL },
    504   { "w14", NULL },
    505   { "w15", NULL },
    506   { "w16", NULL },
    507   { "w17", NULL },
    508   { "w18", NULL },
    509   { "w19", NULL },
    510   { "w20", NULL },
    511   { "w21", NULL },
    512   { "w22", NULL },
    513   { "w23", NULL },
    514   { "w24", NULL },
    515   { "w25", NULL },
    516   { "w26", NULL },
    517   { "w27", NULL },
    518   { "w28", NULL },
    519   { "w29", NULL },
    520   { "w30", NULL },
    521   { "wsp", NULL }
    522 };
    523 
    524 
    525 Debugger::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 
    538 void 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 
    551 void 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 
    571 void 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 
    599 void 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 
    622 void 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 
    647 void 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 
    670 void Debugger::LogSystemRegisters() {
    671   if (log_parameters_ & LOG_SYS_REGS) PrintSystemRegisters();
    672 }
    673 
    674 
    675 void Debugger::LogRegisters() {
    676   if (log_parameters_ & LOG_REGS) PrintRegisters();
    677 }
    678 
    679 
    680 void Debugger::LogFPRegisters() {
    681   if (log_parameters_ & LOG_FP_REGS) PrintFPRegisters();
    682 }
    683 
    684 
    685 void 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?
    695 char* 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 
    726 void 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 
    764 void 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 
    774 void 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 
    784 void 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 
    811 void 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 
    832 static 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 
    857 static 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 
    882 uint8_t* Token::ToAddress(Debugger* debugger) const {
    883   USE(debugger);
    884   VIXL_UNREACHABLE();
    885   return NULL;
    886 }
    887 
    888 
    889 Token* 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 
    926 uint8_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 
    935 void RegisterToken::Print(FILE* out) const {
    936   VIXL_ASSERT(value().IsValid());
    937   fprintf(out, "[Register %s]", Name());
    938 }
    939 
    940 
    941 const 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 
    950 Token* 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 
    971 void 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 
    978 Token* 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 
   1010 uint8_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 
   1018 void IdentifierToken::Print(FILE* out) const {
   1019   fprintf(out, "[Identifier %s]", value());
   1020 }
   1021 
   1022 
   1023 Token* 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 
   1041 uint8_t* AddressToken::ToAddress(Debugger* debugger) const {
   1042   USE(debugger);
   1043   return value();
   1044 }
   1045 
   1046 
   1047 void AddressToken::Print(FILE* out) const {
   1048   fprintf(out, "[Address %p]", value());
   1049 }
   1050 
   1051 
   1052 Token* 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 
   1067 void IntegerToken::Print(FILE* out) const {
   1068   fprintf(out, "[Integer %" PRId64 "]", value());
   1069 }
   1070 
   1071 
   1072 Token* 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 
   1082 Token* 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 
   1153 template<typename T>
   1154 void 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 
   1160 void UnknownToken::Print(FILE* out) const {
   1161   fprintf(out, "[Unknown %s]", unknown_);
   1162 }
   1163 
   1164 
   1165 void DebugCommand::Print(FILE* out) {
   1166   fprintf(out, "%s", name());
   1167 }
   1168 
   1169 
   1170 bool 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 
   1181 DebugCommand* 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 
   1225 void 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 
   1243 bool 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 
   1259 DebugCommand* 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 
   1268 bool 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 
   1276 DebugCommand* 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 
   1285 bool 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 
   1299 void StepCommand::Print(FILE* out) {
   1300   fprintf(out, "%s %" PRId64 "", name(), count());
   1301 }
   1302 
   1303 
   1304 DebugCommand* 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 
   1327 DebugCommand* 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 
   1353 void PrintCommand::Print(FILE* out) {
   1354   fprintf(out, "%s ", name());
   1355   target()->Print(out);
   1356   if (format() != NULL) format()->Print(out);
   1357 }
   1358 
   1359 
   1360 bool 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 
   1407 DebugCommand* 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 
   1474 bool 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 
   1489 void ExamineCommand::Print(FILE* out) {
   1490   fprintf(out, "%s ", name());
   1491   format()->Print(out);
   1492   target()->Print(out);
   1493 }
   1494 
   1495 
   1496 DebugCommand* 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 
   1549 UnknownCommand::~UnknownCommand() {
   1550   const int size = args_.size();
   1551   for (int i = 0; i < size; ++i) {
   1552     delete args_[i];
   1553   }
   1554 }
   1555 
   1556 
   1557 bool 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 
   1573 InvalidCommand::~InvalidCommand() {
   1574   const int size = args_.size();
   1575   for (int i = 0; i < size; ++i) {
   1576     delete args_[i];
   1577   }
   1578 }
   1579 
   1580 
   1581 bool 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