//===-- EmulateInstruction.cpp --------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

#include "lldb/Core/EmulateInstruction.h"

#include "lldb/Core/Address.h"
#include "lldb/Core/DumpRegisterValue.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Symbol/UnwindPlan.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/RegisterValue.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/Stream.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/lldb-forward.h"
#include "lldb/lldb-private-interfaces.h"

#include "llvm/ADT/StringRef.h"

#include <cstring>
#include <memory>

#include <cinttypes>
#include <cstdio>

namespace lldb_private {
class Target;
}

using namespace lldb;
using namespace lldb_private;

EmulateInstruction *
EmulateInstruction::FindPlugin(const ArchSpec &arch,
                               InstructionType supported_inst_type,
                               const char *plugin_name) {
  EmulateInstructionCreateInstance create_callback = nullptr;
  if (plugin_name) {
    create_callback =
        PluginManager::GetEmulateInstructionCreateCallbackForPluginName(
            plugin_name);
    if (create_callback) {
      EmulateInstruction *emulate_insn_ptr =
          create_callback(arch, supported_inst_type);
      if (emulate_insn_ptr)
        return emulate_insn_ptr;
    }
  } else {
    for (uint32_t idx = 0;
         (create_callback =
              PluginManager::GetEmulateInstructionCreateCallbackAtIndex(idx)) !=
         nullptr;
         ++idx) {
      EmulateInstruction *emulate_insn_ptr =
          create_callback(arch, supported_inst_type);
      if (emulate_insn_ptr)
        return emulate_insn_ptr;
    }
  }
  return nullptr;
}

EmulateInstruction::EmulateInstruction(const ArchSpec &arch) : m_arch(arch) {}

bool EmulateInstruction::ReadRegister(const RegisterInfo *reg_info,
                                      RegisterValue &reg_value) {
  if (m_read_reg_callback != nullptr)
    return m_read_reg_callback(this, m_baton, reg_info, reg_value);
  return false;
}

bool EmulateInstruction::ReadRegister(lldb::RegisterKind reg_kind,
                                      uint32_t reg_num,
                                      RegisterValue &reg_value) {
  RegisterInfo reg_info;
  if (GetRegisterInfo(reg_kind, reg_num, reg_info))
    return ReadRegister(&reg_info, reg_value);
  return false;
}

uint64_t EmulateInstruction::ReadRegisterUnsigned(lldb::RegisterKind reg_kind,
                                                  uint32_t reg_num,
                                                  uint64_t fail_value,
                                                  bool *success_ptr) {
  RegisterValue reg_value;
  if (ReadRegister(reg_kind, reg_num, reg_value))
    return reg_value.GetAsUInt64(fail_value, success_ptr);
  if (success_ptr)
    *success_ptr = false;
  return fail_value;
}

uint64_t EmulateInstruction::ReadRegisterUnsigned(const RegisterInfo *reg_info,
                                                  uint64_t fail_value,
                                                  bool *success_ptr) {
  RegisterValue reg_value;
  if (ReadRegister(reg_info, reg_value))
    return reg_value.GetAsUInt64(fail_value, success_ptr);
  if (success_ptr)
    *success_ptr = false;
  return fail_value;
}

bool EmulateInstruction::WriteRegister(const Context &context,
                                       const RegisterInfo *reg_info,
                                       const RegisterValue &reg_value) {
  if (m_write_reg_callback != nullptr)
    return m_write_reg_callback(this, m_baton, context, reg_info, reg_value);
  return false;
}

bool EmulateInstruction::WriteRegister(const Context &context,
                                       lldb::RegisterKind reg_kind,
                                       uint32_t reg_num,
                                       const RegisterValue &reg_value) {
  RegisterInfo reg_info;
  if (GetRegisterInfo(reg_kind, reg_num, reg_info))
    return WriteRegister(context, &reg_info, reg_value);
  return false;
}

