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

#include "lldb/Core/EmulateInstruction.h"

#include "lldb/Core/Address.h"
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Host/Endian.h"
#include "lldb/Symbol/UnwindPlan.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"

using namespace lldb;
using namespace lldb_private;

EmulateInstruction*
EmulateInstruction::FindPlugin (const ArchSpec &arch, InstructionType supported_inst_type, const char *plugin_name)
{
    EmulateInstructionCreateInstance create_callback = NULL;
    if (plugin_name)
    {
        ConstString const_plugin_name (plugin_name);
        create_callback  = PluginManager::GetEmulateInstructionCreateCallbackForPluginName (const_plugin_name);
        if (create_callback)
        {
           	EmulateInstruction *emulate_insn_ptr = create_callback(arch, supported_inst_type);
            if (emulate_insn_ptr)
                return emulate_insn_ptr;
        }
    }
    else
    {
        for (uint32_t idx = 0; (create_callback = PluginManager::GetEmulateInstructionCreateCallbackAtIndex(idx)) != NULL; ++idx)
        {
            EmulateInstruction *emulate_insn_ptr = create_callback(arch, supported_inst_type);
            if (emulate_insn_ptr)
                return emulate_insn_ptr;
        }
    }
    return NULL;
}

EmulateInstruction::EmulateInstruction (const ArchSpec &arch) :
    m_arch (arch),
    m_baton (NULL),
    m_read_mem_callback (&ReadMemoryDefault),
    m_write_mem_callback (&WriteMemoryDefault),
    m_read_reg_callback (&ReadRegisterDefault),
    m_write_reg_callback (&WriteRegisterDefault),
    m_addr (LLDB_INVALID_ADDRESS)
{
    ::memset (&m_opcode, 0, sizeof (m_opcode));
}


bool
EmulateInstruction::ReadRegister (const RegisterInfo *reg_info, RegisterValue& reg_value)
{
    if (m_read_reg_callback)
        return m_read_reg_callback (this, m_baton, reg_info, reg_value);
    return false;
}

bool
EmulateInstruction::ReadRegister (lldb::RegisterKind reg_kind, uint32_t reg_num, RegisterValue& reg_value)
{
    RegisterInfo reg_info;
    if (GetRegisterInfo(reg_kind, reg_num, reg_info))
        return ReadRegister (&reg_info, reg_value);
    return false;
}

uint64_t
EmulateInstruction::ReadRegisterUnsigned (lldb::RegisterKind reg_kind,
                                          uint32_t reg_num,
                                          uint64_t fail_value, 
                                          bool *success_ptr)
{
    RegisterValue reg_value;
    if (ReadRegister (reg_kind, reg_num, reg_value))
        return reg_value.GetAsUInt64(fail_value, success_ptr);
    if (success_ptr)
        *success_ptr = false;
    return fail_value;
}

uint64_t
EmulateInstruction::ReadRegisterUnsigned (const RegisterInfo *reg_info,
                                          uint64_t fail_value, 
                                          bool *success_ptr)
{
    RegisterValue reg_value;
    if (ReadRegister (reg_info, reg_value))
        return reg_value.GetAsUInt64(fail_value, success_ptr);
    if (success_ptr)
        *success_ptr = false;
    return fail_value;
}

bool
EmulateInstruction::WriteRegister (const Context &context, 
                                   const RegisterInfo *reg_info, 
                                   const RegisterValue& reg_value)
{
    if (m_write_reg_callback)
        return m_write_reg_callback (this, m_baton, context, reg_info, reg_value);
    return false;
}

bool
EmulateInstruction::WriteRegister (const Context &context, 
                                   lldb::RegisterKind reg_kind,
                                   uint32_t reg_num, 
                                   const RegisterValue& reg_value)
{
    RegisterInfo reg_info;
    if (GetRegisterInfo(reg_kind, reg_num, reg_info))
        return WriteRegister (context, &reg_info, reg_value);
    return false;
}


