//===-- 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();
        }
    }
    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;
}
