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

#include "ABIMacOSX_i386.h"

#include "lldb/Core/ConstString.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Scalar.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"

#include "llvm/ADT/Triple.h"

#include <vector>

using namespace lldb;
using namespace lldb_private;

static const char *pluginName = "ABIMacOSX_i386";
static const char *pluginDesc = "Mac OS X ABI for i386 targets";
static const char *pluginShort = "abi.macosx-i386";

size_t
ABIMacOSX_i386::GetRedZoneSize () const
{
    return 0;
}

//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
lldb_private::ABI *
ABIMacOSX_i386::CreateInstance (const ArchSpec &arch)
{
    if (arch.GetTriple().getArch() == llvm::Triple::x86)
        return new ABIMacOSX_i386;

    return NULL;
}

bool
ABIMacOSX_i386::PrepareTrivialCall (Thread &thread, 
                                    lldb::addr_t sp, 
                                    lldb::addr_t functionAddress, 
                                    lldb::addr_t returnAddress, 
                                    lldb::addr_t arg,
                                    lldb::addr_t *this_arg,
                                    lldb::addr_t *cmd_arg) const
{
    RegisterContext *reg_ctx = thread.GetRegisterContext().get();
    if (!reg_ctx)
        return false;    
#define CHAIN_EBP

#ifndef CHAIN_EBP
    uint32_t ebpID = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP);
#endif
    uint32_t eipID = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
    uint32_t espID = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
    
    // Make room for the argument(s) on the stack
    
    if (this_arg && cmd_arg)
        sp -= 12;
    else if (this_arg)
        sp -= 8;
    else
        sp -= 4;
    
    // Align the SP
    
    sp &= ~(0xfull); // 16-byte alignment
    
    // Write the argument on the stack
    
    Error error;
    
    if (this_arg && cmd_arg)
    {
        uint32_t cmd_argU32 = *cmd_arg & 0xffffffffull;
        uint32_t this_argU32 = *this_arg & 0xffffffffull;
        uint32_t argU32 = arg & 0xffffffffull;
        
        if (thread.GetProcess().WriteMemory(sp, &this_argU32, sizeof(this_argU32), error) != sizeof(this_argU32))
            return false;
        if (thread.GetProcess().WriteMemory(sp + 4, &cmd_argU32, sizeof(cmd_argU32), error) != sizeof(cmd_argU32))
            return false;
        if (thread.GetProcess().WriteMemory(sp + 8, &argU32, sizeof(argU32), error) != sizeof(argU32))
            return false;
    }
    else if (this_arg)
    {
        uint32_t this_argU32 = *this_arg & 0xffffffffull;
        uint32_t argU32 = arg & 0xffffffffull;
                
        if (thread.GetProcess().WriteMemory(sp, &this_argU32, sizeof(this_argU32), error) != sizeof(this_argU32))
            return false;
        if (thread.GetProcess().WriteMemory(sp + 4, &argU32, sizeof(argU32), error) != sizeof(argU32))
            return false;
    }
    else
    {
        uint32_t argU32 = arg & 0xffffffffull;

        if (thread.GetProcess().WriteMemory (sp, &argU32, sizeof(argU32), error) != sizeof(argU32))
            return false;
    }
    
    // The return address is pushed onto the stack.
    
    sp -= 4;
    uint32_t returnAddressU32 = returnAddress;
    if (thread.GetProcess().WriteMemory (sp, &returnAddressU32, sizeof(returnAddressU32), error) != sizeof(returnAddressU32))
        return false;
    
    // %esp is set to the actual stack value.
    
    if (!reg_ctx->WriteRegisterFromUnsigned(espID, sp))
        return false;
    
#ifndef CHAIN_EBP
    // %ebp is set to a fake value, in our case 0x0x00000000
    
    if (!reg_ctx->WriteRegisterFromUnsigned(ebpID, 0x00000000))
        return false;
#endif
    
    // %eip is set to the address of the called function.
    
    if (!reg_ctx->WriteRegisterFromUnsigned(eipID, functionAddress))
        return false;
    
    return true;
}