bool
EmulateInstruction::WriteRegisterUnsigned (const Context &context,
                                           lldb::RegisterKind reg_kind,
                                           uint32_t reg_num,
                                           uint64_t uint_value)
{
    
    RegisterInfo reg_info;
    if (GetRegisterInfo(reg_kind, reg_num, reg_info))
    {
        RegisterValue reg_value;
        if (reg_value.SetUInt(uint_value, reg_info.byte_size))
            return WriteRegister (context, &reg_info, reg_value);
    }
    return false;
}

bool
EmulateInstruction::WriteRegisterUnsigned (const Context &context,
                                           const RegisterInfo *reg_info,
                                           uint64_t uint_value)
{
    
    if (reg_info)
    {
        RegisterValue reg_value;
        if (reg_value.SetUInt(uint_value, reg_info->byte_size))
                return WriteRegister (context, reg_info, reg_value);
    }
    return false;
}

size_t
EmulateInstruction::ReadMemory (const Context &context, 
                                lldb::addr_t addr, 
                                void *dst,
                                size_t dst_len)
{
    if (m_read_mem_callback)
        return m_read_mem_callback (this, m_baton, context, addr, dst, dst_len) == dst_len;
    return false;
}

uint64_t
EmulateInstruction::ReadMemoryUnsigned (const Context &context, lldb::addr_t addr, size_t byte_size, uint64_t fail_value, bool *success_ptr)
{
    uint64_t uval64 = 0;
    bool success = false;
    if (byte_size <= 8)
    {
        uint8_t buf[sizeof(uint64_t)];
        size_t bytes_read = m_read_mem_callback (this, m_baton, context, addr, buf, byte_size);
        if (bytes_read == byte_size)
        {
            lldb::offset_t offset = 0;
            DataExtractor data (buf, byte_size, GetByteOrder(), GetAddressByteSize());
            uval64 = data.GetMaxU64 (&offset, byte_size);
            success = true;
        }
    }

    if (success_ptr)
        *success_ptr = success;

    if (!success)
        uval64 = fail_value;
    return uval64;
}


bool
EmulateInstruction::WriteMemoryUnsigned (const Context &context, 
                                         lldb::addr_t addr, 
                                         uint64_t uval,
                                         size_t uval_byte_size)
{
    StreamString strm(Stream::eBinary, GetAddressByteSize(), GetByteOrder());
    strm.PutMaxHex64 (uval, uval_byte_size);
    
    size_t bytes_written = m_write_mem_callback (this, m_baton, context, addr, strm.GetData(), uval_byte_size);
    if (bytes_written == uval_byte_size)
        return true;
    return false;
}

bool
EmulateInstruction::WriteMemory (const Context &context, 
                                 lldb::addr_t addr, 
                                 const void *src,
                                 size_t src_len)
{
    if (m_write_mem_callback)
        return m_write_mem_callback (this, m_baton, context, addr, src, src_len) == src_len;
    return false;
}


void
EmulateInstruction::SetBaton (void *baton)
{
    m_baton = baton;
}

void
EmulateInstruction::SetCallbacks (ReadMemoryCallback read_mem_callback,
                                  WriteMemoryCallback write_mem_callback,
                                  ReadRegisterCallback read_reg_callback,
                                  WriteRegisterCallback write_reg_callback)
{
    m_read_mem_callback = read_mem_callback;
    m_write_mem_callback = write_mem_callback;
    m_read_reg_callback = read_reg_callback;
    m_write_reg_callback = write_reg_callback;
}

void
EmulateInstruction::SetReadMemCallback (ReadMemoryCallback read_mem_callback)
{
    m_read_mem_callback = read_mem_callback;
}

                                  
void
EmulateInstruction::SetWriteMemCallback (WriteMemoryCallback write_mem_callback)
{
    m_write_mem_callback = write_mem_callback;
}

                                  
void
EmulateInstruction::SetReadRegCallback (ReadRegisterCallback read_reg_callback)
{
    m_read_reg_callback = read_reg_callback;
}

                                  
void
EmulateInstruction::SetWriteRegCallback (WriteRegisterCallback write_reg_callback)
{
    m_write_reg_callback = write_reg_callback;
}

                                  
                            
