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: EmulateInstructionARM64(const lldb_private::ArchSpec & arch)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 GetPluginNameStatic()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 SupportsEmulatingInstructionsOfTypeStatic(lldb_private::InstructionType inst_type)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 GetPluginName()50 llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } 51 52 bool SetTargetTriple(const lldb_private::ArchSpec &arch) override; 53 SupportsEmulatingInstructionsOfType(lldb_private::InstructionType inst_type)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 TestEmulation(lldb_private::Stream * out_stream,lldb_private::ArchSpec & arch,lldb_private::OptionValueDictionary * test_data)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 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 195