//===-- NativeRegisterContext.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/Target/NativeRegisterContext.h"

#include "lldb/Core/Log.h"
#include "lldb/Core/RegisterValue.h"

#include "lldb/lldb-private-log.h"

#include "Host/common/NativeProcessProtocol.h"
#include "Host/common/NativeThreadProtocol.h"

using namespace lldb;
using namespace lldb_private;

NativeRegisterContext::NativeRegisterContext (NativeThreadProtocol &thread, uint32_t concrete_frame_idx) :
    m_thread (thread),
    m_concrete_frame_idx (concrete_frame_idx)
{
}

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

// FIXME revisit invalidation, process stop ids, etc.  Right now we don't
// support caching in NativeRegisterContext.  We can do this later by
// utilizing NativeProcessProtocol::GetStopID () and adding a stop id to
// NativeRegisterContext.

// void
// NativeRegisterContext::InvalidateIfNeeded (bool force)
// {
//     ProcessSP process_sp (m_thread.GetProcess());
//     bool invalidate = force;
//     uint32_t process_stop_id = UINT32_MAX;

//     if (process_sp)
//         process_stop_id = process_sp->GetStopID();
//     else
//         invalidate = true;

//     if (!invalidate)
//         invalidate = process_stop_id != GetStopID();

//     if (invalidate)
//     {
//         InvalidateAllRegisters ();
//         SetStopID (process_stop_id);
//     }
// }


const RegisterInfo *
NativeRegisterContext::GetRegisterInfoByName (const char *reg_name, uint32_t start_idx)
{
    if (reg_name && reg_name[0])
    {
        const uint32_t num_registers = GetRegisterCount();
        for (uint32_t reg = start_idx; reg < num_registers; ++reg)
        {
            const RegisterInfo * reg_info = GetRegisterInfoAtIndex(reg);

            if ((reg_info->name != nullptr && ::strcasecmp (reg_info->name, reg_name) == 0) ||
                (reg_info->alt_name != nullptr && ::strcasecmp (reg_info->alt_name, reg_name) == 0))
            {
                return reg_info;
            }
        }
    }
    return nullptr;
}

const RegisterInfo *
NativeRegisterContext::GetRegisterInfo (uint32_t kind, uint32_t num)
{
    const uint32_t reg_num = ConvertRegisterKindToRegisterNumber(kind, num);
    if (reg_num == LLDB_INVALID_REGNUM)
        return nullptr;
    return GetRegisterInfoAtIndex (reg_num);
}

const char *
NativeRegisterContext::GetRegisterName (uint32_t reg)
{
    const RegisterInfo * reg_info = GetRegisterInfoAtIndex(reg);
    if (reg_info)
        return reg_info->name;
    return nullptr;
}

const char*
NativeRegisterContext::GetRegisterSetNameForRegisterAtIndex (uint32_t reg_index) const
{
    const RegisterInfo *const reg_info = GetRegisterInfoAtIndex(reg_index);
    if (!reg_info)
        return nullptr;

    for (uint32_t set_index = 0; set_index < GetRegisterSetCount (); ++set_index)
    {
        const RegisterSet *const reg_set = GetRegisterSet (set_index);
        if (!reg_set)
            continue;

        for (uint32_t reg_num_index = 0; reg_num_index < reg_set->num_registers; ++reg_num_index)
        {
            const uint32_t reg_num = reg_set->registers[reg_num_index];
            // FIXME double check we're checking the right register kind here.
            if (reg_info->kinds[RegisterKind::eRegisterKindLLDB] == reg_num)
            {
                // The given register is a member of this register set.  Return the register set name.
                return reg_set->name;
            }
        }
    }

    // Didn't find it.
    return nullptr;
}

lldb::addr_t
NativeRegisterContext::GetPC (lldb::addr_t fail_value)
{
    Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));

    uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
    if (log)
        log->Printf ("NativeRegisterContext::%s using reg index %" PRIu32 " (default %" PRIu64 ")", __FUNCTION__, reg, fail_value);

    const uint64_t retval = ReadRegisterAsUnsigned (reg, fail_value);

    if (log)
        log->Printf ("NativeRegisterContext::%s " PRIu32 " retval %" PRIu64, __FUNCTION__, retval);

    return retval;
}