bool
ABIMacOSX_i386::PrepareNormalCall (Thread &thread,
                                   lldb::addr_t sp,
                                   lldb::addr_t functionAddress,
                                   lldb::addr_t returnAddress,
                                   ValueList &args) const
{
    RegisterContext *reg_ctx = thread.GetRegisterContext().get();
    if (!reg_ctx)
        return false;
    Error error;
    uint32_t ebpID = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP);
    uint32_t eipID = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
    uint32_t espID = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
    
    // Do the argument layout
    
    std::vector <uint32_t> argLayout;   // 4-byte chunks, as discussed in the ABI Function Call Guide
    
    size_t numArgs = args.GetSize();
    size_t index;
    
    for (index = 0; index < numArgs; ++index)
    {
        Value *val = args.GetValueAtIndex(index);
        
        if (!val)
            return false;
        
        switch (val->GetValueType())
        {
        case Value::eValueTypeScalar:
            {
                Scalar &scalar = val->GetScalar();
                switch (scalar.GetType())
                {
                case Scalar::e_void:
                default:
                    return false;
                case Scalar::e_sint: 
                case Scalar::e_uint:
                case Scalar::e_slong:
                case Scalar::e_ulong:
                case Scalar::e_slonglong:
                case Scalar::e_ulonglong:
                    {
                        uint64_t data = scalar.ULongLong();
                        
                        switch (scalar.GetByteSize())
                        {
                        default:
                            return false;
                        case 1:
                            argLayout.push_back((uint32_t)(data & 0xffull));
                            break;
                        case 2:
                            argLayout.push_back((uint32_t)(data & 0xffffull));
                            break;
                        case 4:
                            argLayout.push_back((uint32_t)(data & 0xffffffffull));
                            break;
                        case 8:
                            argLayout.push_back((uint32_t)(data & 0xffffffffull));
                            argLayout.push_back((uint32_t)(data >> 32));
                            break;
                        }
                    }
                    break;
                case Scalar::e_float:
                    {
                        float data = scalar.Float();
                        uint32_t dataRaw = *((uint32_t*)(&data));
                        argLayout.push_back(dataRaw);
                    }
                    break;
                case Scalar::e_double:
                    {
                        double data = scalar.Double();
                        uint32_t *dataRaw = ((uint32_t*)(&data));
                        argLayout.push_back(dataRaw[0]);
                        argLayout.push_back(dataRaw[1]);
                    }
                    break;
                case Scalar::e_long_double:
                    {
                        long double data = scalar.Double();
                        uint32_t *dataRaw = ((uint32_t*)(&data));
                        while ((argLayout.size() * 4) & 0xf)
                            argLayout.push_back(0);
                        argLayout.push_back(dataRaw[0]);
                        argLayout.push_back(dataRaw[1]);
                        argLayout.push_back(dataRaw[2]);
                        argLayout.push_back(dataRaw[3]);
                    }
                    break;
                }
            }
            break;
        case Value::eValueTypeHostAddress:
            switch (val->GetContextType()) 
            {
            default:
                return false;
            case Value::eContextTypeClangType:
                {
                    void *val_type = val->GetClangType();
                    uint32_t cstr_length;
                    
                    if (ClangASTContext::IsCStringType (val_type, cstr_length))
                    {
                        const char *cstr = (const char*)val->GetScalar().ULongLong();
                        cstr_length = strlen(cstr);
                        
                        // Push the string onto the stack immediately.
                        
                        sp -= (cstr_length + 1);
                        
                        if (thread.GetProcess().WriteMemory(sp, cstr, cstr_length + 1, error) != (cstr_length + 1))
                            return false;
                        
                        // Put the address of the string into the argument array.
                        
                        argLayout.push_back((uint32_t)(sp & 0xffffffff));
                    }
                    else
                    {
                        return false;
                    }
                }
                break;
            }
            break;
        case Value::eValueTypeFileAddress:
        case Value::eValueTypeLoadAddress:
        default:
            return false;
        }
    }
    
    // Make room for the arguments on the stack
    
    sp -= 4 * argLayout.size();
    
    // Align the SP
    
    sp &= ~(0xfull); // 16-byte alignment
    
    // Write the arguments on the stack
    
    size_t numChunks = argLayout.size();

    for (index = 0; index < numChunks; ++index)
        if (thread.GetProcess().WriteMemory(sp + (index * 4), &argLayout[index], sizeof(uint32_t), error) != sizeof(uint32_t))
            return false;
    
    // The return address is pushed onto the stack.
    
    sp -= 4;
    uint32_t returnAddressU32 = returnAddress;
    if (thread.GetProcess().WriteMemory (sp, &returnAddressU32, sizeof(returnAddressU32), error) != sizeof(returnAddressU32))
        return false;
    
    // %esp is set to the actual stack value.
    
    if (!reg_ctx->WriteRegisterFromUnsigned(espID, sp))
        return false;
    
    // %ebp is set to a fake value, in our case 0x0x00000000
    
    if (!reg_ctx->WriteRegisterFromUnsigned(ebpID, 0x00000000))
        return false;
    
    // %eip is set to the address of the called function.
    
    if (!reg_ctx->WriteRegisterFromUnsigned(eipID, functionAddress))
        return false;
    
    return true;    
}

