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