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

#include "InferiorCallPOSIX.h"
#include "lldb/Core/Address.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Expression/DiagnosticManager.h"
#include "lldb/Host/Config.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Platform.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/ThreadPlanCallFunction.h"

#ifndef LLDB_DISABLE_POSIX
#include <sys/mman.h>
#else
// define them
#define PROT_NONE 0
#define PROT_READ 1
#define PROT_WRITE 2
#define PROT_EXEC 4
#endif

using namespace lldb;
using namespace lldb_private;

bool
lldb_private::InferiorCallMmap (Process *process,
                                addr_t &allocated_addr,
                                addr_t addr,
                                addr_t length,
                                unsigned prot,
                                unsigned flags,
                                addr_t fd,
                                addr_t offset)
{
    Thread *thread = process->GetThreadList().GetExpressionExecutionThread().get();
    if (thread == NULL)
        return false;

    const bool append = true;
    const bool include_symbols = true;
    const bool include_inlines = false;
    SymbolContextList sc_list;
    const uint32_t count
      = process->GetTarget().GetImages().FindFunctions (ConstString ("mmap"), 
                                                        eFunctionNameTypeFull,
                                                        include_symbols,
                                                        include_inlines,
                                                        append, 
                                                        sc_list);
    if (count > 0)
    {
        SymbolContext sc;
        if (sc_list.GetContextAtIndex(0, sc))
        {
            const uint32_t range_scope = eSymbolContextFunction | eSymbolContextSymbol;
            const bool use_inline_block_range = false;
            EvaluateExpressionOptions options;
            options.SetStopOthers(true);
            options.SetUnwindOnError(true);
            options.SetIgnoreBreakpoints(true);
            options.SetTryAllThreads(true);
            options.SetDebug (false);
            options.SetTimeoutUsec(500000);
            options.SetTrapExceptions(false);

            addr_t prot_arg, flags_arg = 0;
            if (prot == eMmapProtNone)
              prot_arg = PROT_NONE;
            else {
              prot_arg = 0;
              if (prot & eMmapProtExec)
                prot_arg |= PROT_EXEC;
              if (prot & eMmapProtRead)
                prot_arg |= PROT_READ;
              if (prot & eMmapProtWrite)
                prot_arg |= PROT_WRITE;
            }

            const ArchSpec arch =  process->GetTarget().GetArchitecture();
            flags_arg = process->GetTarget().GetPlatform()->ConvertMmapFlagsToPlatform(arch,flags);

            AddressRange mmap_range;
            if (sc.GetAddressRange(range_scope, 0, use_inline_block_range, mmap_range))
            {
                ClangASTContext *clang_ast_context = process->GetTarget().GetScratchClangASTContext();
                CompilerType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
                lldb::addr_t args[] = { addr, length, prot_arg, flags_arg, fd, offset };
                lldb::ThreadPlanSP call_plan_sp(new ThreadPlanCallFunction(*thread, mmap_range.GetBaseAddress(),
                                                                           clang_void_ptr_type, args, options));
                if (call_plan_sp)
                {
                    DiagnosticManager diagnostics;

                    StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
                    if (frame)
                    {
                        ExecutionContext exe_ctx;
                        frame->CalculateExecutionContext (exe_ctx);
                        ExpressionResults result = process->RunThreadPlan(exe_ctx, call_plan_sp, options, diagnostics);
                        if (result == eExpressionCompleted)
                        {

                            allocated_addr = call_plan_sp->GetReturnValueObject()->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
                            if (process->GetAddressByteSize() == 4)
                            {
                                if (allocated_addr == UINT32_MAX)
                                    return false;
                            }
                            else if (process->GetAddressByteSize() == 8)
                            {
                                if (allocated_addr == UINT64_MAX)
                                    return false;
                            }
                            return true;
                        }
                    }
                }
            }
        }
    }

    return false;
}