static bool ReadIntegerArgument(Scalar           &scalar,
                                unsigned int     bit_width,
                                bool             is_signed,
                                Process          &process,
                                addr_t           &current_stack_argument)
{
    if (bit_width > 64)
        return false; // Scalar can't hold large integer arguments
    
    uint64_t arg_contents;
    uint32_t read_data;
    Error error;
    
    if (bit_width > 32)
    {
        if (process.ReadMemory(current_stack_argument, &read_data, sizeof(read_data), error) != sizeof(read_data))
            return false;
        
        arg_contents = read_data;
        
        if (process.ReadMemory(current_stack_argument + 4, &read_data, sizeof(read_data), error) != sizeof(read_data))
            return false;
        
        arg_contents |= ((uint64_t)read_data) << 32;
        
        current_stack_argument += 8;
    }
    else {
        if (process.ReadMemory(current_stack_argument, &read_data, sizeof(read_data), error) != sizeof(read_data))
            return false;
        
        arg_contents = read_data;
        
        current_stack_argument += 4;
    }
    
    if (is_signed)
    {
        switch (bit_width)
        {
        default:
            return false;
        case 8:
            scalar = (int8_t)(arg_contents & 0xff);
            break;
        case 16:
            scalar = (int16_t)(arg_contents & 0xffff);
            break;
        case 32:
            scalar = (int32_t)(arg_contents & 0xffffffff);
            break;
        case 64:
            scalar = (int64_t)arg_contents;
            break;
        }
    }
    else
    {
        switch (bit_width)
        {
        default:
            return false;
        case 8:
            scalar = (uint8_t)(arg_contents & 0xff);
            break;
        case 16:
            scalar = (uint16_t)(arg_contents & 0xffff);
            break;
        case 32:
            scalar = (uint32_t)(arg_contents & 0xffffffff);
            break;
        case 64:
            scalar = (uint64_t)arg_contents;
            break;
        }
    }
    
    return true;
}

bool
ABIMacOSX_i386::GetArgumentValues (Thread &thread,
                                   ValueList &values) const
{
    unsigned int num_values = values.GetSize();
    unsigned int value_index;
    
    // Extract the Clang AST context from the PC so that we can figure out type
    // sizes
    
    clang::ASTContext *ast_context = thread.CalculateTarget()->GetScratchClangASTContext()->getASTContext();
    
    // Get the pointer to the first stack argument so we have a place to start 
    // when reading data
    
    RegisterContext *reg_ctx = thread.GetRegisterContext().get();
    
    if (!reg_ctx)
        return false;
    
    addr_t sp = reg_ctx->GetSP(0);
    
    if (!sp)
        return false;
    
    addr_t current_stack_argument = sp + 4; // jump over return address
    
    for (value_index = 0;
         value_index < num_values;
         ++value_index)
    {
        Value *value = values.GetValueAtIndex(value_index);
        
        if (!value)
            return false;
        
        // We currently only support extracting values with Clang QualTypes.
        // Do we care about others?
        switch (value->GetContextType())
        {
            default:
                return false;
            case Value::eContextTypeClangType:
            {
                void *value_type = value->GetClangType();
                bool is_signed;
                
                if (ClangASTContext::IsIntegerType (value_type, is_signed))
                {
                    size_t bit_width = ClangASTType::GetClangTypeBitWidth(ast_context, value_type);
                    
                    ReadIntegerArgument(value->GetScalar(),
                                        bit_width, 
                                        is_signed,
                                        thread.GetProcess(), 
                                        current_stack_argument);
                }
                else if (ClangASTContext::IsPointerType (value_type))
                {
                    ReadIntegerArgument(value->GetScalar(),
                                        32,
                                        false,
                                        thread.GetProcess(),
                                        current_stack_argument);
                }
            }
                break;
        }
    }
    
    return true;
}

