//===-- EmulateInstruction.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 LLDB_CORE_EMULATEINSTRUCTION_H
#define LLDB_CORE_EMULATEINSTRUCTION_H

#include <optional>
#include <string>

#include "lldb/Core/Address.h"
#include "lldb/Core/Opcode.h"
#include "lldb/Core/PluginInterface.h"
#include "lldb/Utility/ArchSpec.h"
#include "lldb/lldb-defines.h"
#include "lldb/lldb-enumerations.h"
#include "lldb/lldb-private-enumerations.h"
#include "lldb/lldb-private-types.h"
#include "lldb/lldb-types.h"

#include <cstddef>
#include <cstdint>

namespace lldb_private {
class OptionValueDictionary;
class RegisterContext;
class RegisterValue;
class Stream;
class Target;
class UnwindPlan;

/// \class EmulateInstruction EmulateInstruction.h
/// "lldb/Core/EmulateInstruction.h"
/// A class that allows emulation of CPU opcodes.
///
/// This class is a plug-in interface that is accessed through the standard
/// static FindPlugin function call in the EmulateInstruction class. The
/// FindPlugin takes a target triple and returns a new object if there is a
/// plug-in that supports the architecture and OS. Four callbacks and a baton
/// are provided. The four callbacks are read register, write register, read
/// memory and write memory.
///
/// This class is currently designed for these main use cases: - Auto
/// generation of Call Frame Information (CFI) from assembly code - Predicting
/// single step breakpoint locations - Emulating instructions for breakpoint
/// traps
///
/// Objects can be asked to read an instruction which will cause a call to the
/// read register callback to get the PC, followed by a read memory call to
/// read the opcode. If ReadInstruction () returns true, then a call to
/// EmulateInstruction::EvaluateInstruction () can be made. At this point the
/// EmulateInstruction subclass will use all of the callbacks to emulate an
/// instruction.
///
/// Clients that provide the callbacks can either do the read/write
/// registers/memory to actually emulate the instruction on a real or virtual
/// CPU, or watch for the EmulateInstruction::Context which is context for the
/// read/write register/memory which explains why the callback is being
/// called. Examples of a context are: "pushing register 3 onto the stack at
/// offset -12", or "adjusting stack pointer by -16". This extra context
/// allows the generation of
/// CFI information from assembly code without having to actually do
/// the read/write register/memory.
///
/// Clients must be prepared that not all instructions for an Instruction Set
/// Architecture (ISA) will be emulated.
///
/// Subclasses at the very least should implement the instructions that save
/// and restore registers onto the stack and adjustment to the stack pointer.
/// By just implementing a few instructions for an ISA that are the typical
/// prologue opcodes, you can then generate CFI using a class that will soon
/// be available.
///
/// Implementing all of the instructions that affect the PC can then allow
/// single step prediction support.
///
/// Implementing all of the instructions allows for emulation of opcodes for
/// breakpoint traps and will pave the way for "thread centric" debugging. The
/// current debugging model is "process centric" where all threads must be
/// stopped when any thread is stopped; when hitting software breakpoints we
/// must disable the breakpoint by restoring the original breakpoint opcode,
/// single stepping and restoring the breakpoint trap. If all threads were
/// allowed to run then other threads could miss the breakpoint.
///
/// This class centralizes the code that usually is done in separate code
/// paths in a debugger (single step prediction, finding save restore
/// locations of registers for unwinding stack frame variables) and emulating
/// the instruction is just a bonus.

class EmulateInstruction : public PluginInterface {
public:
  static EmulateInstruction *FindPlugin(const ArchSpec &arch,
                                        InstructionType supported_inst_type,
                                        const char *plugin_name);

  enum ContextType {
    eContextInvalid = 0,
    // Read an instruction opcode from memory
    eContextReadOpcode,

    // Usually used for writing a register value whose source value is an
    // immediate
    eContextImmediate,

    // Exclusively used when saving a register to the stack as part of the
    // prologue
    eContextPushRegisterOnStack,

    // Exclusively used when restoring a register off the stack as part of the
    // epilogue
    eContextPopRegisterOffStack,

    // Add or subtract a value from the stack
    eContextAdjustStackPointer,

    // Adjust the frame pointer for the current frame
    eContextSetFramePointer,

    // Typically in an epilogue sequence.  Copy the frame pointer back into the
    // stack pointer, use SP for CFA calculations again.
    eContextRestoreStackPointer,

    // Add or subtract a value from a base address register (other than SP)
    eContextAdjustBaseRegister,

    // Add or subtract a value from the PC or store a value to the PC.
    eContextAdjustPC,

    // Used in WriteRegister callbacks to indicate where the
    eContextRegisterPlusOffset,

    // Used in WriteMemory callback to indicate where the data came from
    eContextRegisterStore,

