EmulateInstruction.h revision 7fac857ec72051dc0a91b027719c275ea672a470
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 ArchSpec &arch, 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        // Add or subtract a value from a base address register (other than SP)
119        // arg0 = register kind for base register
120        // arg1 = register number of base register
121        // arg2 = signed offset being applied to base register
122        eContextAdjustBaseRegister,
123
124        // Used in WriteRegister callbacks to indicate where the
125        // arg0 = source register kind
126        // arg1 = source register number
127        // arg2 = source signed offset
128        eContextRegisterPlusOffset,
129
130        // Used in WriteMemory callback to indicate where the data came from
131        // arg0 = register kind
132        // arg1 = register number (register being stored)
133        // arg2 = address of store
134        eContextRegisterStore,
135
136        eContextRegisterLoad,
137
138        // Used when performing a PC-relative branch where the
139        // arg0 = don't care
140        // arg1 = imm32 (signed offset)
141        // arg2 = target instruction set or don't care
142        eContextRelativeBranchImmediate,
143
144        // Used when performing an absolute branch where the
145        // arg0 = target register kind
146        // arg1 = target register number
147        // arg2 = target instruction set or don't care
148        eContextAbsoluteBranchRegister,
149
150        // Used when performing a supervisor call to an operating system to
151        // provide a service:
152        // arg0 = current instruction set or don't care
153        // arg1 = immediate data or don't care
154        // arg2 = don't care
155        eContextSupervisorCall,
156
157        // Used when random bits are written into a register
158        // arg0 = target register kind
159        // arg1 = target register number
160        // arg2 = don't care
161        eContextWriteRegisterRandomBits,
162
163        // Used when random bits are written to memory
164        // arg0 = target memory address
165        // arg1 = don't care
166        // arg2 = don't care
167        eContextWriteMemoryRandomBits
168    };
169
170    enum InfoType {
171        eInfoTypeRegisterPlusOffset,
172        eInfoTypeRegisterPlusIndirectOffset,
173        eInfoTypeRegisterToRegisterPlusOffset,
174        eInfoTypeOffset,
175        eInfoTypeRegister,
176        eInfoTypeImmediate,
177        eInfoTypeImmediateSigned,
178        eInfoTypeAddress,
179        eInfoTypeModeAndImmediate,
180        eInfoTypeModeAndImmediateSigned,
181        eInfoTypeMode,
182        eInfoTypeNoArgs
183    } InfoType;
184
185    struct Register
186    {
187        uint32_t kind;
188        uint32_t num;
189
190
191        void
192        SetRegister (uint32_t reg_kind, uint32_t reg_num)
193        {
194            kind = reg_kind;
195            num = reg_num;
196        }
197    };
198
199    struct Context
200    {
201        ContextType type;
202        enum InfoType info_type;
203        union
204        {
205            struct RegisterPlusOffset
206            {
207                Register reg;          // base register
208                int64_t signed_offset; // signed offset added to base register
209            } RegisterPlusOffset;
210
211            struct RegisterPlusIndirectOffset
212            {
213                Register base_reg;    // base register number
214                Register offset_reg;  // offset register kind
215            } RegisterPlusIndirectOffset;
216
217            struct RegisterToRegisterPlusOffset
218            {
219                Register data_reg;  // source/target register for data
220                Register base_reg;  // base register for address calculation
221                int64_t offset;     // offset for address calculation
222            } RegisterToRegisterPlusOffset;
223
224            int64_t signed_offset; // signed offset by which to adjust self (for registers only)
225
226            Register reg;          // plain register
227
228            uint64_t immediate;    // immediate value
229
230            int64_t signed_immediate; // signed immediate value
231
232            lldb::addr_t address;        // direct address
233
234            struct ModeAndImmediate
235            {
236                uint32_t mode;        // eModeARM or eModeThumb
237                uint32_t data_value;  // immdiate data
238            } ModeAndImmediate;
239
240            struct ModeAndImmediateSigned
241            {
242                uint32_t mode;             // eModeARM or eModeThumb
243                int32_t signed_data_value; // signed immdiate data
244            } ModeAndImmediateSigned;
245
246            uint32_t mode;         // eModeARM or eModeThumb
247
248        } info;
249
250        void
251        SetRegisterPlusOffset (Register base_reg,
252                               int64_t signed_offset)
253        {
254            info_type = eInfoTypeRegisterPlusOffset;
255            info.RegisterPlusOffset.reg = base_reg;
256            info.RegisterPlusOffset.signed_offset = signed_offset;
257        }
258
259        void
260        SetRegisterPlusIndirectOffset (Register base_reg,
261                                       Register offset_reg)
262        {
263            info_type = eInfoTypeRegisterPlusIndirectOffset;
264            info.RegisterPlusIndirectOffset.base_reg   = base_reg;
265            info.RegisterPlusIndirectOffset.offset_reg = offset_reg;
266        }
267
268        void
269        SetRegisterToRegisterPlusOffset (Register data_reg,
270                                         Register base_reg,
271                                         int64_t offset)
272        {
273            info_type = eInfoTypeRegisterToRegisterPlusOffset;
274            info.RegisterToRegisterPlusOffset.data_reg = data_reg;
275            info.RegisterToRegisterPlusOffset.base_reg = base_reg;
276            info.RegisterToRegisterPlusOffset.offset   = offset;
277        }
278
279        void
280        SetOffset (int64_t signed_offset)
281        {
282            info_type = eInfoTypeOffset;
283            info.signed_offset = signed_offset;
284        }
285
286        void
287        SetRegister (Register reg)
288        {
289            info_type = eInfoTypeRegister;
290            info.reg = reg;
291        }
292
293        void
294        SetImmediate (uint64_t immediate)
295        {
296            info_type = eInfoTypeImmediate;
297            info.immediate = immediate;
298        }
299
300        void
301        SetImmediateSigned (int64_t signed_immediate)
302        {
303            info_type = eInfoTypeImmediateSigned;
304            info.signed_immediate = signed_immediate;
305        }
306
307        void
308        SetAddress (lldb::addr_t address)
309        {
310            info_type = eInfoTypeAddress;
311            info.address = address;
312        }
313        void
314        SetModeAndImmediate (uint32_t mode, uint32_t data_value)
315        {
316            info_type = eInfoTypeModeAndImmediate;
317            info.ModeAndImmediate.mode = mode;
318            info.ModeAndImmediate.data_value = data_value;
319        }
320
321        void
322        SetModeAndImmediateSigned (uint32_t mode, int32_t signed_data_value)
323        {
324            info_type = eInfoTypeModeAndImmediateSigned;
325            info.ModeAndImmediateSigned.mode = mode;
326            info.ModeAndImmediateSigned.signed_data_value = signed_data_value;
327        }
328
329        void
330        SetMode (uint32_t mode)
331        {
332            info_type = eInfoTypeMode;
333            info.mode = mode;
334        }
335
336        void
337        SetNoArgs ()
338        {
339            info_type = eInfoTypeNoArgs;
340        }
341
342    };
343
344    union Opcode
345    {
346        uint8_t inst8;
347        uint16_t inst16;
348        uint32_t inst32;
349        uint64_t inst64;
350        union inst
351        {
352            uint8_t bytes[16];
353            uint8_t length;
354        };
355    };
356
357    enum OpcodeType
358    {
359        eOpcode8,
360        eOpcode16,
361        eOpcode32,
362        eOpcode64,
363        eOpcodeBytes
364    };
365
366    struct Instruction
367    {
368        OpcodeType opcode_type;
369        Opcode opcode;
370    };
371
372    typedef size_t (*ReadMemory) (void *baton,
373                                  const Context &context,
374                                  lldb::addr_t addr,
375                                  void *dst,
376                                  size_t length);
377
378    typedef size_t (*WriteMemory) (void *baton,
379                                   const Context &context,
380                                   lldb::addr_t addr,
381                                   const void *dst,
382                                   size_t length);
383
384    typedef bool   (*ReadRegister)  (void *baton,
385                                     uint32_t reg_kind,
386                                     uint32_t reg_num,
387                                     uint64_t &reg_value);
388
389    typedef bool   (*WriteRegister) (void *baton,
390                                     const Context &context,
391                                     uint32_t reg_kind,
392                                     uint32_t reg_num,
393                                     uint64_t reg_value);
394
395    EmulateInstruction (lldb::ByteOrder byte_order,
396                        uint32_t addr_byte_size,
397                        void *baton,
398                        ReadMemory read_mem_callback,
399                        WriteMemory write_mem_callback,
400                        ReadRegister read_reg_callback,
401                        WriteRegister write_reg_callback);
402
403    virtual ~EmulateInstruction()
404    {
405    }
406
407    virtual bool
408    SetTargetTriple (const ArchSpec &arch) = 0;
409
410    virtual bool
411    ReadInstruction () = 0;
412
413    virtual bool
414    EvaluateInstruction () = 0;
415
416    uint64_t
417    ReadRegisterUnsigned (uint32_t reg_kind,
418                          uint32_t reg_num,
419                          uint64_t fail_value,
420                          bool *success_ptr);
421
422    bool
423    WriteRegisterUnsigned (const Context &context,
424                           uint32_t reg_kind,
425                           uint32_t reg_num,
426                           uint64_t reg_value);
427
428    uint64_t
429    ReadMemoryUnsigned (const Context &context,
430                        lldb::addr_t addr,
431                        size_t byte_size,
432                        uint64_t fail_value,
433                        bool *success_ptr);
434
435    bool
436    WriteMemoryUnsigned (const Context &context,
437                         lldb::addr_t addr,
438                         uint64_t uval,
439                         size_t uval_byte_size);
440
441    uint32_t
442    GetAddressByteSize () const
443    {
444        return m_addr_byte_size;
445    }
446
447    lldb::ByteOrder
448    GetByteOrder () const
449    {
450        return m_byte_order;
451    }
452
453    uint64_t
454    OpcodeAsUnsigned (bool *success_ptr)
455    {
456        if (success_ptr)
457            *success_ptr = true;
458        switch (m_inst.opcode_type)
459        {
460        eOpcode8:   return m_inst.opcode.inst8;
461        eOpcode16:  return m_inst.opcode.inst16;
462        eOpcode32:  return m_inst.opcode.inst32;
463        eOpcode64:  return m_inst.opcode.inst64;
464        eOpcodeBytes:
465            break;
466        }
467        if (success_ptr)
468            *success_ptr = false;
469        return 0;
470    }
471
472protected:
473    lldb::ByteOrder     m_byte_order;
474    uint32_t            m_addr_byte_size;
475    void *              m_baton;
476    ReadMemory          m_read_mem_callback;
477    WriteMemory         m_write_mem_callback;
478    ReadRegister        m_read_reg_callback;
479    WriteRegister       m_write_reg_callback;
480
481    lldb::addr_t m_inst_pc;
482    Instruction m_inst;
483    //------------------------------------------------------------------
484    // For EmulateInstruction only
485    //------------------------------------------------------------------
486    DISALLOW_COPY_AND_ASSIGN (EmulateInstruction);
487};
488
489}   // namespace lldb_private
490
491#endif  // lldb_EmulateInstruction_h_
492