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

#include "lldb/Target/ThreadPlanCallFunction.h"

// C Includes
// C++ Includes
// Other libraries and framework includes
#include "llvm/Support/MachO.h"
// Project includes
#include "lldb/lldb-private-log.h"
#include "lldb/Breakpoint/Breakpoint.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Core/Address.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/Stream.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/LanguageRuntime.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StopInfo.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadPlanRunToAddress.h"

using namespace lldb;
using namespace lldb_private;

//----------------------------------------------------------------------
// ThreadPlanCallFunction: Plan to call a single function
//----------------------------------------------------------------------
bool
ThreadPlanCallFunction::ConstructorSetup (Thread &thread,
                                          ABI *& abi,
                                          lldb::addr_t &start_load_addr,
                                          lldb::addr_t &function_load_addr)
{
    SetIsMasterPlan (true);
    SetOkayToDiscard (false);
    SetPrivate (true);

    ProcessSP process_sp (thread.GetProcess());
    if (!process_sp)
        return false;
    
    abi = process_sp->GetABI().get();
    
    if (!abi)
        return false;
    
    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP));
    
    SetBreakpoints();
    
    m_function_sp = thread.GetRegisterContext()->GetSP() - abi->GetRedZoneSize();
    // If we can't read memory at the point of the process where we are planning to put our function, we're
    // not going to get any further...
    Error error;
    process_sp->ReadUnsignedIntegerFromMemory(m_function_sp, 4, 0, error);
    if (!error.Success())
    {
        m_constructor_errors.Printf ("Trying to put the stack in unreadable memory at: 0x%" PRIx64 ".", m_function_sp);
        if (log)
            log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData());
        return false;
    }
    
    Module *exe_module = GetTarget().GetExecutableModulePointer();

    if (exe_module == NULL)
    {
        m_constructor_errors.Printf ("Can't execute code without an executable module.");
        if (log)
            log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData());
        return false;
    }
    else
    {
        ObjectFile *objectFile = exe_module->GetObjectFile();
        if (!objectFile)
        {
            m_constructor_errors.Printf ("Could not find object file for module \"%s\".", 
                                         exe_module->GetFileSpec().GetFilename().AsCString());

            if (log)
                log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData());
            return false;
        }
        
        m_start_addr = objectFile->GetEntryPointAddress();
        if (!m_start_addr.IsValid())
        {
            m_constructor_errors.Printf ("Could not find entry point address for executable module \"%s\".", 
                                         exe_module->GetFileSpec().GetFilename().AsCString());
            if (log)
                log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData());
            return false;
        }
    }
    
    start_load_addr = m_start_addr.GetLoadAddress (&GetTarget());
    
    // Checkpoint the thread state so we can restore it later.
    if (log && log->GetVerbose())
        ReportRegisterState ("About to checkpoint thread before function call.  Original register state was:");

    if (!thread.CheckpointThreadState (m_stored_thread_state))
    {
        m_constructor_errors.Printf ("Setting up ThreadPlanCallFunction, failed to checkpoint thread state.");
        if (log)
            log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData());
        return false;
    }
    function_load_addr = m_function_addr.GetLoadAddress (&GetTarget());
    
    return true;
}

ThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread,
                                                const Address &function,
                                                const ClangASTType &return_type,
                                                llvm::ArrayRef<addr_t> args,
                                                const EvaluateExpressionOptions &options) :
    ThreadPlan (ThreadPlan::eKindCallFunction, "Call function plan", thread, eVoteNoOpinion, eVoteNoOpinion),
    m_valid (false),
    m_stop_other_threads (options.GetStopOthers()),
    m_unwind_on_error (options.DoesUnwindOnError()),
    m_ignore_breakpoints (options.DoesIgnoreBreakpoints()),
    m_debug_execution (options.GetDebug()),
    m_trap_exceptions (options.GetTrapExceptions()),
    m_function_addr (function),
    m_function_sp (0),
    m_return_type (return_type),
    m_takedown_done (false),
    m_should_clear_objc_exception_bp(false),
    m_should_clear_cxx_exception_bp (false),
    m_stop_address (LLDB_INVALID_ADDRESS)
{
    lldb::addr_t start_load_addr;
    ABI *abi;
    lldb::addr_t function_load_addr;
    if (!ConstructorSetup (thread, abi, start_load_addr, function_load_addr))
        return;
    
    if (!abi->PrepareTrivialCall(thread,
                                 m_function_sp,
                                 function_load_addr,
                                 start_load_addr,
                                 args))
        return;
    
    ReportRegisterState ("Function call was set up.  Register state was:");
    
    m_valid = true;    
}