    eContextRegisterLoad,

    // Used when performing a PC-relative branch where the
    eContextRelativeBranchImmediate,

    // Used when performing an absolute branch where the
    eContextAbsoluteBranchRegister,

    // Used when performing a supervisor call to an operating system to provide
    // a service:
    eContextSupervisorCall,

    // Used when performing a MemU operation to read the PC-relative offset
    // from an address.
    eContextTableBranchReadMemory,

    // Used when random bits are written into a register
    eContextWriteRegisterRandomBits,

    // Used when random bits are written to memory
    eContextWriteMemoryRandomBits,

    eContextArithmetic,

    eContextAdvancePC,

    eContextReturnFromException
  };

  enum InfoType {
    eInfoTypeRegisterPlusOffset,
    eInfoTypeRegisterPlusIndirectOffset,
    eInfoTypeRegisterToRegisterPlusOffset,
    eInfoTypeRegisterToRegisterPlusIndirectOffset,
    eInfoTypeRegisterRegisterOperands,
    eInfoTypeOffset,
    eInfoTypeRegister,
    eInfoTypeImmediate,
    eInfoTypeImmediateSigned,
    eInfoTypeAddress,
    eInfoTypeISAAndImmediate,
    eInfoTypeISAAndImmediateSigned,
    eInfoTypeISA,
    eInfoTypeNoArgs
  };

  struct Context {
    ContextType type = eContextInvalid;

  private:
    enum InfoType info_type = eInfoTypeNoArgs;

  public:
    enum InfoType GetInfoType() const { return info_type; }
    union ContextInfo {
      struct RegisterPlusOffset {
        RegisterInfo reg;      // base register
        int64_t signed_offset; // signed offset added to base register
      } RegisterPlusOffset;

      struct RegisterPlusIndirectOffset {
        RegisterInfo base_reg;   // base register number
        RegisterInfo offset_reg; // offset register kind
      } RegisterPlusIndirectOffset;

      struct RegisterToRegisterPlusOffset {
        RegisterInfo data_reg; // source/target register for data
        RegisterInfo base_reg; // base register for address calculation
        int64_t offset;        // offset for address calculation
      } RegisterToRegisterPlusOffset;

      struct RegisterToRegisterPlusIndirectOffset {
        RegisterInfo base_reg;   // base register for address calculation
        RegisterInfo offset_reg; // offset register for address calculation
        RegisterInfo data_reg;   // source/target register for data
      } RegisterToRegisterPlusIndirectOffset;

      struct RegisterRegisterOperands {
        RegisterInfo
            operand1; // register containing first operand for binary op
        RegisterInfo
            operand2; // register containing second operand for binary op
      } RegisterRegisterOperands;

      int64_t signed_offset; // signed offset by which to adjust self (for
                             // registers only)

      RegisterInfo reg; // plain register

      uint64_t unsigned_immediate; // unsigned immediate value
      int64_t signed_immediate;    // signed immediate value

      lldb::addr_t address; // direct address

      struct ISAAndImmediate {
        uint32_t isa;
        uint32_t unsigned_data32; // immediate data
      } ISAAndImmediate;

      struct ISAAndImmediateSigned {
        uint32_t isa;
        int32_t signed_data32; // signed immediate data
      } ISAAndImmediateSigned;

      uint32_t isa;
    } info;
    static_assert(std::is_trivial<ContextInfo>::value,
                  "ContextInfo must be trivial.");

    Context() = default;

    void SetRegisterPlusOffset(RegisterInfo base_reg, int64_t signed_offset) {
      info_type = eInfoTypeRegisterPlusOffset;
      info.RegisterPlusOffset.reg = base_reg;
      info.RegisterPlusOffset.signed_offset = signed_offset;
    }

    void SetRegisterPlusIndirectOffset(RegisterInfo base_reg,
                                       RegisterInfo offset_reg) {
      info_type = eInfoTypeRegisterPlusIndirectOffset;
      info.RegisterPlusIndirectOffset.base_reg = base_reg;
      info.RegisterPlusIndirectOffset.offset_reg = offset_reg;
    }

    void SetRegisterToRegisterPlusOffset(RegisterInfo data_reg,
                                         RegisterInfo base_reg,
                                         int64_t offset) {
      info_type = eInfoTypeRegisterToRegisterPlusOffset;
      info.RegisterToRegisterPlusOffset.data_reg = data_reg;
      info.RegisterToRegisterPlusOffset.base_reg = base_reg;
      info.RegisterToRegisterPlusOffset.offset = offset;
    }

