1*30fdc8d8SChris Lattner //===-- ThreadPlanStepOverBreakpoint.cpp ------------------------*- C++ -*-===//
2*30fdc8d8SChris Lattner //
3*30fdc8d8SChris Lattner //                     The LLVM Compiler Infrastructure
4*30fdc8d8SChris Lattner //
5*30fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source
6*30fdc8d8SChris Lattner // License. See LICENSE.TXT for details.
7*30fdc8d8SChris Lattner //
8*30fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
9*30fdc8d8SChris Lattner 
10*30fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepOverBreakpoint.h"
11*30fdc8d8SChris Lattner 
12*30fdc8d8SChris Lattner // C Includes
13*30fdc8d8SChris Lattner // C++ Includes
14*30fdc8d8SChris Lattner // Other libraries and framework includes
15*30fdc8d8SChris Lattner // Project includes
16*30fdc8d8SChris Lattner #include "lldb/lldb-private-log.h"
17*30fdc8d8SChris Lattner #include "lldb/Core/Log.h"
18*30fdc8d8SChris Lattner #include "lldb/Core/Stream.h"
19*30fdc8d8SChris Lattner #include "lldb/Target/Process.h"
20*30fdc8d8SChris Lattner #include "lldb/Target/RegisterContext.h"
21*30fdc8d8SChris Lattner 
22*30fdc8d8SChris Lattner using namespace lldb;
23*30fdc8d8SChris Lattner using namespace lldb_private;
24*30fdc8d8SChris Lattner 
25*30fdc8d8SChris Lattner //----------------------------------------------------------------------
26*30fdc8d8SChris Lattner // ThreadPlanStepOverBreakpoint: Single steps over a breakpoint bp_site_sp at the pc.
27*30fdc8d8SChris Lattner //----------------------------------------------------------------------
28*30fdc8d8SChris Lattner 
29*30fdc8d8SChris Lattner ThreadPlanStepOverBreakpoint::ThreadPlanStepOverBreakpoint (Thread &thread) :
30*30fdc8d8SChris Lattner     ThreadPlan ("Step over breakpoint trap",
31*30fdc8d8SChris Lattner                 thread,
32*30fdc8d8SChris Lattner                 eVoteNo,
33*30fdc8d8SChris Lattner                 eVoteNoOpinion),  // We need to report the run since this happens
34*30fdc8d8SChris Lattner                             // first in the thread plan stack when stepping
35*30fdc8d8SChris Lattner                             // over a breakpoint
36*30fdc8d8SChris Lattner     m_breakpoint_addr (LLDB_INVALID_ADDRESS)
37*30fdc8d8SChris Lattner {
38*30fdc8d8SChris Lattner     m_breakpoint_addr = m_thread.GetRegisterContext()->GetPC();
39*30fdc8d8SChris Lattner     m_breakpoint_site_id =  m_thread.GetProcess().GetBreakpointSiteList().FindIDByAddress (m_breakpoint_addr);
40*30fdc8d8SChris Lattner 
41*30fdc8d8SChris Lattner }
42*30fdc8d8SChris Lattner 
43*30fdc8d8SChris Lattner ThreadPlanStepOverBreakpoint::~ThreadPlanStepOverBreakpoint ()
44*30fdc8d8SChris Lattner {
45*30fdc8d8SChris Lattner }
46*30fdc8d8SChris Lattner 
47*30fdc8d8SChris Lattner void
48*30fdc8d8SChris Lattner ThreadPlanStepOverBreakpoint::GetDescription (Stream *s, lldb::DescriptionLevel level)
49*30fdc8d8SChris Lattner {
50*30fdc8d8SChris Lattner     s->Printf("Single stepping past breakpoint site %d at 0x%llx", m_breakpoint_site_id, (uint64_t)m_breakpoint_addr);
51*30fdc8d8SChris Lattner }
52*30fdc8d8SChris Lattner 
53*30fdc8d8SChris Lattner bool
54*30fdc8d8SChris Lattner ThreadPlanStepOverBreakpoint::ValidatePlan (Stream *error)
55*30fdc8d8SChris Lattner {
56*30fdc8d8SChris Lattner     return true;
57*30fdc8d8SChris Lattner }
58*30fdc8d8SChris Lattner 
59*30fdc8d8SChris Lattner bool
60*30fdc8d8SChris Lattner ThreadPlanStepOverBreakpoint::PlanExplainsStop ()
61*30fdc8d8SChris Lattner {
62*30fdc8d8SChris Lattner     return true;
63*30fdc8d8SChris Lattner }
64*30fdc8d8SChris Lattner 
65*30fdc8d8SChris Lattner bool
66*30fdc8d8SChris Lattner ThreadPlanStepOverBreakpoint::ShouldStop (Event *event_ptr)
67*30fdc8d8SChris Lattner {
68*30fdc8d8SChris Lattner     return false;
69*30fdc8d8SChris Lattner }
70*30fdc8d8SChris Lattner 
71*30fdc8d8SChris Lattner bool
72*30fdc8d8SChris Lattner ThreadPlanStepOverBreakpoint::StopOthers ()
73*30fdc8d8SChris Lattner {
74*30fdc8d8SChris Lattner     return true;
75*30fdc8d8SChris Lattner }
76*30fdc8d8SChris Lattner 
77*30fdc8d8SChris Lattner StateType
78*30fdc8d8SChris Lattner ThreadPlanStepOverBreakpoint::RunState ()
79*30fdc8d8SChris Lattner {
80*30fdc8d8SChris Lattner     return eStateStepping;
81*30fdc8d8SChris Lattner }
82*30fdc8d8SChris Lattner 
83*30fdc8d8SChris Lattner bool
84*30fdc8d8SChris Lattner ThreadPlanStepOverBreakpoint::WillResume (StateType resume_state, bool current_plan)
85*30fdc8d8SChris Lattner {
86*30fdc8d8SChris Lattner     ThreadPlan::WillResume (resume_state, current_plan);
87*30fdc8d8SChris Lattner 
88*30fdc8d8SChris Lattner     if (current_plan)
89*30fdc8d8SChris Lattner     {
90*30fdc8d8SChris Lattner         BreakpointSiteSP bp_site_sp (m_thread.GetProcess().GetBreakpointSiteList().FindByAddress (m_breakpoint_addr));
91*30fdc8d8SChris Lattner         if (bp_site_sp  && bp_site_sp->IsEnabled())
92*30fdc8d8SChris Lattner             m_thread.GetProcess().DisableBreakpoint (bp_site_sp.get());
93*30fdc8d8SChris Lattner     }
94*30fdc8d8SChris Lattner     return true;
95*30fdc8d8SChris Lattner }
96*30fdc8d8SChris Lattner 
97*30fdc8d8SChris Lattner bool
98*30fdc8d8SChris Lattner ThreadPlanStepOverBreakpoint::WillStop ()
99*30fdc8d8SChris Lattner {
100*30fdc8d8SChris Lattner     BreakpointSiteSP bp_site_sp (m_thread.GetProcess().GetBreakpointSiteList().FindByAddress (m_breakpoint_addr));
101*30fdc8d8SChris Lattner     if (bp_site_sp)
102*30fdc8d8SChris Lattner         m_thread.GetProcess().EnableBreakpoint (bp_site_sp.get());
103*30fdc8d8SChris Lattner     return true;
104*30fdc8d8SChris Lattner }
105*30fdc8d8SChris Lattner 
106*30fdc8d8SChris Lattner bool
107*30fdc8d8SChris Lattner ThreadPlanStepOverBreakpoint::MischiefManaged ()
108*30fdc8d8SChris Lattner {
109*30fdc8d8SChris Lattner     lldb::addr_t pc_addr = m_thread.GetRegisterContext()->GetPC();
110*30fdc8d8SChris Lattner 
111*30fdc8d8SChris Lattner     if (pc_addr == m_breakpoint_addr)
112*30fdc8d8SChris Lattner     {
113*30fdc8d8SChris Lattner         // If we are still at the PC of our breakpoint, then for some reason we didn't
114*30fdc8d8SChris Lattner         // get a chance to run.
115*30fdc8d8SChris Lattner         return false;
116*30fdc8d8SChris Lattner     }
117*30fdc8d8SChris Lattner     else
118*30fdc8d8SChris Lattner     {
119*30fdc8d8SChris Lattner         Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
120*30fdc8d8SChris Lattner         if (log)
121*30fdc8d8SChris Lattner             log->Printf("Completed step over breakpoint plan.");
122*30fdc8d8SChris Lattner         // Otherwise, re-enable the breakpoint we were stepping over, and we're done.
123*30fdc8d8SChris Lattner         BreakpointSiteSP bp_site_sp (m_thread.GetProcess().GetBreakpointSiteList().FindByAddress (m_breakpoint_addr));
124*30fdc8d8SChris Lattner         if (bp_site_sp)
125*30fdc8d8SChris Lattner             m_thread.GetProcess().EnableBreakpoint (bp_site_sp.get());
126*30fdc8d8SChris Lattner         ThreadPlan::MischiefManaged ();
127*30fdc8d8SChris Lattner         return true;
128*30fdc8d8SChris Lattner     }
129*30fdc8d8SChris Lattner }
130*30fdc8d8SChris Lattner 
131