//
//  Read & Write Memory and Registers callback functions.
//

size_t 
EmulateInstruction::ReadMemoryFrame (EmulateInstruction *instruction,
                                     void *baton,
                                     const Context &context, 
                                     lldb::addr_t addr, 
                                     void *dst,
                                     size_t dst_len)
{
    if (!baton || dst == NULL || dst_len == 0)
        return 0;

    StackFrame *frame = (StackFrame *) baton;

    ProcessSP process_sp (frame->CalculateProcess());
    if (process_sp)
    {
        Error error;
        return process_sp->ReadMemory (addr, dst, dst_len, error);
    }
    return 0;
}

size_t 
EmulateInstruction::WriteMemoryFrame (EmulateInstruction *instruction,
                                      void *baton,
                                      const Context &context, 
                                      lldb::addr_t addr, 
                                      const void *src,
                                      size_t src_len)
{
    if (!baton || src == NULL || src_len == 0)
        return 0;
    
    StackFrame *frame = (StackFrame *) baton;

    ProcessSP process_sp (frame->CalculateProcess());
    if (process_sp)
    {
        Error error;
        return process_sp->WriteMemory (addr, src, src_len, error);
    }
    
    return 0;
}

bool   
EmulateInstruction::ReadRegisterFrame  (EmulateInstruction *instruction,
                                        void *baton,
                                        const RegisterInfo *reg_info,
                                        RegisterValue &reg_value)
{
    if (!baton)
        return false;
        
    StackFrame *frame = (StackFrame *) baton;
    return frame->GetRegisterContext()->ReadRegister (reg_info, reg_value);
}

bool   
EmulateInstruction::WriteRegisterFrame (EmulateInstruction *instruction,
                                        void *baton,
                                        const Context &context, 
                                        const RegisterInfo *reg_info,
                                        const RegisterValue &reg_value)
{
    if (!baton)
        return false;
        
    StackFrame *frame = (StackFrame *) baton;
    return frame->GetRegisterContext()->WriteRegister (reg_info, reg_value);
}

size_t 
EmulateInstruction::ReadMemoryDefault (EmulateInstruction *instruction,
                                       void *baton,
                                       const Context &context, 
                                       lldb::addr_t addr, 
                                       void *dst,
                                       size_t length)
{
    StreamFile strm (stdout, false);
    strm.Printf ("    Read from Memory (address = 0x%" PRIx64 ", length = %" PRIu64 ", context = ", addr, (uint64_t)length);
    context.Dump (strm, instruction);    
    strm.EOL();
    *((uint64_t *) dst) = 0xdeadbeef;
    return length;
}

size_t 
EmulateInstruction::WriteMemoryDefault (EmulateInstruction *instruction,
                                        void *baton,
                                        const Context &context, 
                                        lldb::addr_t addr, 
                                        const void *dst,
                                        size_t length)
{
    StreamFile strm (stdout, false);
    strm.Printf ("    Write to Memory (address = 0x%" PRIx64 ", length = %" PRIu64 ", context = ", addr, (uint64_t)length);
    context.Dump (strm, instruction);    
    strm.EOL();
    return length;
}

bool   
EmulateInstruction::ReadRegisterDefault  (EmulateInstruction *instruction,
                                          void *baton,
                                          const RegisterInfo *reg_info,
                                          RegisterValue &reg_value)
{
    StreamFile strm (stdout, false);
    strm.Printf ("  Read Register (%s)\n", reg_info->name);
    lldb::RegisterKind reg_kind;
    uint32_t reg_num;
    if (GetBestRegisterKindAndNumber (reg_info, reg_kind, reg_num))
        reg_value.SetUInt64((uint64_t)reg_kind << 24 | reg_num);
    else
        reg_value.SetUInt64(0);

    return true;
}

bool   
EmulateInstruction::WriteRegisterDefault (EmulateInstruction *instruction,
                                          void *baton,
                                          const Context &context, 
                                          const RegisterInfo *reg_info,
                                          const RegisterValue &reg_value)
{
    StreamFile strm (stdout, false);
    strm.Printf ("    Write to Register (name = %s, value = " , reg_info->name);
    reg_value.Dump(&strm, reg_info, false, false, eFormatDefault);
    strm.PutCString (", context = ");
    context.Dump (strm, instruction);        
    strm.EOL();
    return true;
}

