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

#include "RegisterContextMemory.h"

// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "DynamicRegisterInfo.h"
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Thread.h"

using namespace lldb;
using namespace lldb_private;

//----------------------------------------------------------------------
// RegisterContextMemory constructor
//----------------------------------------------------------------------
RegisterContextMemory::RegisterContextMemory
(
    Thread &thread,
    uint32_t concrete_frame_idx,
    DynamicRegisterInfo &reg_infos,
    addr_t reg_data_addr
) :
    RegisterContext (thread, concrete_frame_idx),
    m_reg_infos (reg_infos),
    m_reg_valid (),
    m_reg_data (),
    m_reg_data_addr (reg_data_addr)
{
    // Resize our vector of bools to contain one bool for every register.
    // We will use these boolean values to know when a register value
    // is valid in m_reg_data.
    const size_t num_regs = reg_infos.GetNumRegisters();
    assert (num_regs > 0);
    m_reg_valid.resize (num_regs);

    // Make a heap based buffer that is big enough to store all registers
    DataBufferSP reg_data_sp(new DataBufferHeap (reg_infos.GetRegisterDataByteSize(), 0));
    m_reg_data.SetData (reg_data_sp);
}

//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
RegisterContextMemory::~RegisterContextMemory()
{
}

void
RegisterContextMemory::InvalidateAllRegisters ()
{
    if (m_reg_data_addr != LLDB_INVALID_ADDRESS)
        SetAllRegisterValid (false);
}

void
RegisterContextMemory::SetAllRegisterValid (bool b)
{
    std::vector<bool>::iterator pos, end = m_reg_valid.end();
    for (pos = m_reg_valid.begin(); pos != end; ++pos)
        *pos = b;
}

size_t
RegisterContextMemory::GetRegisterCount ()
{
    return m_reg_infos.GetNumRegisters ();
}

const RegisterInfo *
RegisterContextMemory::GetRegisterInfoAtIndex (size_t reg)
{
    return m_reg_infos.GetRegisterInfoAtIndex (reg);
}

size_t
RegisterContextMemory::GetRegisterSetCount ()
{
    return m_reg_infos.GetNumRegisterSets ();
}

const RegisterSet *
RegisterContextMemory::GetRegisterSet (size_t reg_set)
{
    return m_reg_infos.GetRegisterSet (reg_set);
}

uint32_t
RegisterContextMemory::ConvertRegisterKindToRegisterNumber (lldb::RegisterKind kind, uint32_t num)
{
    return m_reg_infos.ConvertRegisterKindToRegisterNumber (kind, num);
}

bool
RegisterContextMemory::ReadRegister (const RegisterInfo *reg_info, RegisterValue &reg_value)
{
    const uint32_t reg_num = reg_info->kinds[eRegisterKindLLDB];
    if (!m_reg_valid[reg_num])
    {                         
        if (!ReadAllRegisterValues(m_reg_data.GetSharedDataBuffer ()))
            return false;
    }
    const bool partial_data_ok = false;
    return reg_value.SetValueFromData(reg_info, m_reg_data, reg_info->byte_offset, partial_data_ok).Success();
}

bool
RegisterContextMemory::WriteRegister (const RegisterInfo *reg_info, const RegisterValue &reg_value)
{
    if (m_reg_data_addr != LLDB_INVALID_ADDRESS)
    {
        const uint32_t reg_num = reg_info->kinds[eRegisterKindLLDB];
        addr_t reg_addr = m_reg_data_addr + reg_info->byte_offset;
        Error error (WriteRegisterValueToMemory(reg_info, reg_addr, reg_info->byte_size, reg_value));
        m_reg_valid[reg_num] = false;
        return error.Success();
    }
    return false;
}

bool
RegisterContextMemory::ReadAllRegisterValues (DataBufferSP &data_sp)
{
    if (m_reg_data_addr != LLDB_INVALID_ADDRESS)
    {
        ProcessSP process_sp (CalculateProcess());
        if (process_sp)
        {
            Error error;
            if (process_sp->ReadMemory(m_reg_data_addr, data_sp->GetBytes(), data_sp->GetByteSize(), error) == data_sp->GetByteSize())
            {
                SetAllRegisterValid (true);
                return true;
            }
        }
    }
    return false;
}

bool
RegisterContextMemory::WriteAllRegisterValues (const DataBufferSP &data_sp)
{
    if (m_reg_data_addr != LLDB_INVALID_ADDRESS)
    {
        ProcessSP process_sp (CalculateProcess());
        if (process_sp)
        {
            Error error;
            SetAllRegisterValid (false);
            if (process_sp->WriteMemory(m_reg_data_addr, data_sp->GetBytes(), data_sp->GetByteSize(), error) == data_sp->GetByteSize())
                return true;
        }
    }
    return false;
}

void
RegisterContextMemory::SetAllRegisterData  (const lldb::DataBufferSP &data_sp)
{
    m_reg_data.SetData(data_sp);
    SetAllRegisterValid (true);    
}
