//===-- RegisterContextThreadMemory.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/Target/OperatingSystem.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/Status.h"
#include "lldb/lldb-private.h"

#include "RegisterContextThreadMemory.h"

using namespace lldb;
using namespace lldb_private;

RegisterContextThreadMemory::RegisterContextThreadMemory(
    Thread &thread, lldb::addr_t register_data_addr)
    : RegisterContext(thread, 0), m_thread_wp(thread.shared_from_this()),
      m_reg_ctx_sp(), m_register_data_addr(register_data_addr), m_stop_id(0) {}

RegisterContextThreadMemory::~RegisterContextThreadMemory() = default;

void RegisterContextThreadMemory::UpdateRegisterContext() {
  std::lock_guard<std::mutex> lock(m_update_register_ctx_lock);

  ThreadSP thread_sp(m_thread_wp.lock());
  if (thread_sp) {
    ProcessSP process_sp(thread_sp->GetProcess());

    if (process_sp) {
      const uint32_t stop_id = process_sp->GetModID().GetStopID();
      if (m_stop_id != stop_id) {
        m_stop_id = stop_id;
        m_reg_ctx_sp.reset();
      }
      if (!m_reg_ctx_sp) {
        ThreadSP backing_thread_sp(thread_sp->GetBackingThread());
        if (backing_thread_sp) {
          m_reg_ctx_sp = backing_thread_sp->GetRegisterContext();
        } else {
          OperatingSystem *os = process_sp->GetOperatingSystem();
          if (os->IsOperatingSystemPluginThread(thread_sp))
            m_reg_ctx_sp = os->CreateRegisterContextForThread(
                thread_sp.get(), m_register_data_addr);
        }
      }
    } else {
      m_reg_ctx_sp.reset();
    }
  } else {
    m_reg_ctx_sp.reset();
  }
}

// Subclasses must override these functions
void RegisterContextThreadMemory::InvalidateAllRegisters() {
  UpdateRegisterContext();
  if (m_reg_ctx_sp)
    m_reg_ctx_sp->InvalidateAllRegisters();
}

size_t RegisterContextThreadMemory::GetRegisterCount() {
  UpdateRegisterContext();
  if (m_reg_ctx_sp)
    return m_reg_ctx_sp->GetRegisterCount();
  return 0;
}

const RegisterInfo *
RegisterContextThreadMemory::GetRegisterInfoAtIndex(size_t reg) {
  UpdateRegisterContext();
  if (m_reg_ctx_sp)
    return m_reg_ctx_sp->GetRegisterInfoAtIndex(reg);
  return nullptr;
}

size_t RegisterContextThreadMemory::GetRegisterSetCount() {
  UpdateRegisterContext();
  if (m_reg_ctx_sp)
    return m_reg_ctx_sp->GetRegisterSetCount();
  return 0;
}

const RegisterSet *RegisterContextThreadMemory::GetRegisterSet(size_t reg_set) {
  UpdateRegisterContext();
  if (m_reg_ctx_sp)
    return m_reg_ctx_sp->GetRegisterSet(reg_set);
  return nullptr;
}

bool RegisterContextThreadMemory::ReadRegister(const RegisterInfo *reg_info,
                                               RegisterValue &reg_value) {
  UpdateRegisterContext();
  if (m_reg_ctx_sp)
    return m_reg_ctx_sp->ReadRegister(reg_info, reg_value);
  return false;
}

bool RegisterContextThreadMemory::WriteRegister(
    const RegisterInfo *reg_info, const RegisterValue &reg_value) {
  UpdateRegisterContext();
  if (m_reg_ctx_sp)
    return m_reg_ctx_sp->WriteRegister(reg_info, reg_value);
  return false;
}

bool RegisterContextThreadMemory::ReadAllRegisterValues(
    lldb::WritableDataBufferSP &data_sp) {
  UpdateRegisterContext();
  if (m_reg_ctx_sp)
    return m_reg_ctx_sp->ReadAllRegisterValues(data_sp);
  return false;
}

bool RegisterContextThreadMemory::ReadAllRegisterValues(
    lldb_private::RegisterCheckpoint &reg_checkpoint) {
  UpdateRegisterContext();
  if (m_reg_ctx_sp)
    return m_reg_ctx_sp->ReadAllRegisterValues(reg_checkpoint);
  return false;
}

