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