Coverage Report

Created: 2022-01-25 06:29

/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 <string>
13
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"
23
24
#include <cstddef>
25
#include <cstdint>
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
93
class EmulateInstruction : public PluginInterface {
94
public:
95
  static EmulateInstruction *FindPlugin(const ArchSpec &arch,
96
                                        InstructionType supported_inst_type,
97
                                        const char *plugin_name);
98
99
  enum ContextType {
100
    eContextInvalid = 0,
101
    // Read an instruction opcode from memory
102
    eContextReadOpcode,
103
104
    // Usually used for writing a register value whose source value is an
105
    // immediate
106
    eContextImmediate,
107
108
    // Exclusively used when saving a register to the stack as part of the
109
    // prologue
110
    eContextPushRegisterOnStack,
111
112
    // Exclusively used when restoring a register off the stack as part of the
113
    // epilogue
114
    eContextPopRegisterOffStack,
115
116
    // Add or subtract a value from the stack
117
    eContextAdjustStackPointer,
118
119
    // Adjust the frame pointer for the current frame
120
    eContextSetFramePointer,
121
122
    // Typically in an epilogue sequence.  Copy the frame pointer back into the
123
    // stack pointer, use SP for CFA calculations again.
124
    eContextRestoreStackPointer,
125
126
    // Add or subtract a value from a base address register (other than SP)
127
    eContextAdjustBaseRegister,
128
129
    // Add or subtract a value from the PC or store a value to the PC.
130
    eContextAdjustPC,
131
132
    // Used in WriteRegister callbacks to indicate where the
133
    eContextRegisterPlusOffset,
134
135
    // Used in WriteMemory callback to indicate where the data came from
136
    eContextRegisterStore,
137
138
    eContextRegisterLoad,
139
140
    // Used when performing a PC-relative branch where the
141
    eContextRelativeBranchImmediate,
142
143
    // Used when performing an absolute branch where the
144
    eContextAbsoluteBranchRegister,
145
146
    // Used when performing a supervisor call to an operating system to provide
147
    // a service:
148
    eContextSupervisorCall,
149
150
    // Used when performing a MemU operation to read the PC-relative offset
151
    // from an address.
152
    eContextTableBranchReadMemory,
153
154
    // Used when random bits are written into a register
155
    eContextWriteRegisterRandomBits,
156
157
    // Used when random bits are written to memory
158
    eContextWriteMemoryRandomBits,
159
160
    eContextArithmetic,
161
162
    eContextAdvancePC,
163
164
    eContextReturnFromException
165
  };
166
167
  enum InfoType {
168
    eInfoTypeRegisterPlusOffset,
169
    eInfoTypeRegisterPlusIndirectOffset,
170
    eInfoTypeRegisterToRegisterPlusOffset,
171
    eInfoTypeRegisterToRegisterPlusIndirectOffset,
172
    eInfoTypeRegisterRegisterOperands,
173
    eInfoTypeOffset,
174
    eInfoTypeRegister,
175
    eInfoTypeImmediate,
176
    eInfoTypeImmediateSigned,
177
    eInfoTypeAddress,
178
    eInfoTypeISAAndImmediate,
179
    eInfoTypeISAAndImmediateSigned,
180
    eInfoTypeISA,
181
    eInfoTypeNoArgs
182
  } InfoType;
183
184
  struct Context {
185
    ContextType type = eContextInvalid;
186
    enum InfoType info_type = eInfoTypeNoArgs;
187
    union {
188
      struct RegisterPlusOffset {
189
        RegisterInfo reg;      // base register
190
        int64_t signed_offset; // signed offset added to base register
191
      } RegisterPlusOffset;
192
193
      struct RegisterPlusIndirectOffset {
194
        RegisterInfo base_reg;   // base register number
195
        RegisterInfo offset_reg; // offset register kind
196
      } RegisterPlusIndirectOffset;
197
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;
203
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;
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
215
      } RegisterRegisterOperands;
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 {
228
        uint32_t isa;
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
235
      } ISAAndImmediateSigned;
236
237
      uint32_t isa;
238
    } info;
239
240
451
    Context() = default;
241
242
150
    void SetRegisterPlusOffset(RegisterInfo base_reg, int64_t signed_offset) {
243
150
      info_type = eInfoTypeRegisterPlusOffset;
244
150
      info.RegisterPlusOffset.reg = base_reg;
245
150
      info.RegisterPlusOffset.signed_offset = signed_offset;
246
150
    }
247
248
    void SetRegisterPlusIndirectOffset(RegisterInfo base_reg,
249
0
                                       RegisterInfo offset_reg) {
250
0
      info_type = eInfoTypeRegisterPlusIndirectOffset;
251
0
      info.RegisterPlusIndirectOffset.base_reg = base_reg;
252
0
      info.RegisterPlusIndirectOffset.offset_reg = offset_reg;
253
0
    }
254
255
    void SetRegisterToRegisterPlusOffset(RegisterInfo data_reg,
256
                                         RegisterInfo base_reg,
257
89
                                         int64_t offset) {
258
89
      info_type = eInfoTypeRegisterToRegisterPlusOffset;
259
89
      info.RegisterToRegisterPlusOffset.data_reg = data_reg;
260
89
      info.RegisterToRegisterPlusOffset.base_reg = base_reg;
261
89
      info.RegisterToRegisterPlusOffset.offset = offset;
262
89
    }
263
264
    void SetRegisterToRegisterPlusIndirectOffset(RegisterInfo base_reg,
265
                                                 RegisterInfo offset_reg,
266
0
                                                 RegisterInfo data_reg) {
267
0
      info_type = eInfoTypeRegisterToRegisterPlusIndirectOffset;
268
0
      info.RegisterToRegisterPlusIndirectOffset.base_reg = base_reg;
269
0
      info.RegisterToRegisterPlusIndirectOffset.offset_reg = offset_reg;
270
0
      info.RegisterToRegisterPlusIndirectOffset.data_reg = data_reg;
271
0
    }
272
273
    void SetRegisterRegisterOperands(RegisterInfo op1_reg,
274
16
                                     RegisterInfo op2_reg) {
275
16
      info_type = eInfoTypeRegisterRegisterOperands;
276
16
      info.RegisterRegisterOperands.operand1 = op1_reg;
277
16
      info.RegisterRegisterOperands.operand2 = op2_reg;
278
16
    }
279
280
0
    void SetOffset(int64_t signed_offset) {
281
0
      info_type = eInfoTypeOffset;
282
0
      info.signed_offset = signed_offset;
283
0
    }
284
285
0
    void SetRegister(RegisterInfo reg) {
286
0
      info_type = eInfoTypeRegister;
287
0
      info.reg = reg;
288
0
    }
289
290
1
    void SetImmediate(uint64_t immediate) {
291
1
      info_type = eInfoTypeImmediate;
292
1
      info.unsigned_immediate = immediate;
293
1
    }
294
295
39
    void SetImmediateSigned(int64_t signed_immediate) {
296
39
      info_type = eInfoTypeImmediateSigned;
297
39
      info.signed_immediate = signed_immediate;
298
39
    }
299
300
77
    void SetAddress(lldb::addr_t address) {
301
77
      info_type = eInfoTypeAddress;
302
77
      info.address = address;
303
77
    }
304
0
    void SetISAAndImmediate(uint32_t isa, uint32_t data) {
305
0
      info_type = eInfoTypeISAAndImmediate;
306
0
      info.ISAAndImmediate.isa = isa;
307
0
      info.ISAAndImmediate.unsigned_data32 = data;
308
0
    }
309
310
1
    void SetISAAndImmediateSigned(uint32_t isa, int32_t data) {
311
1
      info_type = eInfoTypeISAAndImmediateSigned;
312
1
      info.ISAAndImmediateSigned.isa = isa;
313
1
      info.ISAAndImmediateSigned.signed_data32 = data;
314
1
    }
315
316
1
    void SetISA(uint32_t isa) {
317
1
      info_type = eInfoTypeISA;
318
1
      info.isa = isa;
319
1
    }
320
321
181
    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.
349
  typedef uint32_t InstructionCondition;
350
  static const InstructionCondition UnconditionalCondition = UINT32_MAX;
351
352
  EmulateInstruction(const ArchSpec &arch);
353
354
188
  ~EmulateInstruction() override = default;
355
356
  // Mandatory overrides
357
  virtual bool
358
  SupportsEmulatingInstructionsOfType(InstructionType inst_type) = 0;
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
272
  virtual InstructionCondition GetInstructionCondition() {
367
272
    return UnconditionalCondition;
368
272
  }
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
424
162
  uint32_t GetAddressByteSize() const { return m_arch.GetAddressByteSize(); }
425
426
115
  lldb::ByteOrder GetByteOrder() const { return m_arch.GetByteOrder(); }
427
428
0
  const Opcode &GetOpcode() const { return m_opcode; }
429
430
0
  lldb::addr_t GetAddress() const { return m_addr; }
431
432
94
  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
487
  static uint32_t GetInternalRegisterNumber(RegisterContext *reg_ctx,
488
                                            const RegisterInfo &reg_info);
489
490
protected:
491
  ArchSpec m_arch;
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;
498
  Opcode m_opcode;
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