//===-- RegisterContextThreadMemory.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/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() {}

void RegisterContextThreadMemory::UpdateRegisterContext() {
  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::DataBufferSP &data_sp) {
  UpdateRegisterContext();
  if (m_reg_ctx_sp)
    return m_reg_ctx_sp->ReadAllRegisterValues(data_sp);
  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::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 false;
}

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

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);
  Status error;
  error.SetErrorString("invalid register context");
  return error;
}

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);
  Status error;
  error.SetErrorString("invalid register context");
  return error;
}
