//===-- 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 (uint32_t 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 (uint32_t 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, 
                                   uint32_t 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,
                                           uint32_t 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);
    uint32_t reg_kind, 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, 
                                                  uint32_t &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[eRegisterKindGCC];
    if (reg_num != LLDB_INVALID_REGNUM)
    {
        reg_kind = eRegisterKindGCC;
        return true;
    }

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

uint32_t
EmulateInstruction::GetInternalRegisterNumber (RegisterContext *reg_ctx, const RegisterInfo &reg_info)
{
    uint32_t reg_kind, 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;
}


