Home | History | Annotate | Download | only in a64
      1 // Copyright 2013, ARM Limited
      2 // All rights reserved.
      3 //
      4 // Redistribution and use in source and binary forms, with or without
      5 // modification, are permitted provided that the following conditions are met:
      6 //
      7 //   * Redistributions of source code must retain the above copyright notice,
      8 //     this list of conditions and the following disclaimer.
      9 //   * Redistributions in binary form must reproduce the above copyright notice,
     10 //     this list of conditions and the following disclaimer in the documentation
     11 //     and/or other materials provided with the distribution.
     12 //   * Neither the name of ARM Limited nor the names of its contributors may be
     13 //     used to endorse or promote products derived from this software without
     14 //     specific prior written permission.
     15 //
     16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
     17 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     18 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     19 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
     20 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     21 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     22 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
     23 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     24 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26 
     27 #ifndef VIXL_A64_DEBUGGER_A64_H_
     28 #define VIXL_A64_DEBUGGER_A64_H_
     29 
     30 #include <ctype.h>
     31 #include <limits.h>
     32 #include <errno.h>
     33 #include <vector>
     34 
     35 #include "globals-vixl.h"
     36 #include "utils-vixl.h"
     37 #include "a64/constants-a64.h"
     38 #include "a64/simulator-a64.h"
     39 
     40 namespace vixl {
     41 
     42 // Debug instructions.
     43 //
     44 // VIXL's macro-assembler and debugger support a few pseudo instructions to
     45 // make debugging easier. These pseudo instructions do not exist on real
     46 // hardware.
     47 //
     48 // Each debug pseudo instruction is represented by a HLT instruction. The HLT
     49 // immediate field is used to identify the type of debug pseudo isntruction.
     50 // Each pseudo instruction use a custom encoding for additional arguments, as
     51 // described below.
     52 
     53 // Unreachable
     54 //
     55 // Instruction which should never be executed. This is used as a guard in parts
     56 // of the code that should not be reachable, such as in data encoded inline in
     57 // the instructions.
     58 const Instr kUnreachableOpcode = 0xdeb0;
     59 
     60 // Trace
     61 //  - parameter: TraceParameter stored as a uint32_t
     62 //  - command: TraceCommand stored as a uint32_t
     63 //
     64 // Allow for trace management in the generated code. See the corresponding
     65 // enums for more information on permitted actions.
     66 const Instr kTraceOpcode = 0xdeb2;
     67 const unsigned kTraceParamsOffset = 1 * kInstructionSize;
     68 const unsigned kTraceCommandOffset = 2 * kInstructionSize;
     69 const unsigned kTraceLength = 3 * kInstructionSize;
     70 
     71 // Log
     72 //  - parameter: TraceParameter stored as a uint32_t
     73 //
     74 // Output the requested information.
     75 const Instr kLogOpcode = 0xdeb3;
     76 const unsigned kLogParamsOffset = 1 * kInstructionSize;
     77 const unsigned kLogLength = 2 * kInstructionSize;
     78 
     79 // Trace commands.
     80 enum TraceCommand {
     81   TRACE_ENABLE   = 1,
     82   TRACE_DISABLE  = 2
     83 };
     84 
     85 // Trace parameters.
     86 enum TraceParameters {
     87   LOG_DISASM     = 1 << 0,  // Log disassembly.
     88   LOG_REGS       = 1 << 1,  // Log general purpose registers.
     89   LOG_FP_REGS    = 1 << 2,  // Log floating-point registers.
     90   LOG_SYS_REGS   = 1 << 3,  // Log the flags and system registers.
     91 
     92   LOG_STATE      = LOG_REGS | LOG_FP_REGS | LOG_SYS_REGS,
     93   LOG_ALL        = LOG_DISASM | LOG_REGS | LOG_FP_REGS | LOG_SYS_REGS
     94 };
     95 
     96 // Debugger parameters
     97 enum DebugParameters {
     98   DBG_ACTIVE = 1 << 0,  // The debugger is active.
     99   DBG_BREAK  = 1 << 1   // The debugger is at a breakpoint.
    100 };
    101 
    102 // Forward declarations.
    103 class DebugCommand;
    104 class Token;
    105 class FormatToken;
    106 
    107 class Debugger : public Simulator {
    108  public:
    109   Debugger(Decoder* decoder, FILE* stream = stdout);
    110 
    111   virtual void Run();
    112   void VisitException(Instruction* instr);
    113 
    114   inline int log_parameters() {
    115     // The simulator can control disassembly, so make sure that the Debugger's
    116     // log parameters agree with it.
    117     if (disasm_trace()) {
    118       log_parameters_ |= LOG_DISASM;
    119     }
    120     return log_parameters_;
    121   }
    122   inline void set_log_parameters(int parameters) {
    123     set_disasm_trace((parameters & LOG_DISASM) != 0);
    124     log_parameters_ = parameters;
    125 
    126     update_pending_request();
    127   }
    128 
    129   inline int debug_parameters() { return debug_parameters_; }
    130   inline void set_debug_parameters(int parameters) {
    131     debug_parameters_ = parameters;
    132 
    133     update_pending_request();
    134   }
    135 
    136   // Numbers of instructions to execute before the debugger shell is given
    137   // back control.
    138   inline int steps() { return steps_; }
    139   inline void set_steps(int value) {
    140     VIXL_ASSERT(value > 1);
    141     steps_ = value;
    142   }
    143 
    144   inline bool IsDebuggerRunning() {
    145     return (debug_parameters_ & DBG_ACTIVE) != 0;
    146   }
    147 
    148   inline bool pending_request() { return pending_request_; }
    149   inline void update_pending_request() {
    150     const int kLoggingMask = LOG_STATE;
    151     const bool logging = (log_parameters_ & kLoggingMask) != 0;
    152     const bool debugging = IsDebuggerRunning();
    153 
    154     pending_request_ = logging || debugging;
    155   }
    156 
    157   void PrintInstructions(void* address, int64_t count = 1);
    158   void PrintMemory(const uint8_t* address,
    159                    const FormatToken* format,
    160                    int64_t count = 1);
    161   void PrintRegister(const Register& target_reg,
    162                      const char* name,
    163                      const FormatToken* format);
    164   void PrintFPRegister(const FPRegister& target_fpreg,
    165                        const FormatToken* format);
    166 
    167  private:
    168   void LogSystemRegisters();
    169   void LogRegisters();
    170   void LogFPRegisters();
    171   void LogProcessorState();
    172   char* ReadCommandLine(const char* prompt, char* buffer, int length);
    173   void RunDebuggerShell();
    174   void DoBreakpoint(Instruction* instr);
    175   void DoUnreachable(Instruction* instr);
    176   void DoTrace(Instruction* instr);
    177   void DoLog(Instruction* instr);
    178 
    179   int  log_parameters_;
    180   int  debug_parameters_;
    181   bool pending_request_;
    182   int steps_;
    183   DebugCommand* last_command_;
    184   PrintDisassembler* disasm_;
    185   Decoder* printer_;
    186 
    187   // Length of the biggest command line accepted by the debugger shell.
    188   static const int kMaxDebugShellLine = 256;
    189 };
    190 
    191 }  // namespace vixl
    192 
    193 #endif  // VIXL_A64_DEBUGGER_A64_H_
    194