bool
lldb_private::InferiorCallMunmap (Process *process,
                                  addr_t addr,
                                  addr_t length)
{
   Thread *thread = process->GetThreadList().GetExpressionExecutionThread().get();
   if (thread == NULL)
       return false;
   
   const bool append = true;
   const bool include_symbols = true;
   const bool include_inlines = false;
   SymbolContextList sc_list;
   const uint32_t count
     = process->GetTarget().GetImages().FindFunctions (ConstString ("munmap"), 
                                                       eFunctionNameTypeFull,
                                                       include_symbols, 
                                                       include_inlines,
                                                       append, 
                                                       sc_list);
   if (count > 0)
   {
       SymbolContext sc;
       if (sc_list.GetContextAtIndex(0, sc))
       {
            const uint32_t range_scope = eSymbolContextFunction | eSymbolContextSymbol;
            const bool use_inline_block_range = false;
            EvaluateExpressionOptions options;
            options.SetStopOthers(true);
            options.SetUnwindOnError(true);
            options.SetIgnoreBreakpoints(true);
            options.SetTryAllThreads(true);
            options.SetDebug (false);
            options.SetTimeoutUsec(500000);
            options.SetTrapExceptions(false);
           
            AddressRange munmap_range;
            if (sc.GetAddressRange(range_scope, 0, use_inline_block_range, munmap_range))
            {
                lldb::addr_t args[] = { addr, length };
                lldb::ThreadPlanSP call_plan_sp(
                    new ThreadPlanCallFunction(*thread, munmap_range.GetBaseAddress(), CompilerType(), args, options));
                if (call_plan_sp)
                {
                    DiagnosticManager diagnostics;

                    StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
                    if (frame)
                    {
                        ExecutionContext exe_ctx;
                        frame->CalculateExecutionContext (exe_ctx);
                        ExpressionResults result = process->RunThreadPlan(exe_ctx, call_plan_sp, options, diagnostics);
                        if (result == eExpressionCompleted)
                        {
                            return true;
                        }
                    }
                }
            }
        }
    }

    return false;
}

// FIXME: This has nothing to do with Posix, it is just a convenience function that calls a
// function of the form "void * (*)(void)".  We should find a better place to put this.

bool
lldb_private::InferiorCall (Process *process,
                            const Address *address,
                            addr_t &returned_func,
                            bool trap_exceptions)
{
    Thread *thread = process->GetThreadList().GetExpressionExecutionThread().get();
    if (thread == NULL || address == NULL)
        return false;

    EvaluateExpressionOptions options;
    options.SetStopOthers(true);
    options.SetUnwindOnError(true);
    options.SetIgnoreBreakpoints(true);
    options.SetTryAllThreads(true);
    options.SetDebug (false);
    options.SetTimeoutUsec(500000);
    options.SetTrapExceptions(trap_exceptions);

    ClangASTContext *clang_ast_context = process->GetTarget().GetScratchClangASTContext();
    CompilerType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
    lldb::ThreadPlanSP call_plan_sp(
        new ThreadPlanCallFunction(*thread, *address, clang_void_ptr_type, llvm::ArrayRef<addr_t>(), options));
    if (call_plan_sp)
    {
        DiagnosticManager diagnostics;

        StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
        if (frame)
        {
            ExecutionContext exe_ctx;
            frame->CalculateExecutionContext (exe_ctx);
            ExpressionResults result = process->RunThreadPlan(exe_ctx, call_plan_sp, options, diagnostics);
            if (result == eExpressionCompleted)
            {
                returned_func = call_plan_sp->GetReturnValueObject()->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);

                if (process->GetAddressByteSize() == 4)
                {
                    if (returned_func == UINT32_MAX)
                        return false;
                }
                else if (process->GetAddressByteSize() == 8)
                {
                    if (returned_func == UINT64_MAX)
                        return false;
                }
                return true;
            }
        }
    }

    return false;
}
