• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===-- EmulateInstruction.h ------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLDB_CORE_EMULATEINSTRUCTION_H
10 #define LLDB_CORE_EMULATEINSTRUCTION_H
11 
12 #include <string>
13 
14 #include "lldb/Core/Address.h"
15 #include "lldb/Core/Opcode.h"
16 #include "lldb/Core/PluginInterface.h"
17 #include "lldb/Utility/ArchSpec.h"
18 #include "lldb/lldb-defines.h"
19 #include "lldb/lldb-enumerations.h"
20 #include "lldb/lldb-private-enumerations.h"
21 #include "lldb/lldb-private-types.h"
22 #include "lldb/lldb-types.h"
23 
24 #include <stddef.h>
25 #include <stdint.h>
26 
27 namespace lldb_private {
28 class OptionValueDictionary;
29 class RegisterContext;
30 class RegisterValue;
31 class Stream;
32 class Target;
33 class UnwindPlan;
34 
35 /// \class EmulateInstruction EmulateInstruction.h
36 /// "lldb/Core/EmulateInstruction.h"
37 /// A class that allows emulation of CPU opcodes.
38 ///
39 /// This class is a plug-in interface that is accessed through the standard
40 /// static FindPlugin function call in the EmulateInstruction class. The
41 /// FindPlugin takes a target triple and returns a new object if there is a
42 /// plug-in that supports the architecture and OS. Four callbacks and a baton
43 /// are provided. The four callbacks are read register, write register, read
44 /// memory and write memory.
45 ///
46 /// This class is currently designed for these main use cases: - Auto
47 /// generation of Call Frame Information (CFI) from assembly code - Predicting
48 /// single step breakpoint locations - Emulating instructions for breakpoint
49 /// traps
50 ///
51 /// Objects can be asked to read an instruction which will cause a call to the
52 /// read register callback to get the PC, followed by a read memory call to
53 /// read the opcode. If ReadInstruction () returns true, then a call to
54 /// EmulateInstruction::EvaluateInstruction () can be made. At this point the
55 /// EmulateInstruction subclass will use all of the callbacks to emulate an
56 /// instruction.
57 ///
58 /// Clients that provide the callbacks can either do the read/write
59 /// registers/memory to actually emulate the instruction on a real or virtual
60 /// CPU, or watch for the EmulateInstruction::Context which is context for the
61 /// read/write register/memory which explains why the callback is being
62 /// called. Examples of a context are: "pushing register 3 onto the stack at
63 /// offset -12", or "adjusting stack pointer by -16". This extra context
64 /// allows the generation of
65 /// CFI information from assembly code without having to actually do
66 /// the read/write register/memory.
67 ///
68 /// Clients must be prepared that not all instructions for an Instruction Set
69 /// Architecture (ISA) will be emulated.
70 ///
71 /// Subclasses at the very least should implement the instructions that save
72 /// and restore registers onto the stack and adjustment to the stack pointer.
73 /// By just implementing a few instructions for an ISA that are the typical
74 /// prologue opcodes, you can then generate CFI using a class that will soon
75 /// be available.
76 ///
77 /// Implementing all of the instructions that affect the PC can then allow
78 /// single step prediction support.
79 ///
80 /// Implementing all of the instructions allows for emulation of opcodes for
81 /// breakpoint traps and will pave the way for "thread centric" debugging. The
82 /// current debugging model is "process centric" where all threads must be
83 /// stopped when any thread is stopped; when hitting software breakpoints we
84 /// must disable the breakpoint by restoring the original breakpoint opcode,
85 /// single stepping and restoring the breakpoint trap. If all threads were
86 /// allowed to run then other threads could miss the breakpoint.
87 ///
88 /// This class centralizes the code that usually is done in separate code
89 /// paths in a debugger (single step prediction, finding save restore
90 /// locations of registers for unwinding stack frame variables) and emulating
91 /// the instruction is just a bonus.
92 
93 class EmulateInstruction : public PluginInterface {
94 public:
95   static EmulateInstruction *FindPlugin(const ArchSpec &arch,
96                                         InstructionType supported_inst_type,
97                                         const char *plugin_name);
98 
99   enum ContextType {
100     eContextInvalid = 0,
101     // Read an instruction opcode from memory
102     eContextReadOpcode,
103 
104     // Usually used for writing a register value whose source value is an
105     // immediate
106     eContextImmediate,
107 
108     // Exclusively used when saving a register to the stack as part of the
109     // prologue
110     eContextPushRegisterOnStack,
111 
112     // Exclusively used when restoring a register off the stack as part of the
113     // epilogue
114     eContextPopRegisterOffStack,
115 
116     // Add or subtract a value from the stack
117     eContextAdjustStackPointer,
118 
119     // Adjust the frame pointer for the current frame
120     eContextSetFramePointer,
121 
122     // Typically in an epilogue sequence.  Copy the frame pointer back into the
123     // stack pointer, use SP for CFA calculations again.
124     eContextRestoreStackPointer,
125 
126     // Add or subtract a value from a base address register (other than SP)
127     eContextAdjustBaseRegister,
128 
129     // Add or subtract a value from the PC or store a value to the PC.
130     eContextAdjustPC,
131 
132     // Used in WriteRegister callbacks to indicate where the
133     eContextRegisterPlusOffset,
134 
135     // Used in WriteMemory callback to indicate where the data came from
136     eContextRegisterStore,
137 
138     eContextRegisterLoad,
139 
140     // Used when performing a PC-relative branch where the
141     eContextRelativeBranchImmediate,
142 
143     // Used when performing an absolute branch where the
144     eContextAbsoluteBranchRegister,
145 
146     // Used when performing a supervisor call to an operating system to provide
147     // a service:
148     eContextSupervisorCall,
149 
150     // Used when performing a MemU operation to read the PC-relative offset
151     // from an address.
152     eContextTableBranchReadMemory,
153 
154     // Used when random bits are written into a register
155     eContextWriteRegisterRandomBits,
156 
157     // Used when random bits are written to memory
158     eContextWriteMemoryRandomBits,
159 
160     eContextArithmetic,
161 
162     eContextAdvancePC,
163 
164     eContextReturnFromException
165   };
166 
167   enum InfoType {
168     eInfoTypeRegisterPlusOffset,
169     eInfoTypeRegisterPlusIndirectOffset,
170     eInfoTypeRegisterToRegisterPlusOffset,
171     eInfoTypeRegisterToRegisterPlusIndirectOffset,
172     eInfoTypeRegisterRegisterOperands,
173     eInfoTypeOffset,
174     eInfoTypeRegister,
175     eInfoTypeImmediate,
176     eInfoTypeImmediateSigned,
177     eInfoTypeAddress,
178     eInfoTypeISAAndImmediate,
179     eInfoTypeISAAndImmediateSigned,
180     eInfoTypeISA,
181     eInfoTypeNoArgs
182   } InfoType;
183 
184   struct Context {
185     ContextType type;
186     enum InfoType info_type;
187     union {
188       struct RegisterPlusOffset {
189         RegisterInfo reg;      // base register
190         int64_t signed_offset; // signed offset added to base register
191       } RegisterPlusOffset;
192 
193       struct RegisterPlusIndirectOffset {
194         RegisterInfo base_reg;   // base register number
195         RegisterInfo offset_reg; // offset register kind
196       } RegisterPlusIndirectOffset;
197 
198       struct RegisterToRegisterPlusOffset {
199         RegisterInfo data_reg; // source/target register for data
200         RegisterInfo base_reg; // base register for address calculation
201         int64_t offset;        // offset for address calculation
202       } RegisterToRegisterPlusOffset;
203 
204       struct RegisterToRegisterPlusIndirectOffset {
205         RegisterInfo base_reg;   // base register for address calculation
206         RegisterInfo offset_reg; // offset register for address calculation
207         RegisterInfo data_reg;   // source/target register for data
208       } RegisterToRegisterPlusIndirectOffset;
209 
210       struct RegisterRegisterOperands {
211         RegisterInfo
212             operand1; // register containing first operand for binary op
213         RegisterInfo
214             operand2; // register containing second operand for binary op
215       } RegisterRegisterOperands;
216 
217       int64_t signed_offset; // signed offset by which to adjust self (for
218                              // registers only)
219 
220       RegisterInfo reg; // plain register
221 
222       uint64_t unsigned_immediate; // unsigned immediate value
223       int64_t signed_immediate;    // signed immediate value
224 
225       lldb::addr_t address; // direct address
226 
227       struct ISAAndImmediate {
228         uint32_t isa;
229         uint32_t unsigned_data32; // immediate data
230       } ISAAndImmediate;
231 
232       struct ISAAndImmediateSigned {
233         uint32_t isa;
234         int32_t signed_data32; // signed immediate data
235       } ISAAndImmediateSigned;
236 
237       uint32_t isa;
238     } info;
239 
ContextContext240     Context() : type(eContextInvalid), info_type(eInfoTypeNoArgs) {}
241 
SetRegisterPlusOffsetContext242     void SetRegisterPlusOffset(RegisterInfo base_reg, int64_t signed_offset) {
243       info_type = eInfoTypeRegisterPlusOffset;
244       info.RegisterPlusOffset.reg = base_reg;
245       info.RegisterPlusOffset.signed_offset = signed_offset;
246     }
247 
SetRegisterPlusIndirectOffsetContext248     void SetRegisterPlusIndirectOffset(RegisterInfo base_reg,
249                                        RegisterInfo offset_reg) {
250       info_type = eInfoTypeRegisterPlusIndirectOffset;
251       info.RegisterPlusIndirectOffset.base_reg = base_reg;
252       info.RegisterPlusIndirectOffset.offset_reg = offset_reg;
253     }
254 
SetRegisterToRegisterPlusOffsetContext255     void SetRegisterToRegisterPlusOffset(RegisterInfo data_reg,
256                                          RegisterInfo base_reg,
257                                          int64_t offset) {
258       info_type = eInfoTypeRegisterToRegisterPlusOffset;
259       info.RegisterToRegisterPlusOffset.data_reg = data_reg;
260       info.RegisterToRegisterPlusOffset.base_reg = base_reg;
261       info.RegisterToRegisterPlusOffset.offset = offset;
262     }
263 
SetRegisterToRegisterPlusIndirectOffsetContext264     void SetRegisterToRegisterPlusIndirectOffset(RegisterInfo base_reg,
265                                                  RegisterInfo offset_reg,
266                                                  RegisterInfo data_reg) {
267       info_type = eInfoTypeRegisterToRegisterPlusIndirectOffset;
268       info.RegisterToRegisterPlusIndirectOffset.base_reg = base_reg;
269       info.RegisterToRegisterPlusIndirectOffset.offset_reg = offset_reg;
270       info.RegisterToRegisterPlusIndirectOffset.data_reg = data_reg;
271     }
272 
SetRegisterRegisterOperandsContext273     void SetRegisterRegisterOperands(RegisterInfo op1_reg,
274                                      RegisterInfo op2_reg) {
275       info_type = eInfoTypeRegisterRegisterOperands;
276       info.RegisterRegisterOperands.operand1 = op1_reg;
277       info.RegisterRegisterOperands.operand2 = op2_reg;
278     }
279 
SetOffsetContext280     void SetOffset(int64_t signed_offset) {
281       info_type = eInfoTypeOffset;
282       info.signed_offset = signed_offset;
283     }
284 
SetRegisterContext285     void SetRegister(RegisterInfo reg) {
286       info_type = eInfoTypeRegister;
287       info.reg = reg;
288     }
289 
SetImmediateContext290     void SetImmediate(uint64_t immediate) {
291       info_type = eInfoTypeImmediate;
292       info.unsigned_immediate = immediate;
293     }
294 
SetImmediateSignedContext295     void SetImmediateSigned(int64_t signed_immediate) {
296       info_type = eInfoTypeImmediateSigned;
297       info.signed_immediate = signed_immediate;
298     }
299 
SetAddressContext300     void SetAddress(lldb::addr_t address) {
301       info_type = eInfoTypeAddress;
302       info.address = address;
303     }
SetISAAndImmediateContext304     void SetISAAndImmediate(uint32_t isa, uint32_t data) {
305       info_type = eInfoTypeISAAndImmediate;
306       info.ISAAndImmediate.isa = isa;
307       info.ISAAndImmediate.unsigned_data32 = data;
308     }
309 
SetISAAndImmediateSignedContext310     void SetISAAndImmediateSigned(uint32_t isa, int32_t data) {
311       info_type = eInfoTypeISAAndImmediateSigned;
312       info.ISAAndImmediateSigned.isa = isa;
313       info.ISAAndImmediateSigned.signed_data32 = data;
314     }
315 
SetISAContext316     void SetISA(uint32_t isa) {
317       info_type = eInfoTypeISA;
318       info.isa = isa;
319     }
320 
SetNoArgsContext321     void SetNoArgs() { info_type = eInfoTypeNoArgs; }
322 
323     void Dump(Stream &s, EmulateInstruction *instruction) const;
324   };
325 
326   typedef size_t (*ReadMemoryCallback)(EmulateInstruction *instruction,
327                                        void *baton, const Context &context,
328                                        lldb::addr_t addr, void *dst,
329                                        size_t length);
330 
331   typedef size_t (*WriteMemoryCallback)(EmulateInstruction *instruction,
332                                         void *baton, const Context &context,
333                                         lldb::addr_t addr, const void *dst,
334                                         size_t length);
335 
336   typedef bool (*ReadRegisterCallback)(EmulateInstruction *instruction,
337                                        void *baton,
338                                        const RegisterInfo *reg_info,
339                                        RegisterValue &reg_value);
340 
341   typedef bool (*WriteRegisterCallback)(EmulateInstruction *instruction,
342                                         void *baton, const Context &context,
343                                         const RegisterInfo *reg_info,
344                                         const RegisterValue &reg_value);
345 
346   // Type to represent the condition of an instruction. The UINT32 value is
347   // reserved for the unconditional case and all other value can be used in an
348   // architecture dependent way.
349   typedef uint32_t InstructionCondition;
350   static const InstructionCondition UnconditionalCondition = UINT32_MAX;
351 
352   EmulateInstruction(const ArchSpec &arch);
353 
354   ~EmulateInstruction() override = default;
355 
356   // Mandatory overrides
357   virtual bool
358   SupportsEmulatingInstructionsOfType(InstructionType inst_type) = 0;
359 
360   virtual bool SetTargetTriple(const ArchSpec &arch) = 0;
361 
362   virtual bool ReadInstruction() = 0;
363 
364   virtual bool EvaluateInstruction(uint32_t evaluate_options) = 0;
365 
GetInstructionCondition()366   virtual InstructionCondition GetInstructionCondition() {
367     return UnconditionalCondition;
368   }
369 
370   virtual bool TestEmulation(Stream *out_stream, ArchSpec &arch,
371                              OptionValueDictionary *test_data) = 0;
372 
373   virtual bool GetRegisterInfo(lldb::RegisterKind reg_kind, uint32_t reg_num,
374                                RegisterInfo &reg_info) = 0;
375 
376   // Optional overrides
377   virtual bool SetInstruction(const Opcode &insn_opcode,
378                               const Address &inst_addr, Target *target);
379 
380   virtual bool CreateFunctionEntryUnwind(UnwindPlan &unwind_plan);
381 
382   static const char *TranslateRegister(lldb::RegisterKind reg_kind,
383                                        uint32_t reg_num, std::string &reg_name);
384 
385   // RegisterInfo variants
386   bool ReadRegister(const RegisterInfo *reg_info, RegisterValue &reg_value);
387 
388   uint64_t ReadRegisterUnsigned(const RegisterInfo *reg_info,
389                                 uint64_t fail_value, bool *success_ptr);
390 
391   bool WriteRegister(const Context &context, const RegisterInfo *ref_info,
392                      const RegisterValue &reg_value);
393 
394   bool WriteRegisterUnsigned(const Context &context,
395                              const RegisterInfo *reg_info, uint64_t reg_value);
396 
397   // Register kind and number variants
398   bool ReadRegister(lldb::RegisterKind reg_kind, uint32_t reg_num,
399                     RegisterValue &reg_value);
400 
401   bool WriteRegister(const Context &context, lldb::RegisterKind reg_kind,
402                      uint32_t reg_num, const RegisterValue &reg_value);
403 
404   uint64_t ReadRegisterUnsigned(lldb::RegisterKind reg_kind, uint32_t reg_num,
405                                 uint64_t fail_value, bool *success_ptr);
406 
407   bool WriteRegisterUnsigned(const Context &context,
408                              lldb::RegisterKind reg_kind, uint32_t reg_num,
409                              uint64_t reg_value);
410 
411   size_t ReadMemory(const Context &context, lldb::addr_t addr, void *dst,
412                     size_t dst_len);
413 
414   uint64_t ReadMemoryUnsigned(const Context &context, lldb::addr_t addr,
415                               size_t byte_size, uint64_t fail_value,
416                               bool *success_ptr);
417 
418   bool WriteMemory(const Context &context, lldb::addr_t addr, const void *src,
419                    size_t src_len);
420 
421   bool WriteMemoryUnsigned(const Context &context, lldb::addr_t addr,
422                            uint64_t uval, size_t uval_byte_size);
423 
GetAddressByteSize()424   uint32_t GetAddressByteSize() const { return m_arch.GetAddressByteSize(); }
425 
GetByteOrder()426   lldb::ByteOrder GetByteOrder() const { return m_arch.GetByteOrder(); }
427 
GetOpcode()428   const Opcode &GetOpcode() const { return m_opcode; }
429 
GetAddress()430   lldb::addr_t GetAddress() const { return m_addr; }
431 
GetArchitecture()432   const ArchSpec &GetArchitecture() const { return m_arch; }
433 
434   static size_t ReadMemoryFrame(EmulateInstruction *instruction, void *baton,
435                                 const Context &context, lldb::addr_t addr,
436                                 void *dst, size_t length);
437 
438   static size_t WriteMemoryFrame(EmulateInstruction *instruction, void *baton,
439                                  const Context &context, lldb::addr_t addr,
440                                  const void *dst, size_t length);
441 
442   static bool ReadRegisterFrame(EmulateInstruction *instruction, void *baton,
443                                 const RegisterInfo *reg_info,
444                                 RegisterValue &reg_value);
445 
446   static bool WriteRegisterFrame(EmulateInstruction *instruction, void *baton,
447                                  const Context &context,
448                                  const RegisterInfo *reg_info,
449                                  const RegisterValue &reg_value);
450 
451   static size_t ReadMemoryDefault(EmulateInstruction *instruction, void *baton,
452                                   const Context &context, lldb::addr_t addr,
453                                   void *dst, size_t length);
454 
455   static size_t WriteMemoryDefault(EmulateInstruction *instruction, void *baton,
456                                    const Context &context, lldb::addr_t addr,
457                                    const void *dst, size_t length);
458 
459   static bool ReadRegisterDefault(EmulateInstruction *instruction, void *baton,
460                                   const RegisterInfo *reg_info,
461                                   RegisterValue &reg_value);
462 
463   static bool WriteRegisterDefault(EmulateInstruction *instruction, void *baton,
464                                    const Context &context,
465                                    const RegisterInfo *reg_info,
466                                    const RegisterValue &reg_value);
467 
468   void SetBaton(void *baton);
469 
470   void SetCallbacks(ReadMemoryCallback read_mem_callback,
471                     WriteMemoryCallback write_mem_callback,
472                     ReadRegisterCallback read_reg_callback,
473                     WriteRegisterCallback write_reg_callback);
474 
475   void SetReadMemCallback(ReadMemoryCallback read_mem_callback);
476 
477   void SetWriteMemCallback(WriteMemoryCallback write_mem_callback);
478 
479   void SetReadRegCallback(ReadRegisterCallback read_reg_callback);
480 
481   void SetWriteRegCallback(WriteRegisterCallback write_reg_callback);
482 
483   static bool GetBestRegisterKindAndNumber(const RegisterInfo *reg_info,
484                                            lldb::RegisterKind &reg_kind,
485                                            uint32_t &reg_num);
486 
487   static uint32_t GetInternalRegisterNumber(RegisterContext *reg_ctx,
488                                             const RegisterInfo &reg_info);
489 
490 protected:
491   ArchSpec m_arch;
492   void *m_baton = nullptr;
493   ReadMemoryCallback m_read_mem_callback = &ReadMemoryDefault;
494   WriteMemoryCallback m_write_mem_callback = &WriteMemoryDefault;
495   ReadRegisterCallback m_read_reg_callback = &ReadRegisterDefault;
496   WriteRegisterCallback m_write_reg_callback = &WriteRegisterDefault;
497   lldb::addr_t m_addr = LLDB_INVALID_ADDRESS;
498   Opcode m_opcode;
499 
500 private:
501   // For EmulateInstruction only
502   EmulateInstruction(const EmulateInstruction &) = delete;
503   const EmulateInstruction &operator=(const EmulateInstruction &) = delete;
504 };
505 
506 } // namespace lldb_private
507 
508 #endif // LLDB_CORE_EMULATEINSTRUCTION_H
509