reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137
  138
  139
  140
  141
  142
  143
  144
  145
  146
  147
  148
  149
  150
  151
  152
  153
  154
  155
  156
  157
  158
  159
  160
  161
  162
  163
  164
  165
  166
  167
  168
  169
  170
  171
  172
  173
  174
  175
  176
  177
  178
  179
  180
  181
  182
  183
  184
  185
  186
  187
  188
  189
  190
  191
  192
//===-- EmulateInstructionARM64.h -------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef EmulateInstructionARM64_h_
#define EmulateInstructionARM64_h_

#include "Plugins/Process/Utility/ARMDefines.h"
#include "lldb/Core/EmulateInstruction.h"
#include "lldb/Interpreter/OptionValue.h"
#include "lldb/Utility/Status.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 &reg_info) override;

  bool
  CreateFunctionEntryUnwind(lldb_private::UnwindPlan &unwind_plan) override;

  enum AddrMode { AddrMode_OFF, AddrMode_PRE, AddrMode_POST };

  enum BranchType {
    BranchType_CALL,
    BranchType_ERET,
    BranchType_DRET,
    BranchType_RET,
    BranchType_JMP
  };

  enum CountOp { CountOp_CLZ, CountOp_CLS, CountOp_CNT };

  enum RevOp { RevOp_RBIT, RevOp_REV16, RevOp_REV32, RevOp_REV64 };

  enum BitwiseOp { BitwiseOp_NOT, BitwiseOp_RBIT };

  enum ExceptionLevel { EL0 = 0, EL1 = 1, EL2 = 2, EL3 = 3 };

  enum ExtendType {
    ExtendType_SXTB,
    ExtendType_SXTH,
    ExtendType_SXTW,
    ExtendType_SXTX,
    ExtendType_UXTB,
    ExtendType_UXTH,
    ExtendType_UXTW,
    ExtendType_UXTX
  };

  enum ExtractType { ExtractType_LEFT, ExtractType_RIGHT };

  enum LogicalOp { LogicalOp_AND, LogicalOp_EOR, LogicalOp_ORR };

  enum MemOp { MemOp_LOAD, MemOp_STORE, MemOp_PREFETCH, MemOp_NOP };

  enum MoveWideOp { MoveWideOp_N, MoveWideOp_Z, MoveWideOp_K };

  enum ShiftType { ShiftType_LSL, ShiftType_LSR, ShiftType_ASR, ShiftType_ROR };

  enum StackPointerSelection { SP0 = 0, SPx = 1 };

  enum Unpredictable { Unpredictable_WBOVERLAP, Unpredictable_LDPOVERLAP };

  enum ConstraintType {
    Constraint_NONE,
    Constraint_UNKNOWN,
    Constraint_SUPPRESSWB,
    Constraint_NOP
  };

  enum AccType {
    AccType_NORMAL,
    AccType_UNPRIV,
    AccType_STREAM,
    AccType_ALIGNED,
    AccType_ORDERED
  };

  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 <AddrMode a_mode> bool EmulateLDPSTP(const uint32_t opcode);

  template <AddrMode a_mode> 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_