//===-- 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)
    {
        create_callback  = PluginManager::GetEmulateInstructionCreateCallbackForPluginName (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)
        {
            uint32_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%llx, length = %zu, context = ", addr, 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%llx, length = %zu, context = ", addr, 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%+lld)",
                         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%+lld, 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 = %+lld)", info.signed_offset);
        break;
        
    case eInfoTypeRegister:
        strm.Printf (" (reg = %s)", info.reg.name);
        break;
        
    case eInfoTypeImmediate:
        strm.Printf (" (unsigned_immediate = %llu (0x%16.16llx))", 
                     info.unsigned_immediate, 
                     info.unsigned_immediate);
        break;

    case eInfoTypeImmediateSigned:
        strm.Printf (" (signed_immediate = %+lld (0x%16.16llx))", 
                     info.signed_immediate, 
                     info.signed_immediate);
        break;
        
    case eInfoTypeAddress:
        strm.Printf (" (address = 0x%llx)", 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;

    default:
        strm.Printf (" (unknown <info_type>)");
        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;
}