bool EmulateInstruction::WriteRegisterUnsigned(const Context &context,
                                               lldb::RegisterKind reg_kind,
                                               uint32_t reg_num,
                                               uint64_t uint_value) {
  RegisterInfo reg_info;
  if (GetRegisterInfo(reg_kind, reg_num, reg_info)) {
    RegisterValue reg_value;
    if (reg_value.SetUInt(uint_value, reg_info.byte_size))
      return WriteRegister(context, &reg_info, reg_value);
  }
  return false;
}

bool EmulateInstruction::WriteRegisterUnsigned(const Context &context,
                                               const RegisterInfo *reg_info,
                                               uint64_t uint_value) {
  if (reg_info != nullptr) {
    RegisterValue reg_value;
    if (reg_value.SetUInt(uint_value, reg_info->byte_size))
      return WriteRegister(context, reg_info, reg_value);
  }
  return false;
}

size_t EmulateInstruction::ReadMemory(const Context &context, lldb::addr_t addr,
                                      void *dst, size_t dst_len) {
  if (m_read_mem_callback != nullptr)
    return m_read_mem_callback(this, m_baton, context, addr, dst, dst_len) ==
           dst_len;
  return false;
}

uint64_t EmulateInstruction::ReadMemoryUnsigned(const Context &context,
                                                lldb::addr_t addr,
                                                size_t byte_size,
                                                uint64_t fail_value,
                                                bool *success_ptr) {
  uint64_t uval64 = 0;
  bool success = false;
  if (byte_size <= 8) {
    uint8_t buf[sizeof(uint64_t)];
    size_t bytes_read =
        m_read_mem_callback(this, m_baton, context, addr, buf, byte_size);
    if (bytes_read == byte_size) {
      lldb::offset_t offset = 0;
      DataExtractor data(buf, byte_size, GetByteOrder(), GetAddressByteSize());
      uval64 = data.GetMaxU64(&offset, byte_size);
      success = true;
    }
  }

  if (success_ptr)
    *success_ptr = success;

  if (!success)
    uval64 = fail_value;
  return uval64;
}

bool EmulateInstruction::WriteMemoryUnsigned(const Context &context,
                                             lldb::addr_t addr, uint64_t uval,
                                             size_t uval_byte_size) {
  StreamString strm(Stream::eBinary, GetAddressByteSize(), GetByteOrder());
  strm.PutMaxHex64(uval, uval_byte_size);

  size_t bytes_written = m_write_mem_callback(
      this, m_baton, context, addr, strm.GetString().data(), uval_byte_size);
  return (bytes_written == uval_byte_size);
}

bool EmulateInstruction::WriteMemory(const Context &context, lldb::addr_t addr,
                                     const void *src, size_t src_len) {
  if (m_write_mem_callback != nullptr)
    return m_write_mem_callback(this, m_baton, context, addr, src, src_len) ==
           src_len;
  return false;
}

void EmulateInstruction::SetBaton(void *baton) { m_baton = baton; }

void EmulateInstruction::SetCallbacks(
    ReadMemoryCallback read_mem_callback,
    WriteMemoryCallback write_mem_callback,
    ReadRegisterCallback read_reg_callback,
    WriteRegisterCallback write_reg_callback) {
  m_read_mem_callback = read_mem_callback;
  m_write_mem_callback = write_mem_callback;
  m_read_reg_callback = read_reg_callback;
  m_write_reg_callback = write_reg_callback;
}

void EmulateInstruction::SetReadMemCallback(
    ReadMemoryCallback read_mem_callback) {
  m_read_mem_callback = read_mem_callback;
}

void EmulateInstruction::SetWriteMemCallback(
    WriteMemoryCallback write_mem_callback) {
  m_write_mem_callback = write_mem_callback;
}

void EmulateInstruction::SetReadRegCallback(
    ReadRegisterCallback read_reg_callback) {
  m_read_reg_callback = read_reg_callback;
}

void EmulateInstruction::SetWriteRegCallback(
    WriteRegisterCallback write_reg_callback) {
  m_write_reg_callback = write_reg_callback;
}

