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

// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/Target/RegisterContext.h"
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/Scalar.h"
#include "lldb/Host/Endian.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/Target.h"
#include "lldb/Core/Module.h"
#include "lldb/Expression/DWARFExpression.h"
#include "lldb/Core/Value.h"

using namespace lldb;
using namespace lldb_private;

RegisterContext::RegisterContext (Thread &thread, uint32_t concrete_frame_idx) :
    m_thread (thread),
    m_concrete_frame_idx (concrete_frame_idx),
    m_stop_id (thread.GetProcess()->GetStopID())
{
}

RegisterContext::~RegisterContext() = default;

void
RegisterContext::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 *
RegisterContext::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;
}

uint32_t
RegisterContext::UpdateDynamicRegisterSize (const lldb_private::ArchSpec &arch,
                                            RegisterInfo* reg_info)
{
    ExecutionContext exe_ctx (CalculateThread());

    // In MIPS, the floating point registers size is depends on FR bit of SR register.
    // if SR.FR  == 1 then all floating point registers are 64 bits.
    // else they are all 32 bits.
    
    int expr_result;
    uint32_t addr_size =  arch.GetAddressByteSize ();
    const uint8_t* dwarf_opcode_ptr = reg_info->dynamic_size_dwarf_expr_bytes;
    const size_t dwarf_opcode_len = reg_info->dynamic_size_dwarf_len;

    DataExtractor dwarf_data (dwarf_opcode_ptr, dwarf_opcode_len, 
                              arch.GetByteOrder (), addr_size);
    ModuleSP opcode_ctx;
    DWARFExpression dwarf_expr (opcode_ctx, dwarf_data, nullptr, 0, dwarf_opcode_len);
    Value result;
    Error error;
    const lldb::offset_t offset = 0;
    if (dwarf_expr.Evaluate (&exe_ctx, nullptr, nullptr, this, opcode_ctx, dwarf_data, nullptr,
                             offset, dwarf_opcode_len, eRegisterKindDWARF, nullptr, nullptr, result, &error))
    {
        expr_result = result.GetScalar ().SInt (-1);
        switch (expr_result)
        {
            case 0: return 4;
            case 1: return 8;
            default: return reg_info->byte_size;
        }
    }
    else
    {
        printf ("Error executing DwarfExpression::Evaluate %s\n", error.AsCString());
        return reg_info->byte_size;
    }
}

const RegisterInfo *
RegisterContext::GetRegisterInfo (lldb::RegisterKind 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 *
RegisterContext::GetRegisterName (uint32_t reg)
{
    const RegisterInfo * reg_info = GetRegisterInfoAtIndex(reg);
    if (reg_info)
        return reg_info->name;
    return nullptr;
}

uint64_t
RegisterContext::GetPC(uint64_t fail_value)
{
    uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
    uint64_t pc = ReadRegisterAsUnsigned (reg, fail_value);

    if (pc != fail_value)
    {
        TargetSP target_sp = m_thread.CalculateTarget();
        if (target_sp)
        {
            Target *target = target_sp.get();
            if (target)
                pc = target->GetOpcodeLoadAddress (pc, eAddressClassCode);
        }
    }

    return pc;
}

bool
RegisterContext::SetPC(uint64_t pc)
{
    uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
    bool success = WriteRegisterFromUnsigned (reg, pc);
    if (success)
    {
        StackFrameSP frame_sp(m_thread.GetFrameWithConcreteFrameIndex (m_concrete_frame_idx));
        if (frame_sp)
            frame_sp->ChangePC(pc);
        else
            m_thread.ClearStackFrames ();
    }
    return success;
}

bool
RegisterContext::SetPC(Address addr)
{
    TargetSP target_sp = m_thread.CalculateTarget();
    Target *target = target_sp.get();

    lldb::addr_t callAddr = addr.GetCallableLoadAddress (target);
    if (callAddr == LLDB_INVALID_ADDRESS)
        return false;

    return SetPC (callAddr);
}

uint64_t
RegisterContext::GetSP(uint64_t fail_value)
{
    uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
    return ReadRegisterAsUnsigned (reg, fail_value);
}

bool
RegisterContext::SetSP(uint64_t sp)
{
    uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
    return WriteRegisterFromUnsigned (reg, sp);
}

uint64_t
RegisterContext::GetFP(uint64_t fail_value)
{
    uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP);
    return ReadRegisterAsUnsigned (reg, fail_value);
}

bool
RegisterContext::SetFP(uint64_t fp)
{
    uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP);
    return WriteRegisterFromUnsigned (reg, fp);
}

uint64_t
RegisterContext::GetReturnAddress (uint64_t fail_value)
{
    uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);
    return ReadRegisterAsUnsigned (reg, fail_value);
}

uint64_t
RegisterContext::GetFlags (uint64_t fail_value)
{
    uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS);
    return ReadRegisterAsUnsigned (reg, fail_value);
}

