//===-- RegisterContextThreadMemory.cpp -------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "lldb/lldb-private.h"
#include "lldb/Core/Error.h"
#include "lldb/Target/OperatingSystem.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Thread.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(), LLDB_INVALID_ADDRESS);
                }                
            }
        }
    }
    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 NULL;
}

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 NULL;
}

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 (uint32_t 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;
}

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

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