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

#include "lldb/Host/windows/HostThreadWindows.h"
#include "lldb/Host/windows/windows.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/Status.h"
#include "lldb/lldb-private-types.h"

#include "ProcessWindowsLog.h"
#include "RegisterContextWindows.h"
#include "TargetThreadWindows.h"

#include "llvm/ADT/STLExtras.h"
#include "lldb/Target/Target.h"

using namespace lldb;
using namespace lldb_private;

const DWORD kWinContextFlags = CONTEXT_ALL;

// Constructors and Destructors
RegisterContextWindows::RegisterContextWindows(Thread &thread,
                                               uint32_t concrete_frame_idx)
    : RegisterContext(thread, concrete_frame_idx), m_context(),
      m_context_stale(true) {}

RegisterContextWindows::~RegisterContextWindows() {}

void RegisterContextWindows::InvalidateAllRegisters() {
  m_context_stale = true;
}

bool RegisterContextWindows::ReadAllRegisterValues(
    lldb::DataBufferSP &data_sp) {

  if (!CacheAllRegisterValues())
    return false;

  data_sp.reset(new DataBufferHeap(sizeof(CONTEXT), 0));
  memcpy(data_sp->GetBytes(), &m_context, sizeof(m_context));

  return true;
}

bool RegisterContextWindows::WriteAllRegisterValues(
    const lldb::DataBufferSP &data_sp) {
  assert(data_sp->GetByteSize() >= sizeof(m_context));
  memcpy(&m_context, data_sp->GetBytes(), sizeof(m_context));

  return ApplyAllRegisterValues();
}

uint32_t RegisterContextWindows::ConvertRegisterKindToRegisterNumber(
    lldb::RegisterKind kind, uint32_t num) {
  const uint32_t num_regs = GetRegisterCount();

  assert(kind < kNumRegisterKinds);
  for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) {
    const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg_idx);

    if (reg_info->kinds[kind] == num)
      return reg_idx;
  }

  return LLDB_INVALID_REGNUM;
}

bool RegisterContextWindows::HardwareSingleStep(bool enable) { return false; }

bool RegisterContextWindows::AddHardwareBreakpoint(uint32_t slot,
                                                   lldb::addr_t address,
                                                   uint32_t size, bool read,
                                                   bool write) {
  if (slot >= NUM_HARDWARE_BREAKPOINT_SLOTS)
    return false;

  switch (size) {
  case 1:
  case 2:
  case 4:
#if defined(_WIN64)
  case 8:
#endif
    break;
  default:
    return false;
  }

  if (!CacheAllRegisterValues())
    return false;

#if defined(__i386__) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_AMD64)
  unsigned shift = 2 * slot;
  m_context.Dr7 |= 1ULL << shift;

  (&m_context.Dr0)[slot] = address;

  shift = 18 + 4 * slot;
  m_context.Dr7 &= ~(3ULL << shift);
  m_context.Dr7 |= (size == 8 ? 2ULL : size - 1) << shift;

  shift = 16 + 4 * slot;
  m_context.Dr7 &= ~(3ULL << shift);
  m_context.Dr7 |= (read ? 3ULL : (write ? 1ULL : 0)) << shift;

  return ApplyAllRegisterValues();

#else
  Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_REGISTERS);
  LLDB_LOG(log, "hardware breakpoints not currently supported on this arch");
  return false;
#endif
}

bool RegisterContextWindows::RemoveHardwareBreakpoint(uint32_t slot) {
  if (slot >= NUM_HARDWARE_BREAKPOINT_SLOTS)
    return false;

  if (!CacheAllRegisterValues())
    return false;

#if defined(__i386__) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_AMD64)
  unsigned shift = 2 * slot;
  m_context.Dr7 &= ~(1ULL << shift);

  return ApplyAllRegisterValues();
#else
  return false;
#endif
}

uint32_t RegisterContextWindows::GetTriggeredHardwareBreakpointSlotId() {
  if (!CacheAllRegisterValues())
    return LLDB_INVALID_INDEX32;

#if defined(__i386__) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_AMD64)
  for (unsigned i = 0UL; i < NUM_HARDWARE_BREAKPOINT_SLOTS; i++)
    if (m_context.Dr6 & (1ULL << i))
      return i;
#endif

  return LLDB_INVALID_INDEX32;
}

bool RegisterContextWindows::CacheAllRegisterValues() {
  Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_REGISTERS);
  if (!m_context_stale)
    return true;

  TargetThreadWindows &wthread = static_cast<TargetThreadWindows &>(m_thread);
  uint8_t buffer[2048];
  memset(buffer, 0, sizeof(buffer));
  PCONTEXT tmpContext = NULL;
  DWORD contextLength = (DWORD)sizeof(buffer);
  if (!::InitializeContext(buffer, kWinContextFlags, &tmpContext,
                           &contextLength)) {
    return false;
  }
  memcpy(&m_context, tmpContext, sizeof(m_context));
  if (::SuspendThread(
          wthread.GetHostThread().GetNativeThread().GetSystemHandle()) ==
      (DWORD)-1) {
    return false;
  }
  if (!::GetThreadContext(
          wthread.GetHostThread().GetNativeThread().GetSystemHandle(),
          &m_context)) {
    LLDB_LOG(
        log,
        "GetThreadContext failed with error {0} while caching register values.",
        ::GetLastError());
    return false;
  }
  if (::ResumeThread(
          wthread.GetHostThread().GetNativeThread().GetSystemHandle()) ==
      (DWORD)-1) {
    return false;
  }
  LLDB_LOG(log, "successfully updated the register values.");
  m_context_stale = false;
  return true;
}

bool RegisterContextWindows::ApplyAllRegisterValues() {
  TargetThreadWindows &wthread = static_cast<TargetThreadWindows &>(m_thread);
  return ::SetThreadContext(
      wthread.GetHostThread().GetNativeThread().GetSystemHandle(), &m_context);
}
