EmulateInstruction.h revision 9dd30d0b56d859a0ca600760e46b74a6b674672d
1//===-- EmulateInstruction.h ------------------------------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef lldb_EmulateInstruction_h_
11#define lldb_EmulateInstruction_h_
12
13#include "lldb/lldb-include.h"
14#include "lldb/Core/PluginInterface.h"
15
16//----------------------------------------------------------------------
17/// @class EmulateInstruction EmulateInstruction.h "lldb/Core/EmulateInstruction.h"
18/// @brief A class that allows emulation of CPU opcodes.
19///
20/// This class is a plug-in interface that is accessed through the
21/// standard static FindPlugin function call in the EmulateInstruction
22/// class. The FindPlugin takes a target triple and returns a new object
23/// if there is a plug-in that supports the architecture and OS. Four
24/// callbacks and a baton are provided. The four callbacks are read
25/// register, write register, read memory and write memory.
26///
27/// This class is currently designed for these main use cases:
28/// - Auto generation of Call Frame Information (CFI) from assembly code
29/// - Predicting single step breakpoint locations
30/// - Emulating instructions for breakpoint traps
31///
32/// Objects can be asked to read an instruction which will cause a call
33/// to the read register callback to get the PC, followed by a read
34/// memory call to read the opcode. If ReadInstruction () returns true,
35/// then a call to EmulateInstruction::EvaluateInstruction () can be
36/// made. At this point the EmulateInstruction subclass will use all of
37/// the callbacks to emulate an instruction.
38///
39/// Clients that provide the callbacks can either do the read/write
40/// registers/memory to actually emulate the instruction on a real or
41/// virtual CPU, or watch for the EmulateInstruction::Context which
42/// is context for the read/write register/memory which explains why
43/// the callback is being called. Examples of a context are:
44/// "pushing register 3 onto the stack at offset -12", or "adjusting
45/// stack pointer by -16". This extra context allows the generation of
46/// CFI information from assembly code without having to actually do
47/// the read/write register/memory.
48///
49/// Clients must be prepared that not all instructions for an
50/// Instruction Set Architecture (ISA) will be emulated.
51///
52/// Subclasses at the very least should implement the instructions that
53/// save and restore regiters onto the stack and adjustment to the stack
54/// pointer. By just implementing a few instructions for an ISA that are
55/// the typical prologue opcodes, you can then generate CFI using a
56/// class that will soon be available.
57///
58/// Implmenting all of the instructions that affect the PC can then
59/// allow single step prediction support.
60///
61/// Implmenting all of the instructions allows for emulation of opcodes
62/// for breakpoint traps and will pave the way for "thread centric"
63/// debugging. The current debugging model is "process centric" where
64/// all threads must be stopped when any thread is stopped since when
65/// hitting software breakpoints once must disable the breakpoint by
66/// restoring the original breakpoint opcde, single stepping and
67/// restoring the breakpoint trap. If all threads were allowed to run
68/// then other threads could miss the breakpoint.
69///
70/// This class centralizes the code that usually is done in separate
71/// code paths in a debugger (single step prediction, finding save
72/// restore locations of registers for unwinding stack frame variables,
73/// and emulating the intruction is just a bonus.
74//----------------------------------------------------------------------
75
76namespace lldb_private {
77
78class EmulateInstruction :
79    public PluginInterface
80{
81public:
82
83    static EmulateInstruction*
84    FindPlugin (const ConstString &triple, const char *plugin_name);
85
86    enum ContextType
87    {
88        eContextInvalid = 0,
89        // Read an instruciton opcode from memory
90        eContextReadOpcode,
91
92        // Usually used for writing a register value whose source value in an
93        // immediate
94        eContextImmediate,
95
96        // Exclusively used when saving a register to the stack as part of the
97        // prologue
98        // arg0 = register kind
99        // arg1 = register number
100        // arg2 = signed offset from current SP value where register is being
101        //        stored
102        eContextPushRegisterOnStack,
103
104        // Exclusively used when restoring a register off the stack as part of
105        // the epilogue
106        // arg0 = register kind
107        // arg1 = register number
108        // arg2 = signed offset from current SP value where register is being
109        //        restored
110        eContextPopRegisterOffStack,
111
112        // Add or subtract a value from the stack
113        // arg0 = register kind for SP
114        // arg1 = register number for SP
115        // arg2 = signed offset being applied to the SP value
116        eContextAdjustStackPointer,
117
118        // Used in WriteRegister callbacks to indicate where the
119        // arg0 = source register kind
120        // arg1 = source register number
121        // arg2 = source signed offset
122        eContextRegisterPlusOffset,
123
124        // Used when performing a PC-relative branch where the
125        // arg0 = don't care
126        // arg1 = imm32 (signed offset)
127        // arg2 = target instruction set or don't care
128        eContextRelativeBranchImmediate,
129
130        // Used when performing an absolute branch where the
131        // arg0 = target register kind
132        // arg1 = target register number
133        // arg2 = target instruction set or don't care
134        eContextAbsoluteBranchRegister,
135
136        // Used when performing a supervisor call to an operating system to
137        // provide a service:
138        // arg0 = current instruction set or don't care
139        // arg1 = immediate data or don't care
140        // arg2 = don't care
141        eContextSupervisorCall
142    };
143
144    struct Context
145    {
146        ContextType type;
147        lldb::addr_t arg0;      // Register kind.
148        lldb::addr_t arg1;      // Register spec.
149        int64_t arg2;           // Possible negative value.
150    };
151
152    union Opcode
153    {
154        uint8_t inst8;
155        uint16_t inst16;
156        uint32_t inst32;
157        uint64_t inst64;
158        union inst
159        {
160            uint8_t bytes[16];
161            uint8_t length;
162        };
163    };
164
165    enum OpcodeType
166    {
167        eOpcode8,
168        eOpcode16,
169        eOpcode32,
170        eOpcode64,
171        eOpcodeBytes
172    };
173
174    struct Instruction
175    {
176        OpcodeType opcode_type;
177        Opcode opcode;
178    };
179
180    typedef size_t (*ReadMemory) (void *baton,
181                                  const Context &context,
182                                  lldb::addr_t addr,
183                                  void *dst,
184                                  size_t length);
185
186    typedef size_t (*WriteMemory) (void *baton,
187                                   const Context &context,
188                                   lldb::addr_t addr,
189                                   const void *dst,
190                                   size_t length);
191
192    typedef bool   (*ReadRegister)  (void *baton,
193                                     uint32_t reg_kind,
194                                     uint32_t reg_num,
195                                     uint64_t &reg_value);
196
197    typedef bool   (*WriteRegister) (void *baton,
198                                     const Context &context,
199                                     uint32_t reg_kind,
200                                     uint32_t reg_num,
201                                     uint64_t reg_value);
202
203    EmulateInstruction (lldb::ByteOrder byte_order,
204                        uint32_t addr_byte_size,
205                        void *baton,
206                        ReadMemory read_mem_callback,
207                        WriteMemory write_mem_callback,
208                        ReadRegister read_reg_callback,
209                        WriteRegister write_reg_callback);
210
211    virtual ~EmulateInstruction()
212    {
213    }
214
215    virtual bool
216    SetTargetTriple (const ConstString &triple) = 0;
217
218    virtual bool
219    ReadInstruction () = 0;
220
221    virtual bool
222    EvaluateInstruction () = 0;
223
224    uint64_t
225    ReadRegisterUnsigned (uint32_t reg_kind,
226                          uint32_t reg_num,
227                          uint64_t fail_value,
228                          bool *success_ptr);
229
230    bool
231    WriteRegisterUnsigned (const Context &context,
232                           uint32_t reg_kind,
233                           uint32_t reg_num,
234                           uint64_t reg_value);
235
236    uint64_t
237    ReadMemoryUnsigned (const Context &context,
238                        lldb::addr_t addr,
239                        size_t byte_size,
240                        uint64_t fail_value,
241                        bool *success_ptr);
242
243    bool
244    WriteMemoryUnsigned (const Context &context,
245                         lldb::addr_t addr,
246                         uint64_t uval,
247                         size_t uval_byte_size);
248
249    uint32_t
250    GetAddressByteSize () const
251    {
252        return m_addr_byte_size;
253    }
254
255    lldb::ByteOrder
256    GetByteOrder () const
257    {
258        return m_byte_order;
259    }
260
261    uint64_t
262    OpcodeAsUnsigned (bool *success_ptr)
263    {
264        if (success_ptr)
265            *success_ptr = true;
266        switch (m_inst.opcode_type)
267        {
268        eOpcode8:   return m_inst.opcode.inst8;
269        eOpcode16:  return m_inst.opcode.inst16;
270        eOpcode32:  return m_inst.opcode.inst32;
271        eOpcode64:  return m_inst.opcode.inst64;
272        eOpcodeBytes:
273            break;
274        }
275        if (success_ptr)
276            *success_ptr = false;
277        return 0;
278    }
279
280protected:
281    lldb::ByteOrder     m_byte_order;
282    uint32_t            m_addr_byte_size;
283    void *              m_baton;
284    ReadMemory          m_read_mem_callback;
285    WriteMemory         m_write_mem_callback;
286    ReadRegister        m_read_reg_callback;
287    WriteRegister       m_write_reg_callback;
288
289    lldb::addr_t m_inst_pc;
290    Instruction m_inst;
291    //------------------------------------------------------------------
292    // For EmulateInstruction only
293    //------------------------------------------------------------------
294    DISALLOW_COPY_AND_ASSIGN (EmulateInstruction);
295};
296
297}   // namespace lldb_private
298
299#endif  // lldb_EmulateInstruction_h_
300