void
EmulateInstruction::Context::Dump (Stream &strm, 
                                   EmulateInstruction *instruction) const
{
    switch (type)
    {
        case eContextReadOpcode:
            strm.PutCString ("reading opcode");
            break;
            
        case eContextImmediate:
            strm.PutCString ("immediate");
            break;
            
        case eContextPushRegisterOnStack:
            strm.PutCString ("push register");
            break;
            
        case eContextPopRegisterOffStack:
            strm.PutCString ("pop register");
            break;
            
        case eContextAdjustStackPointer:
            strm.PutCString ("adjust sp");
            break;
            
        case eContextSetFramePointer:
            strm.PutCString ("set frame pointer");
            break;
            
        case eContextAdjustBaseRegister:
            strm.PutCString ("adjusting (writing value back to) a base register");
            break;
            
        case eContextRegisterPlusOffset:
            strm.PutCString ("register + offset");
            break;
            
        case eContextRegisterStore:
            strm.PutCString ("store register");
            break;
            
        case eContextRegisterLoad:
            strm.PutCString ("load register");
            break;
            
        case eContextRelativeBranchImmediate:
            strm.PutCString ("relative branch immediate");
            break;
            
        case eContextAbsoluteBranchRegister:
            strm.PutCString ("absolute branch register");
            break;
            
        case eContextSupervisorCall:
            strm.PutCString ("supervisor call");
            break;
            
        case eContextTableBranchReadMemory:
            strm.PutCString ("table branch read memory");
            break;
            
        case eContextWriteRegisterRandomBits:
            strm.PutCString ("write random bits to a register");
            break;
            
        case eContextWriteMemoryRandomBits:
            strm.PutCString ("write random bits to a memory address");
            break;
            
        case eContextArithmetic:
            strm.PutCString ("arithmetic");
            break;
            
        case eContextReturnFromException:
            strm.PutCString ("return from exception");
            break;
            
        default:
            strm.PutCString ("unrecognized context.");
            break;
    }
    
    switch (info_type)
    {
    case eInfoTypeRegisterPlusOffset:
        {
            strm.Printf (" (reg_plus_offset = %s%+" PRId64 ")",
                         info.RegisterPlusOffset.reg.name,
                         info.RegisterPlusOffset.signed_offset);
        }
        break;

    case eInfoTypeRegisterPlusIndirectOffset:
        {
            strm.Printf (" (reg_plus_reg = %s + %s)",
                         info.RegisterPlusIndirectOffset.base_reg.name,
                         info.RegisterPlusIndirectOffset.offset_reg.name);
        }
        break;

    case eInfoTypeRegisterToRegisterPlusOffset:
        {
            strm.Printf (" (base_and_imm_offset = %s%+" PRId64 ", data_reg = %s)",
                         info.RegisterToRegisterPlusOffset.base_reg.name, 
                         info.RegisterToRegisterPlusOffset.offset,
                         info.RegisterToRegisterPlusOffset.data_reg.name);
        }
        break;

    case eInfoTypeRegisterToRegisterPlusIndirectOffset:
        {
            strm.Printf (" (base_and_reg_offset = %s + %s, data_reg = %s)",
                         info.RegisterToRegisterPlusIndirectOffset.base_reg.name, 
                         info.RegisterToRegisterPlusIndirectOffset.offset_reg.name, 
                         info.RegisterToRegisterPlusIndirectOffset.data_reg.name);
        }
        break;
    
    case eInfoTypeRegisterRegisterOperands:
        {
            strm.Printf (" (register to register binary op: %s and %s)", 
                         info.RegisterRegisterOperands.operand1.name,
                         info.RegisterRegisterOperands.operand2.name);
        }
        break;

    case eInfoTypeOffset:
        strm.Printf (" (signed_offset = %+" PRId64 ")", info.signed_offset);
        break;
        
    case eInfoTypeRegister:
        strm.Printf (" (reg = %s)", info.reg.name);
        break;
        
    case eInfoTypeImmediate:
        strm.Printf (" (unsigned_immediate = %" PRIu64 " (0x%16.16" PRIx64 "))",
                     info.unsigned_immediate, 
                     info.unsigned_immediate);
        break;

    case eInfoTypeImmediateSigned:
        strm.Printf (" (signed_immediate = %+" PRId64 " (0x%16.16" PRIx64 "))",
                     info.signed_immediate, 
                     info.signed_immediate);
        break;
        
    case eInfoTypeAddress:
        strm.Printf (" (address = 0x%" PRIx64 ")", info.address);
        break;
        
    case eInfoTypeISAAndImmediate:
        strm.Printf (" (isa = %u, unsigned_immediate = %u (0x%8.8x))", 
                     info.ISAAndImmediate.isa,
                     info.ISAAndImmediate.unsigned_data32,
                     info.ISAAndImmediate.unsigned_data32);
        break;
        
    case eInfoTypeISAAndImmediateSigned:
        strm.Printf (" (isa = %u, signed_immediate = %i (0x%8.8x))", 
                     info.ISAAndImmediateSigned.isa,
                     info.ISAAndImmediateSigned.signed_data32,
                     info.ISAAndImmediateSigned.signed_data32);
        break;
        
    case eInfoTypeISA:
        strm.Printf (" (isa = %u)", info.isa);
        break;
        
    case eInfoTypeNoArgs:
        break;
    }
}