bool RegisterContextThreadMemory::WriteAllRegisterValues(
    const lldb::DataBufferSP &data_sp) {
  UpdateRegisterContext();
  if (m_reg_ctx_sp)
    return m_reg_ctx_sp->WriteAllRegisterValues(data_sp);
  return false;
}

bool RegisterContextThreadMemory::WriteAllRegisterValues(
    const lldb_private::RegisterCheckpoint &reg_checkpoint) {
  UpdateRegisterContext();
  if (m_reg_ctx_sp)
    return m_reg_ctx_sp->WriteAllRegisterValues(reg_checkpoint);
  return false;
}

bool RegisterContextThreadMemory::CopyFromRegisterContext(
    lldb::RegisterContextSP reg_ctx_sp) {
  UpdateRegisterContext();
  if (m_reg_ctx_sp)
    return m_reg_ctx_sp->CopyFromRegisterContext(reg_ctx_sp);
  return false;
}

uint32_t RegisterContextThreadMemory::ConvertRegisterKindToRegisterNumber(
    lldb::RegisterKind kind, uint32_t num) {
  UpdateRegisterContext();
  if (m_reg_ctx_sp)
    return m_reg_ctx_sp->ConvertRegisterKindToRegisterNumber(kind, num);
  return LLDB_INVALID_REGNUM;
}

uint32_t RegisterContextThreadMemory::NumSupportedHardwareBreakpoints() {
  UpdateRegisterContext();
  if (m_reg_ctx_sp)
    return m_reg_ctx_sp->NumSupportedHardwareBreakpoints();
  return 0;
}

uint32_t RegisterContextThreadMemory::SetHardwareBreakpoint(lldb::addr_t addr,
                                                            size_t size) {
  UpdateRegisterContext();
  if (m_reg_ctx_sp)
    return m_reg_ctx_sp->SetHardwareBreakpoint(addr, size);
  return 0;
}

bool RegisterContextThreadMemory::ClearHardwareBreakpoint(uint32_t hw_idx) {
  UpdateRegisterContext();
  if (m_reg_ctx_sp)
    return m_reg_ctx_sp->ClearHardwareBreakpoint(hw_idx);
  return false;
}

uint32_t RegisterContextThreadMemory::NumSupportedHardwareWatchpoints() {
  UpdateRegisterContext();
  if (m_reg_ctx_sp)
    return m_reg_ctx_sp->NumSupportedHardwareWatchpoints();
  return 0;
}

uint32_t RegisterContextThreadMemory::SetHardwareWatchpoint(lldb::addr_t addr,
                                                            size_t size,
                                                            bool read,
                                                            bool write) {
  UpdateRegisterContext();
  if (m_reg_ctx_sp)
    return m_reg_ctx_sp->SetHardwareWatchpoint(addr, size, read, write);
  return 0;
}

bool RegisterContextThreadMemory::ClearHardwareWatchpoint(uint32_t hw_index) {
  UpdateRegisterContext();
  if (m_reg_ctx_sp)
    return m_reg_ctx_sp->ClearHardwareWatchpoint(hw_index);
  return false;
}

bool RegisterContextThreadMemory::HardwareSingleStep(bool enable) {
  UpdateRegisterContext();
  if (m_reg_ctx_sp)
    return m_reg_ctx_sp->HardwareSingleStep(enable);
  return false;
}

Status RegisterContextThreadMemory::ReadRegisterValueFromMemory(
    const lldb_private::RegisterInfo *reg_info, lldb::addr_t src_addr,
    uint32_t src_len, RegisterValue &reg_value) {
  UpdateRegisterContext();
  if (m_reg_ctx_sp)
    return m_reg_ctx_sp->ReadRegisterValueFromMemory(reg_info, src_addr,
                                                     src_len, reg_value);
  return Status::FromErrorString("invalid register context");
}

Status RegisterContextThreadMemory::WriteRegisterValueToMemory(
    const lldb_private::RegisterInfo *reg_info, lldb::addr_t dst_addr,
    uint32_t dst_len, const RegisterValue &reg_value) {
  UpdateRegisterContext();
  if (m_reg_ctx_sp)
    return m_reg_ctx_sp->WriteRegisterValueToMemory(reg_info, dst_addr, dst_len,
                                                    reg_value);
  return Status::FromErrorString("invalid register context");
}
