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 <optional>
13#include <string>
14
15#include "lldb/Core/Address.h"
16#include "lldb/Core/Opcode.h"
19#include "lldb/lldb-defines.h"
23#include "lldb/lldb-types.h"
24
25#include <cstddef>
26#include <cstdint>
27
28namespace lldb_private {
29class OptionValueDictionary;
30class RegisterContext;
31class RegisterValue;
32class Stream;
33class Target;
34class UnwindPlan;
35
36/// \class EmulateInstruction EmulateInstruction.h
37/// "lldb/Core/EmulateInstruction.h"
38/// A class that allows emulation of CPU opcodes.
39///
40/// This class is a plug-in interface that is accessed through the standard
41/// static FindPlugin function call in the EmulateInstruction class. The
42/// FindPlugin takes a target triple and returns a new object if there is a
43/// plug-in that supports the architecture and OS. Four callbacks and a baton
44/// are provided. The four callbacks are read register, write register, read
45/// memory and write memory.
46///
47/// This class is currently designed for these main use cases: - Auto
48/// generation of Call Frame Information (CFI) from assembly code - Predicting
49/// single step breakpoint locations - Emulating instructions for breakpoint
50/// traps
51///
52/// Objects can be asked to read an instruction which will cause a call to the
53/// read register callback to get the PC, followed by a read memory call to
54/// read the opcode. If ReadInstruction () returns true, then a call to
55/// EmulateInstruction::EvaluateInstruction () can be made. At this point the
56/// EmulateInstruction subclass will use all of the callbacks to emulate an
57/// instruction.
58///
59/// Clients that provide the callbacks can either do the read/write
60/// registers/memory to actually emulate the instruction on a real or virtual
61/// CPU, or watch for the EmulateInstruction::Context which is context for the
62/// read/write register/memory which explains why the callback is being
63/// called. Examples of a context are: "pushing register 3 onto the stack at
64/// offset -12", or "adjusting stack pointer by -16". This extra context
65/// allows the generation of
66/// CFI information from assembly code without having to actually do
67/// the read/write register/memory.
68///
69/// Clients must be prepared that not all instructions for an Instruction Set
70/// Architecture (ISA) will be emulated.
71///
72/// Subclasses at the very least should implement the instructions that save
73/// and restore registers onto the stack and adjustment to the stack pointer.
74/// By just implementing a few instructions for an ISA that are the typical
75/// prologue opcodes, you can then generate CFI using a class that will soon
76/// be available.
77///
78/// Implementing all of the instructions that affect the PC can then allow
79/// single step prediction support.
80///
81/// Implementing all of the instructions allows for emulation of opcodes for
82/// breakpoint traps and will pave the way for "thread centric" debugging. The
83/// current debugging model is "process centric" where all threads must be
84/// stopped when any thread is stopped; when hitting software breakpoints we
85/// must disable the breakpoint by restoring the original breakpoint opcode,
86/// single stepping and restoring the breakpoint trap. If all threads were
87/// allowed to run then other threads could miss the breakpoint.
88///
89/// This class centralizes the code that usually is done in separate code
90/// paths in a debugger (single step prediction, finding save restore
91/// locations of registers for unwinding stack frame variables) and emulating
92/// the instruction is just a bonus.
93
95public:
96 static EmulateInstruction *FindPlugin(const ArchSpec &arch,
97 InstructionType supported_inst_type,
98 const char *plugin_name);
99
102 // Read an instruction opcode from memory
104
105 // Usually used for writing a register value whose source value is an
106 // immediate
108
109 // Exclusively used when saving a register to the stack as part of the
110 // prologue
112
113 // Exclusively used when restoring a register off the stack as part of the
114 // epilogue
116
117 // Add or subtract a value from the stack
119
120 // Adjust the frame pointer for the current frame
122
123 // Typically in an epilogue sequence. Copy the frame pointer back into the
124 // stack pointer, use SP for CFA calculations again.
126
127 // Add or subtract a value from a base address register (other than SP)
129
130 // Add or subtract a value from the PC or store a value to the PC.
132
133 // Used in WriteRegister callbacks to indicate where the
135
136 // Used in WriteMemory callback to indicate where the data came from
138
140
141 // Used when performing a PC-relative branch where the
143
144 // Used when performing an absolute branch where the
146
147 // Used when performing a supervisor call to an operating system to provide
148 // a service:
150
151 // Used when performing a MemU operation to read the PC-relative offset
152 // from an address.
154
155 // Used when random bits are written into a register
157
158 // Used when random bits are written to memory
160
162
164
166 };
167
168 enum InfoType {
183 };
184
185 struct Context {
187
188 private:
190
191 public:
192 enum InfoType GetInfoType() const { return info_type; }
195 RegisterInfo reg; // base register
196 int64_t signed_offset; // signed offset added to base register
197 } RegisterPlusOffset;
198
200 RegisterInfo base_reg; // base register number
201 RegisterInfo offset_reg; // offset register kind
202 } RegisterPlusIndirectOffset;
203
205 RegisterInfo data_reg; // source/target register for data
206 RegisterInfo base_reg; // base register for address calculation
207 int64_t offset; // offset for address calculation
208 } RegisterToRegisterPlusOffset;
209
211 RegisterInfo base_reg; // base register for address calculation
212 RegisterInfo offset_reg; // offset register for address calculation
213 RegisterInfo data_reg; // source/target register for data
214 } RegisterToRegisterPlusIndirectOffset;
215
217 RegisterInfo
218 operand1; // register containing first operand for binary op
219 RegisterInfo
220 operand2; // register containing second operand for binary op
221 } RegisterRegisterOperands;
222
223 int64_t signed_offset; // signed offset by which to adjust self (for
224 // registers only)
225
226 RegisterInfo reg; // plain register
227
228 uint64_t unsigned_immediate; // unsigned immediate value
229 int64_t signed_immediate; // signed immediate value
230
231 lldb::addr_t address; // direct address
232
235 uint32_t unsigned_data32; // immediate data
236 } ISAAndImmediate;
237
240 int32_t signed_data32; // signed immediate data
241 } ISAAndImmediateSigned;
242
245 static_assert(std::is_trivial<ContextInfo>::value,
246 "ContextInfo must be trivial.");
247
248 Context() = default;
249
250 void SetRegisterPlusOffset(RegisterInfo base_reg, int64_t signed_offset) {
252 info.RegisterPlusOffset.reg = base_reg;
253 info.RegisterPlusOffset.signed_offset = signed_offset;
254 }
255
256 void SetRegisterPlusIndirectOffset(RegisterInfo base_reg,
257 RegisterInfo offset_reg) {
261 }
262
263 void SetRegisterToRegisterPlusOffset(RegisterInfo data_reg,
264 RegisterInfo base_reg,
265 int64_t offset) {
270 }
271
272 void SetRegisterToRegisterPlusIndirectOffset(RegisterInfo base_reg,
273 RegisterInfo offset_reg,
274 RegisterInfo data_reg) {
279 }
280
281 void SetRegisterRegisterOperands(RegisterInfo op1_reg,
282 RegisterInfo op2_reg) {
286 }
287
288 void SetOffset(int64_t signed_offset) {
290 info.signed_offset = signed_offset;
291 }
292
293 void SetRegister(RegisterInfo reg) {
295 info.reg = reg;
296 }
297
298 void SetImmediate(uint64_t immediate) {
300 info.unsigned_immediate = immediate;
301 }
302
303 void SetImmediateSigned(int64_t signed_immediate) {
305 info.signed_immediate = signed_immediate;
306 }
307
308 void SetAddress(lldb::addr_t address) {
310 info.address = address;
311 }
316 }
317
318 void SetISAAndImmediateSigned(uint32_t isa, int32_t data) {
322 }
323
324 void SetISA(uint32_t isa) {
326 info.isa = isa;
327 }
328
330
331 void Dump(Stream &s, EmulateInstruction *instruction) const;
332 };
333
334 typedef size_t (*ReadMemoryCallback)(EmulateInstruction *instruction,
335 void *baton, const Context &context,
336 lldb::addr_t addr, void *dst,
337 size_t length);
338
339 typedef size_t (*WriteMemoryCallback)(EmulateInstruction *instruction,
340 void *baton, const Context &context,
341 lldb::addr_t addr, const void *dst,
342 size_t length);
343
344 typedef bool (*ReadRegisterCallback)(EmulateInstruction *instruction,
345 void *baton,
346 const RegisterInfo *reg_info,
347 RegisterValue &reg_value);
348
349 typedef bool (*WriteRegisterCallback)(EmulateInstruction *instruction,
350 void *baton, const Context &context,
351 const RegisterInfo *reg_info,
352 const RegisterValue &reg_value);
353
354 // Type to represent the condition of an instruction. The UINT32 value is
355 // reserved for the unconditional case and all other value can be used in an
356 // architecture dependent way.
359
360 EmulateInstruction(const ArchSpec &arch);
361
362 ~EmulateInstruction() override = default;
363
364 // Mandatory overrides
365 virtual bool
367
368 virtual bool SetTargetTriple(const ArchSpec &arch) = 0;
369
370 virtual bool ReadInstruction() = 0;
371
372 virtual bool EvaluateInstruction(uint32_t evaluate_options) = 0;
373
376 }
377
378 virtual bool TestEmulation(Stream *out_stream, ArchSpec &arch,
379 OptionValueDictionary *test_data) = 0;
380
381 virtual std::optional<RegisterInfo>
383
384 // Optional overrides
385 virtual bool SetInstruction(const Opcode &insn_opcode,
386 const Address &inst_addr, Target *target);
387
388 virtual bool CreateFunctionEntryUnwind(UnwindPlan &unwind_plan);
389
390 static const char *TranslateRegister(lldb::RegisterKind reg_kind,
391 uint32_t reg_num, std::string &reg_name);
392
393 // RegisterInfo variants
394 std::optional<RegisterValue> ReadRegister(const RegisterInfo &reg_info);
395
396 uint64_t ReadRegisterUnsigned(const RegisterInfo &reg_info,
397 uint64_t fail_value, bool *success_ptr);
398
399 bool WriteRegister(const Context &context, const RegisterInfo &ref_info,
400 const RegisterValue &reg_value);
401
402 bool WriteRegisterUnsigned(const Context &context,
403 const RegisterInfo &reg_info, uint64_t reg_value);
404
405 // Register kind and number variants
406 bool ReadRegister(lldb::RegisterKind reg_kind, uint32_t reg_num,
407 RegisterValue &reg_value);
408
409 bool WriteRegister(const Context &context, lldb::RegisterKind reg_kind,
410 uint32_t reg_num, const RegisterValue &reg_value);
411
412 uint64_t ReadRegisterUnsigned(lldb::RegisterKind reg_kind, uint32_t reg_num,
413 uint64_t fail_value, bool *success_ptr);
414
415 bool WriteRegisterUnsigned(const Context &context,
416 lldb::RegisterKind reg_kind, uint32_t reg_num,
417 uint64_t reg_value);
418
419 size_t ReadMemory(const Context &context, lldb::addr_t addr, void *dst,
420 size_t dst_len);
421
422 uint64_t ReadMemoryUnsigned(const Context &context, lldb::addr_t addr,
423 size_t byte_size, uint64_t fail_value,
424 bool *success_ptr);
425
426 bool WriteMemory(const Context &context, lldb::addr_t addr, const void *src,
427 size_t src_len);
428
429 bool WriteMemoryUnsigned(const Context &context, lldb::addr_t addr,
430 uint64_t uval, size_t uval_byte_size);
431
433
435
436 const Opcode &GetOpcode() const { return m_opcode; }
437
438 lldb::addr_t GetAddress() const { return m_addr; }
439
440 const ArchSpec &GetArchitecture() const { return m_arch; }
441
442 static size_t ReadMemoryFrame(EmulateInstruction *instruction, void *baton,
443 const Context &context, lldb::addr_t addr,
444 void *dst, size_t length);
445
446 static size_t WriteMemoryFrame(EmulateInstruction *instruction, void *baton,
447 const Context &context, lldb::addr_t addr,
448 const void *dst, size_t length);
449
450 static bool ReadRegisterFrame(EmulateInstruction *instruction, void *baton,
451 const RegisterInfo *reg_info,
452 RegisterValue &reg_value);
453
454 static bool WriteRegisterFrame(EmulateInstruction *instruction, void *baton,
455 const Context &context,
456 const RegisterInfo *reg_info,
457 const RegisterValue &reg_value);
458
459 static size_t ReadMemoryDefault(EmulateInstruction *instruction, void *baton,
460 const Context &context, lldb::addr_t addr,
461 void *dst, size_t length);
462
463 static size_t WriteMemoryDefault(EmulateInstruction *instruction, void *baton,
464 const Context &context, lldb::addr_t addr,
465 const void *dst, size_t length);
466
467 static bool ReadRegisterDefault(EmulateInstruction *instruction, void *baton,
468 const RegisterInfo *reg_info,
469 RegisterValue &reg_value);
470
471 static bool WriteRegisterDefault(EmulateInstruction *instruction, void *baton,
472 const Context &context,
473 const RegisterInfo *reg_info,
474 const RegisterValue &reg_value);
475
476 void SetBaton(void *baton);
477
478 void SetCallbacks(ReadMemoryCallback read_mem_callback,
479 WriteMemoryCallback write_mem_callback,
480 ReadRegisterCallback read_reg_callback,
481 WriteRegisterCallback write_reg_callback);
482
483 void SetReadMemCallback(ReadMemoryCallback read_mem_callback);
484
485 void SetWriteMemCallback(WriteMemoryCallback write_mem_callback);
486
487 void SetReadRegCallback(ReadRegisterCallback read_reg_callback);
488
489 void SetWriteRegCallback(WriteRegisterCallback write_reg_callback);
490
491 static bool GetBestRegisterKindAndNumber(const RegisterInfo *reg_info,
492 lldb::RegisterKind &reg_kind,
493 uint32_t &reg_num);
494
496 const RegisterInfo &reg_info);
497
498protected:
500 void *m_baton = nullptr;
507
508private:
509 // For EmulateInstruction only
512};
513
514} // namespace lldb_private
515
516#endif // LLDB_CORE_EMULATEINSTRUCTION_H
A section + offset based address class.
Definition: Address.h:59
An architecture specification class.
Definition: ArchSpec.h:32
uint32_t GetAddressByteSize() const
Returns the size in bytes of an address of the current architecture.
Definition: ArchSpec.cpp:694
lldb::ByteOrder GetByteOrder() const
Returns the byte order for the architecture specification.
Definition: ArchSpec.cpp:741
"lldb/Core/EmulateInstruction.h" A class that allows emulation of CPU opcodes.
static bool GetBestRegisterKindAndNumber(const RegisterInfo *reg_info, lldb::RegisterKind &reg_kind, uint32_t &reg_num)
static bool WriteRegisterDefault(EmulateInstruction *instruction, void *baton, const Context &context, const RegisterInfo *reg_info, const RegisterValue &reg_value)
static size_t WriteMemoryFrame(EmulateInstruction *instruction, void *baton, const Context &context, lldb::addr_t addr, const void *dst, size_t length)
const EmulateInstruction & operator=(const EmulateInstruction &)=delete
WriteMemoryCallback m_write_mem_callback
lldb::ByteOrder GetByteOrder() const
void SetWriteRegCallback(WriteRegisterCallback write_reg_callback)
virtual bool TestEmulation(Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data)=0
bool(* WriteRegisterCallback)(EmulateInstruction *instruction, void *baton, const Context &context, const RegisterInfo *reg_info, const RegisterValue &reg_value)
void SetCallbacks(ReadMemoryCallback read_mem_callback, WriteMemoryCallback write_mem_callback, ReadRegisterCallback read_reg_callback, WriteRegisterCallback write_reg_callback)
static bool ReadRegisterDefault(EmulateInstruction *instruction, void *baton, const RegisterInfo *reg_info, RegisterValue &reg_value)
virtual bool CreateFunctionEntryUnwind(UnwindPlan &unwind_plan)
const ArchSpec & GetArchitecture() const
EmulateInstruction(const EmulateInstruction &)=delete
bool WriteMemoryUnsigned(const Context &context, lldb::addr_t addr, uint64_t uval, size_t uval_byte_size)
~EmulateInstruction() override=default
virtual bool SupportsEmulatingInstructionsOfType(InstructionType inst_type)=0
virtual InstructionCondition GetInstructionCondition()
virtual bool EvaluateInstruction(uint32_t evaluate_options)=0
static uint32_t GetInternalRegisterNumber(RegisterContext *reg_ctx, const RegisterInfo &reg_info)
void SetReadRegCallback(ReadRegisterCallback read_reg_callback)
static const InstructionCondition UnconditionalCondition
size_t ReadMemory(const Context &context, lldb::addr_t addr, void *dst, size_t dst_len)
std::optional< RegisterValue > ReadRegister(const RegisterInfo &reg_info)
ReadRegisterCallback m_read_reg_callback
size_t(* WriteMemoryCallback)(EmulateInstruction *instruction, void *baton, const Context &context, lldb::addr_t addr, const void *dst, size_t length)
static size_t ReadMemoryFrame(EmulateInstruction *instruction, void *baton, const Context &context, lldb::addr_t addr, void *dst, size_t length)
bool WriteRegister(const Context &context, const RegisterInfo &ref_info, const RegisterValue &reg_value)
bool WriteRegisterUnsigned(const Context &context, const RegisterInfo &reg_info, uint64_t reg_value)
virtual bool SetTargetTriple(const ArchSpec &arch)=0
bool WriteMemory(const Context &context, lldb::addr_t addr, const void *src, size_t src_len)
uint64_t ReadMemoryUnsigned(const Context &context, lldb::addr_t addr, size_t byte_size, uint64_t fail_value, bool *success_ptr)
WriteRegisterCallback m_write_reg_callback
static size_t WriteMemoryDefault(EmulateInstruction *instruction, void *baton, const Context &context, lldb::addr_t addr, const void *dst, size_t length)
size_t(* ReadMemoryCallback)(EmulateInstruction *instruction, void *baton, const Context &context, lldb::addr_t addr, void *dst, size_t length)
void SetReadMemCallback(ReadMemoryCallback read_mem_callback)
static bool WriteRegisterFrame(EmulateInstruction *instruction, void *baton, const Context &context, const RegisterInfo *reg_info, const RegisterValue &reg_value)
static const char * TranslateRegister(lldb::RegisterKind reg_kind, uint32_t reg_num, std::string &reg_name)
static bool ReadRegisterFrame(EmulateInstruction *instruction, void *baton, const RegisterInfo *reg_info, RegisterValue &reg_value)
bool(* ReadRegisterCallback)(EmulateInstruction *instruction, void *baton, const RegisterInfo *reg_info, RegisterValue &reg_value)
virtual std::optional< RegisterInfo > GetRegisterInfo(lldb::RegisterKind reg_kind, uint32_t reg_num)=0
static size_t ReadMemoryDefault(EmulateInstruction *instruction, void *baton, const Context &context, lldb::addr_t addr, void *dst, size_t length)
virtual bool SetInstruction(const Opcode &insn_opcode, const Address &inst_addr, Target *target)
static EmulateInstruction * FindPlugin(const ArchSpec &arch, InstructionType supported_inst_type, const char *plugin_name)
uint64_t ReadRegisterUnsigned(const RegisterInfo &reg_info, uint64_t fail_value, bool *success_ptr)
void SetWriteMemCallback(WriteMemoryCallback write_mem_callback)
A stream class that can stream formatted output to a file.
Definition: Stream.h:28
#define LLDB_INVALID_ADDRESS
Definition: lldb-defines.h:74
#define UINT32_MAX
Definition: lldb-defines.h:19
A class that represents a running process on the host machine.
InstructionType
Instruction types.
ByteOrder
Byte ordering definitions.
uint64_t addr_t
Definition: lldb-types.h:83
RegisterKind
Register numbering types.
void SetRegisterRegisterOperands(RegisterInfo op1_reg, RegisterInfo op2_reg)
void Dump(Stream &s, EmulateInstruction *instruction) const
void SetISAAndImmediate(uint32_t isa, uint32_t data)
void SetISAAndImmediateSigned(uint32_t isa, int32_t data)
void SetRegisterPlusOffset(RegisterInfo base_reg, int64_t signed_offset)
union lldb_private::EmulateInstruction::Context::ContextInfo info
void SetImmediateSigned(int64_t signed_immediate)
void SetRegisterToRegisterPlusIndirectOffset(RegisterInfo base_reg, RegisterInfo offset_reg, RegisterInfo data_reg)
void SetRegisterToRegisterPlusOffset(RegisterInfo data_reg, RegisterInfo base_reg, int64_t offset)
void SetRegisterPlusIndirectOffset(RegisterInfo base_reg, RegisterInfo offset_reg)
struct lldb_private::EmulateInstruction::Context::ContextInfo::ISAAndImmediateSigned ISAAndImmediateSigned
struct lldb_private::EmulateInstruction::Context::ContextInfo::RegisterRegisterOperands RegisterRegisterOperands
struct lldb_private::EmulateInstruction::Context::ContextInfo::RegisterPlusOffset RegisterPlusOffset
struct lldb_private::EmulateInstruction::Context::ContextInfo::RegisterPlusIndirectOffset RegisterPlusIndirectOffset
struct lldb_private::EmulateInstruction::Context::ContextInfo::RegisterToRegisterPlusIndirectOffset RegisterToRegisterPlusIndirectOffset
struct lldb_private::EmulateInstruction::Context::ContextInfo::RegisterToRegisterPlusOffset RegisterToRegisterPlusOffset
struct lldb_private::EmulateInstruction::Context::ContextInfo::ISAAndImmediate ISAAndImmediate