blob: 6a6ac50cb601c3c84aa54e59ba3f7e5f89dc1cbf [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- BreakpointLocationList.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
11// C Includes
12// C++ Includes
13// Other libraries and framework includes
14// Project includes
15#include "lldb/Breakpoint/BreakpointLocationList.h"
16#include "lldb/Breakpoint/BreakpointLocation.h"
17#include "lldb/Core/ModuleList.h"
18#include "lldb/Target/Target.h"
19
20using namespace lldb;
21using namespace lldb_private;
22
23BreakpointLocationList::BreakpointLocationList() :
24 m_locations(),
25 m_address_to_location (),
26 m_mutex (Mutex::eMutexTypeRecursive),
27 m_next_id (0)
28{
29}
30
31BreakpointLocationList::~BreakpointLocationList()
32{
33}
34
Greg Clayton54e7afa2010-07-09 20:39:50 +000035lldb::break_id_t
Chris Lattner24943d22010-06-08 16:52:24 +000036BreakpointLocationList::Add (BreakpointLocationSP &bp_loc_sp)
37{
38 if (bp_loc_sp)
39 {
40 Mutex::Locker locker (m_mutex);
41 m_locations.push_back (bp_loc_sp);
42 m_address_to_location[bp_loc_sp->GetAddress()] = bp_loc_sp;
43 return bp_loc_sp->GetID();
44 }
45 return LLDB_INVALID_BREAK_ID;
46}
47
48bool
Greg Clayton54e7afa2010-07-09 20:39:50 +000049BreakpointLocationList::ShouldStop (StoppointCallbackContext *context, lldb::break_id_t break_id)
Chris Lattner24943d22010-06-08 16:52:24 +000050{
51 BreakpointLocationSP bp = FindByID (break_id);
52 if (bp)
53 {
54 // Let the BreakpointLocation decide if it should stop here (could not have
55 // reached it's target hit count yet, or it could have a callback
56 // that decided it shouldn't stop (shared library loads/unloads).
57 return bp->ShouldStop (context);
58 }
59 // We should stop here since this BreakpointLocation isn't valid anymore or it
60 // doesn't exist.
61 return true;
62}
63
Greg Clayton54e7afa2010-07-09 20:39:50 +000064lldb::break_id_t
Chris Lattner24943d22010-06-08 16:52:24 +000065BreakpointLocationList::FindIDByAddress (Address &addr)
66{
67 BreakpointLocationSP bp_loc_sp = FindByAddress (addr);
68 if (bp_loc_sp)
69 {
70 return bp_loc_sp->GetID();
71 }
72 return LLDB_INVALID_BREAK_ID;
73}
74
75bool
Greg Clayton54e7afa2010-07-09 20:39:50 +000076BreakpointLocationList::Remove (lldb::break_id_t break_id)
Chris Lattner24943d22010-06-08 16:52:24 +000077{
78 Mutex::Locker locker (m_mutex);
79 collection::iterator pos = GetIDIterator(break_id); // Predicate
80 if (pos != m_locations.end())
81 {
82 m_address_to_location.erase ((*pos)->GetAddress());
83 m_locations.erase(pos);
84 return true;
85 }
86 return false;
87}
88
89
90class BreakpointLocationIDMatches
91{
92public:
Greg Clayton54e7afa2010-07-09 20:39:50 +000093 BreakpointLocationIDMatches (lldb::break_id_t break_id) :
Chris Lattner24943d22010-06-08 16:52:24 +000094 m_break_id(break_id)
95 {
96 }
97
98 bool operator() (const BreakpointLocationSP &bp_loc_sp) const
99 {
100 return m_break_id == bp_loc_sp->GetID();
101 }
102
103private:
Greg Clayton54e7afa2010-07-09 20:39:50 +0000104 const lldb::break_id_t m_break_id;
Chris Lattner24943d22010-06-08 16:52:24 +0000105};
106
107class BreakpointLocationAddressMatches
108{
109public:
110 BreakpointLocationAddressMatches (Address& addr) :
111 m_addr(addr)
112 {
113 }
114
115 bool operator() (const BreakpointLocationSP& bp_loc_sp) const
116 {
117 return Address::CompareFileAddress(m_addr, bp_loc_sp->GetAddress()) == 0;
118 }
119
120private:
121 const Address &m_addr;
122};
123
124BreakpointLocationList::collection::iterator
Greg Clayton54e7afa2010-07-09 20:39:50 +0000125BreakpointLocationList::GetIDIterator (lldb::break_id_t break_id)
Chris Lattner24943d22010-06-08 16:52:24 +0000126{
127 Mutex::Locker locker (m_mutex);
128 return std::find_if (m_locations.begin(),
129 m_locations.end(),
130 BreakpointLocationIDMatches(break_id));
131}
132
133BreakpointLocationList::collection::const_iterator
Greg Clayton54e7afa2010-07-09 20:39:50 +0000134BreakpointLocationList::GetIDConstIterator (lldb::break_id_t break_id) const
Chris Lattner24943d22010-06-08 16:52:24 +0000135{
136 Mutex::Locker locker (m_mutex);
137 return std::find_if (m_locations.begin(),
138 m_locations.end(),
139 BreakpointLocationIDMatches(break_id));
140}
141
142BreakpointLocationSP
Greg Clayton54e7afa2010-07-09 20:39:50 +0000143BreakpointLocationList::FindByID (lldb::break_id_t break_id)
Chris Lattner24943d22010-06-08 16:52:24 +0000144{
145 Mutex::Locker locker (m_mutex);
146 BreakpointLocationSP stop_sp;
147 collection::iterator pos = GetIDIterator(break_id);
148 if (pos != m_locations.end())
149 stop_sp = *pos;
150
151 return stop_sp;
152}
153
154const BreakpointLocationSP
Greg Clayton54e7afa2010-07-09 20:39:50 +0000155BreakpointLocationList::FindByID (lldb::break_id_t break_id) const
Chris Lattner24943d22010-06-08 16:52:24 +0000156{
157 Mutex::Locker locker (m_mutex);
158 BreakpointLocationSP stop_sp;
159 collection::const_iterator pos = GetIDConstIterator(break_id);
160 if (pos != m_locations.end())
161 stop_sp = *pos;
162
163 return stop_sp;
164}
165
166size_t
167BreakpointLocationList::FindInModule (Module *module,
168 BreakpointLocationCollection& bp_loc_list)
169{
170 Mutex::Locker locker (m_mutex);
171 const size_t orig_size = bp_loc_list.GetSize();
172 collection::iterator pos, end = m_locations.end();
173
174 for (pos = m_locations.begin(); pos != end; ++pos)
175 {
176 bool seen = false;
177 BreakpointLocationSP break_loc = (*pos);
178 const Section *section = break_loc->GetAddress().GetSection();
179 if (section)
180 {
181 if (section->GetModule() == module)
182 {
183 if (!seen)
184 {
185 seen = true;
186 bp_loc_list.Add (break_loc);
187 }
188
189 }
190 }
191 }
192 return bp_loc_list.GetSize() - orig_size;
193}
194
Chris Lattner24943d22010-06-08 16:52:24 +0000195const BreakpointLocationSP
196BreakpointLocationList::FindByAddress (Address &addr) const
197{
198 Mutex::Locker locker (m_mutex);
199 BreakpointLocationSP stop_sp;
200 if (!m_locations.empty())
201 {
202 addr_map::const_iterator pos = m_address_to_location.find (addr);
203 if (pos != m_address_to_location.end())
204 stop_sp = pos->second;
205 }
206
207 return stop_sp;
208}
209
210void
211BreakpointLocationList::Dump (Stream *s) const
212{
213 s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
214 s->Indent();
215 Mutex::Locker locker (m_mutex);
216 s->Printf("BreakpointLocationList with %zu BreakpointLocations:\n", m_locations.size());
217 s->IndentMore();
218 collection::const_iterator pos, end = m_locations.end();
219 for (pos = m_locations.begin(); pos != end; ++pos)
220 (*pos).get()->Dump(s);
221 s->IndentLess();
222}
223
224
225BreakpointLocationSP
226BreakpointLocationList::GetByIndex (uint32_t i)
227{
228 Mutex::Locker locker (m_mutex);
229 BreakpointLocationSP stop_sp;
Greg Clayton54e7afa2010-07-09 20:39:50 +0000230 if (i < m_locations.size())
Chris Lattner24943d22010-06-08 16:52:24 +0000231 stop_sp = m_locations[i];
232
233 return stop_sp;
234}
235
236const BreakpointLocationSP
237BreakpointLocationList::GetByIndex (uint32_t i) const
238{
239 Mutex::Locker locker (m_mutex);
240 BreakpointLocationSP stop_sp;
Greg Clayton54e7afa2010-07-09 20:39:50 +0000241 if (i < m_locations.size())
Chris Lattner24943d22010-06-08 16:52:24 +0000242 stop_sp = m_locations[i];
243
244 return stop_sp;
245}
246
247void
248BreakpointLocationList::ClearAllBreakpointSites ()
249{
250 Mutex::Locker locker (m_mutex);
251 collection::iterator pos, end = m_locations.end();
252 for (pos = m_locations.begin(); pos != end; ++pos)
253 (*pos)->ClearBreakpointSite();
254}
255
256void
257BreakpointLocationList::ResolveAllBreakpointSites ()
258{
259 Mutex::Locker locker (m_mutex);
260 collection::iterator pos, end = m_locations.end();
261
262 for (pos = m_locations.begin(); pos != end; ++pos)
263 (*pos)->ResolveBreakpointSite();
264}
265
266size_t
267BreakpointLocationList::GetNumResolvedLocations() const
268{
269 Mutex::Locker locker (m_mutex);
270 size_t resolve_count = 0;
271 collection::const_iterator pos, end = m_locations.end();
272 for (pos = m_locations.begin(); pos != end; ++pos)
273 {
274 if ((*pos)->IsResolved())
275 ++resolve_count;
276 }
277 return resolve_count;
278}
279
280break_id_t
281BreakpointLocationList::GetNextID()
282{
283 return ++m_next_id;
284}
285
286void
287BreakpointLocationList::GetDescription (Stream *s, lldb::DescriptionLevel level)
288{
289 Mutex::Locker locker (m_mutex);
290 collection::iterator pos, end = m_locations.end();
291
292 for (pos = m_locations.begin(); pos != end; ++pos)
293 {
294 s->Printf(" ");
295 (*pos)->GetDescription(s, level);
296 }
297}
298