Path: blob/main/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.h
39645 views
//===-- EmulateInstructionARM64.h -------------------------------*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#ifndef LLDB_SOURCE_PLUGINS_INSTRUCTION_ARM64_EMULATEINSTRUCTIONARM64_H9#define LLDB_SOURCE_PLUGINS_INSTRUCTION_ARM64_EMULATEINSTRUCTIONARM64_H1011#include "Plugins/Process/Utility/ARMDefines.h"12#include "lldb/Core/EmulateInstruction.h"13#include "lldb/Interpreter/OptionValue.h"14#include "lldb/Utility/Status.h"15#include <optional>1617class EmulateInstructionARM64 : public lldb_private::EmulateInstruction {18public:19EmulateInstructionARM64(const lldb_private::ArchSpec &arch)20: EmulateInstruction(arch), m_opcode_pstate(), m_emulated_pstate(),21m_ignore_conditions(false) {}2223static void Initialize();2425static void Terminate();2627static llvm::StringRef GetPluginNameStatic() { return "arm64"; }2829static llvm::StringRef GetPluginDescriptionStatic();3031static lldb_private::EmulateInstruction *32CreateInstance(const lldb_private::ArchSpec &arch,33lldb_private::InstructionType inst_type);3435static bool SupportsEmulatingInstructionsOfTypeStatic(36lldb_private::InstructionType inst_type) {37switch (inst_type) {38case lldb_private::eInstructionTypeAny:39case lldb_private::eInstructionTypePrologueEpilogue:40return true;4142case lldb_private::eInstructionTypePCModifying:43case lldb_private::eInstructionTypeAll:44return false;45}46return false;47}4849llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }5051bool SetTargetTriple(const lldb_private::ArchSpec &arch) override;5253bool SupportsEmulatingInstructionsOfType(54lldb_private::InstructionType inst_type) override {55return SupportsEmulatingInstructionsOfTypeStatic(inst_type);56}5758bool ReadInstruction() override;5960bool EvaluateInstruction(uint32_t evaluate_options) override;6162bool TestEmulation(lldb_private::Stream &out_stream,63lldb_private::ArchSpec &arch,64lldb_private::OptionValueDictionary *test_data) override {65return false;66}6768std::optional<lldb_private::RegisterInfo>69GetRegisterInfo(lldb::RegisterKind reg_kind, uint32_t reg_num) override;7071bool72CreateFunctionEntryUnwind(lldb_private::UnwindPlan &unwind_plan) override;7374enum AddrMode { AddrMode_OFF, AddrMode_PRE, AddrMode_POST };7576enum BranchType {77BranchType_CALL,78BranchType_ERET,79BranchType_DRET,80BranchType_RET,81BranchType_JMP82};8384enum CountOp { CountOp_CLZ, CountOp_CLS, CountOp_CNT };8586enum RevOp { RevOp_RBIT, RevOp_REV16, RevOp_REV32, RevOp_REV64 };8788enum BitwiseOp { BitwiseOp_NOT, BitwiseOp_RBIT };8990enum ExceptionLevel { EL0 = 0, EL1 = 1, EL2 = 2, EL3 = 3 };9192enum ExtendType {93ExtendType_SXTB,94ExtendType_SXTH,95ExtendType_SXTW,96ExtendType_SXTX,97ExtendType_UXTB,98ExtendType_UXTH,99ExtendType_UXTW,100ExtendType_UXTX101};102103enum ExtractType { ExtractType_LEFT, ExtractType_RIGHT };104105enum LogicalOp { LogicalOp_AND, LogicalOp_EOR, LogicalOp_ORR };106107enum MemOp { MemOp_LOAD, MemOp_STORE, MemOp_PREFETCH, MemOp_NOP };108109enum MoveWideOp { MoveWideOp_N, MoveWideOp_Z, MoveWideOp_K };110111enum ShiftType { ShiftType_LSL, ShiftType_LSR, ShiftType_ASR, ShiftType_ROR };112113enum StackPointerSelection { SP0 = 0, SPx = 1 };114115enum Unpredictable { Unpredictable_WBOVERLAP, Unpredictable_LDPOVERLAP };116117enum ConstraintType {118Constraint_NONE,119Constraint_UNKNOWN,120Constraint_SUPPRESSWB,121Constraint_NOP122};123124enum AccType {125AccType_NORMAL,126AccType_UNPRIV,127AccType_STREAM,128AccType_ALIGNED,129AccType_ORDERED130};131132typedef struct {133uint32_t N : 1, V : 1, C : 1,134Z : 1, // condition code flags – can also be accessed as135// PSTATE.[N,Z,C,V]136Q : 1, // AArch32 only – CSPR.Q bit137IT : 8, // AArch32 only – CPSR.IT bits138J : 1, // AArch32 only – CSPR.J bit139T : 1, // AArch32 only – CPSR.T bit140SS : 1, // Single step process state bit141IL : 1, // Illegal state bit142D : 1, A : 1, I : 1,143F : 1, // Interrupt masks – can also be accessed as PSTATE.[D,A,I,F]144E : 1, // AArch32 only – CSPR.E bit145M : 5, // AArch32 only – mode encodings146RW : 1, // Current register width – 0 is AArch64, 1 is AArch32147EL : 2, // Current exception level (see ExceptionLevel enum)148SP : 1; // AArch64 only - Stack Pointer selection (see149// StackPointerSelection enum)150} ProcState;151152protected:153static uint64_t AddWithCarry(uint32_t N, uint64_t x, uint64_t y, bool carry_in,154EmulateInstructionARM64::ProcState &proc_state);155156typedef struct {157uint32_t mask;158uint32_t value;159uint32_t vfp_variants;160bool (EmulateInstructionARM64::*callback)(const uint32_t opcode);161const char *name;162} Opcode;163164static Opcode *GetOpcodeForInstruction(const uint32_t opcode);165166uint32_t GetFramePointerRegisterNumber() const;167168bool BranchTo(const Context &context, uint32_t N, lldb::addr_t target);169170bool ConditionHolds(const uint32_t cond);171172bool UsingAArch32();173174bool EmulateADDSUBImm(const uint32_t opcode);175176template <AddrMode a_mode> bool EmulateLDPSTP(const uint32_t opcode);177178template <AddrMode a_mode> bool EmulateLDRSTRImm(const uint32_t opcode);179180bool EmulateB(const uint32_t opcode);181182bool EmulateBcond(const uint32_t opcode);183184bool EmulateCBZ(const uint32_t opcode);185186bool EmulateTBZ(const uint32_t opcode);187188ProcState m_opcode_pstate;189ProcState m_emulated_pstate; // This can get updated by the opcode.190bool m_ignore_conditions;191};192193#endif // LLDB_SOURCE_PLUGINS_INSTRUCTION_ARM64_EMULATEINSTRUCTIONARM64_H194195196