195 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLDB_SOURCE_PLUGINS_INSTRUCTION_ARM64_EMULATEINSTRUCTIONARM64_H10#define LLDB_SOURCE_PLUGINS_INSTRUCTION_ARM64_EMULATEINSTRUCTIONARM64_H11 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 bool73 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_JMP83 };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_UXTX102 };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_NOP123 };124 125 enum AccType {126 AccType_NORMAL,127 AccType_UNPRIV,128 AccType_STREAM,129 AccType_ALIGNED,130 AccType_ORDERED131 };132 133 typedef struct {134 uint32_t N : 1, V : 1, C : 1,135 Z : 1, // condition code flags – can also be accessed as136 // PSTATE.[N,Z,C,V]137 Q : 1, // AArch32 only – CSPR.Q bit138 IT : 8, // AArch32 only – CPSR.IT bits139 J : 1, // AArch32 only – CSPR.J bit140 T : 1, // AArch32 only – CPSR.T bit141 SS : 1, // Single step process state bit142 IL : 1, // Illegal state bit143 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 bit146 M : 5, // AArch32 only – mode encodings147 RW : 1, // Current register width – 0 is AArch64, 1 is AArch32148 EL : 2, // Current exception level (see ExceptionLevel enum)149 SP : 1; // AArch64 only - Stack Pointer selection (see150 // 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_H195