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

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

#include "lldb/Host/common/NativeProcessProtocol.h"
#include "lldb/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;
}

lldb::addr_t
NativeRegisterContext::GetPCfromBreakpointLocation (lldb::addr_t fail_value)
{
    return GetPC (fail_value);
}

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

Error
NativeRegisterContext::ClearAllHardwareWatchpoints ()
{
    return Error ("not implemented");
}

Error
NativeRegisterContext::IsWatchpointHit(uint32_t wp_index, bool &is_hit)
{
    is_hit = false;
    return Error ("not implemented");
}

Error
NativeRegisterContext::GetWatchpointHitIndex(uint32_t &wp_index, lldb::addr_t trap_addr)
{
    wp_index = LLDB_INVALID_INDEX32;
    return Error ("not implemented");
}

Error
NativeRegisterContext::IsWatchpointVacant (uint32_t wp_index, bool &is_vacant)
{
    is_vacant = false;
    return Error ("not implemented");
}

lldb::addr_t
NativeRegisterContext::GetWatchpointAddress (uint32_t wp_index)
{
    return LLDB_INVALID_ADDRESS;
}

lldb::addr_t
NativeRegisterContext::GetWatchpointHitAddress (uint32_t wp_index)
{
    return LLDB_INVALID_ADDRESS;
}

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

Error
NativeRegisterContext::ReadRegisterValueFromMemory (
    const RegisterInfo *reg_info,
    lldb::addr_t src_addr,
    size_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 size_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)",
                static_cast<uint64_t>(src_len), reg_info->name, static_cast<uint64_t>(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
    size_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",
                static_cast<uint64_t>(bytes_read), static_cast<uint64_t>(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,
    size_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 size_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
            {
                size_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",
                            static_cast<uint64_t>(bytes_written), static_cast<uint64_t>(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;
}


