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