Error
NativeRegisterContext::SetPC (lldb::addr_t pc)
{
    uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
    return WriteRegisterFromUnsigned (reg, pc);
}

lldb::addr_t
NativeRegisterContext::GetSP (lldb::addr_t fail_value)
{
    uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
    return ReadRegisterAsUnsigned (reg, fail_value);
}

Error
NativeRegisterContext::SetSP (lldb::addr_t sp)
{
    uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
    return WriteRegisterFromUnsigned (reg, sp);
}

lldb::addr_t
NativeRegisterContext::GetFP (lldb::addr_t fail_value)
{
    uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP);
    return ReadRegisterAsUnsigned (reg, fail_value);
}

Error
NativeRegisterContext::SetFP (lldb::addr_t fp)
{
    uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP);
    return WriteRegisterFromUnsigned (reg, fp);
}

lldb::addr_t
NativeRegisterContext::GetReturnAddress (lldb::addr_t fail_value)
{
    uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);
    return ReadRegisterAsUnsigned (reg, fail_value);
}

lldb::addr_t
NativeRegisterContext::GetFlags (lldb::addr_t fail_value)
{
    uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS);
    return ReadRegisterAsUnsigned (reg, fail_value);
}


lldb::addr_t
NativeRegisterContext::ReadRegisterAsUnsigned (uint32_t reg, lldb::addr_t fail_value)
{
    if (reg != LLDB_INVALID_REGNUM)
        return ReadRegisterAsUnsigned (GetRegisterInfoAtIndex (reg), fail_value);
    return fail_value;
}

uint64_t
NativeRegisterContext::ReadRegisterAsUnsigned (const RegisterInfo *reg_info, lldb::addr_t fail_value)
{
    Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));

    if (reg_info)
    {
        RegisterValue value;
        Error error = ReadRegister (reg_info, value);
        if (error.Success ())
        {
            if (log)
                log->Printf ("NativeRegisterContext::%s ReadRegister() succeeded, value %" PRIu64, __FUNCTION__, value.GetAsUInt64());
            return value.GetAsUInt64();
        }
        else
        {
            if (log)
                log->Printf ("NativeRegisterContext::%s ReadRegister() failed, error %s", __FUNCTION__, error.AsCString ());
        }
    }
    else
    {
        if (log)
            log->Printf ("NativeRegisterContext::%s ReadRegister() null reg_info", __FUNCTION__);
    }
    return fail_value;
}

Error
NativeRegisterContext::WriteRegisterFromUnsigned (uint32_t reg, uint64_t uval)
{
    if (reg == LLDB_INVALID_REGNUM)
        return Error ("NativeRegisterContext::%s (): reg is invalid", __FUNCTION__);
    return WriteRegisterFromUnsigned (GetRegisterInfoAtIndex (reg), uval);
}

Error
NativeRegisterContext::WriteRegisterFromUnsigned (const RegisterInfo *reg_info, uint64_t uval)
{
    assert (reg_info);
    if (!reg_info)
        return Error ("reg_info is nullptr");

    RegisterValue value;
    if (!value.SetUInt(uval, reg_info->byte_size))
        return Error ("RegisterValue::SetUInt () failed");

    return WriteRegister (reg_info, value);
}

lldb::tid_t
NativeRegisterContext::GetThreadID() const
{
    return m_thread.GetID();
}

uint32_t
NativeRegisterContext::NumSupportedHardwareBreakpoints ()
{
    return 0;
}

uint32_t
NativeRegisterContext::SetHardwareBreakpoint (lldb::addr_t addr, size_t size)
{
    return LLDB_INVALID_INDEX32;
}

bool
NativeRegisterContext::ClearHardwareBreakpoint (uint32_t hw_idx)
{
    return false;
}


uint32_t
NativeRegisterContext::NumSupportedHardwareWatchpoints ()
{
    return 0;
}

uint32_t
NativeRegisterContext::SetHardwareWatchpoint (lldb::addr_t addr, size_t size, uint32_t watch_flags)
{
    return LLDB_INVALID_INDEX32;
}

bool
NativeRegisterContext::ClearHardwareWatchpoint (uint32_t hw_index)
{
    return false;
}

bool
NativeRegisterContext::HardwareSingleStep (bool enable)
{
    return false;
}