    void SetRegisterToRegisterPlusIndirectOffset(RegisterInfo base_reg,
                                                 RegisterInfo offset_reg,
                                                 RegisterInfo data_reg) {
      info_type = eInfoTypeRegisterToRegisterPlusIndirectOffset;
      info.RegisterToRegisterPlusIndirectOffset.base_reg = base_reg;
      info.RegisterToRegisterPlusIndirectOffset.offset_reg = offset_reg;
      info.RegisterToRegisterPlusIndirectOffset.data_reg = data_reg;
    }

    void SetRegisterRegisterOperands(RegisterInfo op1_reg,
                                     RegisterInfo op2_reg) {
      info_type = eInfoTypeRegisterRegisterOperands;
      info.RegisterRegisterOperands.operand1 = op1_reg;
      info.RegisterRegisterOperands.operand2 = op2_reg;
    }

    void SetOffset(int64_t signed_offset) {
      info_type = eInfoTypeOffset;
      info.signed_offset = signed_offset;
    }

    void SetRegister(RegisterInfo reg) {
      info_type = eInfoTypeRegister;
      info.reg = reg;
    }

    void SetImmediate(uint64_t immediate) {
      info_type = eInfoTypeImmediate;
      info.unsigned_immediate = immediate;
    }

    void SetImmediateSigned(int64_t signed_immediate) {
      info_type = eInfoTypeImmediateSigned;
      info.signed_immediate = signed_immediate;
    }

    void SetAddress(lldb::addr_t address) {
      info_type = eInfoTypeAddress;
      info.address = address;
    }
    void SetISAAndImmediate(uint32_t isa, uint32_t data) {
      info_type = eInfoTypeISAAndImmediate;
      info.ISAAndImmediate.isa = isa;
      info.ISAAndImmediate.unsigned_data32 = data;
    }

    void SetISAAndImmediateSigned(uint32_t isa, int32_t data) {
      info_type = eInfoTypeISAAndImmediateSigned;
      info.ISAAndImmediateSigned.isa = isa;
      info.ISAAndImmediateSigned.signed_data32 = data;
    }

    void SetISA(uint32_t isa) {
      info_type = eInfoTypeISA;
      info.isa = isa;
    }

    void SetNoArgs() { info_type = eInfoTypeNoArgs; }

    void Dump(Stream &s, EmulateInstruction *instruction) const;
  };

  typedef size_t (*ReadMemoryCallback)(EmulateInstruction *instruction,
                                       void *baton, const Context &context,
                                       lldb::addr_t addr, void *dst,
                                       size_t length);

  typedef size_t (*WriteMemoryCallback)(EmulateInstruction *instruction,
                                        void *baton, const Context &context,
                                        lldb::addr_t addr, const void *dst,
                                        size_t length);

  typedef bool (*ReadRegisterCallback)(EmulateInstruction *instruction,
                                       void *baton,
                                       const RegisterInfo *reg_info,
                                       RegisterValue &reg_value);

  typedef bool (*WriteRegisterCallback)(EmulateInstruction *instruction,
                                        void *baton, const Context &context,
                                        const RegisterInfo *reg_info,
                                        const RegisterValue &reg_value);

  // Type to represent the condition of an instruction. The UINT32 value is
  // reserved for the unconditional case and all other value can be used in an
  // architecture dependent way.
  typedef uint32_t InstructionCondition;
  static const InstructionCondition UnconditionalCondition = UINT32_MAX;

  EmulateInstruction(const ArchSpec &arch);

  ~EmulateInstruction() override = default;

  // Mandatory overrides
  virtual bool
  SupportsEmulatingInstructionsOfType(InstructionType inst_type) = 0;

  virtual bool SetTargetTriple(const ArchSpec &arch) = 0;

  virtual bool ReadInstruction() = 0;

  virtual bool EvaluateInstruction(uint32_t evaluate_options) = 0;

  virtual InstructionCondition GetInstructionCondition() {
    return UnconditionalCondition;
  }

  virtual bool TestEmulation(Stream &out_stream, ArchSpec &arch,
                             OptionValueDictionary *test_data) = 0;

  virtual std::optional<RegisterInfo>
  GetRegisterInfo(lldb::RegisterKind reg_kind, uint32_t reg_num) = 0;

  // Optional overrides
  virtual bool SetInstruction(const Opcode &insn_opcode,
                              const Address &inst_addr, Target *target);

  virtual bool CreateFunctionEntryUnwind(UnwindPlan &unwind_plan);

  static const char *TranslateRegister(lldb::RegisterKind reg_kind,
                                       uint32_t reg_num, std::string &reg_name);

  // RegisterInfo variants
  std::optional<RegisterValue> ReadRegister(const RegisterInfo &reg_info);

  uint64_t ReadRegisterUnsigned(const RegisterInfo &reg_info,
                                uint64_t fail_value, bool *success_ptr);

  bool WriteRegister(const Context &context, const RegisterInfo &ref_info,
                     const RegisterValue &reg_value);

