1*30fdc8d8SChris Lattner //===-- ThreadPlanRunToAddress.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/ThreadPlanRunToAddress.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/Target.h"
20*30fdc8d8SChris Lattner #include "lldb/Target/Process.h"
21*30fdc8d8SChris Lattner #include "lldb/Target/Thread.h"
22*30fdc8d8SChris Lattner #include "lldb/Target/RegisterContext.h"
23*30fdc8d8SChris Lattner 
24*30fdc8d8SChris Lattner using namespace lldb;
25*30fdc8d8SChris Lattner using namespace lldb_private;
26*30fdc8d8SChris Lattner 
27*30fdc8d8SChris Lattner //----------------------------------------------------------------------
28*30fdc8d8SChris Lattner // ThreadPlanRunToAddress: Continue plan
29*30fdc8d8SChris Lattner //----------------------------------------------------------------------
30*30fdc8d8SChris Lattner 
31*30fdc8d8SChris Lattner ThreadPlanRunToAddress::ThreadPlanRunToAddress
32*30fdc8d8SChris Lattner (
33*30fdc8d8SChris Lattner     Thread &thread,
34*30fdc8d8SChris Lattner     Address &address,
35*30fdc8d8SChris Lattner     bool stop_others
36*30fdc8d8SChris Lattner ) :
37*30fdc8d8SChris Lattner     ThreadPlan ("Run to breakpoint plan", thread, eVoteNoOpinion, eVoteNoOpinion),
38*30fdc8d8SChris Lattner     m_stop_others (stop_others),
39*30fdc8d8SChris Lattner     m_address (LLDB_INVALID_ADDRESS),
40*30fdc8d8SChris Lattner     m_break_id (LLDB_INVALID_BREAK_ID)
41*30fdc8d8SChris Lattner {
42*30fdc8d8SChris Lattner     m_address = address.GetLoadAddress(&m_thread.GetProcess());
43*30fdc8d8SChris Lattner     SetInitialBreakpoint();
44*30fdc8d8SChris Lattner }
45*30fdc8d8SChris Lattner 
46*30fdc8d8SChris Lattner ThreadPlanRunToAddress::ThreadPlanRunToAddress
47*30fdc8d8SChris Lattner (
48*30fdc8d8SChris Lattner     Thread &thread,
49*30fdc8d8SChris Lattner     lldb::addr_t address,
50*30fdc8d8SChris Lattner     bool stop_others
51*30fdc8d8SChris Lattner ) :
52*30fdc8d8SChris Lattner     ThreadPlan ("Run to breakpoint plan", thread, eVoteNoOpinion, eVoteNoOpinion),
53*30fdc8d8SChris Lattner     m_stop_others (stop_others),
54*30fdc8d8SChris Lattner     m_address (address),
55*30fdc8d8SChris Lattner     m_break_id (LLDB_INVALID_BREAK_ID)
56*30fdc8d8SChris Lattner {
57*30fdc8d8SChris Lattner     SetInitialBreakpoint();
58*30fdc8d8SChris Lattner }
59*30fdc8d8SChris Lattner 
60*30fdc8d8SChris Lattner void
61*30fdc8d8SChris Lattner ThreadPlanRunToAddress::SetInitialBreakpoint ()
62*30fdc8d8SChris Lattner {
63*30fdc8d8SChris Lattner     Breakpoint *breakpoint;
64*30fdc8d8SChris Lattner     breakpoint = m_thread.GetProcess().GetTarget().CreateBreakpoint (m_address, true).get();
65*30fdc8d8SChris Lattner     if (breakpoint != NULL)
66*30fdc8d8SChris Lattner     {
67*30fdc8d8SChris Lattner         m_break_id = breakpoint->GetID();
68*30fdc8d8SChris Lattner         breakpoint->SetThreadID(m_thread.GetID());
69*30fdc8d8SChris Lattner     }
70*30fdc8d8SChris Lattner }
71*30fdc8d8SChris Lattner 
72*30fdc8d8SChris Lattner ThreadPlanRunToAddress::~ThreadPlanRunToAddress ()
73*30fdc8d8SChris Lattner {
74*30fdc8d8SChris Lattner     if (m_break_id != LLDB_INVALID_BREAK_ID)
75*30fdc8d8SChris Lattner     {
76*30fdc8d8SChris Lattner         m_thread.GetProcess().GetTarget().RemoveBreakpointByID (m_break_id);
77*30fdc8d8SChris Lattner     }
78*30fdc8d8SChris Lattner }
79*30fdc8d8SChris Lattner 
80*30fdc8d8SChris Lattner void
81*30fdc8d8SChris Lattner ThreadPlanRunToAddress::GetDescription (Stream *s, lldb::DescriptionLevel level)
82*30fdc8d8SChris Lattner {
83*30fdc8d8SChris Lattner     if (level == lldb::eDescriptionLevelBrief)
84*30fdc8d8SChris Lattner     {
85*30fdc8d8SChris Lattner         s->Printf ("run to address: ");
86*30fdc8d8SChris Lattner         s->Address (m_address, sizeof (addr_t));
87*30fdc8d8SChris Lattner     }
88*30fdc8d8SChris Lattner     else
89*30fdc8d8SChris Lattner     {
90*30fdc8d8SChris Lattner         s->Printf ("Run to address: ");
91*30fdc8d8SChris Lattner         s->Address(m_address, sizeof (addr_t));
92*30fdc8d8SChris Lattner         s->Printf (" using breakpoint: %d - ", m_break_id);
93*30fdc8d8SChris Lattner         Breakpoint *breakpoint = m_thread.GetProcess().GetTarget().GetBreakpointByID (m_break_id).get();
94*30fdc8d8SChris Lattner         if (breakpoint)
95*30fdc8d8SChris Lattner             breakpoint->Dump (s);
96*30fdc8d8SChris Lattner         else
97*30fdc8d8SChris Lattner             s->Printf ("but the breakpoint has been deleted.");
98*30fdc8d8SChris Lattner     }
99*30fdc8d8SChris Lattner }
100*30fdc8d8SChris Lattner 
101*30fdc8d8SChris Lattner bool
102*30fdc8d8SChris Lattner ThreadPlanRunToAddress::ValidatePlan (Stream *error)
103*30fdc8d8SChris Lattner {
104*30fdc8d8SChris Lattner     // If we couldn't set the breakpoint for some reason, then this won't
105*30fdc8d8SChris Lattner     // work.
106*30fdc8d8SChris Lattner     if(m_break_id == LLDB_INVALID_BREAK_ID)
107*30fdc8d8SChris Lattner         return false;
108*30fdc8d8SChris Lattner     else
109*30fdc8d8SChris Lattner         return true;
110*30fdc8d8SChris Lattner }
111*30fdc8d8SChris Lattner 
112*30fdc8d8SChris Lattner bool
113*30fdc8d8SChris Lattner ThreadPlanRunToAddress::PlanExplainsStop ()
114*30fdc8d8SChris Lattner {
115*30fdc8d8SChris Lattner     return AtOurAddress();
116*30fdc8d8SChris Lattner }
117*30fdc8d8SChris Lattner 
118*30fdc8d8SChris Lattner bool
119*30fdc8d8SChris Lattner ThreadPlanRunToAddress::ShouldStop (Event *event_ptr)
120*30fdc8d8SChris Lattner {
121*30fdc8d8SChris Lattner     return false;
122*30fdc8d8SChris Lattner }
123*30fdc8d8SChris Lattner 
124*30fdc8d8SChris Lattner bool
125*30fdc8d8SChris Lattner ThreadPlanRunToAddress::StopOthers ()
126*30fdc8d8SChris Lattner {
127*30fdc8d8SChris Lattner     return m_stop_others;
128*30fdc8d8SChris Lattner }
129*30fdc8d8SChris Lattner 
130*30fdc8d8SChris Lattner void
131*30fdc8d8SChris Lattner ThreadPlanRunToAddress::SetStopOthers (bool new_value)
132*30fdc8d8SChris Lattner {
133*30fdc8d8SChris Lattner     m_stop_others = new_value;
134*30fdc8d8SChris Lattner }
135*30fdc8d8SChris Lattner 
136*30fdc8d8SChris Lattner StateType
137*30fdc8d8SChris Lattner ThreadPlanRunToAddress::RunState ()
138*30fdc8d8SChris Lattner {
139*30fdc8d8SChris Lattner     return eStateRunning;
140*30fdc8d8SChris Lattner }
141*30fdc8d8SChris Lattner 
142*30fdc8d8SChris Lattner bool
143*30fdc8d8SChris Lattner ThreadPlanRunToAddress::WillStop ()
144*30fdc8d8SChris Lattner {
145*30fdc8d8SChris Lattner     return true;
146*30fdc8d8SChris Lattner }
147*30fdc8d8SChris Lattner 
148*30fdc8d8SChris Lattner bool
149*30fdc8d8SChris Lattner ThreadPlanRunToAddress::MischiefManaged ()
150*30fdc8d8SChris Lattner {
151*30fdc8d8SChris Lattner     Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
152*30fdc8d8SChris Lattner 
153*30fdc8d8SChris Lattner     if (AtOurAddress())
154*30fdc8d8SChris Lattner     {
155*30fdc8d8SChris Lattner         // Remove the breakpoint
156*30fdc8d8SChris Lattner         if (m_break_id != LLDB_INVALID_BREAK_ID)
157*30fdc8d8SChris Lattner         {
158*30fdc8d8SChris Lattner             m_thread.GetProcess().GetTarget().RemoveBreakpointByID (m_break_id);
159*30fdc8d8SChris Lattner             m_break_id = LLDB_INVALID_BREAK_ID;
160*30fdc8d8SChris Lattner         }
161*30fdc8d8SChris Lattner 
162*30fdc8d8SChris Lattner         if (log)
163*30fdc8d8SChris Lattner             log->Printf("Completed run to address plan.");
164*30fdc8d8SChris Lattner         ThreadPlan::MischiefManaged ();
165*30fdc8d8SChris Lattner         return true;
166*30fdc8d8SChris Lattner     }
167*30fdc8d8SChris Lattner     else
168*30fdc8d8SChris Lattner         return false;
169*30fdc8d8SChris Lattner }
170*30fdc8d8SChris Lattner 
171*30fdc8d8SChris Lattner bool
172*30fdc8d8SChris Lattner ThreadPlanRunToAddress::AtOurAddress ()
173*30fdc8d8SChris Lattner {
174*30fdc8d8SChris Lattner     lldb::addr_t current_address = m_thread.GetRegisterContext()->GetPC();
175*30fdc8d8SChris Lattner     return m_address == current_address;
176*30fdc8d8SChris Lattner }
177