uint64_t
RegisterContext::ReadRegisterAsUnsigned (uint32_t reg, uint64_t fail_value)
{
    if (reg != LLDB_INVALID_REGNUM)
        return ReadRegisterAsUnsigned (GetRegisterInfoAtIndex (reg), fail_value);
    return fail_value;
}

uint64_t
RegisterContext::ReadRegisterAsUnsigned (const RegisterInfo *reg_info, uint64_t fail_value)
{
    if (reg_info)
    {
        RegisterValue value;
        if (ReadRegister (reg_info, value))
            return value.GetAsUInt64();
    }
    return fail_value;
}

bool
RegisterContext::WriteRegisterFromUnsigned (uint32_t reg, uint64_t uval)
{
    if (reg == LLDB_INVALID_REGNUM)
        return false;
    return WriteRegisterFromUnsigned (GetRegisterInfoAtIndex (reg), uval);
}

bool
RegisterContext::WriteRegisterFromUnsigned (const RegisterInfo *reg_info, uint64_t uval)
{
    if (reg_info)
    {
        RegisterValue value;
        if (value.SetUInt(uval, reg_info->byte_size))
            return WriteRegister (reg_info, value);
    }
    return false;
}

bool
RegisterContext::CopyFromRegisterContext (lldb::RegisterContextSP context)
{
    uint32_t num_register_sets = context->GetRegisterSetCount();
    // We don't know that two threads have the same register context, so require the threads to be the same.
    if (context->GetThreadID() != GetThreadID())
        return false;
    
    if (num_register_sets != GetRegisterSetCount())
        return false;
    
    RegisterContextSP frame_zero_context = m_thread.GetRegisterContext();
    
    for (uint32_t set_idx = 0; set_idx < num_register_sets; ++set_idx)
    {
        const RegisterSet * const reg_set = GetRegisterSet(set_idx);
        
        const uint32_t num_registers = reg_set->num_registers;
        for (uint32_t reg_idx = 0; reg_idx < num_registers; ++reg_idx)
        {
            const uint32_t reg = reg_set->registers[reg_idx];
            const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
            if (!reg_info || reg_info->value_regs)
                continue;
            RegisterValue reg_value;
            
            // If we can reconstruct the register from the frame we are copying from, then do so, otherwise
            // use the value from frame 0.
            if (context->ReadRegister(reg_info, reg_value))
            {
                WriteRegister(reg_info, reg_value);
            }
            else if (frame_zero_context->ReadRegister(reg_info, reg_value))
            {
                WriteRegister(reg_info, reg_value);
            }
        }
    }
    return true;
}

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

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

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

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

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

uint32_t
RegisterContext::SetHardwareWatchpoint (lldb::addr_t addr, size_t size, bool read, bool write)
{
    return LLDB_INVALID_INDEX32;
}

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

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

