• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
log_parameters()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   }
set_log_parameters(int parameters)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 
debug_parameters()129   inline int debug_parameters() { return debug_parameters_; }
set_debug_parameters(int 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.
steps()138   inline int steps() { return steps_; }
set_steps(int value)139   inline void set_steps(int value) {
140     VIXL_ASSERT(value > 1);
141     steps_ = value;
142   }
143 
IsDebuggerRunning()144   inline bool IsDebuggerRunning() {
145     return (debug_parameters_ & DBG_ACTIVE) != 0;
146   }
147 
pending_request()148   inline bool pending_request() { return pending_request_; }
update_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