//
//  Read & Write Memory and Registers callback functions.
//

size_t EmulateInstruction::ReadMemoryFrame(EmulateInstruction *instruction,
                                           void *baton, const Context &context,
                                           lldb::addr_t addr, void *dst,
                                           size_t dst_len) {
  if (baton == nullptr || dst == nullptr || dst_len == 0)
    return 0;

  StackFrame *frame = (StackFrame *)baton;

  ProcessSP process_sp(frame->CalculateProcess());
  if (process_sp) {
    Status error;
    return process_sp->ReadMemory(addr, dst, dst_len, error);
  }
  return 0;
}

size_t EmulateInstruction::WriteMemoryFrame(EmulateInstruction *instruction,
                                            void *baton, const Context &context,
                                            lldb::addr_t addr, const void *src,
                                            size_t src_len) {
  if (baton == nullptr || src == nullptr || src_len == 0)
    return 0;

  StackFrame *frame = (StackFrame *)baton;

  ProcessSP process_sp(frame->CalculateProcess());
  if (process_sp) {
    Status error;
    return process_sp->WriteMemory(addr, src, src_len, error);
  }

  return 0;
}

bool EmulateInstruction::ReadRegisterFrame(EmulateInstruction *instruction,
                                           void *baton,
                                           const RegisterInfo *reg_info,
                                           RegisterValue &reg_value) {
  if (baton == nullptr)
    return false;

  StackFrame *frame = (StackFrame *)baton;
  return frame->GetRegisterContext()->ReadRegister(reg_info, reg_value);
}

bool EmulateInstruction::WriteRegisterFrame(EmulateInstruction *instruction,
                                            void *baton, const Context &context,
                                            const RegisterInfo *reg_info,
                                            const RegisterValue &reg_value) {
  if (baton == nullptr)
    return false;

  StackFrame *frame = (StackFrame *)baton;
  return frame->GetRegisterContext()->WriteRegister(reg_info, reg_value);
}

size_t EmulateInstruction::ReadMemoryDefault(EmulateInstruction *instruction,
                                             void *baton,
                                             const Context &context,
                                             lldb::addr_t addr, void *dst,
                                             size_t length) {
  StreamFile strm(stdout, false);
  strm.Printf("    Read from Memory (address = 0x%" PRIx64 ", length = %" PRIu64
              ", context = ",
              addr, (uint64_t)length);
  context.Dump(strm, instruction);
  strm.EOL();
  *((uint64_t *)dst) = 0xdeadbeef;
  return length;
}

size_t EmulateInstruction::WriteMemoryDefault(EmulateInstruction *instruction,
                                              void *baton,
                                              const Context &context,
                                              lldb::addr_t addr,
                                              const void *dst, size_t length) {
  StreamFile strm(stdout, false);
  strm.Printf("    Write to Memory (address = 0x%" PRIx64 ", length = %" PRIu64
              ", context = ",
              addr, (uint64_t)length);
  context.Dump(strm, instruction);
  strm.EOL();
  return length;
}

bool EmulateInstruction::ReadRegisterDefault(EmulateInstruction *instruction,
                                             void *baton,
                                             const RegisterInfo *reg_info,
                                             RegisterValue &reg_value) {
  StreamFile strm(stdout, false);
  strm.Printf("  Read Register (%s)\n", reg_info->name);
  lldb::RegisterKind reg_kind;
  uint32_t reg_num;
  if (GetBestRegisterKindAndNumber(reg_info, reg_kind, reg_num))
    reg_value.SetUInt64((uint64_t)reg_kind << 24 | reg_num);
  else
    reg_value.SetUInt64(0);

  return true;
}

