1 //===-- EmulateInstruction.h ------------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #ifndef lldb_EmulateInstruction_h_
10 #define lldb_EmulateInstruction_h_
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"
27 namespace lldb_private {
28 class OptionValueDictionary;
29 class RegisterContext;
35 /// \class EmulateInstruction EmulateInstruction.h
36 /// "lldb/Core/EmulateInstruction.h"
37 /// A class that allows emulation of CPU opcodes.
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.
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
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
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.
68 /// Clients must be prepared that not all instructions for an Instruction Set
69 /// Architecture (ISA) will be emulated.
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
77 /// Implementing all of the instructions that affect the PC can then allow
78 /// single step prediction support.
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.
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.
93 class EmulateInstruction : public PluginInterface {
95 static EmulateInstruction *FindPlugin(const ArchSpec &arch,
96 InstructionType supported_inst_type,
97 const char *plugin_name);
101 // Read an instruction opcode from memory
104 // Usually used for writing a register value whose source value is an
108 // Exclusively used when saving a register to the stack as part of the
110 eContextPushRegisterOnStack,
112 // Exclusively used when restoring a register off the stack as part of the
114 eContextPopRegisterOffStack,
116 // Add or subtract a value from the stack
117 eContextAdjustStackPointer,
119 // Adjust the frame pointer for the current frame
120 eContextSetFramePointer,
122 // Typically in an epilogue sequence. Copy the frame pointer back into the
123 // stack pointer, use SP for CFA calculations again.
124 eContextRestoreStackPointer,
126 // Add or subtract a value from a base address register (other than SP)
127 eContextAdjustBaseRegister,
129 // Add or subtract a value from the PC or store a value to the PC.
132 // Used in WriteRegister callbacks to indicate where the
133 eContextRegisterPlusOffset,
135 // Used in WriteMemory callback to indicate where the data came from
136 eContextRegisterStore,
138 eContextRegisterLoad,
140 // Used when performing a PC-relative branch where the
141 eContextRelativeBranchImmediate,
143 // Used when performing an absolute branch where the
144 eContextAbsoluteBranchRegister,
146 // Used when performing a supervisor call to an operating system to provide
148 eContextSupervisorCall,
150 // Used when performing a MemU operation to read the PC-relative offset
152 eContextTableBranchReadMemory,
154 // Used when random bits are written into a register
155 eContextWriteRegisterRandomBits,
157 // Used when random bits are written to memory
158 eContextWriteMemoryRandomBits,
164 eContextReturnFromException
168 eInfoTypeRegisterPlusOffset,
169 eInfoTypeRegisterPlusIndirectOffset,
170 eInfoTypeRegisterToRegisterPlusOffset,
171 eInfoTypeRegisterToRegisterPlusIndirectOffset,
172 eInfoTypeRegisterRegisterOperands,
176 eInfoTypeImmediateSigned,
178 eInfoTypeISAAndImmediate,
179 eInfoTypeISAAndImmediateSigned,
186 enum InfoType info_type;
188 struct RegisterPlusOffset {
189 RegisterInfo reg; // base register
190 int64_t signed_offset; // signed offset added to base register
191 } RegisterPlusOffset;
193 struct RegisterPlusIndirectOffset {
194 RegisterInfo base_reg; // base register number
195 RegisterInfo offset_reg; // offset register kind
196 } RegisterPlusIndirectOffset;
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;
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;
210 struct RegisterRegisterOperands {
212 operand1; // register containing first operand for binary op
214 operand2; // register containing second operand for binary op
215 } RegisterRegisterOperands;
217 int64_t signed_offset; // signed offset by which to adjust self (for
220 RegisterInfo reg; // plain register
222 uint64_t unsigned_immediate; // unsigned immediate value
223 int64_t signed_immediate; // signed immediate value
225 lldb::addr_t address; // direct address
227 struct ISAAndImmediate {
229 uint32_t unsigned_data32; // immediate data
232 struct ISAAndImmediateSigned {
234 int32_t signed_data32; // signed immediate data
235 } ISAAndImmediateSigned;
240 Context() : type(eContextInvalid), info_type(eInfoTypeNoArgs) {}
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;
248 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;
255 void SetRegisterToRegisterPlusOffset(RegisterInfo data_reg,
256 RegisterInfo base_reg,
258 info_type = eInfoTypeRegisterToRegisterPlusOffset;
259 info.RegisterToRegisterPlusOffset.data_reg = data_reg;
260 info.RegisterToRegisterPlusOffset.base_reg = base_reg;
261 info.RegisterToRegisterPlusOffset.offset = offset;
264 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;
273 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;
280 void SetOffset(int64_t signed_offset) {
281 info_type = eInfoTypeOffset;
282 info.signed_offset = signed_offset;
285 void SetRegister(RegisterInfo reg) {
286 info_type = eInfoTypeRegister;
290 void SetImmediate(uint64_t immediate) {
291 info_type = eInfoTypeImmediate;
292 info.unsigned_immediate = immediate;
295 void SetImmediateSigned(int64_t signed_immediate) {
296 info_type = eInfoTypeImmediateSigned;
297 info.signed_immediate = signed_immediate;
300 void SetAddress(lldb::addr_t address) {
301 info_type = eInfoTypeAddress;
302 info.address = address;
304 void SetISAAndImmediate(uint32_t isa, uint32_t data) {
305 info_type = eInfoTypeISAAndImmediate;
306 info.ISAAndImmediate.isa = isa;
307 info.ISAAndImmediate.unsigned_data32 = data;
310 void SetISAAndImmediateSigned(uint32_t isa, int32_t data) {
311 info_type = eInfoTypeISAAndImmediateSigned;
312 info.ISAAndImmediateSigned.isa = isa;
313 info.ISAAndImmediateSigned.signed_data32 = data;
316 void SetISA(uint32_t isa) {
317 info_type = eInfoTypeISA;
321 void SetNoArgs() { info_type = eInfoTypeNoArgs; }
323 void Dump(Stream &s, EmulateInstruction *instruction) const;
326 typedef size_t (*ReadMemoryCallback)(EmulateInstruction *instruction,
327 void *baton, const Context &context,
328 lldb::addr_t addr, void *dst,
331 typedef size_t (*WriteMemoryCallback)(EmulateInstruction *instruction,
332 void *baton, const Context &context,
333 lldb::addr_t addr, const void *dst,
336 typedef bool (*ReadRegisterCallback)(EmulateInstruction *instruction,
338 const RegisterInfo *reg_info,
339 RegisterValue ®_value);
341 typedef bool (*WriteRegisterCallback)(EmulateInstruction *instruction,
342 void *baton, const Context &context,
343 const RegisterInfo *reg_info,
344 const RegisterValue ®_value);
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;
352 EmulateInstruction(const ArchSpec &arch);
354 ~EmulateInstruction() override = default;
356 // Mandatory overrides
358 SupportsEmulatingInstructionsOfType(InstructionType inst_type) = 0;
360 virtual bool SetTargetTriple(const ArchSpec &arch) = 0;
362 virtual bool ReadInstruction() = 0;
364 virtual bool EvaluateInstruction(uint32_t evaluate_options) = 0;
366 virtual InstructionCondition GetInstructionCondition() {
367 return UnconditionalCondition;
370 virtual bool TestEmulation(Stream *out_stream, ArchSpec &arch,
371 OptionValueDictionary *test_data) = 0;
373 virtual bool GetRegisterInfo(lldb::RegisterKind reg_kind, uint32_t reg_num,
374 RegisterInfo ®_info) = 0;
376 // Optional overrides
377 virtual bool SetInstruction(const Opcode &insn_opcode,
378 const Address &inst_addr, Target *target);
380 virtual bool CreateFunctionEntryUnwind(UnwindPlan &unwind_plan);
382 static const char *TranslateRegister(lldb::RegisterKind reg_kind,
383 uint32_t reg_num, std::string ®_name);
385 // RegisterInfo variants
386 bool ReadRegister(const RegisterInfo *reg_info, RegisterValue ®_value);
388 uint64_t ReadRegisterUnsigned(const RegisterInfo *reg_info,
389 uint64_t fail_value, bool *success_ptr);
391 bool WriteRegister(const Context &context, const RegisterInfo *ref_info,
392 const RegisterValue ®_value);
394 bool WriteRegisterUnsigned(const Context &context,
395 const RegisterInfo *reg_info, uint64_t reg_value);
397 // Register kind and number variants
398 bool ReadRegister(lldb::RegisterKind reg_kind, uint32_t reg_num,
399 RegisterValue ®_value);
401 bool WriteRegister(const Context &context, lldb::RegisterKind reg_kind,
402 uint32_t reg_num, const RegisterValue ®_value);
404 uint64_t ReadRegisterUnsigned(lldb::RegisterKind reg_kind, uint32_t reg_num,
405 uint64_t fail_value, bool *success_ptr);
407 bool WriteRegisterUnsigned(const Context &context,
408 lldb::RegisterKind reg_kind, uint32_t reg_num,
411 size_t ReadMemory(const Context &context, lldb::addr_t addr, void *dst,
414 uint64_t ReadMemoryUnsigned(const Context &context, lldb::addr_t addr,
415 size_t byte_size, uint64_t fail_value,
418 bool WriteMemory(const Context &context, lldb::addr_t addr, const void *src,
421 bool WriteMemoryUnsigned(const Context &context, lldb::addr_t addr,
422 uint64_t uval, size_t uval_byte_size);
424 uint32_t GetAddressByteSize() const { return m_arch.GetAddressByteSize(); }
426 lldb::ByteOrder GetByteOrder() const { return m_arch.GetByteOrder(); }
428 const Opcode &GetOpcode() const { return m_opcode; }
430 lldb::addr_t GetAddress() const { return m_addr; }
432 const ArchSpec &GetArchitecture() const { return m_arch; }
434 static size_t ReadMemoryFrame(EmulateInstruction *instruction, void *baton,
435 const Context &context, lldb::addr_t addr,
436 void *dst, size_t length);
438 static size_t WriteMemoryFrame(EmulateInstruction *instruction, void *baton,
439 const Context &context, lldb::addr_t addr,
440 const void *dst, size_t length);
442 static bool ReadRegisterFrame(EmulateInstruction *instruction, void *baton,
443 const RegisterInfo *reg_info,
444 RegisterValue ®_value);
446 static bool WriteRegisterFrame(EmulateInstruction *instruction, void *baton,
447 const Context &context,
448 const RegisterInfo *reg_info,
449 const RegisterValue ®_value);
451 static size_t ReadMemoryDefault(EmulateInstruction *instruction, void *baton,
452 const Context &context, lldb::addr_t addr,
453 void *dst, size_t length);
455 static size_t WriteMemoryDefault(EmulateInstruction *instruction, void *baton,
456 const Context &context, lldb::addr_t addr,
457 const void *dst, size_t length);
459 static bool ReadRegisterDefault(EmulateInstruction *instruction, void *baton,
460 const RegisterInfo *reg_info,
461 RegisterValue ®_value);
463 static bool WriteRegisterDefault(EmulateInstruction *instruction, void *baton,
464 const Context &context,
465 const RegisterInfo *reg_info,
466 const RegisterValue ®_value);
468 void SetBaton(void *baton);
470 void SetCallbacks(ReadMemoryCallback read_mem_callback,
471 WriteMemoryCallback write_mem_callback,
472 ReadRegisterCallback read_reg_callback,
473 WriteRegisterCallback write_reg_callback);
475 void SetReadMemCallback(ReadMemoryCallback read_mem_callback);
477 void SetWriteMemCallback(WriteMemoryCallback write_mem_callback);
479 void SetReadRegCallback(ReadRegisterCallback read_reg_callback);
481 void SetWriteRegCallback(WriteRegisterCallback write_reg_callback);
483 static bool GetBestRegisterKindAndNumber(const RegisterInfo *reg_info,
484 lldb::RegisterKind ®_kind,
487 static uint32_t GetInternalRegisterNumber(RegisterContext *reg_ctx,
488 const RegisterInfo ®_info);
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;
501 // For EmulateInstruction only
502 DISALLOW_COPY_AND_ASSIGN(EmulateInstruction);
505 } // namespace lldb_private
507 #endif // lldb_EmulateInstruction_h_