]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Target/ThreadPlanRunToAddress.cpp
Copy ^/vendor/NetBSD/tests/dist/lib/libc/hash/t_hmac.c to
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Target / ThreadPlanRunToAddress.cpp
1 //===-- 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 // C Includes
11 // C++ Includes
12 // Other libraries and framework includes
13 // Project includes
14 #include "lldb/Target/ThreadPlanRunToAddress.h"
15 #include "lldb/Core/Log.h"
16 #include "lldb/Core/Stream.h"
17 #include "lldb/Target/Target.h"
18 #include "lldb/Target/Process.h"
19 #include "lldb/Target/Thread.h"
20 #include "lldb/Target/RegisterContext.h"
21
22 using namespace lldb;
23 using namespace lldb_private;
24
25 //----------------------------------------------------------------------
26 // ThreadPlanRunToAddress: Continue plan
27 //----------------------------------------------------------------------
28
29 ThreadPlanRunToAddress::ThreadPlanRunToAddress
30 (
31     Thread &thread,
32     Address &address,
33     bool stop_others
34 ) :
35     ThreadPlan (ThreadPlan::eKindRunToAddress, "Run to address plan", thread, eVoteNoOpinion, eVoteNoOpinion),
36     m_stop_others (stop_others),
37     m_addresses (),
38     m_break_ids ()
39 {
40     m_addresses.push_back (address.GetOpcodeLoadAddress (m_thread.CalculateTarget().get()));
41     SetInitialBreakpoints();
42 }
43
44 ThreadPlanRunToAddress::ThreadPlanRunToAddress
45 (
46     Thread &thread,
47     lldb::addr_t address,
48     bool stop_others
49 ) :
50     ThreadPlan (ThreadPlan::eKindRunToAddress, "Run to address plan", thread, eVoteNoOpinion, eVoteNoOpinion),
51     m_stop_others (stop_others),
52     m_addresses (),
53     m_break_ids ()
54 {
55     m_addresses.push_back(m_thread.CalculateTarget()->GetOpcodeLoadAddress(address));
56     SetInitialBreakpoints();
57 }
58
59 ThreadPlanRunToAddress::ThreadPlanRunToAddress
60 (
61     Thread &thread,
62     const std::vector<lldb::addr_t> &addresses,
63     bool stop_others
64 ) :
65     ThreadPlan (ThreadPlan::eKindRunToAddress, "Run to address plan", thread, eVoteNoOpinion, eVoteNoOpinion),
66     m_stop_others (stop_others),
67     m_addresses (addresses),
68     m_break_ids ()
69 {
70     // Convert all addresses into opcode addresses to make sure we set 
71     // breakpoints at the correct address.
72     Target &target = thread.GetProcess()->GetTarget();
73     std::vector<lldb::addr_t>::iterator pos, end = m_addresses.end();
74     for (pos = m_addresses.begin(); pos != end; ++pos)
75         *pos = target.GetOpcodeLoadAddress (*pos);
76
77     SetInitialBreakpoints();
78 }
79
80 void
81 ThreadPlanRunToAddress::SetInitialBreakpoints ()
82 {
83     size_t num_addresses = m_addresses.size();
84     m_break_ids.resize(num_addresses);
85     
86     for (size_t i = 0; i < num_addresses; i++)
87     {
88         Breakpoint *breakpoint;
89         breakpoint = m_thread.CalculateTarget()->CreateBreakpoint (m_addresses[i], true, false).get();
90         if (breakpoint != nullptr)
91         {
92             m_break_ids[i] = breakpoint->GetID();
93             breakpoint->SetThreadID(m_thread.GetID());
94             breakpoint->SetBreakpointKind("run-to-address");
95         }
96     }
97 }
98
99 ThreadPlanRunToAddress::~ThreadPlanRunToAddress ()
100 {
101     size_t num_break_ids = m_break_ids.size();
102     for (size_t i = 0; i <  num_break_ids; i++)
103     {
104         m_thread.CalculateTarget()->RemoveBreakpointByID (m_break_ids[i]);
105     }
106 }
107
108 void
109 ThreadPlanRunToAddress::GetDescription (Stream *s, lldb::DescriptionLevel level)
110 {
111     size_t num_addresses = m_addresses.size();
112     
113     if (level == lldb::eDescriptionLevelBrief)
114     {
115         if (num_addresses == 0)
116         {
117             s->Printf ("run to address with no addresses given.");
118             return;
119         }
120         else if (num_addresses == 1)
121             s->Printf ("run to address: ");
122         else
123             s->Printf ("run to addresses: ");
124             
125         for (size_t i = 0; i < num_addresses; i++)
126         {
127             s->Address (m_addresses[i], sizeof (addr_t));
128             s->Printf(" ");
129         }
130     }
131     else
132     {
133         if (num_addresses == 0)
134         {
135             s->Printf ("run to address with no addresses given.");
136             return;
137         }
138         else if (num_addresses == 1)
139             s->Printf ("Run to address: ");
140         else
141         {
142             s->Printf ("Run to addresses: ");
143         }
144             
145         for (size_t i = 0; i < num_addresses; i++)
146         {
147             if (num_addresses > 1)
148             {
149                 s->Printf("\n");
150                 s->Indent();
151             }
152             
153             s->Address(m_addresses[i], sizeof (addr_t));
154             s->Printf (" using breakpoint: %d - ", m_break_ids[i]);
155             Breakpoint *breakpoint = m_thread.CalculateTarget()->GetBreakpointByID (m_break_ids[i]).get();
156             if (breakpoint)
157                 breakpoint->Dump (s);
158             else
159                 s->Printf ("but the breakpoint has been deleted.");
160         }
161     }
162 }
163
164 bool
165 ThreadPlanRunToAddress::ValidatePlan (Stream *error)
166 {
167     // If we couldn't set the breakpoint for some reason, then this won't
168     // work.
169     bool all_bps_good = true;
170     size_t num_break_ids = m_break_ids.size();
171         
172     for (size_t i = 0; i < num_break_ids; i++)
173     {
174         if (m_break_ids[i] == LLDB_INVALID_BREAK_ID)
175         {
176             all_bps_good = false;
177             if (error)
178             {
179                 error->Printf ("Could not set breakpoint for address: ");
180                 error->Address (m_addresses[i], sizeof (addr_t));
181                 error->Printf ("\n");
182             }
183         }
184     }
185     return all_bps_good;
186 }
187
188 bool
189 ThreadPlanRunToAddress::DoPlanExplainsStop (Event *event_ptr)
190 {
191     return AtOurAddress();
192 }
193
194 bool
195 ThreadPlanRunToAddress::ShouldStop (Event *event_ptr)
196 {
197     return AtOurAddress();
198 }
199
200 bool
201 ThreadPlanRunToAddress::StopOthers ()
202 {
203     return m_stop_others;
204 }
205
206 void
207 ThreadPlanRunToAddress::SetStopOthers (bool new_value)
208 {
209     m_stop_others = new_value;
210 }
211
212 StateType
213 ThreadPlanRunToAddress::GetPlanRunState ()
214 {
215     return eStateRunning;
216 }
217
218 bool
219 ThreadPlanRunToAddress::WillStop ()
220 {
221     return true;
222 }
223
224 bool
225 ThreadPlanRunToAddress::MischiefManaged ()
226 {
227     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
228
229     if (AtOurAddress())
230     {
231         // Remove the breakpoint
232         size_t num_break_ids = m_break_ids.size();
233         
234         for (size_t i = 0; i < num_break_ids; i++)
235         {
236             if (m_break_ids[i] != LLDB_INVALID_BREAK_ID)
237             {
238                 m_thread.CalculateTarget()->RemoveBreakpointByID (m_break_ids[i]);
239                 m_break_ids[i] = LLDB_INVALID_BREAK_ID;
240             }
241         }
242         if (log)
243             log->Printf("Completed run to address plan.");
244         ThreadPlan::MischiefManaged ();
245         return true;
246     }
247     else
248         return false;
249 }
250
251 bool
252 ThreadPlanRunToAddress::AtOurAddress ()
253 {
254     lldb::addr_t current_address = m_thread.GetRegisterContext()->GetPC();
255     bool found_it = false;
256     size_t num_addresses = m_addresses.size();
257     for (size_t i = 0; i < num_addresses; i++)
258     {
259         if (m_addresses[i] == current_address)
260         {
261             found_it = true;
262             break;
263         }
264     }
265     return found_it;
266 }