1//===-- EmulateInstructionARM64.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_SOURCE_PLUGINS_INSTRUCTION_ARM64_EMULATEINSTRUCTIONARM64_H
10#define LLDB_SOURCE_PLUGINS_INSTRUCTION_ARM64_EMULATEINSTRUCTIONARM64_H
11
12#include "Plugins/Process/Utility/ARMDefines.h"
13#include "lldb/Core/EmulateInstruction.h"
14#include "lldb/Interpreter/OptionValue.h"
15#include "lldb/Utility/Status.h"
16#include <optional>
17
18class EmulateInstructionARM64 : public lldb_private::EmulateInstruction {
19public:
20 EmulateInstructionARM64(const lldb_private::ArchSpec &arch)
21 : EmulateInstruction(arch), m_opcode_pstate(), m_emulated_pstate(),
22 m_ignore_conditions(false) {}
23
24 static void Initialize();
25
26 static void Terminate();
27
28 static llvm::StringRef GetPluginNameStatic() { return "arm64"; }
29
30 static llvm::StringRef GetPluginDescriptionStatic();
31
32 static lldb_private::EmulateInstruction *
33 CreateInstance(const lldb_private::ArchSpec &arch,
34 lldb_private::InstructionType inst_type);
35
36 static bool SupportsEmulatingInstructionsOfTypeStatic(
37 lldb_private::InstructionType inst_type) {
38 switch (inst_type) {
39 case lldb_private::eInstructionTypeAny:
40 case lldb_private::eInstructionTypePrologueEpilogue:
41 return true;
42
43 case lldb_private::eInstructionTypePCModifying:
44 case lldb_private::eInstructionTypeAll:
45 return false;
46 }
47 return false;
48 }
49
50 llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
51
52 bool SetTargetTriple(const lldb_private::ArchSpec &arch) override;
53
54 bool SupportsEmulatingInstructionsOfType(
55 lldb_private::InstructionType inst_type) override {
56 return SupportsEmulatingInstructionsOfTypeStatic(inst_type);
57 }
58
59 bool ReadInstruction() override;
60
61 bool EvaluateInstruction(uint32_t evaluate_options) override;
62
63 bool TestEmulation(lldb_private::Stream &out_stream,
64 lldb_private::ArchSpec &arch,
65 lldb_private::OptionValueDictionary *test_data) override {
66 return false;
67 }
68
69 std::optional<lldb_private::RegisterInfo>
70 GetRegisterInfo(lldb::RegisterKind reg_kind, uint32_t reg_num) override;
71
72 bool
73 CreateFunctionEntryUnwind(lldb_private::UnwindPlan &unwind_plan) override;
74
75 enum AddrMode { AddrMode_OFF, AddrMode_PRE, AddrMode_POST };
76
77 enum BranchType {
78 BranchType_CALL,
79 BranchType_ERET,
80 BranchType_DRET,
81 BranchType_RET,
82 BranchType_JMP
83 };
84
85 enum CountOp { CountOp_CLZ, CountOp_CLS, CountOp_CNT };
86
87 enum RevOp { RevOp_RBIT, RevOp_REV16, RevOp_REV32, RevOp_REV64 };
88
89 enum BitwiseOp { BitwiseOp_NOT, BitwiseOp_RBIT };
90
91 enum ExceptionLevel { EL0 = 0, EL1 = 1, EL2 = 2, EL3 = 3 };
92
93 enum ExtendType {
94 ExtendType_SXTB,
95 ExtendType_SXTH,
96 ExtendType_SXTW,
97 ExtendType_SXTX,
98 ExtendType_UXTB,
99 ExtendType_UXTH,
100 ExtendType_UXTW,
101 ExtendType_UXTX
102 };
103
104 enum ExtractType { ExtractType_LEFT, ExtractType_RIGHT };
105
106 enum LogicalOp { LogicalOp_AND, LogicalOp_EOR, LogicalOp_ORR };
107
108 enum MemOp { MemOp_LOAD, MemOp_STORE, MemOp_PREFETCH, MemOp_NOP };
109
110 enum MoveWideOp { MoveWideOp_N, MoveWideOp_Z, MoveWideOp_K };
111
112 enum ShiftType { ShiftType_LSL, ShiftType_LSR, ShiftType_ASR, ShiftType_ROR };
113
114 enum StackPointerSelection { SP0 = 0, SPx = 1 };
115
116 enum Unpredictable { Unpredictable_WBOVERLAP, Unpredictable_LDPOVERLAP };
117
118 enum ConstraintType {
119 Constraint_NONE,
120 Constraint_UNKNOWN,
121 Constraint_SUPPRESSWB,
122 Constraint_NOP
123 };
124
125 enum AccType {
126 AccType_NORMAL,
127 AccType_UNPRIV,
128 AccType_STREAM,
129 AccType_ALIGNED,
130 AccType_ORDERED
131 };
132
133 typedef struct {
134 uint32_t N : 1, V : 1, C : 1,
135 Z : 1, // condition code flags – can also be accessed as
136 // PSTATE.[N,Z,C,V]
137 Q : 1, // AArch32 only – CSPR.Q bit
138 IT : 8, // AArch32 only – CPSR.IT bits
139 J : 1, // AArch32 only – CSPR.J bit
140 T : 1, // AArch32 only – CPSR.T bit
141 SS : 1, // Single step process state bit
142 IL : 1, // Illegal state bit
143 D : 1, A : 1, I : 1,
144 F : 1, // Interrupt masks – can also be accessed as PSTATE.[D,A,I,F]
145 E : 1, // AArch32 only – CSPR.E bit
146 M : 5, // AArch32 only – mode encodings
147 RW : 1, // Current register width – 0 is AArch64, 1 is AArch32
148 EL : 2, // Current exception level (see ExceptionLevel enum)
149 SP : 1; // AArch64 only - Stack Pointer selection (see
150 // StackPointerSelection enum)
151 } ProcState;
152
153protected:
154 static uint64_t AddWithCarry(uint32_t N, uint64_t x, uint64_t y, bool carry_in,
155 EmulateInstructionARM64::ProcState &proc_state);
156
157 typedef struct {
158 uint32_t mask;
159 uint32_t value;
160 uint32_t vfp_variants;
161 bool (EmulateInstructionARM64::*callback)(const uint32_t opcode);
162 const char *name;
163 } Opcode;
164
165 static Opcode *GetOpcodeForInstruction(const uint32_t opcode);
166
167 uint32_t GetFramePointerRegisterNumber() const;
168
169 bool BranchTo(const Context &context, uint32_t N, lldb::addr_t target);
170
171 bool ConditionHolds(const uint32_t cond);
172
173 bool UsingAArch32();
174
175 bool EmulateADDSUBImm(const uint32_t opcode);
176
177 template <AddrMode a_mode> bool EmulateLDPSTP(const uint32_t opcode);
178
179 template <AddrMode a_mode> bool EmulateLDRSTRImm(const uint32_t opcode);
180
181 bool EmulateB(const uint32_t opcode);
182
183 bool EmulateBcond(const uint32_t opcode);
184
185 bool EmulateCBZ(const uint32_t opcode);
186
187 bool EmulateTBZ(const uint32_t opcode);
188
189 ProcState m_opcode_pstate;
190 ProcState m_emulated_pstate; // This can get updated by the opcode.
191 bool m_ignore_conditions;
192};
193
194#endif // LLDB_SOURCE_PLUGINS_INSTRUCTION_ARM64_EMULATEINSTRUCTIONARM64_H
195

source code of lldb/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.h