LLDB  mainline
EmulateInstruction.h
Go to the documentation of this file.
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"
17 #include "lldb/Utility/ArchSpec.h"
18 #include "lldb/lldb-defines.h"
19 #include "lldb/lldb-enumerations.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 
94 public:
95  static EmulateInstruction *FindPlugin(const ArchSpec &arch,
96  InstructionType supported_inst_type,
97  const char *plugin_name);
98 
99  enum ContextType {
101  // Read an instruction opcode from memory
103 
104  // Usually used for writing a register value whose source value is an
105  // immediate
107 
108  // Exclusively used when saving a register to the stack as part of the
109  // prologue
111 
112  // Exclusively used when restoring a register off the stack as part of the
113  // epilogue
115 
116  // Add or subtract a value from the stack
118 
119  // Adjust the frame pointer for the current frame
121 
122  // Typically in an epilogue sequence. Copy the frame pointer back into the
123  // stack pointer, use SP for CFA calculations again.
125 
126  // Add or subtract a value from a base address register (other than SP)
128 
129  // Add or subtract a value from the PC or store a value to the PC.
131 
132  // Used in WriteRegister callbacks to indicate where the
134 
135  // Used in WriteMemory callback to indicate where the data came from
137 
139 
140  // Used when performing a PC-relative branch where the
142 
143  // Used when performing an absolute branch where the
145 
146  // Used when performing a supervisor call to an operating system to provide
147  // a service:
149 
150  // Used when performing a MemU operation to read the PC-relative offset
151  // from an address.
153 
154  // Used when random bits are written into a register
156 
157  // Used when random bits are written to memory
159 
161 
163 
165  };
166 
167  enum InfoType {
182  } InfoType;
183 
184  struct Context {
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
192 
194  RegisterInfo base_reg; // base register number
195  RegisterInfo offset_reg; // offset register kind
197 
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
203 
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
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
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 {
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
236 
237  uint32_t isa;
238  } info;
239 
240  Context() : type(eContextInvalid), info_type(eInfoTypeNoArgs) {}
241 
242  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 
249  RegisterInfo offset_reg) {
251  info.RegisterPlusIndirectOffset.base_reg = base_reg;
252  info.RegisterPlusIndirectOffset.offset_reg = offset_reg;
253  }
254 
256  RegisterInfo base_reg,
257  int64_t offset) {
259  info.RegisterToRegisterPlusOffset.data_reg = data_reg;
260  info.RegisterToRegisterPlusOffset.base_reg = base_reg;
261  info.RegisterToRegisterPlusOffset.offset = offset;
262  }
263 
265  RegisterInfo offset_reg,
266  RegisterInfo data_reg) {
268  info.RegisterToRegisterPlusIndirectOffset.base_reg = base_reg;
269  info.RegisterToRegisterPlusIndirectOffset.offset_reg = offset_reg;
270  info.RegisterToRegisterPlusIndirectOffset.data_reg = data_reg;
271  }
272 
273  void SetRegisterRegisterOperands(RegisterInfo op1_reg,
274  RegisterInfo op2_reg) {
276  info.RegisterRegisterOperands.operand1 = op1_reg;
277  info.RegisterRegisterOperands.operand2 = op2_reg;
278  }
279 
280  void SetOffset(int64_t signed_offset) {
281  info_type = eInfoTypeOffset;
282  info.signed_offset = signed_offset;
283  }
284 
285  void SetRegister(RegisterInfo reg) {
286  info_type = eInfoTypeRegister;
287  info.reg = reg;
288  }
289 
290  void SetImmediate(uint64_t immediate) {
291  info_type = eInfoTypeImmediate;
292  info.unsigned_immediate = immediate;
293  }
294 
296  info_type = eInfoTypeImmediateSigned;
297  info.signed_immediate = signed_immediate;
298  }
299 
301  info_type = eInfoTypeAddress;
302  info.address = address;
303  }
305  info_type = eInfoTypeISAAndImmediate;
306  info.ISAAndImmediate.isa = isa;
307  info.ISAAndImmediate.unsigned_data32 = data;
308  }
309 
310  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 
317  info_type = eInfoTypeISA;
318  info.isa = isa;
319  }
320 
321  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.
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
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 
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 
425 
427 
428  const Opcode &GetOpcode() const { return m_opcode; }
429 
430  lldb::addr_t GetAddress() const { return m_addr; }
431 
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 
488  const RegisterInfo &reg_info);
489 
490 protected:
492  void *m_baton = nullptr;
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
void SetReadMemCallback(ReadMemoryCallback read_mem_callback)
bool WriteMemoryUnsigned(const Context &context, lldb::addr_t addr, uint64_t uval, size_t uval_byte_size)
bool ReadRegister(const RegisterInfo *reg_info, RegisterValue &reg_value)
static const InstructionCondition UnconditionalCondition
EmulateInstruction(const ArchSpec &arch)
struct lldb_private::EmulateInstruction::Context::@6::RegisterPlusOffset RegisterPlusOffset
static size_t WriteMemoryDefault(EmulateInstruction *instruction, void *baton, const Context &context, lldb::addr_t addr, const void *dst, size_t length)
A class that represents a running process on the host machine.
struct lldb_private::EmulateInstruction::Context::@6::RegisterToRegisterPlusOffset RegisterToRegisterPlusOffset
uint64_t ReadRegisterUnsigned(const RegisterInfo *reg_info, uint64_t fail_value, bool *success_ptr)
void Dump(Stream &s, EmulateInstruction *instruction) const
A stream class that can stream formatted output to a file.
Definition: Stream.h:28
virtual bool SetTargetTriple(const ArchSpec &arch)=0
union lldb_private::EmulateInstruction::Context::@6 info
void SetImmediateSigned(int64_t signed_immediate)
uint32_t GetAddressByteSize() const
Returns the size in bytes of an address of the current architecture.
Definition: ArchSpec.cpp:730
bool WriteRegister(const Context &context, const RegisterInfo *ref_info, const RegisterValue &reg_value)
virtual bool GetRegisterInfo(lldb::RegisterKind reg_kind, uint32_t reg_num, RegisterInfo &reg_info)=0
size_t(* WriteMemoryCallback)(EmulateInstruction *instruction, void *baton, const Context &context, lldb::addr_t addr, const void *dst, size_t length)
lldb::ByteOrder GetByteOrder() const
void SetISAAndImmediateSigned(uint32_t isa, int32_t data)
static const char * TranslateRegister(lldb::RegisterKind reg_kind, uint32_t reg_num, std::string &reg_name)
An architecture specification class.
Definition: ArchSpec.h:33
~EmulateInstruction() override=default
"lldb/Core/EmulateInstruction.h" A class that allows emulation of CPU opcodes.
struct lldb_private::EmulateInstruction::Context::@6::RegisterPlusIndirectOffset RegisterPlusIndirectOffset
uint64_t ReadMemoryUnsigned(const Context &context, lldb::addr_t addr, size_t byte_size, uint64_t fail_value, bool *success_ptr)
bool WriteMemory(const Context &context, lldb::addr_t addr, const void *src, size_t src_len)
void SetRegisterToRegisterPlusIndirectOffset(RegisterInfo base_reg, RegisterInfo offset_reg, RegisterInfo data_reg)
static size_t ReadMemoryDefault(EmulateInstruction *instruction, void *baton, const Context &context, lldb::addr_t addr, void *dst, size_t length)
static uint32_t GetInternalRegisterNumber(RegisterContext *reg_ctx, const RegisterInfo &reg_info)
void SetReadRegCallback(ReadRegisterCallback read_reg_callback)
#define UINT32_MAX
Definition: lldb-defines.h:31
const EmulateInstruction & operator=(const EmulateInstruction &)=delete
void SetRegisterPlusOffset(RegisterInfo base_reg, int64_t signed_offset)
#define LLDB_INVALID_ADDRESS
Invalid value definitions.
Definition: lldb-defines.h:85
size_t ReadMemory(const Context &context, lldb::addr_t addr, void *dst, size_t dst_len)
RegisterKind
Register numbering types.
size_t(* ReadMemoryCallback)(EmulateInstruction *instruction, void *baton, const Context &context, lldb::addr_t addr, void *dst, size_t length)
virtual bool SupportsEmulatingInstructionsOfType(InstructionType inst_type)=0
void SetISAAndImmediate(uint32_t isa, uint32_t data)
static bool WriteRegisterDefault(EmulateInstruction *instruction, void *baton, const Context &context, const RegisterInfo *reg_info, const RegisterValue &reg_value)
const ArchSpec & GetArchitecture() const
static bool WriteRegisterFrame(EmulateInstruction *instruction, void *baton, const Context &context, const RegisterInfo *reg_info, const RegisterValue &reg_value)
virtual InstructionCondition GetInstructionCondition()
static EmulateInstruction * FindPlugin(const ArchSpec &arch, InstructionType supported_inst_type, const char *plugin_name)
ByteOrder
Byte ordering definitions.
void SetRegisterPlusIndirectOffset(RegisterInfo base_reg, RegisterInfo offset_reg)
void SetRegisterToRegisterPlusOffset(RegisterInfo data_reg, RegisterInfo base_reg, int64_t offset)
static size_t WriteMemoryFrame(EmulateInstruction *instruction, void *baton, const Context &context, lldb::addr_t addr, const void *dst, size_t length)
lldb::ByteOrder GetByteOrder() const
Returns the byte order for the architecture specification.
Definition: ArchSpec.cpp:777
static bool ReadRegisterDefault(EmulateInstruction *instruction, void *baton, const RegisterInfo *reg_info, RegisterValue &reg_value)
WriteRegisterCallback m_write_reg_callback
WriteMemoryCallback m_write_mem_callback
A section + offset based address class.
Definition: Address.h:59
virtual bool SetInstruction(const Opcode &insn_opcode, const Address &inst_addr, Target *target)
static bool ReadRegisterFrame(EmulateInstruction *instruction, void *baton, const RegisterInfo *reg_info, RegisterValue &reg_value)
InstructionType
Instruction types.
struct lldb_private::EmulateInstruction::Context::@6::ISAAndImmediate ISAAndImmediate
bool(* WriteRegisterCallback)(EmulateInstruction *instruction, void *baton, const Context &context, const RegisterInfo *reg_info, const RegisterValue &reg_value)
static bool GetBestRegisterKindAndNumber(const RegisterInfo *reg_info, lldb::RegisterKind &reg_kind, uint32_t &reg_num)
static size_t ReadMemoryFrame(EmulateInstruction *instruction, void *baton, const Context &context, lldb::addr_t addr, void *dst, size_t length)
uint64_t addr_t
Definition: lldb-types.h:83
struct lldb_private::EmulateInstruction::Context::@6::RegisterRegisterOperands RegisterRegisterOperands
void SetRegisterRegisterOperands(RegisterInfo op1_reg, RegisterInfo op2_reg)
struct lldb_private::EmulateInstruction::Context::@6::RegisterToRegisterPlusIndirectOffset RegisterToRegisterPlusIndirectOffset
ReadRegisterCallback m_read_reg_callback
struct lldb_private::EmulateInstruction::Context::@6::ISAAndImmediateSigned ISAAndImmediateSigned
void SetWriteMemCallback(WriteMemoryCallback write_mem_callback)
bool WriteRegisterUnsigned(const Context &context, const RegisterInfo *reg_info, uint64_t reg_value)
virtual bool TestEmulation(Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data)=0
virtual bool EvaluateInstruction(uint32_t evaluate_options)=0
bool(* ReadRegisterCallback)(EmulateInstruction *instruction, void *baton, const RegisterInfo *reg_info, RegisterValue &reg_value)
void SetWriteRegCallback(WriteRegisterCallback write_reg_callback)
void SetCallbacks(ReadMemoryCallback read_mem_callback, WriteMemoryCallback write_mem_callback, ReadRegisterCallback read_reg_callback, WriteRegisterCallback write_reg_callback)
virtual bool CreateFunctionEntryUnwind(UnwindPlan &unwind_plan)