1b78f13911bfe6eda303e91ef215c87a165aae8aeAlexandre Rames// Copyright 2014, VIXL authors 2ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// All rights reserved. 3ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// 4ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Redistribution and use in source and binary forms, with or without 5ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// modification, are permitted provided that the following conditions are met: 6ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// 7ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// * Redistributions of source code must retain the above copyright notice, 8ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// this list of conditions and the following disclaimer. 9ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// * Redistributions in binary form must reproduce the above copyright notice, 10ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// this list of conditions and the following disclaimer in the documentation 11ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// and/or other materials provided with the distribution. 12ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// * Neither the name of ARM Limited nor the names of its contributors may be 13ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// used to endorse or promote products derived from this software without 14ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// specific prior written permission. 15ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// 16ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// THIS SOFTWARE IS PROVIDED BY ARM LIMITED AND CONTRIBUTORS "AS IS" AND ANY 17ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// DISCLAIMED. IN NO EVENT SHALL ARM LIMITED BE LIABLE FOR ANY DIRECT, INDIRECT, 20ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 22ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 23ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 24ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 25ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 271e85b7f2e8ad2bfb233de29405aade635ed207cePierre Langlois#ifdef VIXL_INCLUDE_SIMULATOR_AARCH64 28b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl 29b49bdb7996e603555eba4c8b56c7325e3e737ab6Alexandre Rames#include "debugger-aarch64.h" 30ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 31ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlnamespace vixl { 3288c46b84df005638546de5e4e965bdcc31352f48Pierre Langloisnamespace aarch64 { 33ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 34ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// List of commands supported by the debugger. 350f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl#define DEBUG_COMMAND_LIST(C) \ 360f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl C(HelpCommand) \ 370f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl C(ContinueCommand) \ 380f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl C(StepCommand) \ 3980497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames C(SkipCommand) \ 400f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl C(DisasmCommand) \ 410f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl C(PrintCommand) \ 420f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl C(ExamineCommand) 43ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 44ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Debugger command lines are broken up in token of different type to make 45ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// processing easier later on. 46ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlclass Token { 47ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl public: 48ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl virtual ~Token() {} 49ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 50ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Token type. 51ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl virtual bool IsRegister() const { return false; } 52ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl virtual bool IsFPRegister() const { return false; } 53ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl virtual bool IsIdentifier() const { return false; } 54ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl virtual bool IsAddress() const { return false; } 55ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl virtual bool IsInteger() const { return false; } 56ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl virtual bool IsFormat() const { return false; } 57ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl virtual bool IsUnknown() const { return false; } 58ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Token properties. 59ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl virtual bool CanAddressMemory() const { return false; } 60684cd2a7f5845539b58d0da7e012e39df49ceff0armvixl virtual uint8_t* ToAddress(Debugger* debugger) const = 0; 61ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl virtual void Print(FILE* out = stdout) const = 0; 62ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 63ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl static Token* Tokenize(const char* arg); 64ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}; 65ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 66ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Tokens often hold one value. 670f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixltemplate <typename T> 680f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixlclass ValueToken : public Token { 69ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl public: 70ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl explicit ValueToken(T value) : value_(value) {} 71ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ValueToken() {} 72ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 73ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl T value() const { return value_; } 74ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 753fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois VIXL_NO_RETURN virtual uint8_t* ToAddress(Debugger* debugger) const 763fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois VIXL_OVERRIDE { 77684cd2a7f5845539b58d0da7e012e39df49ceff0armvixl USE(debugger); 78684cd2a7f5845539b58d0da7e012e39df49ceff0armvixl VIXL_ABORT(); 79684cd2a7f5845539b58d0da7e012e39df49ceff0armvixl } 80684cd2a7f5845539b58d0da7e012e39df49ceff0armvixl 81ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl protected: 82ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl T value_; 83ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}; 84ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 85ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Integer registers (X or W) and their aliases. 86ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Format: wn or xn with 0 <= n < 32 or a name in the aliases list. 87ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlclass RegisterToken : public ValueToken<const Register> { 88ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl public: 89ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl explicit RegisterToken(const Register reg) 90ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl : ValueToken<const Register>(reg) {} 91ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 923fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois virtual bool IsRegister() const VIXL_OVERRIDE { return true; } 933fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois virtual bool CanAddressMemory() const VIXL_OVERRIDE { 943fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois return value().Is64Bits(); 953fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois } 963fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois virtual uint8_t* ToAddress(Debugger* debugger) const VIXL_OVERRIDE; 973fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois virtual void Print(FILE* out = stdout) const VIXL_OVERRIDE; 98ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char* Name() const; 99ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 100ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl static Token* Tokenize(const char* arg); 101ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl static RegisterToken* Cast(Token* tok) { 102b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl VIXL_ASSERT(tok->IsRegister()); 103ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return reinterpret_cast<RegisterToken*>(tok); 104ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 105ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 106ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl private: 107ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl static const int kMaxAliasNumber = 4; 108ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl static const char* kXAliases[kNumberOfRegisters][kMaxAliasNumber]; 109ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl static const char* kWAliases[kNumberOfRegisters][kMaxAliasNumber]; 110ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}; 111ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 112ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Floating point registers (D or S). 113ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Format: sn or dn with 0 <= n < 32. 114ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlclass FPRegisterToken : public ValueToken<const FPRegister> { 115ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl public: 116ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl explicit FPRegisterToken(const FPRegister fpreg) 117ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl : ValueToken<const FPRegister>(fpreg) {} 118ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1193fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois virtual bool IsFPRegister() const VIXL_OVERRIDE { return true; } 1203fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois virtual void Print(FILE* out = stdout) const VIXL_OVERRIDE; 121ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 122ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl static Token* Tokenize(const char* arg); 123ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl static FPRegisterToken* Cast(Token* tok) { 124b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl VIXL_ASSERT(tok->IsFPRegister()); 125ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return reinterpret_cast<FPRegisterToken*>(tok); 126ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 127ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}; 128ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 129ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 130ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Non-register identifiers. 131ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Format: Alphanumeric string starting with a letter. 132ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlclass IdentifierToken : public ValueToken<char*> { 133ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl public: 134ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl explicit IdentifierToken(const char* name) { 135db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl size_t size = strlen(name) + 1; 136ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl value_ = new char[size]; 137ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl strncpy(value_, name, size); 138ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 139ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl virtual ~IdentifierToken() { delete[] value_; } 140ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1413fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois virtual bool IsIdentifier() const VIXL_OVERRIDE { return true; } 1423fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois virtual bool CanAddressMemory() const VIXL_OVERRIDE { 1433fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois return strcmp(value(), "pc") == 0; 1443fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois } 1453fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois virtual uint8_t* ToAddress(Debugger* debugger) const VIXL_OVERRIDE; 1463fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois virtual void Print(FILE* out = stdout) const VIXL_OVERRIDE; 147ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 148ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl static Token* Tokenize(const char* arg); 149ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl static IdentifierToken* Cast(Token* tok) { 150b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl VIXL_ASSERT(tok->IsIdentifier()); 151ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return reinterpret_cast<IdentifierToken*>(tok); 152ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 153ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}; 154ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 155ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// 64-bit address literal. 156ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Format: 0x... with up to 16 hexadecimal digits. 157ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlclass AddressToken : public ValueToken<uint8_t*> { 158ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl public: 159ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl explicit AddressToken(uint8_t* address) : ValueToken<uint8_t*>(address) {} 160ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1613fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois virtual bool IsAddress() const VIXL_OVERRIDE { return true; } 1623fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois virtual bool CanAddressMemory() const VIXL_OVERRIDE { return true; } 1633fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois virtual uint8_t* ToAddress(Debugger* debugger) const VIXL_OVERRIDE; 1643fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois virtual void Print(FILE* out = stdout) const VIXL_OVERRIDE; 165ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 166ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl static Token* Tokenize(const char* arg); 167ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl static AddressToken* Cast(Token* tok) { 168b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl VIXL_ASSERT(tok->IsAddress()); 169ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return reinterpret_cast<AddressToken*>(tok); 170ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 171ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}; 172ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 173ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 174ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// 64-bit decimal integer literal. 175ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Format: n. 176ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlclass IntegerToken : public ValueToken<int64_t> { 177ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl public: 178db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl explicit IntegerToken(int64_t value) : ValueToken<int64_t>(value) {} 179ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1803fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois virtual bool IsInteger() const VIXL_OVERRIDE { return true; } 1813fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois virtual void Print(FILE* out = stdout) const VIXL_OVERRIDE; 182ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 183ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl static Token* Tokenize(const char* arg); 184ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl static IntegerToken* Cast(Token* tok) { 185b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl VIXL_ASSERT(tok->IsInteger()); 186ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return reinterpret_cast<IntegerToken*>(tok); 187ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 188ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}; 189ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 190ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Literal describing how to print a chunk of data (up to 64 bits). 191f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl// Format: .ln 192f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl// where l (letter) is one of 193f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl// * x: hexadecimal 194ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// * s: signed integer 195ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// * u: unsigned integer 196f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl// * f: floating point 197f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl// * i: instruction 198f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl// and n (size) is one of 8, 16, 32 and 64. n should be omitted for 199f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl// instructions. 200ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlclass FormatToken : public Token { 201ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl public: 202ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FormatToken() {} 203ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 2043fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois virtual bool IsFormat() const VIXL_OVERRIDE { return true; } 205ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl virtual int SizeOf() const = 0; 206be0e12aec9f1e1b55004a3d34f80693bf985017fPierre Langlois virtual char GetTypeCode() const = 0; 207ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl virtual void PrintData(void* data, FILE* out = stdout) const = 0; 2083fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois virtual void Print(FILE* out = stdout) const VIXL_OVERRIDE = 0; 209ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 2103fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois VIXL_NO_RETURN virtual uint8_t* ToAddress(Debugger* debugger) const 2113fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois VIXL_OVERRIDE { 212684cd2a7f5845539b58d0da7e012e39df49ceff0armvixl USE(debugger); 213684cd2a7f5845539b58d0da7e012e39df49ceff0armvixl VIXL_ABORT(); 214684cd2a7f5845539b58d0da7e012e39df49ceff0armvixl } 215684cd2a7f5845539b58d0da7e012e39df49ceff0armvixl 216ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl static Token* Tokenize(const char* arg); 217ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl static FormatToken* Cast(Token* tok) { 218b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl VIXL_ASSERT(tok->IsFormat()); 219ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return reinterpret_cast<FormatToken*>(tok); 220ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 221ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}; 222ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 223ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 2240f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixltemplate <typename T> 2250f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixlclass Format : public FormatToken { 226ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl public: 227f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl Format(const char* fmt, char type_code) : fmt_(fmt), type_code_(type_code) {} 228ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 2293fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois virtual int SizeOf() const VIXL_OVERRIDE { return sizeof(T); } 2303fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois virtual char GetTypeCode() const VIXL_OVERRIDE { return type_code_; } 2313fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois virtual void PrintData(void* data, FILE* out = stdout) const VIXL_OVERRIDE { 232ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl T value; 233ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl memcpy(&value, data, sizeof(value)); 234ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl fprintf(out, fmt_, value); 235ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 2363fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois virtual void Print(FILE* out = stdout) const VIXL_OVERRIDE; 237ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 238ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl private: 239ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char* fmt_; 240f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl char type_code_; 241ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}; 242ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 243ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Tokens which don't fit any of the above. 244ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlclass UnknownToken : public Token { 245ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl public: 246ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl explicit UnknownToken(const char* arg) { 247db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl size_t size = strlen(arg) + 1; 248ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl unknown_ = new char[size]; 249ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl strncpy(unknown_, arg, size); 250ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 251ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl virtual ~UnknownToken() { delete[] unknown_; } 2523fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois VIXL_NO_RETURN virtual uint8_t* ToAddress(Debugger* debugger) const 2533fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois VIXL_OVERRIDE { 254684cd2a7f5845539b58d0da7e012e39df49ceff0armvixl USE(debugger); 255684cd2a7f5845539b58d0da7e012e39df49ceff0armvixl VIXL_ABORT(); 256684cd2a7f5845539b58d0da7e012e39df49ceff0armvixl } 257ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 2583fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois virtual bool IsUnknown() const VIXL_OVERRIDE { return true; } 2593fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois virtual void Print(FILE* out = stdout) const VIXL_OVERRIDE; 260ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 261ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl private: 262ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl char* unknown_; 263ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}; 264ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 265ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 266ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// All debugger commands must subclass DebugCommand and implement Run, Print 267ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// and Build. Commands must also define kHelp and kAliases. 268ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlclass DebugCommand { 269ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl public: 270ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl explicit DebugCommand(Token* name) : name_(IdentifierToken::Cast(name)) {} 271ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl DebugCommand() : name_(NULL) {} 272ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl virtual ~DebugCommand() { delete name_; } 273ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 274ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char* name() { return name_->value(); } 2754886a725301d6cc426c2a8151bb48fbec3946b3aAlexandre Rames // Run the command on the given debugger. 2764886a725301d6cc426c2a8151bb48fbec3946b3aAlexandre Rames // Return `true` if control should be given back to the debugger. 2770f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl virtual bool Run(Debugger* debugger) = 0; 278ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl virtual void Print(FILE* out = stdout); 279ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 280ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl static bool Match(const char* name, const char** aliases); 281ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl static DebugCommand* Parse(char* line); 282ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl static void PrintHelp(const char** aliases, 283ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char* args, 284ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char* help); 285ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 286ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl private: 287ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl IdentifierToken* name_; 288ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}; 289ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 290ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// For all commands below see their respective kHelp and kAliases in 291d3832965c62a8ad461b9ea9eb0994ca6b0a3da2cAlexandre Rames// debugger-aarch64.cc 292ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlclass HelpCommand : public DebugCommand { 293ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl public: 294ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl explicit HelpCommand(Token* name) : DebugCommand(name) {} 295ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 2963fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois virtual bool Run(Debugger* debugger) VIXL_OVERRIDE; 297ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 298ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl static DebugCommand* Build(std::vector<Token*> args); 299ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 300ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl static const char* kHelp; 301ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl static const char* kAliases[]; 302ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl static const char* kArguments; 303ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}; 304ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 305ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 306ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlclass ContinueCommand : public DebugCommand { 307ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl public: 308ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl explicit ContinueCommand(Token* name) : DebugCommand(name) {} 309ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 3103fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois virtual bool Run(Debugger* debugger) VIXL_OVERRIDE; 311ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 312ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl static DebugCommand* Build(std::vector<Token*> args); 313ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 314ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl static const char* kHelp; 315ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl static const char* kAliases[]; 316ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl static const char* kArguments; 317ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}; 318ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 319ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 320ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlclass StepCommand : public DebugCommand { 321ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl public: 322ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl StepCommand(Token* name, IntegerToken* count) 323ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl : DebugCommand(name), count_(count) {} 324ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl virtual ~StepCommand() { delete count_; } 325ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 326ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl int64_t count() { return count_->value(); } 3273fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois virtual bool Run(Debugger* debugger) VIXL_OVERRIDE; 3283fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois virtual void Print(FILE* out = stdout) VIXL_OVERRIDE; 329ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 330ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl static DebugCommand* Build(std::vector<Token*> args); 331ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 332ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl static const char* kHelp; 333ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl static const char* kAliases[]; 334ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl static const char* kArguments; 335ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 336ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl private: 337ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl IntegerToken* count_; 338ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}; 339ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 34080497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Ramesclass SkipCommand : public DebugCommand { 34180497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames public: 34280497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames SkipCommand(Token* name, IntegerToken* count) 34380497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames : DebugCommand(name), count_(count) {} 34480497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames virtual ~SkipCommand() { delete count_; } 34580497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames 34680497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames int64_t count() { return count_->value(); } 3473fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois virtual bool Run(Debugger* debugger) VIXL_OVERRIDE; 3483fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois virtual void Print(FILE* out = stdout) VIXL_OVERRIDE; 34980497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames 35080497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames static DebugCommand* Build(std::vector<Token*> args); 35180497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames 35280497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames static const char* kHelp; 35380497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames static const char* kAliases[]; 35480497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames static const char* kArguments; 35580497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames 35680497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames private: 35780497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames IntegerToken* count_; 35880497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames}; 35980497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames 360ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlclass DisasmCommand : public DebugCommand { 361ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl public: 362ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl static DebugCommand* Build(std::vector<Token*> args); 363ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 364ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl static const char* kHelp; 365ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl static const char* kAliases[]; 366ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl static const char* kArguments; 367ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}; 368ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 369ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 370ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlclass PrintCommand : public DebugCommand { 371ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl public: 372f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl PrintCommand(Token* name, Token* target, FormatToken* format) 373f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl : DebugCommand(name), target_(target), format_(format) {} 374f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl virtual ~PrintCommand() { 375f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl delete target_; 376f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl delete format_; 377f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl } 378ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 379ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Token* target() { return target_; } 380f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl FormatToken* format() { return format_; } 3813fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois virtual bool Run(Debugger* debugger) VIXL_OVERRIDE; 3823fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois virtual void Print(FILE* out = stdout) VIXL_OVERRIDE; 383ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 384ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl static DebugCommand* Build(std::vector<Token*> args); 385ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 386ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl static const char* kHelp; 387ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl static const char* kAliases[]; 388ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl static const char* kArguments; 389ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 390ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl private: 391ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Token* target_; 392f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl FormatToken* format_; 393ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}; 394ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 395f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixlclass ExamineCommand : public DebugCommand { 396ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl public: 397f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl ExamineCommand(Token* name, 398f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl Token* target, 399f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl FormatToken* format, 400f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl IntegerToken* count) 401f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl : DebugCommand(name), target_(target), format_(format), count_(count) {} 402f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl virtual ~ExamineCommand() { 403ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl delete target_; 404ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl delete format_; 405f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl delete count_; 406ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 407ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 408ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Token* target() { return target_; } 409ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FormatToken* format() { return format_; } 410f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl IntegerToken* count() { return count_; } 4113fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois virtual bool Run(Debugger* debugger) VIXL_OVERRIDE; 4123fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois virtual void Print(FILE* out = stdout) VIXL_OVERRIDE; 413ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 414ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl static DebugCommand* Build(std::vector<Token*> args); 415ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 416ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl static const char* kHelp; 417ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl static const char* kAliases[]; 418ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl static const char* kArguments; 419ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 420ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl private: 421ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Token* target_; 422ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FormatToken* format_; 423f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl IntegerToken* count_; 424ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}; 425ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 426ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Commands which name does not match any of the known commnand. 427ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlclass UnknownCommand : public DebugCommand { 428ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl public: 429ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl explicit UnknownCommand(std::vector<Token*> args) : args_(args) {} 430ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl virtual ~UnknownCommand(); 431ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 4323fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois virtual bool Run(Debugger* debugger) VIXL_OVERRIDE; 433ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 434ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl private: 435ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl std::vector<Token*> args_; 436ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}; 437ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 438ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Commands which name match a known command but the syntax is invalid. 439ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlclass InvalidCommand : public DebugCommand { 440ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl public: 441ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl InvalidCommand(std::vector<Token*> args, int index, const char* cause) 442ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl : args_(args), index_(index), cause_(cause) {} 443ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl virtual ~InvalidCommand(); 444ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 4453fac43c1a101f98f116e752b80abc122d32b83acPierre Langlois virtual bool Run(Debugger* debugger) VIXL_OVERRIDE; 446ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 447ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl private: 448ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl std::vector<Token*> args_; 449ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl int index_; 450ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char* cause_; 451ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}; 452ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 4530f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixlconst char* HelpCommand::kAliases[] = {"help", NULL}; 454ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlconst char* HelpCommand::kArguments = NULL; 455f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixlconst char* HelpCommand::kHelp = " Print this help."; 456ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 4570f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixlconst char* ContinueCommand::kAliases[] = {"continue", "c", NULL}; 458ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlconst char* ContinueCommand::kArguments = NULL; 459f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixlconst char* ContinueCommand::kHelp = " Resume execution."; 460ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 4610f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixlconst char* StepCommand::kAliases[] = {"stepi", "si", NULL}; 462ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlconst char* StepCommand::kArguments = "[n = 1]"; 463f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixlconst char* StepCommand::kHelp = " Execute n next instruction(s)."; 464ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 46580497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Ramesconst char* SkipCommand::kAliases[] = {"skip", NULL}; 46680497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Ramesconst char* SkipCommand::kArguments = "[n = 1]"; 46780497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Ramesconst char* SkipCommand::kHelp = " Skip the next n instruction(s)."; 46880497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames 4690f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixlconst char* DisasmCommand::kAliases[] = {"disasm", "di", NULL}; 470f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixlconst char* DisasmCommand::kArguments = "[n = 10]"; 471ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlconst char* DisasmCommand::kHelp = 4720f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl " Disassemble n instruction(s) at pc.\n" 4730f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl " This command is equivalent to x pc.i [n = 10]."; 474ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 4750f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixlconst char* PrintCommand::kAliases[] = {"print", "p", NULL}; 4760f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixlconst char* PrintCommand::kArguments = "<entity>[.format]"; 477ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlconst char* PrintCommand::kHelp = 4780f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl " Print the given entity according to the given format.\n" 4790f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl " The format parameter only affects individual registers; it is ignored\n" 4800f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl " for other entities.\n" 4810f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl " <entity> can be one of the following:\n" 4820f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl " * A register name (such as x0, s1, ...).\n" 4830f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl " * 'regs', to print all integer (W and X) registers.\n" 4840f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl " * 'fpregs' to print all floating-point (S and D) registers.\n" 4850f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl " * 'sysregs' to print all system registers (including NZCV).\n" 4860f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl " * 'pc' to print the current program counter.\n"; 4870f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl 4880f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixlconst char* ExamineCommand::kAliases[] = {"m", "mem", "x", NULL}; 489f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixlconst char* ExamineCommand::kArguments = "<addr>[.format] [n = 10]"; 490f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixlconst char* ExamineCommand::kHelp = 4910f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl " Examine memory. Print n items of memory at address <addr> according to\n" 4920f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl " the given [.format].\n" 4930f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl " Addr can be an immediate address, a register name or pc.\n" 4940f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl " Format is made of a type letter: 'x' (hexadecimal), 's' (signed), 'u'\n" 4950f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl " (unsigned), 'f' (floating point), i (instruction) and a size in bits\n" 4960f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl " when appropriate (8, 16, 32, 64)\n" 4970f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl " E.g 'x sp.x64' will print 10 64-bit words from the stack in\n" 4980f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl " hexadecimal format."; 4990f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl 5000f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixlconst char* RegisterToken::kXAliases[kNumberOfRegisters][kMaxAliasNumber] = 5010f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl {{"x0", NULL}, 5020f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl {"x1", NULL}, 5030f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl {"x2", NULL}, 5040f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl {"x3", NULL}, 5050f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl {"x4", NULL}, 5060f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl {"x5", NULL}, 5070f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl {"x6", NULL}, 5080f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl {"x7", NULL}, 5090f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl {"x8", NULL}, 5100f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl {"x9", NULL}, 5110f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl {"x10", NULL}, 5120f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl {"x11", NULL}, 5130f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl {"x12", NULL}, 5140f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl {"x13", NULL}, 5150f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl {"x14", NULL}, 5160f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl {"x15", NULL}, 5170f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl {"ip0", "x16", NULL}, 5180f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl {"ip1", "x17", NULL}, 5190f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl {"x18", "pr", NULL}, 5200f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl {"x19", NULL}, 5210f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl {"x20", NULL}, 5220f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl {"x21", NULL}, 5230f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl {"x22", NULL}, 5240f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl {"x23", NULL}, 5250f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl {"x24", NULL}, 5260f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl {"x25", NULL}, 5270f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl {"x26", NULL}, 5280f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl {"x27", NULL}, 5290f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl {"x28", NULL}, 5300f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl {"fp", "x29", NULL}, 5310f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl {"lr", "x30", NULL}, 5320f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl {"sp", NULL}}; 5330f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl 5340f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixlconst char* RegisterToken::kWAliases[kNumberOfRegisters][kMaxAliasNumber] = 5350f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl {{"w0", NULL}, 5360f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl {"w1", NULL}, 5370f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl {"w2", NULL}, 5380f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl {"w3", NULL}, 5390f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl {"w4", NULL}, 5400f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl {"w5", NULL}, 5410f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl {"w6", NULL}, 5420f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl {"w7", NULL}, 5430f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl {"w8", NULL}, 5440f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl {"w9", NULL}, 5450f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl {"w10", NULL}, 5460f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl {"w11", NULL}, 5470f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl {"w12", NULL}, 5480f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl {"w13", NULL}, 5490f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl {"w14", NULL}, 5500f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl {"w15", NULL}, 5510f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl {"w16", NULL}, 5520f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl {"w17", NULL}, 5530f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl {"w18", NULL}, 5540f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl {"w19", NULL}, 5550f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl {"w20", NULL}, 5560f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl {"w21", NULL}, 5570f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl {"w22", NULL}, 5580f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl {"w23", NULL}, 5590f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl {"w24", NULL}, 5600f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl {"w25", NULL}, 5610f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl {"w26", NULL}, 5620f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl {"w27", NULL}, 5630f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl {"w28", NULL}, 5640f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl {"w29", NULL}, 5650f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl {"w30", NULL}, 5660f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl {"wsp", NULL}}; 567ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 568ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 569ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlDebugger::Debugger(Decoder* decoder, FILE* stream) 570ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl : Simulator(decoder, stream), 5710d68001a97c8b59c52fab68fddd46e8591bec15eAlexandre Rames debugger_active_(false), 572ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl steps_(0), 573ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl last_command_(NULL) { 574ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl disasm_ = new PrintDisassembler(stdout); 575ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl printer_ = new Decoder(); 576ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl printer_->AppendVisitor(disasm_); 577ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 578ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 579db6443499376478f5281607a3923e6ffc4c8d8ecarmvixlDebugger::~Debugger() { 580db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl delete disasm_; 581db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl delete printer_; 582db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl} 583db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl 584ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 585ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Debugger::Run() { 5860f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl // Flush any written registers before executing anything, so that 5870f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl // manually-set registers are logged _before_ the first instruction. 5880f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl LogAllWrittenRegisters(); 5890f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl 590ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl while (pc_ != kEndOfSimAddress) { 5910d68001a97c8b59c52fab68fddd46e8591bec15eAlexandre Rames if (IsDebuggerActive()) RunDebuggerShell(); 592ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ExecuteInstruction(); 593ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 594ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 595ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 596ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 59780497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Ramesvoid Debugger::PrintInstructions(const void* address, 59880497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames int64_t count, 59980497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames const char* prefix) { 600ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (count == 0) { 601ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return; 602ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 603ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 604c68cb64496485710cdb5b8480f8fee287058c93farmvixl const Instruction* from = Instruction::CastConst(address); 605ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (count < 0) { 606ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl count = -count; 607ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl from -= (count - 1) * kInstructionSize; 608ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 609c68cb64496485710cdb5b8480f8fee287058c93farmvixl const Instruction* to = from + count * kInstructionSize; 610ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 6110f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl for (const Instruction* current = from; current < to; 61288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois current = current->GetNextInstruction()) { 61380497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames printf("%s", prefix); 614ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl printer_->Decode(current); 615ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 616ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 617ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 618ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 619ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Debugger::PrintMemory(const uint8_t* address, 620f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl const FormatToken* format, 621f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl int64_t count) { 622ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (count == 0) { 623ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return; 624ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 625ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 626ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const uint8_t* from = address; 627ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl int size = format->SizeOf(); 628ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (count < 0) { 629ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl count = -count; 630ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl from -= (count - 1) * size; 631ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 632ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const uint8_t* to = from + count * size; 633ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 634ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl for (const uint8_t* current = from; current < to; current += size) { 635f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl if (((current - from) % 8) == 0) { 6360f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl printf("\n%p: ", reinterpret_cast<const void*>(current)); 637ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 638ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 6395289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl uint64_t data = Memory::Read<uint64_t>(current); 640ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl format->PrintData(&data); 641ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl printf(" "); 642ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 643ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl printf("\n\n"); 644ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 645ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 646ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 647f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixlvoid Debugger::PrintRegister(const Register& target_reg, 648f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl const char* name, 649f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl const FormatToken* format) { 65088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const uint64_t reg_size = target_reg.GetSizeInBits(); 651f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl const uint64_t format_size = format->SizeOf() * 8; 652f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl const uint64_t count = reg_size / format_size; 653f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl const uint64_t mask = 0xffffffffffffffff >> (64 - format_size); 6540f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl const uint64_t reg_value = 65588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ReadRegister<uint64_t>(target_reg.GetCode(), Reg31IsStackPointer); 656b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl VIXL_ASSERT(count > 0); 657f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl 658f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl printf("%s = ", name); 659f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl for (uint64_t i = 1; i <= count; i++) { 660f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl uint64_t data = reg_value >> (reg_size - (i * format_size)); 661f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl data &= mask; 662f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl format->PrintData(&data); 663f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl printf(" "); 664f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl } 665f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl printf("\n"); 666f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl} 667f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl 668f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl 6695289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl// TODO(all): fix this for vector registers. 670f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixlvoid Debugger::PrintFPRegister(const FPRegister& target_fpreg, 671f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl const FormatToken* format) { 67288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const unsigned fpreg_size = target_fpreg.GetSizeInBits(); 673f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl const uint64_t format_size = format->SizeOf() * 8; 674f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl const uint64_t count = fpreg_size / format_size; 675f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl const uint64_t mask = 0xffffffffffffffff >> (64 - format_size); 67688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const uint64_t fpreg_value = 67788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois ReadVRegister<uint64_t>(fpreg_size, target_fpreg.GetCode()); 678b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl VIXL_ASSERT(count > 0); 679f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl 680f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl if (target_fpreg.Is32Bits()) { 68188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois printf("s%u = ", target_fpreg.GetCode()); 682f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl } else { 68388c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois printf("d%u = ", target_fpreg.GetCode()); 684f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl } 685f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl for (uint64_t i = 1; i <= count; i++) { 686f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl uint64_t data = fpreg_value >> (fpreg_size - (i * format_size)); 687f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl data &= mask; 688f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl format->PrintData(&data); 689f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl printf(" "); 690f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl } 691f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl printf("\n"); 692f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl} 693f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl 694f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl 695c68cb64496485710cdb5b8480f8fee287058c93farmvixlvoid Debugger::VisitException(const Instruction* instr) { 696ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(ExceptionMask)) { 697ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case BRK: 698ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl DoBreakpoint(instr); 699ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return; 7006e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl case HLT: 7016e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl VIXL_FALLTHROUGH(); 7020f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl default: 7030f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl Simulator::VisitException(instr); 704ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 705ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 706ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 707ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 708ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Read a command. A command will be at most kMaxDebugShellLine char long and 709ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// ends with '\n\0'. 710ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// TODO: Should this be a utility function? 711ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlchar* Debugger::ReadCommandLine(const char* prompt, char* buffer, int length) { 712ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl int fgets_calls = 0; 713ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl char* end = NULL; 714ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 715ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl printf("%s", prompt); 716ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl fflush(stdout); 717ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 718ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl do { 719ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (fgets(buffer, length, stdin) == NULL) { 720ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl printf(" ** Error while reading command. **\n"); 721ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return NULL; 722ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 723ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 724ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl fgets_calls++; 725ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl end = strchr(buffer, '\n'); 726ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } while (end == NULL); 727ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 728ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (fgets_calls != 1) { 729ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl printf(" ** Command too long. **\n"); 730ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return NULL; 731ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 732ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 733ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Remove the newline from the end of the command. 734b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl VIXL_ASSERT(end[1] == '\0'); 735b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl VIXL_ASSERT((end - buffer) < (length - 1)); 736ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl end[0] = '\0'; 737ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 738ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return buffer; 739ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 740ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 741ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 742ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Debugger::RunDebuggerShell() { 7430d68001a97c8b59c52fab68fddd46e8591bec15eAlexandre Rames if (IsDebuggerActive()) { 744ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (steps_ > 0) { 745ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Finish stepping first. 746ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl --steps_; 747ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return; 748ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 749ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 75080497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames PrintNextInstruction(); 751ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl bool done = false; 752ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl while (!done) { 753ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl char buffer[kMaxDebugShellLine]; 754ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl char* line = ReadCommandLine("vixl> ", buffer, kMaxDebugShellLine); 755ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 756ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (line == NULL) continue; // An error occurred. 757ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 758ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl DebugCommand* command = DebugCommand::Parse(line); 759ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (command != NULL) { 760ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl last_command_ = command; 761ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 762ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 763ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (last_command_ != NULL) { 764ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl done = last_command_->Run(this); 765ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else { 766ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl printf("No previous command to run!\n"); 767ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 768ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 769ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 770ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 771ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 772ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 773c68cb64496485710cdb5b8480f8fee287058c93farmvixlvoid Debugger::DoBreakpoint(const Instruction* instr) { 774b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl VIXL_ASSERT(instr->Mask(ExceptionMask) == BRK); 775ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 776c68cb64496485710cdb5b8480f8fee287058c93farmvixl printf("Hit breakpoint at pc=%p.\n", reinterpret_cast<const void*>(instr)); 7770d68001a97c8b59c52fab68fddd46e8591bec15eAlexandre Rames ActivateDebugger(); 778ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 779ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 780ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 781ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlstatic bool StringToUInt64(uint64_t* value, const char* line, int base = 10) { 782ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl char* endptr = NULL; 783ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl errno = 0; // Reset errors. 784ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl uint64_t parsed = strtoul(line, &endptr, base); 785ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 786ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (errno == ERANGE) { 787ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Overflow. 788ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return false; 789ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 790ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 791ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (endptr == line) { 792ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // No digits were parsed. 793ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return false; 794ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 795ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 796ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (*endptr != '\0') { 797ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Non-digit characters present at the end. 798ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return false; 799ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 800ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 801ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl *value = parsed; 802ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return true; 803ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 804ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 805ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 806ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlstatic bool StringToInt64(int64_t* value, const char* line, int base = 10) { 807ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl char* endptr = NULL; 808ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl errno = 0; // Reset errors. 809ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl int64_t parsed = strtol(line, &endptr, base); 810ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 811ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (errno == ERANGE) { 812ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Overflow, undeflow. 813ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return false; 814ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 815ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 816ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (endptr == line) { 817ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // No digits were parsed. 818ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return false; 819ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 820ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 821ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (*endptr != '\0') { 822ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Non-digit characters present at the end. 823ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return false; 824ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 825ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 826ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl *value = parsed; 827ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return true; 828ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 829ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 830ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 831ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlToken* Token::Tokenize(const char* arg) { 832ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if ((arg == NULL) || (*arg == '\0')) { 833ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return NULL; 834ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 835ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 836ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // The order is important. For example Identifier::Tokenize would consider 837ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // any register to be a valid identifier. 838ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 839ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Token* token = RegisterToken::Tokenize(arg); 840ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (token != NULL) { 841ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return token; 842ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 843ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 844ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl token = FPRegisterToken::Tokenize(arg); 845ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (token != NULL) { 846ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return token; 847ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 848ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 849ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl token = IdentifierToken::Tokenize(arg); 850ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (token != NULL) { 851ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return token; 852ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 853ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 854ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl token = AddressToken::Tokenize(arg); 855ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (token != NULL) { 856ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return token; 857ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 858ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 859ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl token = IntegerToken::Tokenize(arg); 860ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (token != NULL) { 861ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return token; 862ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 863ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 864ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return new UnknownToken(arg); 865ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 866ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 867ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 868ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixluint8_t* RegisterToken::ToAddress(Debugger* debugger) const { 869b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl VIXL_ASSERT(CanAddressMemory()); 87088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois uint64_t reg_value = 87188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois debugger->ReadXRegister(value().GetCode(), Reg31IsStackPointer); 872ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl uint8_t* address = NULL; 873ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl memcpy(&address, ®_value, sizeof(address)); 874ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return address; 875ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 876ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 877ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 878ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid RegisterToken::Print(FILE* out) const { 879b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl VIXL_ASSERT(value().IsValid()); 880ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl fprintf(out, "[Register %s]", Name()); 881ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 882ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 883ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 884ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlconst char* RegisterToken::Name() const { 885ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (value().Is32Bits()) { 88688c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return kWAliases[value().GetCode()][0]; 887ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else { 88888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return kXAliases[value().GetCode()][0]; 889ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 890ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 891ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 892ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 893ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlToken* RegisterToken::Tokenize(const char* arg) { 894ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl for (unsigned i = 0; i < kNumberOfRegisters; i++) { 895ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Is it a X register or alias? 896ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl for (const char** current = kXAliases[i]; *current != NULL; current++) { 897ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (strcmp(arg, *current) == 0) { 89888c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return new RegisterToken(Register::GetXRegFromCode(i)); 899ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 900ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 901ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 902ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Is it a W register or alias? 903ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl for (const char** current = kWAliases[i]; *current != NULL; current++) { 904ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (strcmp(arg, *current) == 0) { 90588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois return new RegisterToken(Register::GetWRegFromCode(i)); 906ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 907ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 908ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 909ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 910ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return NULL; 911ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 912ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 913ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 914ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid FPRegisterToken::Print(FILE* out) const { 915b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl VIXL_ASSERT(value().IsValid()); 916ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl char prefix = value().Is32Bits() ? 's' : 'd'; 91788c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois fprintf(out, "[FPRegister %c%" PRIu32 "]", prefix, value().GetCode()); 918ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 919ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 920ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 921ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlToken* FPRegisterToken::Tokenize(const char* arg) { 922ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (strlen(arg) < 2) { 923ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return NULL; 924ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 925ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 926ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (*arg) { 927ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 's': 928ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'd': 929ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char* cursor = arg + 1; 930ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl uint64_t code = 0; 931ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (!StringToUInt64(&code, cursor)) { 932ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return NULL; 933ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 934ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 935ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (code > kNumberOfFPRegisters) { 936ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return NULL; 937ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 938ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 9395289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl VRegister fpreg = NoVReg; 940ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (*arg) { 941db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl case 's': 94288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois fpreg = VRegister::GetSRegFromCode(static_cast<unsigned>(code)); 943db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl break; 944db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl case 'd': 94588c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois fpreg = VRegister::GetDRegFromCode(static_cast<unsigned>(code)); 946db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl break; 9470f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl default: 9480f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl VIXL_UNREACHABLE(); 949ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 950ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 951ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return new FPRegisterToken(fpreg); 952ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 953ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 954ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return NULL; 955ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 956ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 957ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 958ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixluint8_t* IdentifierToken::ToAddress(Debugger* debugger) const { 959b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl VIXL_ASSERT(CanAddressMemory()); 96088c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois const Instruction* pc_value = debugger->ReadPc(); 961ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl uint8_t* address = NULL; 962ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl memcpy(&address, &pc_value, sizeof(address)); 963ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return address; 964ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 965ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 966ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid IdentifierToken::Print(FILE* out) const { 967ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl fprintf(out, "[Identifier %s]", value()); 968ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 969ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 970ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 971ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlToken* IdentifierToken::Tokenize(const char* arg) { 972ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (!isalpha(arg[0])) { 973ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return NULL; 974ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 975ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 976ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char* cursor = arg + 1; 977ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl while ((*cursor != '\0') && isalnum(*cursor)) { 978ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ++cursor; 979ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 980ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 981ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (*cursor == '\0') { 982ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return new IdentifierToken(arg); 983ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 984ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 985ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return NULL; 986ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 987ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 988ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 989ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixluint8_t* AddressToken::ToAddress(Debugger* debugger) const { 990ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl USE(debugger); 991ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return value(); 992ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 993ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 994ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 995ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid AddressToken::Print(FILE* out) const { 9960f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl fprintf(out, "[Address %p]", reinterpret_cast<const void*>(value())); 997ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 998ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 999ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1000ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlToken* AddressToken::Tokenize(const char* arg) { 1001ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if ((strlen(arg) < 3) || (arg[0] != '0') || (arg[1] != 'x')) { 1002ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return NULL; 1003ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1004ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1005ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl uint64_t ptr = 0; 1006ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (!StringToUInt64(&ptr, arg, 16)) { 1007ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return NULL; 1008ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1009ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1010ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl uint8_t* address = reinterpret_cast<uint8_t*>(ptr); 1011ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return new AddressToken(address); 1012ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1013ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1014ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1015ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid IntegerToken::Print(FILE* out) const { 1016ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl fprintf(out, "[Integer %" PRId64 "]", value()); 1017ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1018ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1019ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1020ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlToken* IntegerToken::Tokenize(const char* arg) { 1021ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl int64_t value = 0; 1022ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (!StringToInt64(&value, arg)) { 1023ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return NULL; 1024ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1025ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1026ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return new IntegerToken(value); 1027ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1028ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1029ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1030ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlToken* FormatToken::Tokenize(const char* arg) { 1031db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl size_t length = strlen(arg); 1032f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl switch (arg[0]) { 1033f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl case 'x': 1034f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl case 's': 1035f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl case 'u': 1036f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl case 'f': 1037f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl if (length == 1) return NULL; 1038f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl break; 1039f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl case 'i': 1040f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl if (length == 1) return new Format<uint32_t>("%08" PRIx32, 'i'); 10416e2c8275d5f34a531fe1eef7a7aa877601be8558armvixl VIXL_FALLTHROUGH(); 10420f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl default: 10430f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl return NULL; 1044f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl } 1045f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl 1046f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl char* endptr = NULL; 1047f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl errno = 0; // Reset errors. 1048f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl uint64_t count = strtoul(arg + 1, &endptr, 10); 1049f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl 1050f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl if (errno != 0) { 1051f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl // Overflow, etc. 1052ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return NULL; 1053ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1054ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1055f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl if (endptr == arg) { 1056f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl // No digits were parsed. 1057ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return NULL; 1058ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1059ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1060f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl if (*endptr != '\0') { 1061f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl // There are unexpected (non-digit) characters after the number. 1062f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl return NULL; 1063ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1064ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1065f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl switch (arg[0]) { 1066f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl case 'x': 1067f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl switch (count) { 10680f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl case 8: 10690f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl return new Format<uint8_t>("%02" PRIx8, 'x'); 10700f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl case 16: 10710f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl return new Format<uint16_t>("%04" PRIx16, 'x'); 10720f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl case 32: 10730f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl return new Format<uint32_t>("%08" PRIx32, 'x'); 10740f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl case 64: 10750f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl return new Format<uint64_t>("%016" PRIx64, 'x'); 10760f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl default: 10770f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl return NULL; 1078f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl } 1079ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 's': 1080f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl switch (count) { 10810f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl case 8: 10820f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl return new Format<int8_t>("%4" PRId8, 's'); 10830f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl case 16: 10840f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl return new Format<int16_t>("%6" PRId16, 's'); 10850f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl case 32: 10860f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl return new Format<int32_t>("%11" PRId32, 's'); 10870f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl case 64: 10880f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl return new Format<int64_t>("%20" PRId64, 's'); 10890f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl default: 10900f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl return NULL; 1091ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1092ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'u': 1093f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl switch (count) { 10940f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl case 8: 10950f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl return new Format<uint8_t>("%3" PRIu8, 'u'); 10960f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl case 16: 10970f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl return new Format<uint16_t>("%5" PRIu16, 'u'); 10980f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl case 32: 10990f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl return new Format<uint32_t>("%10" PRIu32, 'u'); 11000f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl case 64: 11010f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl return new Format<uint64_t>("%20" PRIu64, 'u'); 11020f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl default: 11030f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl return NULL; 1104ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1105f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl case 'f': 1106f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl switch (count) { 11070f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl case 32: 11080f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl return new Format<float>("%13g", 'f'); 11090f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl case 64: 11100f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl return new Format<double>("%13g", 'f'); 11110f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl default: 11120f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl return NULL; 1113ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1114f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl default: 1115b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl VIXL_UNREACHABLE(); 1116f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl return NULL; 1117ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1118ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1119ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1120ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 11210f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixltemplate <typename T> 1122ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Format<T>::Print(FILE* out) const { 1123b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl unsigned size = sizeof(T) * 8; 1124b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl fprintf(out, "[Format %c%u - %s]", type_code_, size, fmt_); 1125ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1126ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1127ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1128ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid UnknownToken::Print(FILE* out) const { 1129ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl fprintf(out, "[Unknown %s]", unknown_); 1130ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1131ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1132ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 11330f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixlvoid DebugCommand::Print(FILE* out) { fprintf(out, "%s", name()); } 1134ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1135ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1136ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool DebugCommand::Match(const char* name, const char** aliases) { 1137ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl for (const char** current = aliases; *current != NULL; current++) { 1138ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (strcmp(name, *current) == 0) { 11390f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl return true; 1140ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1141ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1142ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1143ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return false; 1144ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1145ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1146ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1147ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlDebugCommand* DebugCommand::Parse(char* line) { 1148ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl std::vector<Token*> args; 1149ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 11500f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl for (char* chunk = strtok(line, " \t"); chunk != NULL; 1151f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl chunk = strtok(NULL, " \t")) { 1152f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl char* dot = strchr(chunk, '.'); 1153f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl if (dot != NULL) { 1154f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl // 'Token.format'. 1155f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl Token* format = FormatToken::Tokenize(dot + 1); 1156f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl if (format != NULL) { 1157f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl *dot = '\0'; 1158f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl args.push_back(Token::Tokenize(chunk)); 1159f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl args.push_back(format); 1160f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl } else { 1161f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl // Error while parsing the format, push the UnknownToken so an error 1162f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl // can be accurately reported. 1163f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl args.push_back(Token::Tokenize(chunk)); 1164f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl } 1165f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl } else { 1166f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl args.push_back(Token::Tokenize(chunk)); 1167f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl } 1168ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1169ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1170ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (args.size() == 0) { 1171ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return NULL; 1172ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1173ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1174ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (!args[0]->IsIdentifier()) { 1175f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl return new InvalidCommand(args, 0, "command name is not valid"); 1176ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1177ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1178ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char* name = IdentifierToken::Cast(args[0])->value(); 11790f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl#define RETURN_IF_MATCH(Command) \ 11800f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl if (Match(name, Command::kAliases)) { \ 11810f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl return Command::Build(args); \ 1182ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1183ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl DEBUG_COMMAND_LIST(RETURN_IF_MATCH); 11840f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl#undef RETURN_IF_MATCH 1185ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1186ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return new UnknownCommand(args); 1187ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1188ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1189ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1190ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid DebugCommand::PrintHelp(const char** aliases, 1191ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char* args, 1192ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char* help) { 1193b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl VIXL_ASSERT(aliases[0] != NULL); 1194b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl VIXL_ASSERT(help != NULL); 1195ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1196ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl printf("\n----\n\n"); 1197ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl for (const char** current = aliases; *current != NULL; current++) { 1198ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (args != NULL) { 1199ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl printf("%s %s\n", *current, args); 1200ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else { 1201ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl printf("%s\n", *current); 1202ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1203ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1204ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl printf("\n%s\n", help); 1205ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1206ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1207ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1208ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool HelpCommand::Run(Debugger* debugger) { 12090d68001a97c8b59c52fab68fddd46e8591bec15eAlexandre Rames VIXL_ASSERT(debugger->IsDebuggerActive()); 1210ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl USE(debugger); 1211ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 12120f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl#define PRINT_HELP(Command) \ 12130f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl DebugCommand::PrintHelp(Command::kAliases, \ 12140f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl Command::kArguments, \ 12150f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl Command::kHelp); 1216ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl DEBUG_COMMAND_LIST(PRINT_HELP); 12170f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl#undef PRINT_HELP 1218ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl printf("\n----\n\n"); 1219ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1220ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return false; 1221ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1222ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1223ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1224ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlDebugCommand* HelpCommand::Build(std::vector<Token*> args) { 1225ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (args.size() != 1) { 1226ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return new InvalidCommand(args, -1, "too many arguments"); 1227ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1228ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1229ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return new HelpCommand(args[0]); 1230ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1231ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1232ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1233ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool ContinueCommand::Run(Debugger* debugger) { 12340d68001a97c8b59c52fab68fddd46e8591bec15eAlexandre Rames VIXL_ASSERT(debugger->IsDebuggerActive()); 1235ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 12360d68001a97c8b59c52fab68fddd46e8591bec15eAlexandre Rames debugger->DeactivateDebugger(); 1237ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return true; 1238ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1239ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1240ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1241ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlDebugCommand* ContinueCommand::Build(std::vector<Token*> args) { 1242ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (args.size() != 1) { 1243ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return new InvalidCommand(args, -1, "too many arguments"); 1244ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1245ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1246ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return new ContinueCommand(args[0]); 1247ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1248ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1249ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1250ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool StepCommand::Run(Debugger* debugger) { 12510d68001a97c8b59c52fab68fddd46e8591bec15eAlexandre Rames VIXL_ASSERT(debugger->IsDebuggerActive()); 1252ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 12534886a725301d6cc426c2a8151bb48fbec3946b3aAlexandre Rames // To avoid recursive calls to the debugger shell when hitting breakpoints 12544886a725301d6cc426c2a8151bb48fbec3946b3aAlexandre Rames // while stepping, stepping is implemented by telling the debugger how many 12554886a725301d6cc426c2a8151bb48fbec3946b3aAlexandre Rames // instructions to execute before starting the shell again. 1256ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl int64_t steps = count(); 12574886a725301d6cc426c2a8151bb48fbec3946b3aAlexandre Rames if (steps <= 0) { 12584886a725301d6cc426c2a8151bb48fbec3946b3aAlexandre Rames if (steps < 0) { 12594886a725301d6cc426c2a8151bb48fbec3946b3aAlexandre Rames printf(" ** invalid value for steps: %" PRId64 " (<0) **\n", steps); 12604886a725301d6cc426c2a8151bb48fbec3946b3aAlexandre Rames } 12614886a725301d6cc426c2a8151bb48fbec3946b3aAlexandre Rames // Execute nothing and stay in the shell. 12624886a725301d6cc426c2a8151bb48fbec3946b3aAlexandre Rames return false; 12634886a725301d6cc426c2a8151bb48fbec3946b3aAlexandre Rames } else { 126488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois debugger->SetSteps(steps - 1); 12654886a725301d6cc426c2a8151bb48fbec3946b3aAlexandre Rames // Relinquish control to the debugger. It will execute the next instruction, 12664886a725301d6cc426c2a8151bb48fbec3946b3aAlexandre Rames // followed by `steps - 1` instructions, before starting the shell again. 12674886a725301d6cc426c2a8151bb48fbec3946b3aAlexandre Rames // (Unless another breakpoint is hit in the meantime.) 12684886a725301d6cc426c2a8151bb48fbec3946b3aAlexandre Rames return true; 1269ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1270ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1271ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1272ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1273ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid StepCommand::Print(FILE* out) { 1274ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl fprintf(out, "%s %" PRId64 "", name(), count()); 1275ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1276ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1277ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1278ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlDebugCommand* StepCommand::Build(std::vector<Token*> args) { 1279ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl IntegerToken* count = NULL; 1280ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (args.size()) { 1281ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 1: { // step [1] 1282ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl count = new IntegerToken(1); 1283ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 1284ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1285ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 2: { // step n 1286ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Token* first = args[1]; 1287ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (!first->IsInteger()) { 1288ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return new InvalidCommand(args, 1, "expects int"); 1289ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1290ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl count = IntegerToken::Cast(first); 1291ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 1292ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1293ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl default: 1294ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return new InvalidCommand(args, -1, "too many arguments"); 1295ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1296ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1297ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return new StepCommand(args[0], count); 1298ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1299ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1300ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 130180497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Ramesbool SkipCommand::Run(Debugger* debugger) { 13020d68001a97c8b59c52fab68fddd46e8591bec15eAlexandre Rames VIXL_ASSERT(debugger->IsDebuggerActive()); 130380497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames 130480497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames int64_t steps = count(); 130580497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames if (steps < 0) { 130680497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames printf(" ** invalid value for steps: %" PRId64 " (<0) **\n", steps); 130780497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames } else { 130880497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames printf("Skipping over %" PRId64 " instructions:\n", steps); 130980497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames debugger->PrintInstructions(debugger->ReadPc(), steps, "Skip: "); 131080497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames debugger->WritePc(debugger->ReadPc() + steps * kInstructionSize); 131180497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames debugger->PrintNextInstruction(); 131280497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames } 131380497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames 131480497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames return false; 131580497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames} 131680497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames 131780497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames 131880497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Ramesvoid SkipCommand::Print(FILE* out) { 131980497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames fprintf(out, "%s %" PRId64 "", name(), count()); 132080497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames} 132180497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames 132280497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames 132380497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre RamesDebugCommand* SkipCommand::Build(std::vector<Token*> args) { 132480497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames IntegerToken* count = NULL; 132580497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames switch (args.size()) { 132680497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames case 1: { // step [1] 132780497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames count = new IntegerToken(1); 132880497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames break; 132980497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames } 133080497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames case 2: { // step n 133180497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames Token* first = args[1]; 133280497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames if (!first->IsInteger()) { 133380497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames return new InvalidCommand(args, 1, "expects int"); 133480497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames } 133580497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames count = IntegerToken::Cast(first); 133680497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames break; 133780497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames } 133880497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames default: 133980497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames return new InvalidCommand(args, -1, "too many arguments"); 134080497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames } 134180497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames 134280497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames return new SkipCommand(args[0], count); 134380497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames} 134480497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames 134580497ed4c9dfd94d77e9a0d0ee89f594dd9fb588Alexandre Rames 1346ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlDebugCommand* DisasmCommand::Build(std::vector<Token*> args) { 1347ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl IntegerToken* count = NULL; 1348ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (args.size()) { 1349f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl case 1: { // disasm [10] 1350f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl count = new IntegerToken(10); 1351ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 1352ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1353f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl case 2: { // disasm n 1354ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Token* first = args[1]; 1355f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl if (!first->IsInteger()) { 1356f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl return new InvalidCommand(args, 1, "expects int"); 1357ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1358f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl 1359f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl count = IntegerToken::Cast(first); 1360ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 1361ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1362ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl default: 1363f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl return new InvalidCommand(args, -1, "too many arguments"); 1364ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1365ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1366f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl Token* target = new IdentifierToken("pc"); 1367f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl FormatToken* format = new Format<uint32_t>("%08" PRIx32, 'i'); 1368f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl return new ExamineCommand(args[0], target, format, count); 1369ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1370ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1371ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1372ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid PrintCommand::Print(FILE* out) { 1373ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl fprintf(out, "%s ", name()); 1374ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl target()->Print(out); 1375f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl if (format() != NULL) format()->Print(out); 1376ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1377ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1378ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1379ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool PrintCommand::Run(Debugger* debugger) { 13800d68001a97c8b59c52fab68fddd46e8591bec15eAlexandre Rames VIXL_ASSERT(debugger->IsDebuggerActive()); 1381ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1382ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Token* tok = target(); 1383ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (tok->IsIdentifier()) { 1384ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl char* identifier = IdentifierToken::Cast(tok)->value(); 1385ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (strcmp(identifier, "regs") == 0) { 1386330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl debugger->PrintRegisters(); 1387ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else if (strcmp(identifier, "fpregs") == 0) { 13885289c5900fb214f2f6aa61e2a9263730dcf4cc17armvixl debugger->PrintVRegisters(); 1389578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } else if (strcmp(identifier, "sysregs") == 0) { 1390330dc7153e671968beb67f09ed2cb7b5bda334dbarmvixl debugger->PrintSystemRegisters(); 1391ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else if (strcmp(identifier, "pc") == 0) { 139288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois printf("pc = %16p\n", reinterpret_cast<const void*>(debugger->ReadPc())); 1393ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else { 1394ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl printf(" ** Unknown identifier to print: %s **\n", identifier); 1395ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1396ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1397ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return false; 1398ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1399ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1400f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl FormatToken* format_tok = format(); 1401b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl VIXL_ASSERT(format_tok != NULL); 1402be0e12aec9f1e1b55004a3d34f80693bf985017fPierre Langlois if (format_tok->GetTypeCode() == 'i') { 1403f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl // TODO(all): Add support for instruction disassembly. 1404f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl printf(" ** unsupported format: instructions **\n"); 1405f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl return false; 1406f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl } 1407f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl 1408ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (tok->IsRegister()) { 1409ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl RegisterToken* reg_tok = RegisterToken::Cast(tok); 1410ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Register reg = reg_tok->value(); 1411f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl debugger->PrintRegister(reg, reg_tok->Name(), format_tok); 1412ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return false; 1413ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1414ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1415ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (tok->IsFPRegister()) { 1416ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FPRegister fpreg = FPRegisterToken::Cast(tok)->value(); 1417f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl debugger->PrintFPRegister(fpreg, format_tok); 1418ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return false; 1419ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1420ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1421b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl VIXL_UNREACHABLE(); 1422ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return false; 1423ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1424ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1425ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1426ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlDebugCommand* PrintCommand::Build(std::vector<Token*> args) { 1427f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl if (args.size() < 2) { 1428f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl return new InvalidCommand(args, -1, "too few arguments"); 1429f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl } 1430f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl 1431f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl Token* target = args[1]; 14320f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl if (!target->IsRegister() && !target->IsFPRegister() && 1433f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl !target->IsIdentifier()) { 1434f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl return new InvalidCommand(args, 1, "expects reg or identifier"); 1435f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl } 1436f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl 1437f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl FormatToken* format = NULL; 1438f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl int target_size = 0; 1439f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl if (target->IsRegister()) { 1440f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl Register reg = RegisterToken::Cast(target)->value(); 144188c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois target_size = reg.GetSizeInBytes(); 1442f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl } else if (target->IsFPRegister()) { 1443f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl FPRegister fpreg = FPRegisterToken::Cast(target)->value(); 144488c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois target_size = fpreg.GetSizeInBytes(); 1445f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl } 1446f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl // If the target is an identifier there must be no format. This is checked 1447f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl // in the switch statement below. 1448f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl 1449ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (args.size()) { 1450ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 2: { 1451f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl if (target->IsRegister()) { 1452f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl switch (target_size) { 14530f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl case 4: 14540f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl format = new Format<uint32_t>("%08" PRIx32, 'x'); 14550f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl break; 14560f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl case 8: 14570f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl format = new Format<uint64_t>("%016" PRIx64, 'x'); 14580f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl break; 14590f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl default: 14600f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl VIXL_UNREACHABLE(); 1461f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl } 1462f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl } else if (target->IsFPRegister()) { 1463f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl switch (target_size) { 14640f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl case 4: 14650f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl format = new Format<float>("%8g", 'f'); 14660f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl break; 14670f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl case 8: 14680f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl format = new Format<double>("%8g", 'f'); 14690f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl break; 14700f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl default: 14710f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl VIXL_UNREACHABLE(); 1472f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl } 1473ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1474ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 1475ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1476f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl case 3: { 1477f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl if (target->IsIdentifier()) { 14780f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl return new InvalidCommand(args, 14790f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl 2, 14800f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl "format is only allowed with registers"); 1481f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl } 1482f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl 1483f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl Token* second = args[2]; 1484f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl if (!second->IsFormat()) { 1485f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl return new InvalidCommand(args, 2, "expects format"); 1486f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl } 1487f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl format = FormatToken::Cast(second); 1488f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl 1489f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl if (format->SizeOf() > target_size) { 1490f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl return new InvalidCommand(args, 2, "format too wide"); 1491f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl } 1492f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl 1493f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl break; 1494f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl } 1495ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl default: 1496ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return new InvalidCommand(args, -1, "too many arguments"); 1497ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1498ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1499f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl return new PrintCommand(args[0], target, format); 1500ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1501ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1502ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1503f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixlbool ExamineCommand::Run(Debugger* debugger) { 15040d68001a97c8b59c52fab68fddd46e8591bec15eAlexandre Rames VIXL_ASSERT(debugger->IsDebuggerActive()); 1505ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1506ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl uint8_t* address = target()->ToAddress(debugger); 15070f35e36b7f5d1d2f4d95989b418447e1a4bcc8cdarmvixl int64_t amount = count()->value(); 1508be0e12aec9f1e1b55004a3d34f80693bf985017fPierre Langlois if (format()->GetTypeCode() == 'i') { 1509f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl debugger->PrintInstructions(address, amount); 1510f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl } else { 1511f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl debugger->PrintMemory(address, format(), amount); 1512f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl } 1513ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1514ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return false; 1515ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1516ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1517ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1518f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixlvoid ExamineCommand::Print(FILE* out) { 1519ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl fprintf(out, "%s ", name()); 1520ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl format()->Print(out); 1521f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl target()->Print(out); 1522ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1523ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1524ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1525f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixlDebugCommand* ExamineCommand::Build(std::vector<Token*> args) { 1526ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (args.size() < 2) { 1527ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return new InvalidCommand(args, -1, "too few arguments"); 1528ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1529ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1530ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Token* target = args[1]; 1531ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (!target->CanAddressMemory()) { 1532ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return new InvalidCommand(args, 1, "expects address"); 1533ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1534ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1535f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl FormatToken* format = NULL; 1536f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl IntegerToken* count = NULL; 1537f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl 1538ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (args.size()) { 1539f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl case 2: { // mem addr[.x64] [10] 1540f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl format = new Format<uint64_t>("%016" PRIx64, 'x'); 1541f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl count = new IntegerToken(10); 1542ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 1543ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1544f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl case 3: { // mem addr.format [10] 1545f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl // mem addr[.x64] n 1546ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Token* second = args[2]; 1547f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl if (second->IsFormat()) { 1548ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl format = FormatToken::Cast(second); 1549f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl count = new IntegerToken(10); 1550f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl break; 1551f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl } else if (second->IsInteger()) { 1552f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl format = new Format<uint64_t>("%016" PRIx64, 'x'); 1553f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl count = IntegerToken::Cast(second); 1554ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else { 1555f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl return new InvalidCommand(args, 2, "expects format or integer"); 1556ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1557b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl VIXL_UNREACHABLE(); 1558ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 1559ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1560f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl case 4: { // mem addr.format n 1561ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Token* second = args[2]; 1562ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Token* third = args[3]; 1563f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl if (!second->IsFormat() || !third->IsInteger()) { 1564f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl return new InvalidCommand(args, -1, "expects addr[.format] [n]"); 1565ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1566f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl format = FormatToken::Cast(second); 1567f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl count = IntegerToken::Cast(third); 1568ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 1569ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1570ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl default: 1571ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return new InvalidCommand(args, -1, "too many arguments"); 1572ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1573ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1574f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl return new ExamineCommand(args[0], target, format, count); 1575ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1576ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1577ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1578ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlUnknownCommand::~UnknownCommand() { 1579db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl const size_t size = args_.size(); 1580db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl for (size_t i = 0; i < size; ++i) { 1581ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl delete args_[i]; 1582ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1583ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1584ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1585ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1586ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool UnknownCommand::Run(Debugger* debugger) { 15870d68001a97c8b59c52fab68fddd46e8591bec15eAlexandre Rames VIXL_ASSERT(debugger->IsDebuggerActive()); 1588ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl USE(debugger); 1589ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1590ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl printf(" ** Unknown Command:"); 1591db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl const size_t size = args_.size(); 1592db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl for (size_t i = 0; i < size; ++i) { 1593ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl printf(" "); 1594ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl args_[i]->Print(stdout); 1595ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1596ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl printf(" **\n"); 1597ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1598ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return false; 1599ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1600ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1601ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1602ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlInvalidCommand::~InvalidCommand() { 1603db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl const size_t size = args_.size(); 1604db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl for (size_t i = 0; i < size; ++i) { 1605ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl delete args_[i]; 1606ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1607ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1608ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1609ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1610ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool InvalidCommand::Run(Debugger* debugger) { 16110d68001a97c8b59c52fab68fddd46e8591bec15eAlexandre Rames VIXL_ASSERT(debugger->IsDebuggerActive()); 1612ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl USE(debugger); 1613ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1614ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl printf(" ** Invalid Command:"); 1615db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl const size_t size = args_.size(); 1616db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl for (size_t i = 0; i < size; ++i) { 1617ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl printf(" "); 1618db6443499376478f5281607a3923e6ffc4c8d8ecarmvixl if (i == static_cast<size_t>(index_)) { 1619ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl printf(">>"); 1620ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl args_[i]->Print(stdout); 1621ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl printf("<<"); 1622ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else { 1623ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl args_[i]->Print(stdout); 1624ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1625ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1626ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl printf(" **\n"); 1627ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl printf(" ** %s\n", cause_); 1628ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1629ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return false; 1630ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1631ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 163288c46b84df005638546de5e4e965bdcc31352f48Pierre Langlois} // namespace aarch64 1633ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} // namespace vixl 1634b0c8ae2a5f0abc58f67322052d39bfd47edb2892armvixl 16351e85b7f2e8ad2bfb233de29405aade635ed207cePierre Langlois#endif // VIXL_INCLUDE_SIMULATOR_AARCH64 1636