ThreadPlanCallFunction::~ThreadPlanCallFunction ()
{
    DoTakedown(PlanSucceeded());
}

void
ThreadPlanCallFunction::ReportRegisterState (const char *message)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP | LIBLLDB_LOG_VERBOSE));
    if (log)
    {
        StreamString strm;
        RegisterContext *reg_ctx = m_thread.GetRegisterContext().get();

        log->PutCString(message);

        RegisterValue reg_value;

        for (uint32_t reg_idx = 0, num_registers = reg_ctx->GetRegisterCount();
             reg_idx < num_registers;
             ++reg_idx)
        {
            const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_idx);
            if (reg_ctx->ReadRegister(reg_info, reg_value))
            {
                reg_value.Dump(&strm, reg_info, true, false, eFormatDefault);
                strm.EOL();
            }
        }
        log->PutCString(strm.GetData());
    }
}

void
ThreadPlanCallFunction::DoTakedown (bool success)
{
    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP));
    
    if (!m_valid)
    {
        //Don't call DoTakedown if we were never valid to begin with.
        if (log)
            log->Printf ("ThreadPlanCallFunction(%p): Log called on ThreadPlanCallFunction that was never valid.", this);
        return;
    }
    
    if (!m_takedown_done)
    {
        if (success)
        {
            ProcessSP process_sp (m_thread.GetProcess());
            const ABI *abi = process_sp ? process_sp->GetABI().get() : NULL;
            if (abi && m_return_type.IsValid())
            {
                const bool persistent = false;
                m_return_valobj_sp = abi->GetReturnValueObject (m_thread, m_return_type, persistent);
            }
        }
        if (log)
            log->Printf ("ThreadPlanCallFunction(%p): DoTakedown called for thread 0x%4.4" PRIx64 ", m_valid: %d complete: %d.\n", this, m_thread.GetID(), m_valid, IsPlanComplete());
        m_takedown_done = true;
        m_stop_address = m_thread.GetStackFrameAtIndex(0)->GetRegisterContext()->GetPC();
        m_real_stop_info_sp = GetPrivateStopInfo ();
        if (!m_thread.RestoreRegisterStateFromCheckpoint(m_stored_thread_state))
        {
            if (log)
                log->Printf("ThreadPlanCallFunction(%p): DoTakedown failed to restore register state", this);
        }
        SetPlanComplete(success);
        ClearBreakpoints();
        if (log && log->GetVerbose())
            ReportRegisterState ("Restoring thread state after function call.  Restored register state:");

    }
    else
    {
        if (log)
            log->Printf ("ThreadPlanCallFunction(%p): DoTakedown called as no-op for thread 0x%4.4" PRIx64 ", m_valid: %d complete: %d.\n", this, m_thread.GetID(), m_valid, IsPlanComplete());
    }
}

void
ThreadPlanCallFunction::WillPop ()
{
    DoTakedown(PlanSucceeded());
}

void
ThreadPlanCallFunction::GetDescription (Stream *s, DescriptionLevel level)
{
    if (level == eDescriptionLevelBrief)
    {
        s->Printf("Function call thread plan");
    }
    else
    {
        TargetSP target_sp (m_thread.CalculateTarget());
        s->Printf("Thread plan to call 0x%" PRIx64, m_function_addr.GetLoadAddress(target_sp.get()));
    }
}

bool
ThreadPlanCallFunction::ValidatePlan (Stream *error)
{
    if (!m_valid)
    {
        if (error)
        {
            if (m_constructor_errors.GetSize() > 0)
                error->PutCString (m_constructor_errors.GetData());
            else
                error->PutCString ("Unknown error");
        }
        return false;
    }

    return true;
}


Vote
ThreadPlanCallFunction::ShouldReportStop(Event *event_ptr)
{
    if (m_takedown_done || IsPlanComplete())
        return eVoteYes;
    else
        return ThreadPlan::ShouldReportStop(event_ptr);
}

