//===-- 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/Host/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 "llvm/Support/ErrorExtras.h"

#include <cstring>
#include <memory>
#include <optional>

#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 (auto create_callback :
         PluginManager::GetEmulateInstructionCreateCallbacks()) {
      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) {}

std::optional<RegisterValue>
EmulateInstruction::ReadRegister(const RegisterInfo &reg_info) {
  if (m_read_reg_callback == nullptr)
    return {};

  RegisterValue reg_value;
  bool success = m_read_reg_callback(this, m_baton, &reg_info, reg_value);
  if (success)
    return reg_value;
  return {};
}

bool EmulateInstruction::ReadRegister(lldb::RegisterKind reg_kind,
                                      uint32_t reg_num,
                                      RegisterValue &reg_value) {
  std::optional<RegisterInfo> reg_info = GetRegisterInfo(reg_kind, reg_num);
  if (!reg_info)
    return false;

  std::optional<RegisterValue> value = ReadRegister(*reg_info);
  if (value)
    reg_value = *value;
  return value.has_value();
}

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) {
  std::optional<RegisterValue> reg_value = ReadRegister(reg_info);
  if (!reg_value) {
    if (success_ptr)
      *success_ptr = false;
    return fail_value;
  }

  return reg_value->GetAsUInt64(fail_value, success_ptr);
}

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) {
  std::optional<RegisterInfo> reg_info = GetRegisterInfo(reg_kind, reg_num);
  if (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) {
  std::optional<RegisterInfo> reg_info = GetRegisterInfo(reg_kind, reg_num);
  if (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) {
  RegisterValue reg_value;
  if (reg_value.SetUInt(uint_value, reg_info.byte_size))
    return WriteRegister(context, reg_info, reg_value);
  return false;
}

bool 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, 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 (GetInfoType()) {
  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;
}

std::unique_ptr<SingleStepBreakpointLocationsPredictor>
EmulateInstruction::CreateBreakpointLocationPredictor(
    std::unique_ptr<EmulateInstruction> emulator_up) {
  auto creator =
      emulator_up->GetSingleStepBreakpointLocationsPredictorCreator();
  return creator(std::move(emulator_up));
}

std::optional<lldb::addr_t> EmulateInstruction::ReadPC() {
  bool success = false;
  auto addr = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC,
                                   LLDB_INVALID_ADDRESS, &success);
  return success ? std::optional<addr_t>(addr) : std::nullopt;
}

bool EmulateInstruction::WritePC(lldb::addr_t addr) {
  EmulateInstruction::Context ctx;
  ctx.type = eContextAdvancePC;
  ctx.SetNoArgs();
  return WriteRegisterUnsigned(ctx, eRegisterKindGeneric,
                               LLDB_REGNUM_GENERIC_PC, addr);
}

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

llvm::Expected<BreakpointLocations>
SingleStepBreakpointLocationsPredictor::GetBreakpointLocations() {
  if (!m_emulator_up->ReadInstruction()) {
    // try to get at least the size of next instruction to set breakpoint.
    llvm::Expected<addr_t> next_pc = GetNextInstructionAddress();
    if (next_pc)
      return BreakpointLocations{*next_pc};
    return next_pc.takeError();
  }

  std::optional<addr_t> entry_pc = m_emulator_up->ReadPC();
  if (!entry_pc)
    return llvm::createStringError("Can't read PC");

  m_emulation_result = m_emulator_up->EvaluateInstruction(
      eEmulateInstructionOptionAutoAdvancePC);

  llvm::Expected<addr_t> next_pc = GetBreakpointLocationAddress(*entry_pc);
  if (next_pc)
    return BreakpointLocations{*next_pc};
  return next_pc.takeError();
}

llvm::Expected<addr_t>
SingleStepBreakpointLocationsPredictor::GetNextInstructionAddress() {
  std::optional<uint32_t> instr_size = m_emulator_up->GetLastInstrSize();
  if (!instr_size)
    return llvm::createStringError("Read instruction failed!");

  std::optional<addr_t> pc = m_emulator_up->ReadPC();
  if (!pc)
    return llvm::createStringError("Can't read PC");

  lldb::addr_t next_pc = *pc + *instr_size;
  return next_pc;
}

llvm::Expected<addr_t>
SingleStepBreakpointLocationsPredictor::GetBreakpointLocationAddress(
    lldb::addr_t entry_pc) {
  std::optional<addr_t> addr = m_emulator_up->ReadPC();
  if (!addr)
    return llvm::createStringError("Can't read PC");
  lldb::addr_t pc = *addr;

  if (m_emulation_result) {
    assert(entry_pc != pc && "Emulation was successfull but PC wasn't updated");
    return pc;
  }

  if (entry_pc == pc) {
    // Emulate instruction failed and it hasn't changed PC. Advance PC with
    // the size of the current opcode because the emulation of all
    // PC modifying instruction should be successful. The failure most
    // likely caused by an unsupported instruction which does not modify PC.
    return pc + m_emulator_up->GetOpcode().GetByteSize();
  }

  // The instruction emulation failed after it modified the PC. It is an
  // unknown error where we can't continue because the next instruction is
  // modifying the PC but we don't  know how.
  return llvm::createStringError("Instruction emulation failed unexpectedly.");
}