bool
ABIMacOSX_i386::GetReturnValue (Thread &thread,
                                Value &value) const
{
    switch (value.GetContextType())
    {
        default:
            return false;
        case Value::eContextTypeClangType:
        {
            // Extract the Clang AST context from the PC so that we can figure out type
            // sizes
            
            clang::ASTContext *ast_context = thread.CalculateTarget()->GetScratchClangASTContext()->getASTContext();
            
            // Get the pointer to the first stack argument so we have a place to start 
            // when reading data
            
            RegisterContext *reg_ctx = thread.GetRegisterContext().get();
            
            void *value_type = value.GetClangType();
            bool is_signed;
            
            if (ClangASTContext::IsIntegerType (value_type, is_signed))
            {
                size_t bit_width = ClangASTType::GetClangTypeBitWidth(ast_context, value_type);
                
                unsigned eax_id = reg_ctx->GetRegisterInfoByName("eax", 0)->kinds[eRegisterKindLLDB];
                unsigned edx_id = reg_ctx->GetRegisterInfoByName("edx", 0)->kinds[eRegisterKindLLDB];
                
                switch (bit_width)
                {
                    default:
                    case 128:
                        // Scalar can't hold 128-bit literals, so we don't handle this
                        return false;
                    case 64:
                        uint64_t raw_value;
                        raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & 0xffffffff;
                        raw_value |= (thread.GetRegisterContext()->ReadRegisterAsUnsigned(edx_id, 0) & 0xffffffff) << 32;
                        if (is_signed)
                            value.GetScalar() = (int64_t)raw_value;
                        else
                            value.GetScalar() = (uint64_t)raw_value;
                        break;
                    case 32:
                        if (is_signed)
                            value.GetScalar() = (int32_t)(thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & 0xffffffff);
                        else
                            value.GetScalar() = (uint32_t)(thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & 0xffffffff);
                        break;
                    case 16:
                        if (is_signed)
                            value.GetScalar() = (int16_t)(thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & 0xffff);
                        else
                            value.GetScalar() = (uint16_t)(thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & 0xffff);
                        break;
                    case 8:
                        if (is_signed)
                            value.GetScalar() = (int8_t)(thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & 0xff);
                        else
                            value.GetScalar() = (uint8_t)(thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & 0xff);
                        break;
                }
            }
            else if (ClangASTContext::IsPointerType (value_type))
            {
                unsigned eax_id = reg_ctx->GetRegisterInfoByName("eax", 0)->kinds[eRegisterKindLLDB];
                uint32_t ptr = thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & 0xffffffff;
                value.GetScalar() = ptr;
            }
            else
            {
                // not handled yet
                return false;
            }
        }
            break;
    }
    
    return true;
}

void
ABIMacOSX_i386::Initialize()
{
    PluginManager::RegisterPlugin (pluginName,
                                   pluginDesc,
                                   CreateInstance);    
}

void
ABIMacOSX_i386::Terminate()
{
    PluginManager::UnregisterPlugin (CreateInstance);
}

//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
const char *
ABIMacOSX_i386::GetPluginName()
{
    return pluginName;
}

const char *
ABIMacOSX_i386::GetShortPluginName()
{
    return pluginShort;
}

uint32_t
ABIMacOSX_i386::GetPluginVersion()
{
    return 1;
}

void
ABIMacOSX_i386::GetPluginCommandHelp (const char *command, Stream *strm)
{
}

Error
ABIMacOSX_i386::ExecutePluginCommand (Args &command, Stream *strm)
{
    Error error;
    error.SetErrorString("No plug-in command are currently supported.");
    return error;
}

Log *
ABIMacOSX_i386::EnablePluginLogging (Stream *strm, Args &command)
{
    return NULL;
}
