//===-- 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;
    
    TargetSP target_sp (thread.CalculateTarget());

    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 = target_sp->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 (target_sp.get());
    
    // 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 (target_sp.get());
    
    return true;
}

ThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread,
                                                const Address &function,
                                                const ClangASTType &return_type,
                                                addr_t arg,
                                                bool stop_other_threads,
                                                bool unwind_on_error,
                                                bool ignore_breakpoints,
                                                addr_t *this_arg,
                                                addr_t *cmd_arg) :
    ThreadPlan (ThreadPlan::eKindCallFunction, "Call function plan", thread, eVoteNoOpinion, eVoteNoOpinion),
    m_valid (false),
    m_stop_other_threads (stop_other_threads),
    m_function_addr (function),
    m_function_sp (0),
    m_return_type (return_type),
    m_takedown_done (false),
    m_stop_address (LLDB_INVALID_ADDRESS),
    m_unwind_on_error (unwind_on_error),
    m_ignore_breakpoints (ignore_breakpoints)
{
    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 (this_arg && cmd_arg)
    {
        if (!abi->PrepareTrivialCall (thread, 
                                      m_function_sp, 
                                      function_load_addr, 
                                      start_load_addr, 
                                      this_arg,
                                      cmd_arg,
                                      &arg))
            return;
    }
    else if (this_arg)
    {
        if (!abi->PrepareTrivialCall (thread, 
                                      m_function_sp, 
                                      function_load_addr, 
                                      start_load_addr, 
                                      this_arg,
                                      &arg))
            return;
    }
    else
    {
        if (!abi->PrepareTrivialCall (thread, 
                                      m_function_sp, 
                                      function_load_addr, 
                                      start_load_addr, 
                                      &arg))
            return;
    }
    
    ReportRegisterState ("Function call was set up.  Register state was:");
    
    m_valid = true;    
}


ThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread,
                                                const Address &function,
                                                const ClangASTType &return_type,
                                                bool stop_other_threads,
                                                bool unwind_on_error,
                                                bool ignore_breakpoints,
                                                addr_t *arg1_ptr,
                                                addr_t *arg2_ptr,
                                                addr_t *arg3_ptr,
                                                addr_t *arg4_ptr,
                                                addr_t *arg5_ptr,
                                                addr_t *arg6_ptr) :
    ThreadPlan (ThreadPlan::eKindCallFunction, "Call function plan", thread, eVoteNoOpinion, eVoteNoOpinion),
    m_valid (false),
    m_stop_other_threads (stop_other_threads),
    m_function_addr (function),
    m_function_sp (0),
    m_return_type (return_type),
    m_takedown_done (false),
    m_stop_address (LLDB_INVALID_ADDRESS),
    m_unwind_on_error (unwind_on_error),
    m_ignore_breakpoints (ignore_breakpoints)
{
    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, 
                                  arg1_ptr,
                                  arg2_ptr,
                                  arg3_ptr,
                                  arg4_ptr,
                                  arg5_ptr,
                                  arg6_ptr))
    {
            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 ();
        m_thread.RestoreRegisterStateFromCheckpoint(m_stored_thread_state);
        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 (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_cxx_language_runtime->SetExceptionBreakpoints();
        if (m_objc_language_runtime)
            m_objc_language_runtime->SetExceptionBreakpoints();
    }
}

void
ThreadPlanCallFunction::ClearBreakpoints ()
{
    if (m_cxx_language_runtime)
        m_cxx_language_runtime->ClearExceptionBreakpoints();
    if (m_objc_language_runtime)
        m_objc_language_runtime->ClearExceptionBreakpoints();
}

bool
ThreadPlanCallFunction::BreakpointsExplainStop()
{
    StopInfoSP stop_info_sp = GetPrivateStopInfo ();
    
    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);
}

