// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "garnet/bin/debug_agent/arch.h"

#include <zircon/syscalls/exception.h>

#include "garnet/bin/debug_agent/arch_x64_helpers.h"
#include "garnet/bin/debug_agent/debugged_thread.h"
#include "garnet/lib/debug_ipc/register_desc.h"
#include "lib/fxl/logging.h"

namespace debug_agent {
namespace arch {

const BreakInstructionType kBreakInstruction = 0xCC;

uint64_t ArchProvider::BreakpointInstructionForSoftwareExceptionAddress(
    uint64_t exception_addr) {
  // An X86 exception is 1 byte and a breakpoint exception is triggered with
  // RIP pointing to the following instruction.
  return exception_addr - 1;
}

uint64_t ArchProvider::NextInstructionForSoftwareExceptionAddress(
    uint64_t exception_addr) {
  // Exception address is the one following the instruction that caused it,
  // so nothing needs to be done.
  return exception_addr;
}

bool ArchProvider::IsBreakpointInstruction(zx::process& process,
                                           uint64_t address) {
  uint8_t data;
  size_t actual_read = 0;
  if (process.read_memory(address, &data, 1, &actual_read) != ZX_OK ||
      actual_read != 1)
    return false;

  // This handles the normal encoding of debug breakpoints (0xCC). It's also
  // possible to cause an interrupt 3 to happen using the opcode sequence
  // 0xCD 0x03 but this has slightly different semantics and no assemblers emit
  // this. We can't easily check for that here since the computation for the
  // instruction address that is passed in assumes a 1-byte instruction. It
  // should be OK to ignore this case in practice.
  return data == kBreakInstruction;
}

uint64_t* ArchProvider::IPInRegs(zx_thread_state_general_regs* regs) {
  return &regs->rip;
}
uint64_t* ArchProvider::SPInRegs(zx_thread_state_general_regs* regs) {
  return &regs->rsp;
}
uint64_t* ArchProvider::BPInRegs(zx_thread_state_general_regs* regs) {
  return &regs->rbp;
}

::debug_ipc::Arch ArchProvider::GetArch() { return ::debug_ipc::Arch::kX64; }

namespace {

using debug_ipc::RegisterID;

inline debug_ipc::Register CreateRegister(RegisterID id, uint32_t length,
                                          const void* val_ptr) {
  debug_ipc::Register reg;
  reg.id = id;
  const uint8_t* ptr = reinterpret_cast<const uint8_t*>(val_ptr);
  reg.data.assign(ptr, ptr + length);
  return reg;
}

inline zx_status_t ReadGeneralRegs(const zx::thread& thread,
                                   std::vector<debug_ipc::Register>* out) {
  // We get the general state registers.
  zx_thread_state_general_regs gen_regs;
  zx_status_t status = thread.read_state(ZX_THREAD_STATE_GENERAL_REGS,
                                         &gen_regs, sizeof(gen_regs));
  if (status != ZX_OK)
    return status;

  out->push_back(CreateRegister(RegisterID::kX64_rax, 8u, &gen_regs.rax));
  out->push_back(CreateRegister(RegisterID::kX64_rbx, 8u, &gen_regs.rbx));
  out->push_back(CreateRegister(RegisterID::kX64_rcx, 8u, &gen_regs.rcx));
  out->push_back(CreateRegister(RegisterID::kX64_rdx, 8u, &gen_regs.rdx));
  out->push_back(CreateRegister(RegisterID::kX64_rsi, 8u, &gen_regs.rsi));
  out->push_back(CreateRegister(RegisterID::kX64_rdi, 8u, &gen_regs.rdi));
  out->push_back(CreateRegister(RegisterID::kX64_rbp, 8u, &gen_regs.rbp));
  out->push_back(CreateRegister(RegisterID::kX64_rsp, 8u, &gen_regs.rsp));
  out->push_back(CreateRegister(RegisterID::kX64_r8, 8u, &gen_regs.r8));
  out->push_back(CreateRegister(RegisterID::kX64_r9, 8u, &gen_regs.r9));
  out->push_back(CreateRegister(RegisterID::kX64_r10, 8u, &gen_regs.r10));
  out->push_back(CreateRegister(RegisterID::kX64_r11, 8u, &gen_regs.r11));
  out->push_back(CreateRegister(RegisterID::kX64_r12, 8u, &gen_regs.r12));
  out->push_back(CreateRegister(RegisterID::kX64_r13, 8u, &gen_regs.r13));
  out->push_back(CreateRegister(RegisterID::kX64_r14, 8u, &gen_regs.r14));
  out->push_back(CreateRegister(RegisterID::kX64_r15, 8u, &gen_regs.r15));
  out->push_back(CreateRegister(RegisterID::kX64_rip, 8u, &gen_regs.rip));
  out->push_back(CreateRegister(RegisterID::kX64_rflags, 8u, &gen_regs.rflags));

  return ZX_OK;
}

inline zx_status_t ReadFPRegs(const zx::thread& thread,
                              std::vector<debug_ipc::Register>* out) {
  zx_thread_state_fp_regs fp_regs;
  zx_status_t status =
      thread.read_state(ZX_THREAD_STATE_FP_REGS, &fp_regs, sizeof(fp_regs));
  if (status != ZX_OK)
    return status;

  out->push_back(CreateRegister(RegisterID::kX64_fcw, 2u, &fp_regs.fcw));
  out->push_back(CreateRegister(RegisterID::kX64_fsw, 2u, &fp_regs.fsw));
  out->push_back(CreateRegister(RegisterID::kX64_ftw, 2u, &fp_regs.ftw));
  out->push_back(CreateRegister(RegisterID::kX64_fop, 2u, &fp_regs.fop));
  out->push_back(CreateRegister(RegisterID::kX64_fip, 2u, &fp_regs.fip));
  out->push_back(CreateRegister(RegisterID::kX64_fdp, 2u, &fp_regs.fdp));

  // Each entry is 16 bytes long, but only 10 are actually used.
  out->push_back(CreateRegister(RegisterID::kX64_st0, 16u, &fp_regs.st[0]));
  out->push_back(CreateRegister(RegisterID::kX64_st1, 16u, &fp_regs.st[1]));
  out->push_back(CreateRegister(RegisterID::kX64_st2, 16u, &fp_regs.st[2]));
  out->push_back(CreateRegister(RegisterID::kX64_st3, 16u, &fp_regs.st[3]));
  out->push_back(CreateRegister(RegisterID::kX64_st4, 16u, &fp_regs.st[4]));
  out->push_back(CreateRegister(RegisterID::kX64_st5, 16u, &fp_regs.st[5]));
  out->push_back(CreateRegister(RegisterID::kX64_st6, 16u, &fp_regs.st[6]));
  out->push_back(CreateRegister(RegisterID::kX64_st7, 16u, &fp_regs.st[7]));

  return ZX_OK;
}

inline zx_status_t ReadVectorRegs(const zx::thread& thread,
                                  std::vector<debug_ipc::Register>* out) {
  zx_thread_state_vector_regs vec_regs;
  zx_status_t status = thread.read_state(ZX_THREAD_STATE_VECTOR_REGS, &vec_regs,
                                         sizeof(vec_regs));
  if (status != ZX_OK)
    return status;

  out->push_back(CreateRegister(RegisterID::kX64_mxcsr, 4u, &vec_regs.mxcsr));

  // TODO(donosoc): For now there is no support of AVX-512 within zircon,
  //                so we're not sending over that data, only AVX.
  //                Enable it when AVX-512 is done.
  auto base = static_cast<uint32_t>(RegisterID::kX64_ymm0);
  for (size_t i = 0; i < 16; i++) {
    auto reg_id = static_cast<RegisterID>(base + i);
    out->push_back(CreateRegister(reg_id, 32u, &vec_regs.zmm[i]));
  }

  return ZX_OK;
}

// TODO: Enable this when the zircon patch for debug registers lands.

inline zx_status_t ReadDebugRegs(const zx::thread& thread,
                                 std::vector<debug_ipc::Register>* out) {
  zx_thread_state_debug_regs_t debug_regs;
  zx_status_t status = thread.read_state(ZX_THREAD_STATE_DEBUG_REGS,
                                         &debug_regs, sizeof(debug_regs));
  if (status != ZX_OK)
    return status;

  out->push_back(CreateRegister(RegisterID::kX64_dr0, 8u, &debug_regs.dr[0]));
  out->push_back(CreateRegister(RegisterID::kX64_dr1, 8u, &debug_regs.dr[1]));
  out->push_back(CreateRegister(RegisterID::kX64_dr2, 8u, &debug_regs.dr[2]));
  out->push_back(CreateRegister(RegisterID::kX64_dr3, 8u, &debug_regs.dr[3]));
  out->push_back(CreateRegister(RegisterID::kX64_dr6, 8u, &debug_regs.dr6));
  out->push_back(CreateRegister(RegisterID::kX64_dr7, 8u, &debug_regs.dr7));

  return ZX_OK;
}

}  // namespace

zx_status_t ArchProvider::ReadRegisters(
    const debug_ipc::RegisterCategory::Type& cat, const zx::thread& thread,
    std::vector<debug_ipc::Register>* out) {
  switch (cat) {
    case debug_ipc::RegisterCategory::Type::kGeneral:
      return ReadGeneralRegs(thread, out);
    case debug_ipc::RegisterCategory::Type::kFP:
      return ReadFPRegs(thread, out);
    case debug_ipc::RegisterCategory::Type::kVector:
      return ReadVectorRegs(thread, out);
    case debug_ipc::RegisterCategory::Type::kDebug:
      return ReadDebugRegs(thread, out);
    case debug_ipc::RegisterCategory::Type::kNone:
      FXL_LOG(ERROR) << "Asking to get none category";
      return ZX_ERR_INVALID_ARGS;
  }
}

zx_status_t ArchProvider::WriteRegisters(const debug_ipc::RegisterCategory& cat,
                                         zx::thread* thread) {
  switch (cat.type) {
    case debug_ipc::RegisterCategory::Type::kGeneral: {
      zx_thread_state_general_regs_t regs;
      zx_status_t res =
          thread->read_state(ZX_THREAD_STATE_GENERAL_REGS, &regs, sizeof(regs));
      if (res != ZX_OK)
        return res;

      // Ovewrite the values.
      res = WriteGeneralRegisters(cat.registers, &regs);
      if (res != ZX_OK)
        return res;

      return thread->write_state(ZX_THREAD_STATE_GENERAL_REGS, &regs,
                                 sizeof(regs));
    }
    case debug_ipc::RegisterCategory::Type::kFP:
    case debug_ipc::RegisterCategory::Type::kVector:
    case debug_ipc::RegisterCategory::Type::kDebug:
      return ZX_ERR_NOT_SUPPORTED;
    case debug_ipc::RegisterCategory::Type::kNone:
      break;
  }
  FXL_NOTREACHED();
  return ZX_ERR_INVALID_ARGS;
}

// Hardware Exceptions ---------------------------------------------------------

uint64_t ArchProvider::BreakpointInstructionForHardwareExceptionAddress(
    uint64_t exception_addr) {
  // x86 returns the instruction *about* to be executed when hitting the hw
  // breakpoint.
  return exception_addr;
}

uint64_t ArchProvider::NextInstructionForHardwareExceptionAddress(
    uint64_t exception_addr) {
  // Exception address is the one following the instruction that caused it,
  // so nothing needs to be done.
  return exception_addr;
}

debug_ipc::NotifyException::Type ArchProvider::DecodeExceptionType(
    const DebuggedThread& thread, uint32_t exception_type) {
  if (exception_type == ZX_EXCP_SW_BREAKPOINT) {
    return debug_ipc::NotifyException::Type::kSoftware;
  } else if (exception_type == ZX_EXCP_HW_BREAKPOINT) {
    zx_thread_state_debug_regs_t debug_regs;
    zx_status_t status = thread.thread().read_state(
        ZX_THREAD_STATE_DEBUG_REGS, &debug_regs, sizeof(debug_regs));

    // Assume single step when in doubt.
    if (status != ZX_OK) {
      FXL_LOG(WARNING) << "Could not access debug registers for thread "
                       << thread.koid();
      return debug_ipc::NotifyException::Type::kSingleStep;
    }

    if (FLAG_VALUE(debug_regs.dr6, kDR6BS)) {
      return debug_ipc::NotifyException::Type::kSingleStep;
    } else if (FLAG_VALUE(debug_regs.dr6, kDR6B0) ||
               FLAG_VALUE(debug_regs.dr6, kDR6B1) ||
               FLAG_VALUE(debug_regs.dr6, kDR6B2) ||
               FLAG_VALUE(debug_regs.dr6, kDR6B3)) {
      return debug_ipc::NotifyException::Type::kHardware;
    } else {
      FXL_NOTREACHED() << "x86: No known hw exception set in DR6";
    }
    return debug_ipc::NotifyException::Type::kSingleStep;
  } else {
    return debug_ipc::NotifyException::Type::kGeneral;
  }
}

zx_status_t ArchProvider::InstallHWBreakpoint(zx::thread* thread,
                                              uint64_t address) {
  // TODO(donosoc): Will assume the thread is stopped. In order to make the
  //                installation robust, we need to stop the thread (if it's not
  //                currently stopped) and them resume it after the breakpoint
  //                is installed.
  zx_thread_state_debug_regs_t debug_regs;
  zx_status_t status = thread->read_state(ZX_THREAD_STATE_DEBUG_REGS,
                                          &debug_regs, sizeof(debug_regs));
  if (status != ZX_OK)
    return status;

  status = SetupHWBreakpoint(address, &debug_regs);
  if (status != ZX_OK)
    return status;

  return thread->write_state(ZX_THREAD_STATE_DEBUG_REGS, &debug_regs,
                             sizeof(debug_regs));
}

zx_status_t ArchProvider::UninstallHWBreakpoint(zx::thread* thread,
                                                uint64_t address) {
  zx_thread_state_debug_regs_t debug_regs;
  zx_status_t status = thread->read_state(ZX_THREAD_STATE_DEBUG_REGS,
                                          &debug_regs, sizeof(debug_regs));
  if (status != ZX_OK)
    return status;

  status = RemoveHWBreakpoint(address, &debug_regs);
  if (status != ZX_OK)
    return status;

  return thread->write_state(ZX_THREAD_STATE_DEBUG_REGS, &debug_regs,
                             sizeof(debug_regs));
}

zx_status_t ArchProvider::InstallWatchpoint(zx::thread*,
                                            const debug_ipc::AddressRange&) {
  FXL_NOTIMPLEMENTED();
  return ZX_OK;
}

zx_status_t ArchProvider::UninstallWatchpoint(zx::thread*,
                                              const debug_ipc::AddressRange&) {
  FXL_NOTIMPLEMENTED();
  return ZX_OK;
}

}  // namespace arch
}  // namespace debug_agent