bool
EmulateInstruction::SetInstruction (const Opcode &opcode, const Address &inst_addr, Target *target)
{
    m_opcode = opcode;
    m_addr = LLDB_INVALID_ADDRESS;
    if (inst_addr.IsValid())
    {
        if (target)
            m_addr = inst_addr.GetLoadAddress (target);
        if (m_addr == LLDB_INVALID_ADDRESS)
            m_addr = inst_addr.GetFileAddress ();
    }
    return true;
}

bool
EmulateInstruction::GetBestRegisterKindAndNumber (const RegisterInfo *reg_info, 
                                                  lldb::RegisterKind &reg_kind,
                                                  uint32_t &reg_num)
{
    // Generic and DWARF should be the two most popular register kinds when
    // emulating instructions since they are the most platform agnostic...
    reg_num = reg_info->kinds[eRegisterKindGeneric];
    if (reg_num != LLDB_INVALID_REGNUM)
    {
        reg_kind = eRegisterKindGeneric;
        return true;
    }
    
    reg_num = reg_info->kinds[eRegisterKindDWARF];
    if (reg_num != LLDB_INVALID_REGNUM)
    {
        reg_kind = eRegisterKindDWARF;
        return true;
    }

    reg_num = reg_info->kinds[eRegisterKindLLDB];
    if (reg_num != LLDB_INVALID_REGNUM)
    {
        reg_kind = eRegisterKindLLDB;
        return true;
    }

    reg_num = reg_info->kinds[eRegisterKindEHFrame];
    if (reg_num != LLDB_INVALID_REGNUM)
    {
        reg_kind = eRegisterKindEHFrame;
        return true;
    }

    reg_num = reg_info->kinds[eRegisterKindProcessPlugin];
    if (reg_num != LLDB_INVALID_REGNUM)
    {
        reg_kind = eRegisterKindProcessPlugin;
        return true;
    }
    return false;
}

uint32_t
EmulateInstruction::GetInternalRegisterNumber (RegisterContext *reg_ctx, const RegisterInfo &reg_info)
{
    lldb::RegisterKind reg_kind;
    uint32_t reg_num;
    if (reg_ctx && GetBestRegisterKindAndNumber (&reg_info, reg_kind, reg_num))
        return reg_ctx->ConvertRegisterKindToRegisterNumber (reg_kind, reg_num);
    return LLDB_INVALID_REGNUM;
}


bool
EmulateInstruction::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan)
{
    unwind_plan.Clear();
    return false;
}


