// 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_x64_helpers.h"

#include <vector>

#include "garnet/bin/debug_agent/arch.h"
#include "lib/fxl/logging.h"

namespace debug_agent {
namespace arch {

namespace {

struct DebugRegMask {
  int index = -1;
  uint64_t bp_mask = 0;   // Enable mask within DR7
  uint64_t rw_mask = 0;   // RW mask within DR7
  uint64_t len_mask = 0;  // LEN mask within DR7
};

const DebugRegMask* GetDebugRegisterMasks(size_t index) {
  static std::vector<DebugRegMask> masks = {
      {0, kDR7L0, kDR7RW0 | (kDR7RW0 << 1), kDR7LEN0 | (kDR7LEN0 << 1)},
      {1, kDR7L1, kDR7RW1 | (kDR7RW1 << 1), kDR7LEN1 | (kDR7LEN1 << 1)},
      {2, kDR7L2, kDR7RW2 | (kDR7RW2 << 1), kDR7LEN2 | (kDR7LEN2 << 1)},
      {3, kDR7L3, kDR7RW3 | (kDR7RW3 << 1), kDR7LEN3 | (kDR7LEN3 << 1)},
  };
  FXL_DCHECK(index < masks.size());
  return &masks[index];
}

}  // namespace

zx_status_t SetupHWBreakpoint(uint64_t address,
                                 zx_thread_state_debug_regs_t* debug_regs) {
  // Search for an unset register.
  // TODO(donosoc): This doesn't check that the address is already set.
  const DebugRegMask* slot = nullptr;
  for (size_t i = 0; i < 4; i++) {
    const DebugRegMask* mask = GetDebugRegisterMasks(i);
    // If it's the same address or it's free, we found our slot.
    bool active = FLAG_VALUE(debug_regs->dr7, mask->bp_mask);
    if (debug_regs->dr[i] == address || !active) {
      slot = mask;
      break;
    }
  }

  if (!slot)
    return ZX_ERR_NO_RESOURCES;

  debug_regs->dr[slot->index] = address;
  // Modify the DR7 register.
  // TODO(donosoc): For now only add execution breakpoints.
  uint64_t dr7 = debug_regs->dr7;
  dr7 |= slot->bp_mask;  // Activate the breakpoint.
  uint64_t mask = ~(slot->rw_mask);
  // TODO(donosoc): Handle LEN properties of the breakpoint.
  dr7 &= mask;
  debug_regs->dr7 = dr7;

  return ZX_OK;
}

zx_status_t RemoveHWBreakpoint(uint64_t address,
                                  zx_thread_state_debug_regs_t* debug_regs) {
  // Search for the address.
  bool found = false;
  for (size_t i = 0; i < 4; i++) {
    if (address != debug_regs->dr[i])
      continue;

    const DebugRegMask* mask = GetDebugRegisterMasks(i);
    // Only unset the
    uint64_t dr7 = debug_regs->dr7;
    dr7 &= ~(mask->bp_mask);  // Disable the breakpoint.

    debug_regs->dr[i] = 0;
    debug_regs->dr7 = dr7;

    found = true;
  }

  // No register found, we warn the caller. No change was issued.
  if (!found)
    return ZX_ERR_OUT_OF_RANGE;

  return ZX_OK;
}

zx_status_t WriteGeneralRegisters(const std::vector<debug_ipc::Register>& regs,
                                  zx_thread_state_general_regs_t* gen_regs) {
  uint32_t begin = static_cast<uint32_t>(debug_ipc::RegisterID::kX64_rax);
  uint32_t end = static_cast<uint32_t>(debug_ipc::RegisterID::kX64_rflags);
  for (const debug_ipc::Register& reg : regs) {
    if (reg.data.size() != 8)
      return ZX_ERR_INVALID_ARGS;

    // zx_thread_state_general_regs has the same layout as the RegisterID enum
    // for x64 general registers.
    uint32_t id = static_cast<uint32_t>(reg.id);
    if (id > end)
      return ZX_ERR_INVALID_ARGS;

    // Insert the value to the correct offset.
    uint32_t offset = id - begin;
    uint64_t* reg_ptr = reinterpret_cast<uint64_t*>(gen_regs);
    reg_ptr += offset;
    *reg_ptr = *reinterpret_cast<const uint64_t*>(reg.data.data());
  }

  return ZX_OK;
}

// Debug functions -------------------------------------------------------------

void PrintGeneralRegisters(const zx_thread_state_general_regs& regs) {
  FXL_LOG(INFO) << "General regs: " << std::endl
                << "rax: 0x" << std::hex << regs.rax << std::endl
                << "rbx: 0x" << std::hex << regs.rbx << std::endl
                << "rcx: 0x" << std::hex << regs.rcx << std::endl
                << "rdx: 0x" << std::hex << regs.rdx << std::endl
                << "rsi: 0x" << std::hex << regs.rsi << std::endl
                << "rdi: 0x" << std::hex << regs.rdi << std::endl
                << "rbp: 0x" << std::hex << regs.rbp << std::endl
                << "rsp: 0x" << std::hex << regs.rsp << std::endl
                << "r8: 0x" << std::hex << regs.r8 << std::endl
                << "r9: 0x" << std::hex << regs.r9 << std::endl
                << "r10: 0x" << std::hex << regs.r10 << std::endl
                << "r11: 0x" << std::hex << regs.r11 << std::endl
                << "r12: 0x" << std::hex << regs.r12 << std::endl
                << "r13: 0x" << std::hex << regs.r13 << std::endl
                << "r14: 0x" << std::hex << regs.r14 << std::endl
                << "r15: 0x" << std::hex << regs.r15 << std::endl
                << "rip: 0x" << std::hex << regs.rip << std::endl
                << "rflags: 0x" << std::hex << regs.rflags;
}

void PrintDebugRegisters(const zx_thread_state_debug_regs_t& regs) {
  FXL_LOG(INFO) << "Regs: " << std::endl
                << "DR0: 0x" << std::hex << regs.dr[0] << std::endl
                << "DR1: 0x" << std::hex << regs.dr[1] << std::endl
                << "DR2: 0x" << std::hex << regs.dr[2] << std::endl
                << "DR3: 0x" << std::hex << regs.dr[3] << std::endl
                << "DR6: 0x" << std::hex << regs.dr6 << std::endl
                << "DR7: 0x" << std::hex << regs.dr7 << std::endl;
}

}  // namespace arch
}  // namespace debug_agent
