//===-- EmulateInstructionARM64.h -------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #ifndef EmulateInstructionARM64_h_ #define EmulateInstructionARM64_h_ // C Includes // C++ Includes // Other libraries and framework includes // Project includes #include "lldb/Core/EmulateInstruction.h" #include "lldb/Core/Error.h" #include "lldb/Interpreter/OptionValue.h" #include "Plugins/Process/Utility/ARMDefines.h" class EmulateInstructionARM64 : public lldb_private::EmulateInstruction { public: EmulateInstructionARM64 (const lldb_private::ArchSpec &arch) : EmulateInstruction (arch), m_opcode_pstate (), m_emulated_pstate (), m_ignore_conditions (false) { } static void Initialize (); static void Terminate (); static lldb_private::ConstString GetPluginNameStatic (); static const char * GetPluginDescriptionStatic (); static lldb_private::EmulateInstruction * CreateInstance (const lldb_private::ArchSpec &arch, lldb_private::InstructionType inst_type); static bool SupportsEmulatingInstructionsOfTypeStatic (lldb_private::InstructionType inst_type) { switch (inst_type) { case lldb_private::eInstructionTypeAny: case lldb_private::eInstructionTypePrologueEpilogue: return true; case lldb_private::eInstructionTypePCModifying: case lldb_private::eInstructionTypeAll: return false; } return false; } lldb_private::ConstString GetPluginName() override; uint32_t GetPluginVersion() override { return 1; } bool SetTargetTriple(const lldb_private::ArchSpec &arch) override; bool SupportsEmulatingInstructionsOfType(lldb_private::InstructionType inst_type) override { return SupportsEmulatingInstructionsOfTypeStatic (inst_type); } bool ReadInstruction() override; bool EvaluateInstruction(uint32_t evaluate_options) override; bool TestEmulation(lldb_private::Stream *out_stream, lldb_private::ArchSpec &arch, lldb_private::OptionValueDictionary *test_data) override { return false; } bool GetRegisterInfo(lldb::RegisterKind reg_kind, uint32_t reg_num, lldb_private::RegisterInfo ®_info) override; bool CreateFunctionEntryUnwind(lldb_private::UnwindPlan &unwind_plan) override; typedef enum { AddrMode_OFF, AddrMode_PRE, AddrMode_POST } AddrMode; typedef enum { BranchType_CALL, BranchType_ERET, BranchType_DRET, BranchType_RET, BranchType_JMP } BranchType; typedef enum { CountOp_CLZ, CountOp_CLS, CountOp_CNT } CountOp; typedef enum { RevOp_RBIT, RevOp_REV16, RevOp_REV32, RevOp_REV64 } RevOp; typedef enum { BitwiseOp_NOT, BitwiseOp_RBIT } BitwiseOp; typedef enum { EL0 = 0, EL1 = 1, EL2 = 2, EL3 = 3 } ExceptionLevel; typedef enum { ExtendType_SXTB, ExtendType_SXTH, ExtendType_SXTW, ExtendType_SXTX, ExtendType_UXTB, ExtendType_UXTH, ExtendType_UXTW, ExtendType_UXTX } ExtendType; typedef enum { ExtractType_LEFT, ExtractType_RIGHT } ExtractType; typedef enum { LogicalOp_AND, LogicalOp_EOR, LogicalOp_ORR } LogicalOp; typedef enum { MemOp_LOAD, MemOp_STORE, MemOp_PREFETCH, MemOp_NOP } MemOp; typedef enum { MoveWideOp_N, MoveWideOp_Z, MoveWideOp_K } MoveWideOp; typedef enum { ShiftType_LSL, ShiftType_LSR, ShiftType_ASR, ShiftType_ROR } ShiftType; typedef enum { SP0 = 0, SPx = 1 } StackPointerSelection; typedef enum { Unpredictable_WBOVERLAP, Unpredictable_LDPOVERLAP } Unpredictable; typedef enum { Constraint_NONE, Constraint_UNKNOWN, Constraint_SUPPRESSWB, Constraint_NOP } ConstraintType; typedef enum { AccType_NORMAL, AccType_UNPRIV, AccType_STREAM, AccType_ALIGNED, AccType_ORDERED } AccType; typedef struct { uint32_t N:1, V:1, C:1, Z:1, // condition code flags – can also be accessed as PSTATE.[N,Z,C,V] Q:1, // AArch32 only – CSPR.Q bit IT:8, // AArch32 only – CPSR.IT bits J:1, // AArch32 only – CSPR.J bit T:1, // AArch32 only – CPSR.T bit SS:1, // Single step process state bit IL:1, // Illegal state bit D:1, A:1, I:1, F:1, // Interrupt masks – can also be accessed as PSTATE.[D,A,I,F] E:1, // AArch32 only – CSPR.E bit M:5, // AArch32 only – mode encodings RW:1, // Current register width – 0 is AArch64, 1 is AArch32 EL:2, // Current exception level (see ExceptionLevel enum) SP:1; // AArch64 only - Stack Pointer selection (see StackPointerSelection enum) } ProcState; protected: typedef struct { uint32_t mask; uint32_t value; uint32_t vfp_variants; bool (EmulateInstructionARM64::*callback) (const uint32_t opcode); const char *name; } Opcode; static Opcode* GetOpcodeForInstruction (const uint32_t opcode); uint32_t GetFramePointerRegisterNumber() const; bool BranchTo (const Context &context, uint32_t N, lldb::addr_t target); bool ConditionHolds (const uint32_t cond); bool UsingAArch32 (); bool EmulateADDSUBImm (const uint32_t opcode); template bool EmulateLDPSTP (const uint32_t opcode); template bool EmulateLDRSTRImm (const uint32_t opcode); bool EmulateB (const uint32_t opcode); bool EmulateBcond (const uint32_t opcode); bool EmulateCBZ (const uint32_t opcode); bool EmulateTBZ (const uint32_t opcode); ProcState m_opcode_pstate; ProcState m_emulated_pstate; // This can get updated by the opcode. bool m_ignore_conditions; }; #endif // EmulateInstructionARM64_h_