  bool WriteRegisterUnsigned(const Context &context,
                             const RegisterInfo &reg_info, uint64_t reg_value);

  // Register kind and number variants
  bool ReadRegister(lldb::RegisterKind reg_kind, uint32_t reg_num,
                    RegisterValue &reg_value);

  bool WriteRegister(const Context &context, lldb::RegisterKind reg_kind,
                     uint32_t reg_num, const RegisterValue &reg_value);

  uint64_t ReadRegisterUnsigned(lldb::RegisterKind reg_kind, uint32_t reg_num,
                                uint64_t fail_value, bool *success_ptr);

  bool WriteRegisterUnsigned(const Context &context,
                             lldb::RegisterKind reg_kind, uint32_t reg_num,
                             uint64_t reg_value);

  size_t ReadMemory(const Context &context, lldb::addr_t addr, void *dst,
                    size_t dst_len);

  uint64_t ReadMemoryUnsigned(const Context &context, lldb::addr_t addr,
                              size_t byte_size, uint64_t fail_value,
                              bool *success_ptr);

  bool WriteMemory(const Context &context, lldb::addr_t addr, const void *src,
                   size_t src_len);

  bool WriteMemoryUnsigned(const Context &context, lldb::addr_t addr,
                           uint64_t uval, size_t uval_byte_size);

  uint32_t GetAddressByteSize() const { return m_arch.GetAddressByteSize(); }

  lldb::ByteOrder GetByteOrder() const { return m_arch.GetByteOrder(); }

  const Opcode &GetOpcode() const { return m_opcode; }

  lldb::addr_t GetAddress() const { return m_addr; }

  const ArchSpec &GetArchitecture() const { return m_arch; }

  static size_t ReadMemoryFrame(EmulateInstruction *instruction, void *baton,
                                const Context &context, lldb::addr_t addr,
                                void *dst, size_t length);

  static size_t WriteMemoryFrame(EmulateInstruction *instruction, void *baton,
                                 const Context &context, lldb::addr_t addr,
                                 const void *dst, size_t length);

  static bool ReadRegisterFrame(EmulateInstruction *instruction, void *baton,
                                const RegisterInfo *reg_info,
                                RegisterValue &reg_value);

  static bool WriteRegisterFrame(EmulateInstruction *instruction, void *baton,
                                 const Context &context,
                                 const RegisterInfo *reg_info,
                                 const RegisterValue &reg_value);

  static size_t ReadMemoryDefault(EmulateInstruction *instruction, void *baton,
                                  const Context &context, lldb::addr_t addr,
                                  void *dst, size_t length);

  static size_t WriteMemoryDefault(EmulateInstruction *instruction, void *baton,
                                   const Context &context, lldb::addr_t addr,
                                   const void *dst, size_t length);

  static bool ReadRegisterDefault(EmulateInstruction *instruction, void *baton,
                                  const RegisterInfo *reg_info,
                                  RegisterValue &reg_value);

  static bool WriteRegisterDefault(EmulateInstruction *instruction, void *baton,
                                   const Context &context,
                                   const RegisterInfo *reg_info,
                                   const RegisterValue &reg_value);

  void SetBaton(void *baton);

  void SetCallbacks(ReadMemoryCallback read_mem_callback,
                    WriteMemoryCallback write_mem_callback,
                    ReadRegisterCallback read_reg_callback,
                    WriteRegisterCallback write_reg_callback);

  void SetReadMemCallback(ReadMemoryCallback read_mem_callback);

  void SetWriteMemCallback(WriteMemoryCallback write_mem_callback);

  void SetReadRegCallback(ReadRegisterCallback read_reg_callback);

  void SetWriteRegCallback(WriteRegisterCallback write_reg_callback);

  static bool GetBestRegisterKindAndNumber(const RegisterInfo *reg_info,
                                           lldb::RegisterKind &reg_kind,
                                           uint32_t &reg_num);

  static uint32_t GetInternalRegisterNumber(RegisterContext *reg_ctx,
                                            const RegisterInfo &reg_info);

protected:
  ArchSpec m_arch;
  void *m_baton = nullptr;
  ReadMemoryCallback m_read_mem_callback = &ReadMemoryDefault;
  WriteMemoryCallback m_write_mem_callback = &WriteMemoryDefault;
  ReadRegisterCallback m_read_reg_callback = &ReadRegisterDefault;
  WriteRegisterCallback m_write_reg_callback = &WriteRegisterDefault;
  lldb::addr_t m_addr = LLDB_INVALID_ADDRESS;
  Opcode m_opcode;

private:
  // For EmulateInstruction only
  EmulateInstruction(const EmulateInstruction &) = delete;
  const EmulateInstruction &operator=(const EmulateInstruction &) = delete;
};

} // namespace lldb_private

#endif // LLDB_CORE_EMULATEINSTRUCTION_H