Error
RegisterContext::ReadRegisterValueFromMemory (const RegisterInfo *reg_info,
                                              lldb::addr_t src_addr, 
                                              uint32_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 uint32_t dst_len = reg_info->byte_size;
    
    if (src_len > dst_len)
    {
        error.SetErrorStringWithFormat("%u bytes is too big to store in register %s (%u bytes)", src_len, reg_info->name, dst_len);
        return error;
    }
    
    ProcessSP process_sp (m_thread.GetProcess());
    if (process_sp)
    {
        uint8_t src[RegisterValue::kMaxRegisterByteSize];
       
        // Read the memory
        const uint32_t bytes_read = process_sp->ReadMemory (src_addr, src, src_len, error);

        // Make sure the memory read succeeded...
        if (bytes_read != src_len)
        {
            if (error.Success())
            {
                // This might happen if we read _some_ bytes but not all
                error.SetErrorStringWithFormat("read %u of %u 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.
        reg_value.SetFromMemoryData (reg_info, 
                                     src, 
                                     src_len, 
                                     process_sp->GetByteOrder(), 
                                     error);
    }
    else
        error.SetErrorString("invalid process");

    return error;
}

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

    Error error;

    ProcessSP 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.

        const uint32_t bytes_copied = reg_value.GetAsMemoryData (reg_info, 
                                                                 dst, 
                                                                 dst_len, 
                                                                 process_sp->GetByteOrder(), 
                                                                 error);

        if (error.Success())
        {
            if (bytes_copied == 0)
            {
                error.SetErrorString("byte copy failed.");
            }
            else
            {
                const uint32_t bytes_written = process_sp->WriteMemory (dst_addr, dst, bytes_copied, error);
                if (bytes_written != bytes_copied)
                {
                    if (error.Success())
                    {
                        // This might happen if we read _some_ bytes but not all
                        error.SetErrorStringWithFormat("only wrote %u of %u bytes", bytes_written, bytes_copied);
                    }
                }
            }
        }
    }
    else
        error.SetErrorString("invalid process");

    return error;
}

bool
RegisterContext::ReadAllRegisterValues (lldb_private::RegisterCheckpoint &reg_checkpoint)
{
    return ReadAllRegisterValues(reg_checkpoint.GetData());
}

bool
RegisterContext::WriteAllRegisterValues (const lldb_private::RegisterCheckpoint &reg_checkpoint)
{
    return WriteAllRegisterValues(reg_checkpoint.GetData());
}

TargetSP
RegisterContext::CalculateTarget ()
{
    return m_thread.CalculateTarget();
}

ProcessSP
RegisterContext::CalculateProcess ()
{
    return m_thread.CalculateProcess ();
}

ThreadSP
RegisterContext::CalculateThread ()
{
    return m_thread.shared_from_this();
}

StackFrameSP
RegisterContext::CalculateStackFrame ()
{
    // Register contexts might belong to many frames if we have inlined 
    // functions inside a frame since all inlined functions share the
    // same registers, so we can't definitively say which frame we come from...
    return StackFrameSP();
}

void
RegisterContext::CalculateExecutionContext (ExecutionContext &exe_ctx)
{
    m_thread.CalculateExecutionContext (exe_ctx);
}

bool
RegisterContext::ConvertBetweenRegisterKinds (lldb::RegisterKind source_rk, uint32_t source_regnum, lldb::RegisterKind target_rk, uint32_t& target_regnum)
{
    const uint32_t num_registers = GetRegisterCount();
    for (uint32_t reg = 0; reg < num_registers; ++reg)
    {
        const RegisterInfo * reg_info = GetRegisterInfoAtIndex (reg);

        if (reg_info->kinds[source_rk] == source_regnum)
        {
            target_regnum = reg_info->kinds[target_rk];
            return (target_regnum != LLDB_INVALID_REGNUM);
        } 
    }
    return false;
}

//bool
//RegisterContext::ReadRegisterValue (uint32_t reg, Scalar &value)
//{
//    DataExtractor data;
//    if (!ReadRegisterBytes (reg, data))
//        return false;
//
//    const RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg);
//    uint32_t offset = 0;
//    switch (reg_info->encoding)
//    {
//    case eEncodingInvalid:
//    case eEncodingVector:
//        break;
//
//    case eEncodingUint:
//        switch (reg_info->byte_size)
//        {
//        case 1:
//            {
//                value = data.GetU8 (&offset);
//                return true;
//            }
//        case 2:
//            {
//                value = data.GetU16 (&offset);
//                return true;
//            }
//        case 4:
//            {
//                value = data.GetU32 (&offset);
//                return true;
//            }
//        case 8:
//            {
//                value = data.GetU64 (&offset);
//                return true;
//            }
//        }
//        break;
//    case eEncodingSint:
//        switch (reg_info->byte_size)
//        {
//        case 1:
//            {
//                int8_t v;
//                if (data.ExtractBytes (0, sizeof (int8_t), endian::InlHostByteOrder(), &v) != sizeof (int8_t))
//                    return false;
//                value = v;
//                return true;
//            }
//        case 2:
//            {
//                int16_t v;
//                if (data.ExtractBytes (0, sizeof (int16_t), endian::InlHostByteOrder(), &v) != sizeof (int16_t))
//                    return false;
//                value = v;
//                return true;
//            }
//        case 4:
//            {
//                int32_t v;
//                if (data.ExtractBytes (0, sizeof (int32_t), endian::InlHostByteOrder(), &v) != sizeof (int32_t))
//                    return false;
//                value = v;
//                return true;
//            }
//        case 8:
//            {
//                int64_t v;
//                if (data.ExtractBytes (0, sizeof (int64_t), endian::InlHostByteOrder(), &v) != sizeof (int64_t))
//                    return false;
//                value = v;
//                return true;
//            }
//        }
//        break;
//    case eEncodingIEEE754:
//        switch (reg_info->byte_size)
//        {
//        case sizeof (float):
//            {
//                float v;
//                if (data.ExtractBytes (0, sizeof (float), endian::InlHostByteOrder(), &v) != sizeof (float))
//                    return false;
//                value = v;
//                return true;
//            }
//        case sizeof (double):
//            {
//                double v;
//                if (data.ExtractBytes (0, sizeof (double), endian::InlHostByteOrder(), &v) != sizeof (double))
//                    return false;
//                value = v;
//                return true;
//            }
//        case sizeof (long double):
//            {
//                double v;
//                if (data.ExtractBytes (0, sizeof (long double), endian::InlHostByteOrder(), &v) != sizeof (long double))
//                    return false;
//                value = v;
//                return true;
//            }
//        }
//        break;
//    }
//    return false;
//}
//
//bool 
//RegisterContext::WriteRegisterValue (uint32_t reg, const Scalar &value)
//{
//    DataExtractor data;
//    if (!value.IsValid())
//        return false;
//    if (!value.GetData (data))
//        return false;
//
//    return WriteRegisterBytes (reg, data);
//}
