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

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

using namespace lldb;
using namespace lldb_private;

//----------------------------------------------------------------------
// ThreadPlanStepOverBreakpoint: Single steps over a breakpoint bp_site_sp at the pc.
//----------------------------------------------------------------------

ThreadPlanStepOverBreakpoint::ThreadPlanStepOverBreakpoint (Thread &thread) :
    ThreadPlan (ThreadPlan::eKindStepOverBreakpoint, "Step over breakpoint trap",
                thread,
                eVoteNo,
                eVoteNoOpinion),  // We need to report the run since this happens
                            // first in the thread plan stack when stepping
                            // over a breakpoint
    m_breakpoint_addr (LLDB_INVALID_ADDRESS),
    m_auto_continue(false),
    m_reenabled_breakpoint_site (false)

{
    m_breakpoint_addr = m_thread.GetRegisterContext()->GetPC();
    m_breakpoint_site_id =  m_thread.GetProcess()->GetBreakpointSiteList().FindIDByAddress (m_breakpoint_addr);
}

ThreadPlanStepOverBreakpoint::~ThreadPlanStepOverBreakpoint ()
{
}

void
ThreadPlanStepOverBreakpoint::GetDescription (Stream *s, lldb::DescriptionLevel level)
{
    s->Printf("Single stepping past breakpoint site %" PRIu64 " at 0x%" PRIx64, m_breakpoint_site_id, (uint64_t)m_breakpoint_addr);
}

bool
ThreadPlanStepOverBreakpoint::ValidatePlan (Stream *error)
{
    return true;
}

bool
ThreadPlanStepOverBreakpoint::DoPlanExplainsStop (Event *event_ptr)
{
    StopInfoSP stop_info_sp = GetPrivateStopInfo ();
    if (stop_info_sp)
    {
        // It's a little surprising that we stop here for a breakpoint hit.  However, when you single step ONTO a breakpoint
        // we still want to call that a breakpoint hit, and trigger the actions, etc.  Otherwise you would see the
        // PC at the breakpoint without having triggered the actions, then you'd continue, the PC wouldn't change,
        // and you'd see the breakpoint hit, which would be odd.
        // So the lower levels fake "step onto breakpoint address" and return that as a breakpoint.  So our trace
        // step COULD appear as a breakpoint hit if the next instruction also contained a breakpoint.
        StopReason reason = stop_info_sp->GetStopReason();

        switch (reason)
        {
        case eStopReasonTrace:
        case eStopReasonNone:
            return true;
        case eStopReasonBreakpoint:
            // It's a little surprising that we stop here for a breakpoint hit.  However, when you single step ONTO a
            // breakpoint we still want to call that a breakpoint hit, and trigger the actions, etc.  Otherwise you
            // would see the PC at the breakpoint without having triggered the actions, then you'd continue, the PC
            // wouldn't change, and you'd see the breakpoint hit, which would be odd.
            // So the lower levels fake "step onto breakpoint address" and return that as a breakpoint hit.  So our trace
            // step COULD appear as a breakpoint hit if the next instruction also contained a breakpoint.  We don't want
            // to handle that, since we really don't know what to do with breakpoint hits.  But make sure we don't set
            // ourselves to auto-continue or we'll wrench control away from the plans that can deal with this.
            SetAutoContinue(false);
            return false;
        default:
            return false;
        }
    }
    return false;
}

bool
ThreadPlanStepOverBreakpoint::ShouldStop (Event *event_ptr)
{
    return !ShouldAutoContinue(event_ptr);
}

bool
ThreadPlanStepOverBreakpoint::StopOthers ()
{
    return true;
}

StateType
ThreadPlanStepOverBreakpoint::GetPlanRunState ()
{
    return eStateStepping;
}

bool
ThreadPlanStepOverBreakpoint::DoWillResume (StateType resume_state, bool current_plan)
{
    if (current_plan)
    {
        BreakpointSiteSP bp_site_sp (m_thread.GetProcess()->GetBreakpointSiteList().FindByAddress (m_breakpoint_addr));
        if (bp_site_sp  && bp_site_sp->IsEnabled())
            m_thread.GetProcess()->DisableBreakpointSite (bp_site_sp.get());
    }
    return true;
}

bool
ThreadPlanStepOverBreakpoint::WillStop ()
{
    ReenableBreakpointSite ();
    return true;
}

bool
ThreadPlanStepOverBreakpoint::MischiefManaged ()
{
    lldb::addr_t pc_addr = m_thread.GetRegisterContext()->GetPC();

    if (pc_addr == m_breakpoint_addr)
    {
        // If we are still at the PC of our breakpoint, then for some reason we didn't
        // get a chance to run.
        return false;
    }
    else
    {
        Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
        if (log)
            log->Printf("Completed step over breakpoint plan.");
        // Otherwise, re-enable the breakpoint we were stepping over, and we're done.
        ReenableBreakpointSite ();
        ThreadPlan::MischiefManaged ();
        return true;
    }
}

void
ThreadPlanStepOverBreakpoint::ReenableBreakpointSite ()
{
    if (!m_reenabled_breakpoint_site)
    {
        m_reenabled_breakpoint_site = true;
        BreakpointSiteSP bp_site_sp (m_thread.GetProcess()->GetBreakpointSiteList().FindByAddress (m_breakpoint_addr));
        if (bp_site_sp)
        {
            m_thread.GetProcess()->EnableBreakpointSite (bp_site_sp.get());
        }
    }
}
void
ThreadPlanStepOverBreakpoint::ThreadDestroyed ()
{
    ReenableBreakpointSite ();
}

void
ThreadPlanStepOverBreakpoint::SetAutoContinue (bool do_it)
{
    m_auto_continue = do_it;
}

bool
ThreadPlanStepOverBreakpoint::ShouldAutoContinue (Event *event_ptr)
{
    return m_auto_continue;
}

bool
ThreadPlanStepOverBreakpoint::IsPlanStale()
{
    return m_thread.GetRegisterContext()->GetPC() != m_breakpoint_addr;
}

