EmulateInstruction.h revision ea69d6ddc37e25d57973699463110b6c3233f0a0
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 <string>
14
15#include "lldb/lldb-public.h"
16#include "lldb/Core/ArchSpec.h"
17#include "lldb/Core/PluginInterface.h"
18#include "lldb/Core/Opcode.h"
19
20//----------------------------------------------------------------------
21/// @class EmulateInstruction EmulateInstruction.h "lldb/Core/EmulateInstruction.h"
22/// @brief A class that allows emulation of CPU opcodes.
23///
24/// This class is a plug-in interface that is accessed through the
25/// standard static FindPlugin function call in the EmulateInstruction
26/// class. The FindPlugin takes a target triple and returns a new object
27/// if there is a plug-in that supports the architecture and OS. Four
28/// callbacks and a baton are provided. The four callbacks are read
29/// register, write register, read memory and write memory.
30///
31/// This class is currently designed for these main use cases:
32/// - Auto generation of Call Frame Information (CFI) from assembly code
33/// - Predicting single step breakpoint locations
34/// - Emulating instructions for breakpoint traps
35///
36/// Objects can be asked to read an instruction which will cause a call
37/// to the read register callback to get the PC, followed by a read
38/// memory call to read the opcode. If ReadInstruction () returns true,
39/// then a call to EmulateInstruction::EvaluateInstruction () can be
40/// made. At this point the EmulateInstruction subclass will use all of
41/// the callbacks to emulate an instruction.
42///
43/// Clients that provide the callbacks can either do the read/write
44/// registers/memory to actually emulate the instruction on a real or
45/// virtual CPU, or watch for the EmulateInstruction::Context which
46/// is context for the read/write register/memory which explains why
47/// the callback is being called. Examples of a context are:
48/// "pushing register 3 onto the stack at offset -12", or "adjusting
49/// stack pointer by -16". This extra context allows the generation of
50/// CFI information from assembly code without having to actually do
51/// the read/write register/memory.
52///
53/// Clients must be prepared that not all instructions for an
54/// Instruction Set Architecture (ISA) will be emulated.
55///
56/// Subclasses at the very least should implement the instructions that
57/// save and restore regiters onto the stack and adjustment to the stack
58/// pointer. By just implementing a few instructions for an ISA that are
59/// the typical prologue opcodes, you can then generate CFI using a
60/// class that will soon be available.
61///
62/// Implmenting all of the instructions that affect the PC can then
63/// allow single step prediction support.
64///
65/// Implmenting all of the instructions allows for emulation of opcodes
66/// for breakpoint traps and will pave the way for "thread centric"
67/// debugging. The current debugging model is "process centric" where
68/// all threads must be stopped when any thread is stopped since when
69/// hitting software breakpoints once must disable the breakpoint by
70/// restoring the original breakpoint opcde, single stepping and
71/// restoring the breakpoint trap. If all threads were allowed to run
72/// then other threads could miss the breakpoint.
73///
74/// This class centralizes the code that usually is done in separate
75/// code paths in a debugger (single step prediction, finding save
76/// restore locations of registers for unwinding stack frame variables,
77/// and emulating the intruction is just a bonus.
78//----------------------------------------------------------------------
79
80namespace lldb_private {
81
82class EmulateInstruction :
83    public PluginInterface
84{
85public:
86
87    static EmulateInstruction*
88    FindPlugin (const ArchSpec &arch, const char *plugin_name);
89
90    enum ContextType
91    {
92        eContextInvalid = 0,
93        // Read an instruciton opcode from memory
94        eContextReadOpcode,
95
96        // Usually used for writing a register value whose source value in an
97        // immediate
98        eContextImmediate,
99
100        // Exclusively used when saving a register to the stack as part of the
101        // prologue
102        eContextPushRegisterOnStack,
103
104        // Exclusively used when restoring a register off the stack as part of
105        // the epilogue
106        eContextPopRegisterOffStack,
107
108        // Add or subtract a value from the stack
109        eContextAdjustStackPointer,
110
111        // Add or subtract a value from a base address register (other than SP)
112        eContextAdjustBaseRegister,
113
114        // Used in WriteRegister callbacks to indicate where the
115        eContextRegisterPlusOffset,
116
117        // Used in WriteMemory callback to indicate where the data came from
118        eContextRegisterStore,
119
120        eContextRegisterLoad,
121
122        // Used when performing a PC-relative branch where the
123        eContextRelativeBranchImmediate,
124
125        // Used when performing an absolute branch where the
126        eContextAbsoluteBranchRegister,
127
128        // Used when performing a supervisor call to an operating system to
129        // provide a service:
130        eContextSupervisorCall,
131
132        // Used when performing a MemU operation to read the PC-relative offset
133        // from an address.
134        eContextTableBranchReadMemory,
135
136        // Used when random bits are written into a register
137        eContextWriteRegisterRandomBits,
138
139        // Used when random bits are written to memory
140        eContextWriteMemoryRandomBits,
141
142        eContextMultiplication,
143
144        eContextAddition,
145
146        eContextSubtraction,
147
148        eContextReturnFromException
149    };
150
151    enum InfoType {
152        eInfoTypeRegisterPlusOffset,
153        eInfoTypeRegisterPlusIndirectOffset,
154        eInfoTypeRegisterToRegisterPlusOffset,
155        eInfoTypeRegisterToRegisterPlusIndirectOffset,
156        eInfoTypeRegisterRegisterOperands,
157        eInfoTypeOffset,
158        eInfoTypeRegister,
159        eInfoTypeImmediate,
160        eInfoTypeImmediateSigned,
161        eInfoTypeAddress,
162        eInfoTypeModeAndImmediate,
163        eInfoTypeModeAndImmediateSigned,
164        eInfoTypeMode,
165        eInfoTypeNoArgs
166    } InfoType;
167
168    struct Register
169    {
170        uint32_t kind;
171        uint32_t num;
172
173
174        void
175        SetRegister (uint32_t reg_kind, uint32_t reg_num)
176        {
177            kind = reg_kind;
178            num = reg_num;
179        }
180    };
181
182    struct Context
183    {
184        ContextType type;
185        enum InfoType info_type;
186        union
187        {
188            struct RegisterPlusOffset
189            {
190                Register reg;          // base register
191                int64_t signed_offset; // signed offset added to base register
192            } RegisterPlusOffset;
193
194            struct RegisterPlusIndirectOffset
195            {
196                Register base_reg;    // base register number
197                Register offset_reg;  // offset register kind
198            } RegisterPlusIndirectOffset;
199
200            struct RegisterToRegisterPlusOffset
201            {
202                Register data_reg;  // source/target register for data
203                Register base_reg;  // base register for address calculation
204                int64_t offset;     // offset for address calculation
205            } RegisterToRegisterPlusOffset;
206
207            struct RegisterToRegisterPlusIndirectOffset
208            {
209                Register base_reg;   // base register for address calculation
210                Register offset_reg; // offset register for address calculation
211                Register data_reg;   // source/target register for data
212            } RegisterToRegisterPlusIndirectOffset;
213
214            struct RegisterRegisterOperands
215            {
216                Register operand1;  // register containing first operand for binary op
217                Register operand2;  // register containing second operand for binary op
218            } RegisterRegisterOperands;
219
220            int64_t signed_offset; // signed offset by which to adjust self (for registers only)
221
222            Register reg;          // plain register
223
224            uint64_t immediate;    // immediate value
225
226            int64_t signed_immediate; // signed immediate value
227
228            lldb::addr_t address;        // direct address
229
230            struct ModeAndImmediate
231            {
232                uint32_t mode;        // eModeARM or eModeThumb
233                uint32_t data_value;  // immdiate data
234            } ModeAndImmediate;
235
236            struct ModeAndImmediateSigned
237            {
238                uint32_t mode;             // eModeARM or eModeThumb
239                int32_t signed_data_value; // signed immdiate data
240            } ModeAndImmediateSigned;
241
242            uint32_t mode;         // eModeARM or eModeThumb
243
244        } info;
245
246        void
247        SetRegisterPlusOffset (Register base_reg,
248                               int64_t signed_offset)
249        {
250            info_type = eInfoTypeRegisterPlusOffset;
251            info.RegisterPlusOffset.reg = base_reg;
252            info.RegisterPlusOffset.signed_offset = signed_offset;
253        }
254
255        void
256        SetRegisterPlusIndirectOffset (Register base_reg,
257                                       Register offset_reg)
258        {
259            info_type = eInfoTypeRegisterPlusIndirectOffset;
260            info.RegisterPlusIndirectOffset.base_reg   = base_reg;
261            info.RegisterPlusIndirectOffset.offset_reg = offset_reg;
262        }
263
264        void
265        SetRegisterToRegisterPlusOffset (Register data_reg,
266                                         Register base_reg,
267                                         int64_t offset)
268        {
269            info_type = eInfoTypeRegisterToRegisterPlusOffset;
270            info.RegisterToRegisterPlusOffset.data_reg = data_reg;
271            info.RegisterToRegisterPlusOffset.base_reg = base_reg;
272            info.RegisterToRegisterPlusOffset.offset   = offset;
273        }
274
275        void
276        SetRegisterToRegisterPlusIndirectOffset (Register base_reg,
277                                                 Register offset_reg,
278                                                 Register data_reg)
279        {
280            info_type = eInfoTypeRegisterToRegisterPlusIndirectOffset;
281            info.RegisterToRegisterPlusIndirectOffset.base_reg   = base_reg;
282            info.RegisterToRegisterPlusIndirectOffset.offset_reg = offset_reg;
283            info.RegisterToRegisterPlusIndirectOffset.data_reg   = data_reg;
284        }
285
286        void
287        SetRegisterRegisterOperands (Register op1_reg,
288                                     Register op2_reg)
289        {
290            info_type = eInfoTypeRegisterRegisterOperands;
291            info.RegisterRegisterOperands.operand1 = op1_reg;
292            info.RegisterRegisterOperands.operand2 = op2_reg;
293        }
294
295        void
296        SetOffset (int64_t signed_offset)
297        {
298            info_type = eInfoTypeOffset;
299            info.signed_offset = signed_offset;
300        }
301
302        void
303        SetRegister (Register reg)
304        {
305            info_type = eInfoTypeRegister;
306            info.reg = reg;
307        }
308
309        void
310        SetImmediate (uint64_t immediate)
311        {
312            info_type = eInfoTypeImmediate;
313            info.immediate = immediate;
314        }
315
316        void
317        SetImmediateSigned (int64_t signed_immediate)
318        {
319            info_type = eInfoTypeImmediateSigned;
320            info.signed_immediate = signed_immediate;
321        }
322
323        void
324        SetAddress (lldb::addr_t address)
325        {
326            info_type = eInfoTypeAddress;
327            info.address = address;
328        }
329        void
330        SetModeAndImmediate (uint32_t mode, uint32_t data_value)
331        {
332            info_type = eInfoTypeModeAndImmediate;
333            info.ModeAndImmediate.mode = mode;
334            info.ModeAndImmediate.data_value = data_value;
335        }
336
337        void
338        SetModeAndImmediateSigned (uint32_t mode, int32_t signed_data_value)
339        {
340            info_type = eInfoTypeModeAndImmediateSigned;
341            info.ModeAndImmediateSigned.mode = mode;
342            info.ModeAndImmediateSigned.signed_data_value = signed_data_value;
343        }
344
345        void
346        SetMode (uint32_t mode)
347        {
348            info_type = eInfoTypeMode;
349            info.mode = mode;
350        }
351
352        void
353        SetNoArgs ()
354        {
355            info_type = eInfoTypeNoArgs;
356        }
357
358    };
359
360    static void
361    PrintContext (const char *context_type, const Context &context);
362
363    typedef size_t (*ReadMemory) (void *baton,
364                                  const Context &context,
365                                  lldb::addr_t addr,
366                                  void *dst,
367                                  size_t length);
368
369    typedef size_t (*WriteMemory) (void *baton,
370                                   const Context &context,
371                                   lldb::addr_t addr,
372                                   const void *dst,
373                                   size_t length);
374
375    typedef bool   (*ReadRegister)  (void *baton,
376                                     uint32_t reg_kind,
377                                     uint32_t reg_num,
378                                     uint64_t &reg_value);
379
380    typedef bool   (*WriteRegister) (void *baton,
381                                     const Context &context,
382                                     uint32_t reg_kind,
383                                     uint32_t reg_num,
384                                     uint64_t reg_value);
385
386    EmulateInstruction (lldb::ByteOrder byte_order,
387                        uint32_t addr_byte_size,
388                        const ArchSpec &arch,
389                        void *baton,
390                        ReadMemory read_mem_callback,
391                        WriteMemory write_mem_callback,
392                        ReadRegister read_reg_callback,
393                        WriteRegister write_reg_callback);
394
395    EmulateInstruction (lldb::ByteOrder byte_order,
396                        uint32_t addr_byte_size,
397                        const ArchSpec &arch);
398
399    virtual ~EmulateInstruction()
400    {
401    }
402
403    virtual bool
404    SetTargetTriple (const ArchSpec &arch) = 0;
405
406    virtual bool
407    ReadInstruction () = 0;
408
409    virtual bool
410    SetInstruction (const Opcode &insn_opcode, const Address &inst_addr) = 0;
411
412    virtual bool
413    EvaluateInstruction () = 0;
414
415    static void
416    TranslateRegister (uint32_t reg_kind, uint32_t reg_num, std::string &reg_name);
417
418    uint64_t
419    ReadRegisterUnsigned (uint32_t reg_kind,
420                          uint32_t reg_num,
421                          uint64_t fail_value,
422                          bool *success_ptr);
423
424    bool
425    WriteRegisterUnsigned (const Context &context,
426                           uint32_t reg_kind,
427                           uint32_t reg_num,
428                           uint64_t reg_value);
429
430    uint64_t
431    ReadMemoryUnsigned (const Context &context,
432                        lldb::addr_t addr,
433                        size_t byte_size,
434                        uint64_t fail_value,
435                        bool *success_ptr);
436
437    bool
438    WriteMemoryUnsigned (const Context &context,
439                         lldb::addr_t addr,
440                         uint64_t uval,
441                         size_t uval_byte_size);
442
443    uint32_t
444    GetAddressByteSize () const
445    {
446        return m_addr_byte_size;
447    }
448
449    lldb::ByteOrder
450    GetByteOrder () const
451    {
452        return m_byte_order;
453    }
454
455    const Opcode &
456    GetOpcode () const
457    {
458        return m_opcode;
459    }
460
461
462    static size_t
463    ReadMemoryFrame (void *baton,
464                     const Context &context,
465                     lldb::addr_t addr,
466                     void *dst,
467                     size_t length);
468
469    static size_t
470    WriteMemoryFrame (void *baton,
471                      const Context &context,
472                      lldb::addr_t addr,
473                      const void *dst,
474                      size_t length);
475
476    static bool
477    ReadRegisterFrame  (void *baton,
478                        uint32_t reg_kind,
479                        uint32_t reg_num,
480                        uint64_t &reg_value);
481
482
483    static bool
484    WriteRegisterFrame (void *baton,
485                        const Context &context,
486                        uint32_t reg_kind,
487                        uint32_t reg_num,
488                        uint64_t reg_value);
489
490    static size_t
491    ReadMemoryDefault (void *baton,
492                       const Context &context,
493                       lldb::addr_t addr,
494                       void *dst,
495                       size_t length);
496
497    static size_t
498    WriteMemoryDefault (void *baton,
499                        const Context &context,
500                        lldb::addr_t addr,
501                        const void *dst,
502                        size_t length);
503
504    static bool
505    ReadRegisterDefault  (void *baton,
506                          uint32_t reg_kind,
507                          uint32_t reg_num,
508                          uint64_t &reg_value);
509
510
511    static bool
512    WriteRegisterDefault (void *baton,
513                          const Context &context,
514                          uint32_t reg_kind,
515                          uint32_t reg_num,
516                          uint64_t reg_value);
517
518    void
519    SetBaton (void *baton);
520
521    void
522    SetCallbacks (ReadMemory read_mem_callback,
523                  WriteMemory write_mem_callback,
524                  ReadRegister read_reg_callback,
525                  WriteRegister write_reg_callback);
526
527    void
528    SetReadMemCallback (ReadMemory read_mem_callback);
529
530    void
531    SetWriteMemCallback (WriteMemory write_mem_callback);
532
533    void
534    SetReadRegCallback (ReadRegister read_reg_callback);
535
536    void
537    SetWriteRegCallback (WriteRegister write_reg_callback);
538
539
540protected:
541    lldb::ByteOrder     m_byte_order;
542    uint32_t            m_addr_byte_size;
543    ArchSpec            m_arch;
544    void *              m_baton;
545    ReadMemory          m_read_mem_callback;
546    WriteMemory         m_write_mem_callback;
547    ReadRegister        m_read_reg_callback;
548    WriteRegister       m_write_reg_callback;
549    lldb::addr_t        m_opcode_pc;
550    Opcode              m_opcode;
551    //------------------------------------------------------------------
552    // For EmulateInstruction only
553    //------------------------------------------------------------------
554    DISALLOW_COPY_AND_ASSIGN (EmulateInstruction);
555};
556
557}   // namespace lldb_private
558
559#endif  // lldb_EmulateInstruction_h_
560