//===-- RegisterContextWindows.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/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() = default;

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

bool RegisterContextWindows::ReadAllRegisterValues(
    lldb::WritableDataBufferSP &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 = GetLog(WindowsLog::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 = GetLog(WindowsLog::Registers);
  if (!m_context_stale)
    return true;

  TargetThreadWindows &wthread = static_cast<TargetThreadWindows &>(m_thread);
  memset(&m_context, 0, sizeof(m_context));
  m_context.ContextFlags = kWinContextFlags;
  if (::SuspendThread(
          wthread.GetHostThread().GetNativeThread().GetSystemHandle()) ==
      static_cast<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()) ==
      static_cast<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);
}
