/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.h
Line | Count | Source (jump to first uncovered line) |
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 | | |
18 | | class EmulateInstructionARM64 : public lldb_private::EmulateInstruction { |
19 | | public: |
20 | | EmulateInstructionARM64(const lldb_private::ArchSpec &arch) |
21 | | : EmulateInstruction(arch), m_opcode_pstate(), m_emulated_pstate(), |
22 | 28 | m_ignore_conditions(false) {} |
23 | | |
24 | | static void Initialize(); |
25 | | |
26 | | static void Terminate(); |
27 | | |
28 | 3.92k | 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 | 15.2k | lldb_private::InstructionType inst_type) { |
38 | 15.2k | switch (inst_type) { |
39 | 0 | case lldb_private::eInstructionTypeAny: |
40 | 15.2k | case lldb_private::eInstructionTypePrologueEpilogue: |
41 | 15.2k | return true; |
42 | | |
43 | 0 | case lldb_private::eInstructionTypePCModifying: |
44 | 0 | case lldb_private::eInstructionTypeAll: |
45 | 0 | return false; |
46 | 15.2k | } |
47 | 0 | return false; |
48 | 15.2k | } |
49 | | |
50 | 0 | llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } |
51 | | |
52 | | bool SetTargetTriple(const lldb_private::ArchSpec &arch) override; |
53 | | |
54 | | bool SupportsEmulatingInstructionsOfType( |
55 | 0 | lldb_private::InstructionType inst_type) override { |
56 | 0 | return SupportsEmulatingInstructionsOfTypeStatic(inst_type); |
57 | 0 | } |
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 | 0 | lldb_private::OptionValueDictionary *test_data) override { |
66 | 0 | return false; |
67 | 0 | } |
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 | | |
153 | | protected: |
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 |