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