bool
ThreadPlanCallFunction::DoPlanExplainsStop (Event *event_ptr)
{    
    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP|LIBLLDB_LOG_PROCESS));
    m_real_stop_info_sp = GetPrivateStopInfo ();
    
    // If our subplan knows why we stopped, even if it's done (which would forward the question to us)
    // we answer yes.
    if (m_subplan_sp.get() != NULL && m_subplan_sp->PlanExplainsStop(event_ptr))
    {
        SetPlanComplete();
        return true;
    }
    
    // Check if the breakpoint is one of ours.
    
    StopReason stop_reason;
    if (!m_real_stop_info_sp)
        stop_reason = eStopReasonNone;
    else
        stop_reason = m_real_stop_info_sp->GetStopReason();
    if (log)
        log->Printf ("ThreadPlanCallFunction::PlanExplainsStop: Got stop reason - %s.", Thread::StopReasonAsCString(stop_reason));

    if (stop_reason == eStopReasonBreakpoint && BreakpointsExplainStop())
        return true;
    
    // We control breakpoints separately from other "stop reasons."  So first,
    // check the case where we stopped for an internal breakpoint, in that case, continue on.
    // If it is not an internal breakpoint, consult m_ignore_breakpoints.
    
    
    if (stop_reason == eStopReasonBreakpoint)
    {
        ProcessSP process_sp (m_thread.CalculateProcess());
        uint64_t break_site_id = m_real_stop_info_sp->GetValue();
        BreakpointSiteSP bp_site_sp;
        if (process_sp)
            bp_site_sp = process_sp->GetBreakpointSiteList().FindByID(break_site_id);
        if (bp_site_sp)
        {
            uint32_t num_owners = bp_site_sp->GetNumberOfOwners();
            bool is_internal = true;
            for (uint32_t i = 0; i < num_owners; i++)
            {
                Breakpoint &bp = bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint();
                if (log)
                    log->Printf ("ThreadPlanCallFunction::PlanExplainsStop: hit breakpoint %d while calling function", bp.GetID());
                
                if (!bp.IsInternal())
                {
                    is_internal = false;
                    break;
                }
            }
            if (is_internal)
            {
                if (log)
                    log->Printf ("ThreadPlanCallFunction::PlanExplainsStop hit an internal breakpoint, not stopping.");
                return false;
            }
        }

        if (m_ignore_breakpoints)
        {
            if (log)
                log->Printf("ThreadPlanCallFunction::PlanExplainsStop: we are ignoring breakpoints, overriding breakpoint stop info ShouldStop, returning true");
            m_real_stop_info_sp->OverrideShouldStop(false);
            return true;
        }
        else
        {
            if (log)
                log->Printf("ThreadPlanCallFunction::PlanExplainsStop: we are not ignoring breakpoints, overriding breakpoint stop info ShouldStop, returning true");
            m_real_stop_info_sp->OverrideShouldStop(true);
            return false;
        }
    }
    else if (!m_unwind_on_error)
    {
        // If we don't want to discard this plan, than any stop we don't understand should be propagated up the stack.
        return false;
    }
    else
    {
        // If the subplan is running, any crashes are attributable to us.
        // If we want to discard the plan, then we say we explain the stop
        // but if we are going to be discarded, let whoever is above us
        // explain the stop.
        // But don't discard the plan if the stop would restart itself (for instance if it is a
        // signal that is set not to stop.  Check that here first.  We just say we explain the stop
        // but aren't done and everything will continue on from there.
        
        if (m_real_stop_info_sp->ShouldStopSynchronous(event_ptr))
        {
            SetPlanComplete(false);
            if (m_subplan_sp)
            {
                if (m_unwind_on_error)
                    return true;
                else
                    return false;
            }
            else
                return false;
        }
        else
            return true;
    }
}

bool
ThreadPlanCallFunction::ShouldStop (Event *event_ptr)
{
    // We do some computation in DoPlanExplainsStop that may or may not set the plan as complete.
    // We need to do that here to make sure our state is correct.
    DoPlanExplainsStop(event_ptr);
    
    if (IsPlanComplete())
    {
        ReportRegisterState ("Function completed.  Register state was:");
        return true;
    }
    else
    {
        return false;
    }
}

