//===-- ThreadPlanStepOut.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/ThreadPlanStepOut.h"

// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/Breakpoint/Breakpoint.h"
#include "lldb/lldb-private-log.h"
#include "lldb/Core/Log.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StopInfo.h"
#include "lldb/Target/Target.h"

using namespace lldb;
using namespace lldb_private;

//----------------------------------------------------------------------
// ThreadPlanStepOut: Step out of the current frame
//----------------------------------------------------------------------

ThreadPlanStepOut::ThreadPlanStepOut
(
    Thread &thread,
    SymbolContext *context,
    bool first_insn,
    bool stop_others,
    Vote stop_vote,
    Vote run_vote,
    uint32_t frame_idx
) :
    ThreadPlan (ThreadPlan::eKindStepOut, "Step out", thread, stop_vote, run_vote),
    m_step_from_context (context),
    m_step_from_insn (LLDB_INVALID_ADDRESS),
    m_return_bp_id (LLDB_INVALID_BREAK_ID),
    m_return_addr (LLDB_INVALID_ADDRESS),
    m_first_insn (first_insn),
    m_stop_others (stop_others)
{
    m_step_from_insn = m_thread.GetRegisterContext()->GetPC(0);

    // Find the return address and set a breakpoint there:
    // FIXME - can we do this more securely if we know first_insn?

    StackFrameSP return_frame_sp (m_thread.GetStackFrameAtIndex(frame_idx + 1));
    if (return_frame_sp)
    {
        // TODO: check for inlined frames and do the right thing...
        m_return_addr = return_frame_sp->GetRegisterContext()->GetPC();
        Breakpoint *return_bp = m_thread.GetProcess().GetTarget().CreateBreakpoint (m_return_addr, true).get();
        if (return_bp != NULL)
        {
            return_bp->SetThreadID(m_thread.GetID());
            m_return_bp_id = return_bp->GetID();
        }
    }

    m_stack_depth = m_thread.GetStackFrameCount() - frame_idx;
}

ThreadPlanStepOut::~ThreadPlanStepOut ()
{
    if (m_return_bp_id != LLDB_INVALID_BREAK_ID)
        m_thread.GetProcess().GetTarget().RemoveBreakpointByID(m_return_bp_id);
}

void
ThreadPlanStepOut::GetDescription (Stream *s, lldb::DescriptionLevel level)
{
    if (level == lldb::eDescriptionLevelBrief)
        s->Printf ("step out");
    else
    {
        s->Printf ("Stepping out from address 0x%llx to return address 0x%llx using breakpoint site %d",
                   (uint64_t)m_step_from_insn,
                   (uint64_t)m_return_addr,
                   m_return_bp_id);
    }
}

bool
ThreadPlanStepOut::ValidatePlan (Stream *error)
{
    if (m_return_bp_id == LLDB_INVALID_BREAK_ID)
        return false;
    else
        return true;
}

bool
ThreadPlanStepOut::PlanExplainsStop ()
{
    // We don't explain signals or breakpoints (breakpoints that handle stepping in or
    // out will be handled by a child plan.
    StopInfoSP stop_info_sp = GetPrivateStopReason();
    if (stop_info_sp)
    {
        StopReason reason = stop_info_sp->GetStopReason();
        switch (reason)
        {
        case eStopReasonBreakpoint:
        {
            // If this is OUR breakpoint, we're fine, otherwise we don't know why this happened...
            BreakpointSiteSP site_sp (m_thread.GetProcess().GetBreakpointSiteList().FindByID (stop_info_sp->GetValue()));
            if (site_sp && site_sp->IsBreakpointAtThisSite (m_return_bp_id))
            {
                const uint32_t num_frames = m_thread.GetStackFrameCount();
                if (m_stack_depth > num_frames)
                    SetPlanComplete();

                // If there was only one owner, then we're done.  But if we also hit some
                // user breakpoint on our way out, we should mark ourselves as done, but
                // also not claim to explain the stop, since it is more important to report
                // the user breakpoint than the step out completion.

                if (site_sp->GetNumberOfOwners() == 1)
                    return true;
                
            }
            return false;
        }
        case eStopReasonWatchpoint:
        case eStopReasonSignal:
        case eStopReasonException:
            return false;

        default:
            return true;
        }
    }
    return true;
}

bool
ThreadPlanStepOut::ShouldStop (Event *event_ptr)
{
    if (IsPlanComplete() || m_stack_depth > m_thread.GetStackFrameCount())
    {
        SetPlanComplete();
        return true;
    }
    else
        return false;
}

bool
ThreadPlanStepOut::StopOthers ()
{
    return m_stop_others;
}

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

bool
ThreadPlanStepOut::WillResume (StateType resume_state, bool current_plan)
{
    ThreadPlan::WillResume (resume_state, current_plan);
    if (m_return_bp_id == LLDB_INVALID_BREAK_ID)
        return false;

    if (current_plan)
    {
        Breakpoint *return_bp = m_thread.GetProcess().GetTarget().GetBreakpointByID(m_return_bp_id).get();
        if (return_bp != NULL)
            return_bp->SetEnabled (true);
    }
    return true;
}

bool
ThreadPlanStepOut::WillStop ()
{
    Breakpoint *return_bp = m_thread.GetProcess().GetTarget().GetBreakpointByID(m_return_bp_id).get();
    if (return_bp != NULL)
        return_bp->SetEnabled (false);
    return true;
}

bool
ThreadPlanStepOut::MischiefManaged ()
{
    if (m_return_bp_id == LLDB_INVALID_BREAK_ID)
    {
        // If I couldn't set this breakpoint, then I'm just going to jettison myself.
        return true;
    }
    else if (IsPlanComplete())
    {
        // Did I reach my breakpoint?  If so I'm done.
        //
        // I also check the stack depth, since if we've blown past the breakpoint for some
        // reason and we're now stopping for some other reason altogether, then we're done
        // with this step out operation.

        LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
        if (log)
            log->Printf("Completed step out plan.");
        m_thread.GetProcess().GetTarget().RemoveBreakpointByID (m_return_bp_id);
        m_return_bp_id = LLDB_INVALID_BREAK_ID;
        ThreadPlan::MischiefManaged ();
        return true;
    }
    else
    {
        return false;
    }
}