Error
NativeRegisterContext::ReadRegisterValueFromMemory (
    const RegisterInfo *reg_info,
    lldb::addr_t src_addr,
    lldb::addr_t src_len,
    RegisterValue &reg_value)
{
    Error error;
    if (reg_info == nullptr)
    {
        error.SetErrorString ("invalid register info argument.");
        return error;
    }


    // Moving from addr into a register
    //
    // Case 1: src_len == dst_len
    //
    //   |AABBCCDD| Address contents
    //   |AABBCCDD| Register contents
    //
    // Case 2: src_len > dst_len
    //
    //   Error!  (The register should always be big enough to hold the data)
    //
    // Case 3: src_len < dst_len
    //
    //   |AABB| Address contents
    //   |AABB0000| Register contents [on little-endian hardware]
    //   |0000AABB| Register contents [on big-endian hardware]
    if (src_len > RegisterValue::kMaxRegisterByteSize)
    {
        error.SetErrorString ("register too small to receive memory data");
        return error;
    }

    const lldb::addr_t dst_len = reg_info->byte_size;

    if (src_len > dst_len)
    {
        error.SetErrorStringWithFormat("%" PRIu64 " bytes is too big to store in register %s (%" PRIu64 " bytes)", src_len, reg_info->name, dst_len);
        return error;
    }

    NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
    if (!process_sp)
    {
        error.SetErrorString("invalid process");
        return error;
    }

    uint8_t src[RegisterValue::kMaxRegisterByteSize];

    // Read the memory
    lldb::addr_t bytes_read;
    error = process_sp->ReadMemory (src_addr, src, src_len, bytes_read);
    if (error.Fail ())
        return error;

    // Make sure the memory read succeeded...
    if (bytes_read != src_len)
    {
        // This might happen if we read _some_ bytes but not all
        error.SetErrorStringWithFormat("read %" PRIu64 " of %" PRIu64 " bytes", bytes_read, src_len);
        return error;
    }

    // We now have a memory buffer that contains the part or all of the register
    // value. Set the register value using this memory data.
    // TODO: we might need to add a parameter to this function in case the byte
    // order of the memory data doesn't match the process. For now we are assuming
    // they are the same.
    lldb::ByteOrder byte_order;
    if (!process_sp->GetByteOrder (byte_order))
    {
        error.SetErrorString ( "NativeProcessProtocol::GetByteOrder () failed");
        return error;
    }

    reg_value.SetFromMemoryData (
        reg_info,
        src,
        src_len,
        byte_order,
        error);

    return error;
}

Error
NativeRegisterContext::WriteRegisterValueToMemory (
    const RegisterInfo *reg_info,
    lldb::addr_t dst_addr,
    lldb::addr_t dst_len,
    const RegisterValue &reg_value)
{
    
    uint8_t dst[RegisterValue::kMaxRegisterByteSize];

    Error error;

    NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
    if (process_sp)
    {

        // TODO: we might need to add a parameter to this function in case the byte
        // order of the memory data doesn't match the process. For now we are assuming
        // they are the same.
        lldb::ByteOrder byte_order;
        if (!process_sp->GetByteOrder (byte_order))
            return Error ("NativeProcessProtocol::GetByteOrder () failed");

        const lldb::addr_t bytes_copied = reg_value.GetAsMemoryData (
            reg_info,
            dst,
            dst_len,
            byte_order,
            error);

        if (error.Success())
        {
            if (bytes_copied == 0)
            {
                error.SetErrorString("byte copy failed.");
            }
            else
            {
                lldb::addr_t bytes_written;
                error = process_sp->WriteMemory (dst_addr, dst, bytes_copied, bytes_written);
                if (error.Fail ())
                    return error;

                if (bytes_written != bytes_copied)
                {
                    // This might happen if we read _some_ bytes but not all
                    error.SetErrorStringWithFormat("only wrote %" PRIu64 " of %" PRIu64 " bytes", bytes_written, bytes_copied);
                }
            }
        }
    }
    else
        error.SetErrorString("invalid process");

    return error;
}

uint32_t
NativeRegisterContext::ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num) const
{
    const uint32_t num_regs = GetRegisterCount();

    assert (kind < kNumRegisterKinds);
    for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx)
    {
        const RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg_idx);

        if (reg_info->kinds[kind] == num)
            return reg_idx;
    }

    return LLDB_INVALID_REGNUM;
}