bool EmulateInstruction::WriteRegisterDefault(EmulateInstruction *instruction,
                                              void *baton,
                                              const Context &context,
                                              const RegisterInfo *reg_info,
                                              const RegisterValue &reg_value) {
  StreamFile strm(stdout, false);
  strm.Printf("    Write to Register (name = %s, value = ", reg_info->name);
  DumpRegisterValue(reg_value, &strm, reg_info, false, false, eFormatDefault);
  strm.PutCString(", context = ");
  context.Dump(strm, instruction);
  strm.EOL();
  return true;
}

void EmulateInstruction::Context::Dump(Stream &strm,
                                       EmulateInstruction *instruction) const {
  switch (type) {
  case eContextReadOpcode:
    strm.PutCString("reading opcode");
    break;

  case eContextImmediate:
    strm.PutCString("immediate");
    break;

  case eContextPushRegisterOnStack:
    strm.PutCString("push register");
    break;

  case eContextPopRegisterOffStack:
    strm.PutCString("pop register");
    break;

  case eContextAdjustStackPointer:
    strm.PutCString("adjust sp");
    break;

  case eContextSetFramePointer:
    strm.PutCString("set frame pointer");
    break;

  case eContextAdjustBaseRegister:
    strm.PutCString("adjusting (writing value back to) a base register");
    break;

  case eContextRegisterPlusOffset:
    strm.PutCString("register + offset");
    break;

  case eContextRegisterStore:
    strm.PutCString("store register");
    break;

  case eContextRegisterLoad:
    strm.PutCString("load register");
    break;

  case eContextRelativeBranchImmediate:
    strm.PutCString("relative branch immediate");
    break;

  case eContextAbsoluteBranchRegister:
    strm.PutCString("absolute branch register");
    break;

  case eContextSupervisorCall:
    strm.PutCString("supervisor call");
    break;

  case eContextTableBranchReadMemory:
    strm.PutCString("table branch read memory");
    break;

  case eContextWriteRegisterRandomBits:
    strm.PutCString("write random bits to a register");
    break;

  case eContextWriteMemoryRandomBits:
    strm.PutCString("write random bits to a memory address");
    break;

  case eContextArithmetic:
    strm.PutCString("arithmetic");
    break;

  case eContextReturnFromException:
    strm.PutCString("return from exception");
    break;

  default:
    strm.PutCString("unrecognized context.");
    break;
  }

  switch (info_type) {
  case eInfoTypeRegisterPlusOffset:
    strm.Printf(" (reg_plus_offset = %s%+" PRId64 ")",
                info.RegisterPlusOffset.reg.name,
                info.RegisterPlusOffset.signed_offset);
    break;

  case eInfoTypeRegisterPlusIndirectOffset:
    strm.Printf(" (reg_plus_reg = %s + %s)",
                info.RegisterPlusIndirectOffset.base_reg.name,
                info.RegisterPlusIndirectOffset.offset_reg.name);
    break;

  case eInfoTypeRegisterToRegisterPlusOffset:
    strm.Printf(" (base_and_imm_offset = %s%+" PRId64 ", data_reg = %s)",
                info.RegisterToRegisterPlusOffset.base_reg.name,
                info.RegisterToRegisterPlusOffset.offset,
                info.RegisterToRegisterPlusOffset.data_reg.name);
    break;

  case eInfoTypeRegisterToRegisterPlusIndirectOffset:
    strm.Printf(" (base_and_reg_offset = %s + %s, data_reg = %s)",
                info.RegisterToRegisterPlusIndirectOffset.base_reg.name,
                info.RegisterToRegisterPlusIndirectOffset.offset_reg.name,
                info.RegisterToRegisterPlusIndirectOffset.data_reg.name);
    break;

  case eInfoTypeRegisterRegisterOperands:
    strm.Printf(" (register to register binary op: %s and %s)",
                info.RegisterRegisterOperands.operand1.name,
                info.RegisterRegisterOperands.operand2.name);
    break;

  case eInfoTypeOffset:
    strm.Printf(" (signed_offset = %+" PRId64 ")", info.signed_offset);
    break;

  case eInfoTypeRegister:
    strm.Printf(" (reg = %s)", info.reg.name);
    break;

  case eInfoTypeImmediate:
    strm.Printf(" (unsigned_immediate = %" PRIu64 " (0x%16.16" PRIx64 "))",
                info.unsigned_immediate, info.unsigned_immediate);
    break;

  case eInfoTypeImmediateSigned:
    strm.Printf(" (signed_immediate = %+" PRId64 " (0x%16.16" PRIx64 "))",
                info.signed_immediate, info.signed_immediate);
    break;

  case eInfoTypeAddress:
    strm.Printf(" (address = 0x%" PRIx64 ")", info.address);
    break;

  case eInfoTypeISAAndImmediate:
    strm.Printf(" (isa = %u, unsigned_immediate = %u (0x%8.8x))",
                info.ISAAndImmediate.isa, info.ISAAndImmediate.unsigned_data32,
                info.ISAAndImmediate.unsigned_data32);
    break;

  case eInfoTypeISAAndImmediateSigned:
    strm.Printf(" (isa = %u, signed_immediate = %i (0x%8.8x))",
                info.ISAAndImmediateSigned.isa,
                info.ISAAndImmediateSigned.signed_data32,
                info.ISAAndImmediateSigned.signed_data32);
    break;

  case eInfoTypeISA:
    strm.Printf(" (isa = %u)", info.isa);
    break;

  case eInfoTypeNoArgs:
    break;
  }
}