bool
ThreadPlanCallFunction::StopOthers ()
{
    return m_stop_other_threads;
}

void
ThreadPlanCallFunction::SetStopOthers (bool new_value)
{
    if (m_subplan_sp)
    {
        ThreadPlanRunToAddress *address_plan = static_cast<ThreadPlanRunToAddress *>(m_subplan_sp.get());
        address_plan->SetStopOthers(new_value);
    }
    m_stop_other_threads = new_value;
}

StateType
ThreadPlanCallFunction::GetPlanRunState ()
{
    return eStateRunning;
}

void
ThreadPlanCallFunction::DidPush ()
{
//#define SINGLE_STEP_EXPRESSIONS
    
    // Now set the thread state to "no reason" so we don't run with whatever signal was outstanding...
    // Wait till the plan is pushed so we aren't changing the stop info till we're about to run.
    
    GetThread().SetStopInfoToNothing();
    
#ifndef SINGLE_STEP_EXPRESSIONS
    m_subplan_sp.reset(new ThreadPlanRunToAddress(m_thread, m_start_addr, m_stop_other_threads));
    
    m_thread.QueueThreadPlan(m_subplan_sp, false);
    m_subplan_sp->SetPrivate (true);
#endif
}

bool
ThreadPlanCallFunction::WillStop ()
{
    return true;
}

bool
ThreadPlanCallFunction::MischiefManaged ()
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
    
    if (IsPlanComplete())
    {
        if (log)
            log->Printf("ThreadPlanCallFunction(%p): Completed call function plan.", this);

        ThreadPlan::MischiefManaged ();
        return true;
    }
    else
    {
        return false;
    }
}

void
ThreadPlanCallFunction::SetBreakpoints ()
{
    ProcessSP process_sp (m_thread.CalculateProcess());
    if (m_trap_exceptions && process_sp)
    {
        m_cxx_language_runtime = process_sp->GetLanguageRuntime(eLanguageTypeC_plus_plus);
        m_objc_language_runtime = process_sp->GetLanguageRuntime(eLanguageTypeObjC);
    
        if (m_cxx_language_runtime)
        {
            m_should_clear_cxx_exception_bp = !m_cxx_language_runtime->ExceptionBreakpointsAreSet();
            m_cxx_language_runtime->SetExceptionBreakpoints();
        }
        if (m_objc_language_runtime)
        {
            m_should_clear_objc_exception_bp = !m_objc_language_runtime->ExceptionBreakpointsAreSet();
            m_objc_language_runtime->SetExceptionBreakpoints();
        }
    }
}

void
ThreadPlanCallFunction::ClearBreakpoints ()
{
    if (m_trap_exceptions)
    {
        if (m_cxx_language_runtime && m_should_clear_cxx_exception_bp)
            m_cxx_language_runtime->ClearExceptionBreakpoints();
        if (m_objc_language_runtime && m_should_clear_objc_exception_bp)
            m_objc_language_runtime->ClearExceptionBreakpoints();
    }
}

bool
ThreadPlanCallFunction::BreakpointsExplainStop()
{
    StopInfoSP stop_info_sp = GetPrivateStopInfo ();
    
    if (m_trap_exceptions)
    {
        if ((m_cxx_language_runtime &&
                m_cxx_language_runtime->ExceptionBreakpointsExplainStop(stop_info_sp))
           ||(m_objc_language_runtime &&
                m_objc_language_runtime->ExceptionBreakpointsExplainStop(stop_info_sp)))
        {
            Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP));
            if (log)
                log->Printf ("ThreadPlanCallFunction::BreakpointsExplainStop - Hit an exception breakpoint, setting plan complete.");
            
            SetPlanComplete(false);
            
            // If the user has set the ObjC language breakpoint, it would normally get priority over our internal
            // catcher breakpoint, but in this case we can't let that happen, so force the ShouldStop here.
            stop_info_sp->OverrideShouldStop (true);
            return true;
        }
    }
    
    return false;
}

bool
ThreadPlanCallFunction::RestoreThreadState()
{
    return GetThread().RestoreThreadStateFromCheckpoint(m_stored_thread_state);
}

