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
218 operand1; // register containing first operand for binary op
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
234 uint32_t isa;
235 uint32_t unsigned_data32; // immediate data
236 } ISAAndImmediate;
237
239 uint32_t isa;
240 int32_t signed_data32; // signed immediate data
241 } ISAAndImmediateSigned;
242
243 uint32_t isa;
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
257 RegisterInfo offset_reg) {
261 }
262
264 RegisterInfo base_reg,
265 int64_t offset) {
270 }
271
273 RegisterInfo offset_reg,
274 RegisterInfo data_reg) {
279 }
280
282 RegisterInfo op2_reg) {
286 }
287
288 void SetOffset(int64_t signed_offset) {
290 info.signed_offset = signed_offset;
291 }
292
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 }
312 void SetISAAndImmediate(uint32_t isa, uint32_t data) {
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.
357 typedef uint32_t InstructionCondition;
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 std::optional<uint32_t> GetLastInstrSize() { return std::nullopt; }
373
374 virtual bool EvaluateInstruction(uint32_t evaluate_options) = 0;
375
378 }
379
380 virtual bool TestEmulation(Stream &out_stream, ArchSpec &arch,
381 OptionValueDictionary *test_data) = 0;
382
383 virtual std::optional<RegisterInfo>
384 GetRegisterInfo(lldb::RegisterKind reg_kind, uint32_t reg_num) = 0;
385
386 // Optional overrides
387 virtual bool SetInstruction(const Opcode &insn_opcode,
388 const Address &inst_addr, Target *target);
389
390 virtual bool CreateFunctionEntryUnwind(UnwindPlan &unwind_plan);
391
392 static const char *TranslateRegister(lldb::RegisterKind reg_kind,
393 uint32_t reg_num, std::string &reg_name);
394
395 // RegisterInfo variants
396 std::optional<RegisterValue> ReadRegister(const RegisterInfo &reg_info);
397
398 uint64_t ReadRegisterUnsigned(const RegisterInfo &reg_info,
399 uint64_t fail_value, bool *success_ptr);
400
401 bool WriteRegister(const Context &context, const RegisterInfo &ref_info,
402 const RegisterValue &reg_value);
403
404 bool WriteRegisterUnsigned(const Context &context,
405 const RegisterInfo &reg_info, uint64_t reg_value);
406
407 // Register kind and number variants
408 bool ReadRegister(lldb::RegisterKind reg_kind, uint32_t reg_num,
409 RegisterValue &reg_value);
410
411 bool WriteRegister(const Context &context, lldb::RegisterKind reg_kind,
412 uint32_t reg_num, const RegisterValue &reg_value);
413
414 uint64_t ReadRegisterUnsigned(lldb::RegisterKind reg_kind, uint32_t reg_num,
415 uint64_t fail_value, bool *success_ptr);
416
417 bool WriteRegisterUnsigned(const Context &context,
418 lldb::RegisterKind reg_kind, uint32_t reg_num,
419 uint64_t reg_value);
420
421 size_t ReadMemory(const Context &context, lldb::addr_t addr, void *dst,
422 size_t dst_len);
423
424 uint64_t ReadMemoryUnsigned(const Context &context, lldb::addr_t addr,
425 size_t byte_size, uint64_t fail_value,
426 bool *success_ptr);
427
428 bool WriteMemory(const Context &context, lldb::addr_t addr, const void *src,
429 size_t src_len);
430
431 bool WriteMemoryUnsigned(const Context &context, lldb::addr_t addr,
432 uint64_t uval, size_t uval_byte_size);
433
434 uint32_t GetAddressByteSize() const { return m_arch.GetAddressByteSize(); }
435
437
438 const Opcode &GetOpcode() const { return m_opcode; }
439
440 lldb::addr_t GetAddress() const { return m_addr; }
441
442 const ArchSpec &GetArchitecture() const { return m_arch; }
443
444 static size_t ReadMemoryFrame(EmulateInstruction *instruction, void *baton,
445 const Context &context, lldb::addr_t addr,
446 void *dst, size_t length);
447
448 static size_t WriteMemoryFrame(EmulateInstruction *instruction, void *baton,
449 const Context &context, lldb::addr_t addr,
450 const void *dst, size_t length);
451
452 static bool ReadRegisterFrame(EmulateInstruction *instruction, void *baton,
453 const RegisterInfo *reg_info,
454 RegisterValue &reg_value);
455
456 static bool WriteRegisterFrame(EmulateInstruction *instruction, void *baton,
457 const Context &context,
458 const RegisterInfo *reg_info,
459 const RegisterValue &reg_value);
460
461 static size_t ReadMemoryDefault(EmulateInstruction *instruction, void *baton,
462 const Context &context, lldb::addr_t addr,
463 void *dst, size_t length);
464
465 static size_t WriteMemoryDefault(EmulateInstruction *instruction, void *baton,
466 const Context &context, lldb::addr_t addr,
467 const void *dst, size_t length);
468
469 static bool ReadRegisterDefault(EmulateInstruction *instruction, void *baton,
470 const RegisterInfo *reg_info,
471 RegisterValue &reg_value);
472
473 static bool WriteRegisterDefault(EmulateInstruction *instruction, void *baton,
474 const Context &context,
475 const RegisterInfo *reg_info,
476 const RegisterValue &reg_value);
477
478 void SetBaton(void *baton);
479
480 void SetCallbacks(ReadMemoryCallback read_mem_callback,
481 WriteMemoryCallback write_mem_callback,
482 ReadRegisterCallback read_reg_callback,
483 WriteRegisterCallback write_reg_callback);
484
485 void SetReadMemCallback(ReadMemoryCallback read_mem_callback);
486
487 void SetWriteMemCallback(WriteMemoryCallback write_mem_callback);
488
489 void SetReadRegCallback(ReadRegisterCallback read_reg_callback);
490
491 void SetWriteRegCallback(WriteRegisterCallback write_reg_callback);
492
493 static bool GetBestRegisterKindAndNumber(const RegisterInfo *reg_info,
494 lldb::RegisterKind &reg_kind,
495 uint32_t &reg_num);
496
497 static uint32_t GetInternalRegisterNumber(RegisterContext *reg_ctx,
498 const RegisterInfo &reg_info);
499
500protected:
502 void *m_baton = nullptr;
509
510private:
511 // For EmulateInstruction only
514};
515
516} // namespace lldb_private
517
518#endif // LLDB_CORE_EMULATEINSTRUCTION_H
A section + offset based address class.
Definition: Address.h:62
An architecture specification class.
Definition: ArchSpec.h:31
uint32_t GetAddressByteSize() const
Returns the size in bytes of an address of the current architecture.
Definition: ArchSpec.cpp:709
lldb::ByteOrder GetByteOrder() const
Returns the byte order for the architecture specification.
Definition: ArchSpec.cpp:756
"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)
virtual std::optional< uint32_t > GetLastInstrSize()
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:82
#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:80
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)
Every register is described in detail including its name, alternate name (optional),...
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