Coverage Report

Created: 2023-09-30 09:22

/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/include/lldb/Core/EmulateInstruction.h
Line
Count
Source (jump to first uncovered line)
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"
17
#include "lldb/Core/PluginInterface.h"
18
#include "lldb/Utility/ArchSpec.h"
19
#include "lldb/lldb-defines.h"
20
#include "lldb/lldb-enumerations.h"
21
#include "lldb/lldb-private-enumerations.h"
22
#include "lldb/lldb-private-types.h"
23
#include "lldb/lldb-types.h"
24
25
#include <cstddef>
26
#include <cstdint>
27
28
namespace lldb_private {
29
class OptionValueDictionary;
30
class RegisterContext;
31
class RegisterValue;
32
class Stream;
33
class Target;
34
class 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
94
class EmulateInstruction : public PluginInterface {
95
public:
96
  static EmulateInstruction *FindPlugin(const ArchSpec &arch,
97
                                        InstructionType supported_inst_type,
98
                                        const char *plugin_name);
99
100
  enum ContextType {
101
    eContextInvalid = 0,
102
    // Read an instruction opcode from memory
103
    eContextReadOpcode,
104
105
    // Usually used for writing a register value whose source value is an
106
    // immediate
107
    eContextImmediate,
108
109
    // Exclusively used when saving a register to the stack as part of the
110
    // prologue
111
    eContextPushRegisterOnStack,
112
113
    // Exclusively used when restoring a register off the stack as part of the
114
    // epilogue
115
    eContextPopRegisterOffStack,
116
117
    // Add or subtract a value from the stack
118
    eContextAdjustStackPointer,
119
120
    // Adjust the frame pointer for the current frame
121
    eContextSetFramePointer,
122
123
    // Typically in an epilogue sequence.  Copy the frame pointer back into the
124
    // stack pointer, use SP for CFA calculations again.
125
    eContextRestoreStackPointer,
126
127
    // Add or subtract a value from a base address register (other than SP)
128
    eContextAdjustBaseRegister,
129
130
    // Add or subtract a value from the PC or store a value to the PC.
131
    eContextAdjustPC,
132
133
    // Used in WriteRegister callbacks to indicate where the
134
    eContextRegisterPlusOffset,
135
136
    // Used in WriteMemory callback to indicate where the data came from
137
    eContextRegisterStore,
138
139
    eContextRegisterLoad,
140
141
    // Used when performing a PC-relative branch where the
142
    eContextRelativeBranchImmediate,
143
144
    // Used when performing an absolute branch where the
145
    eContextAbsoluteBranchRegister,
146
147
    // Used when performing a supervisor call to an operating system to provide
148
    // a service:
149
    eContextSupervisorCall,
150
151
    // Used when performing a MemU operation to read the PC-relative offset
152
    // from an address.
153
    eContextTableBranchReadMemory,
154
155
    // Used when random bits are written into a register
156
    eContextWriteRegisterRandomBits,
157
158
    // Used when random bits are written to memory
159
    eContextWriteMemoryRandomBits,
160
161
    eContextArithmetic,
162
163
    eContextAdvancePC,
164
165
    eContextReturnFromException
166
  };
167
168
  enum InfoType {
169
    eInfoTypeRegisterPlusOffset,
170
    eInfoTypeRegisterPlusIndirectOffset,
171
    eInfoTypeRegisterToRegisterPlusOffset,
172
    eInfoTypeRegisterToRegisterPlusIndirectOffset,
173
    eInfoTypeRegisterRegisterOperands,
174
    eInfoTypeOffset,
175
    eInfoTypeRegister,
176
    eInfoTypeImmediate,
177
    eInfoTypeImmediateSigned,
178
    eInfoTypeAddress,
179
    eInfoTypeISAAndImmediate,
180
    eInfoTypeISAAndImmediateSigned,
181
    eInfoTypeISA,
182
    eInfoTypeNoArgs
183
  };
184
185
  struct Context {
186
    ContextType type = eContextInvalid;
187
188
  private:
189
    enum InfoType info_type = eInfoTypeNoArgs;
190
191
  public:
192
117
    enum InfoType GetInfoType() const { return info_type; }
193
    union ContextInfo {
194
      struct RegisterPlusOffset {
195
        RegisterInfo reg;      // base register
196
        int64_t signed_offset; // signed offset added to base register
197
      } RegisterPlusOffset;
198
199
      struct RegisterPlusIndirectOffset {
200
        RegisterInfo base_reg;   // base register number
201
        RegisterInfo offset_reg; // offset register kind
202
      } RegisterPlusIndirectOffset;
203
204
      struct RegisterToRegisterPlusOffset {
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
210
      struct RegisterToRegisterPlusIndirectOffset {
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
216
      struct RegisterRegisterOperands {
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
233
      struct ISAAndImmediate {
234
        uint32_t isa;
235
        uint32_t unsigned_data32; // immediate data
236
      } ISAAndImmediate;
237
238
      struct ISAAndImmediateSigned {
239
        uint32_t isa;
240
        int32_t signed_data32; // signed immediate data
241
      } ISAAndImmediateSigned;
242
243
      uint32_t isa;
244
    } info;
245
    static_assert(std::is_trivial<ContextInfo>::value,
246
                  "ContextInfo must be trivial.");
247
248
796
    Context() = default;
249
250
153
    void SetRegisterPlusOffset(RegisterInfo base_reg, int64_t signed_offset) {
251
153
      info_type = eInfoTypeRegisterPlusOffset;
252
153
      info.RegisterPlusOffset.reg = base_reg;
253
153
      info.RegisterPlusOffset.signed_offset = signed_offset;
254
153
    }
255
256
    void SetRegisterPlusIndirectOffset(RegisterInfo base_reg,
257
0
                                       RegisterInfo offset_reg) {
258
0
      info_type = eInfoTypeRegisterPlusIndirectOffset;
259
0
      info.RegisterPlusIndirectOffset.base_reg = base_reg;
260
0
      info.RegisterPlusIndirectOffset.offset_reg = offset_reg;
261
0
    }
262
263
    void SetRegisterToRegisterPlusOffset(RegisterInfo data_reg,
264
                                         RegisterInfo base_reg,
265
99
                                         int64_t offset) {
266
99
      info_type = eInfoTypeRegisterToRegisterPlusOffset;
267
99
      info.RegisterToRegisterPlusOffset.data_reg = data_reg;
268
99
      info.RegisterToRegisterPlusOffset.base_reg = base_reg;
269
99
      info.RegisterToRegisterPlusOffset.offset = offset;
270
99
    }
271
272
    void SetRegisterToRegisterPlusIndirectOffset(RegisterInfo base_reg,
273
                                                 RegisterInfo offset_reg,
274
0
                                                 RegisterInfo data_reg) {
275
0
      info_type = eInfoTypeRegisterToRegisterPlusIndirectOffset;
276
0
      info.RegisterToRegisterPlusIndirectOffset.base_reg = base_reg;
277
0
      info.RegisterToRegisterPlusIndirectOffset.offset_reg = offset_reg;
278
0
      info.RegisterToRegisterPlusIndirectOffset.data_reg = data_reg;
279
0
    }
280
281
    void SetRegisterRegisterOperands(RegisterInfo op1_reg,
282
16
                                     RegisterInfo op2_reg) {
283
16
      info_type = eInfoTypeRegisterRegisterOperands;
284
16
      info.RegisterRegisterOperands.operand1 = op1_reg;
285
16
      info.RegisterRegisterOperands.operand2 = op2_reg;
286
16
    }
287
288
0
    void SetOffset(int64_t signed_offset) {
289
0
      info_type = eInfoTypeOffset;
290
0
      info.signed_offset = signed_offset;
291
0
    }
292
293
0
    void SetRegister(RegisterInfo reg) {
294
0
      info_type = eInfoTypeRegister;
295
0
      info.reg = reg;
296
0
    }
297
298
1
    void SetImmediate(uint64_t immediate) {
299
1
      info_type = eInfoTypeImmediate;
300
1
      info.unsigned_immediate = immediate;
301
1
    }
302
303
42
    void SetImmediateSigned(int64_t signed_immediate) {
304
42
      info_type = eInfoTypeImmediateSigned;
305
42
      info.signed_immediate = signed_immediate;
306
42
    }
307
308
83
    void SetAddress(lldb::addr_t address) {
309
83
      info_type = eInfoTypeAddress;
310
83
      info.address = address;
311
83
    }
312
0
    void SetISAAndImmediate(uint32_t isa, uint32_t data) {
313
0
      info_type = eInfoTypeISAAndImmediate;
314
0
      info.ISAAndImmediate.isa = isa;
315
0
      info.ISAAndImmediate.unsigned_data32 = data;
316
0
    }
317
318
1
    void SetISAAndImmediateSigned(uint32_t isa, int32_t data) {
319
1
      info_type = eInfoTypeISAAndImmediateSigned;
320
1
      info.ISAAndImmediateSigned.isa = isa;
321
1
      info.ISAAndImmediateSigned.signed_data32 = data;
322
1
    }
323
324
1
    void SetISA(uint32_t isa) {
325
1
      info_type = eInfoTypeISA;
326
1
      info.isa = isa;
327
1
    }
328
329
514
    void SetNoArgs() { info_type = eInfoTypeNoArgs; }
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;
358
  static const InstructionCondition UnconditionalCondition = UINT32_MAX;
359
360
  EmulateInstruction(const ArchSpec &arch);
361
362
252
  ~EmulateInstruction() override = default;
363
364
  // Mandatory overrides
365
  virtual bool
366
  SupportsEmulatingInstructionsOfType(InstructionType inst_type) = 0;
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
374
284
  virtual InstructionCondition GetInstructionCondition() {
375
284
    return UnconditionalCondition;
376
284
  }
377
378
  virtual bool TestEmulation(Stream &out_stream, ArchSpec &arch,
379
                             OptionValueDictionary *test_data) = 0;
380
381
  virtual std::optional<RegisterInfo>
382
  GetRegisterInfo(lldb::RegisterKind reg_kind, uint32_t reg_num) = 0;
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
432
275
  uint32_t GetAddressByteSize() const { return m_arch.GetAddressByteSize(); }
433
434
225
  lldb::ByteOrder GetByteOrder() const { return m_arch.GetByteOrder(); }
435
436
0
  const Opcode &GetOpcode() const { return m_opcode; }
437
438
0
  lldb::addr_t GetAddress() const { return m_addr; }
439
440
98
  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
495
  static uint32_t GetInternalRegisterNumber(RegisterContext *reg_ctx,
496
                                            const RegisterInfo &reg_info);
497
498
protected:
499
  ArchSpec m_arch;
500
  void *m_baton = nullptr;
501
  ReadMemoryCallback m_read_mem_callback = &ReadMemoryDefault;
502
  WriteMemoryCallback m_write_mem_callback = &WriteMemoryDefault;
503
  ReadRegisterCallback m_read_reg_callback = &ReadRegisterDefault;
504
  WriteRegisterCallback m_write_reg_callback = &WriteRegisterDefault;
505
  lldb::addr_t m_addr = LLDB_INVALID_ADDRESS;
506
  Opcode m_opcode;
507
508
private:
509
  // For EmulateInstruction only
510
  EmulateInstruction(const EmulateInstruction &) = delete;
511
  const EmulateInstruction &operator=(const EmulateInstruction &) = delete;
512
};
513
514
} // namespace lldb_private
515
516
#endif // LLDB_CORE_EMULATEINSTRUCTION_H