bool EmulateInstruction::SetInstruction(const Opcode &opcode,
                                        const Address &inst_addr,
                                        Target *target) {
  m_opcode = opcode;
  m_addr = LLDB_INVALID_ADDRESS;
  if (inst_addr.IsValid()) {
    if (target != nullptr)
      m_addr = inst_addr.GetLoadAddress(target);
    if (m_addr == LLDB_INVALID_ADDRESS)
      m_addr = inst_addr.GetFileAddress();
  }
  return true;
}

bool EmulateInstruction::GetBestRegisterKindAndNumber(
    const RegisterInfo *reg_info, lldb::RegisterKind &reg_kind,
    uint32_t &reg_num) {
  // Generic and DWARF should be the two most popular register kinds when
  // emulating instructions since they are the most platform agnostic...
  reg_num = reg_info->kinds[eRegisterKindGeneric];
  if (reg_num != LLDB_INVALID_REGNUM) {
    reg_kind = eRegisterKindGeneric;
    return true;
  }

  reg_num = reg_info->kinds[eRegisterKindDWARF];
  if (reg_num != LLDB_INVALID_REGNUM) {
    reg_kind = eRegisterKindDWARF;
    return true;
  }

  reg_num = reg_info->kinds[eRegisterKindLLDB];
  if (reg_num != LLDB_INVALID_REGNUM) {
    reg_kind = eRegisterKindLLDB;
    return true;
  }

  reg_num = reg_info->kinds[eRegisterKindEHFrame];
  if (reg_num != LLDB_INVALID_REGNUM) {
    reg_kind = eRegisterKindEHFrame;
    return true;
  }

  reg_num = reg_info->kinds[eRegisterKindProcessPlugin];
  if (reg_num != LLDB_INVALID_REGNUM) {
    reg_kind = eRegisterKindProcessPlugin;
    return true;
  }
  return false;
}

uint32_t
EmulateInstruction::GetInternalRegisterNumber(RegisterContext *reg_ctx,
                                              const RegisterInfo &reg_info) {
  lldb::RegisterKind reg_kind;
  uint32_t reg_num;
  if (reg_ctx && GetBestRegisterKindAndNumber(&reg_info, reg_kind, reg_num))
    return reg_ctx->ConvertRegisterKindToRegisterNumber(reg_kind, reg_num);
  return LLDB_INVALID_REGNUM;
}

bool EmulateInstruction::CreateFunctionEntryUnwind(UnwindPlan &unwind_plan) {
  unwind_plan.Clear();
  return false;
}
