blob: 22a4ff0c68ee471669f03e35275ca4c220686ed4 [file] [log] [blame]
Chris Lattner30fdc8d2010-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"
Michael Sartainc87e7522013-07-16 21:22:53 +000017#include "lldb/Breakpoint/Breakpoint.h"
Greg Clayton1f746072012-08-29 21:13:06 +000018#include "lldb/Core/Section.h"
Michael Sartainc87e7522013-07-16 21:22:53 +000019#include "lldb/Target/Target.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000020
21using namespace lldb;
22using namespace lldb_private;
23
Jim Inghame6bc6cb2012-02-08 05:23:15 +000024BreakpointLocationList::BreakpointLocationList(Breakpoint &owner) :
Bill Wendlingc9851e22012-04-03 04:14:58 +000025 m_owner (owner),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000026 m_locations(),
27 m_address_to_location (),
Jim Inghame6bc6cb2012-02-08 05:23:15 +000028 m_mutex (Mutex::eMutexTypeRecursive),
Bill Wendlingc9851e22012-04-03 04:14:58 +000029 m_next_id (0),
30 m_new_location_recorder (NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000031{
32}
33
34BreakpointLocationList::~BreakpointLocationList()
35{
36}
37
Greg Claytonc0d34462011-02-05 00:38:04 +000038BreakpointLocationSP
Jim Inghame6bc6cb2012-02-08 05:23:15 +000039BreakpointLocationList::Create (const Address &addr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000040{
Greg Claytonc0d34462011-02-05 00:38:04 +000041 Mutex::Locker locker (m_mutex);
42 // The location ID is just the size of the location list + 1
Greg Claytone72dfb32012-02-24 01:59:29 +000043 lldb::break_id_t bp_loc_id = ++m_next_id;
Jim Inghame6bc6cb2012-02-08 05:23:15 +000044 BreakpointLocationSP bp_loc_sp (new BreakpointLocation (bp_loc_id, m_owner, addr));
Greg Claytonc0d34462011-02-05 00:38:04 +000045 m_locations.push_back (bp_loc_sp);
46 m_address_to_location[addr] = bp_loc_sp;
47 return bp_loc_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000048}
49
50bool
Greg Claytonc982c762010-07-09 20:39:50 +000051BreakpointLocationList::ShouldStop (StoppointCallbackContext *context, lldb::break_id_t break_id)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000052{
53 BreakpointLocationSP bp = FindByID (break_id);
54 if (bp)
55 {
56 // Let the BreakpointLocation decide if it should stop here (could not have
57 // reached it's target hit count yet, or it could have a callback
58 // that decided it shouldn't stop (shared library loads/unloads).
59 return bp->ShouldStop (context);
60 }
61 // We should stop here since this BreakpointLocation isn't valid anymore or it
62 // doesn't exist.
63 return true;
64}
65
Greg Claytonc982c762010-07-09 20:39:50 +000066lldb::break_id_t
Greg Claytonc0d34462011-02-05 00:38:04 +000067BreakpointLocationList::FindIDByAddress (const Address &addr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000068{
69 BreakpointLocationSP bp_loc_sp = FindByAddress (addr);
70 if (bp_loc_sp)
71 {
72 return bp_loc_sp->GetID();
73 }
74 return LLDB_INVALID_BREAK_ID;
75}
76
Chris Lattner30fdc8d2010-06-08 16:52:24 +000077BreakpointLocationSP
Greg Claytonc982c762010-07-09 20:39:50 +000078BreakpointLocationList::FindByID (lldb::break_id_t break_id) const
Chris Lattner30fdc8d2010-06-08 16:52:24 +000079{
Greg Claytonc0d34462011-02-05 00:38:04 +000080 BreakpointLocationSP bp_loc_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000081 Mutex::Locker locker (m_mutex);
Greg Claytonc0d34462011-02-05 00:38:04 +000082 // We never remove a breakpoint locations, so the ID can be translated into
83 // the location index by subtracting 1
84 uint32_t idx = break_id - 1;
85 if (idx <= m_locations.size())
86 {
87 bp_loc_sp = m_locations[idx];
88 }
89 return bp_loc_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000090}
91
92size_t
93BreakpointLocationList::FindInModule (Module *module,
94 BreakpointLocationCollection& bp_loc_list)
95{
96 Mutex::Locker locker (m_mutex);
97 const size_t orig_size = bp_loc_list.GetSize();
98 collection::iterator pos, end = m_locations.end();
99
100 for (pos = m_locations.begin(); pos != end; ++pos)
101 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000102 BreakpointLocationSP break_loc = (*pos);
Greg Claytone72dfb32012-02-24 01:59:29 +0000103 SectionSP section_sp (break_loc->GetAddress().GetSection());
104 if (section_sp && section_sp->GetModule().get() == module)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000105 {
Johnny Chen0861be02011-08-11 21:43:13 +0000106 bp_loc_list.Add (break_loc);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000107 }
108 }
109 return bp_loc_list.GetSize() - orig_size;
110}
111
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000112const BreakpointLocationSP
Greg Claytonc0d34462011-02-05 00:38:04 +0000113BreakpointLocationList::FindByAddress (const Address &addr) const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000114{
115 Mutex::Locker locker (m_mutex);
Greg Claytonc0d34462011-02-05 00:38:04 +0000116 BreakpointLocationSP bp_loc_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000117 if (!m_locations.empty())
118 {
Michael Sartainc87e7522013-07-16 21:22:53 +0000119 Address so_addr;
120
121 if (addr.IsSectionOffset())
122 {
123 so_addr = addr;
124 }
125 else
126 {
127 // Try and resolve as a load address if possible.
128 m_owner.GetTarget().GetSectionLoadList().ResolveLoadAddress (addr.GetOffset(), so_addr);
129 if (!so_addr.IsValid())
130 {
131 // The address didn't resolve, so just set to passed in addr.
132 so_addr = addr;
133 }
134 }
135
136 addr_map::const_iterator pos = m_address_to_location.find (so_addr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000137 if (pos != m_address_to_location.end())
Greg Claytonc0d34462011-02-05 00:38:04 +0000138 bp_loc_sp = pos->second;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000139 }
140
Greg Claytonc0d34462011-02-05 00:38:04 +0000141 return bp_loc_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000142}
143
144void
145BreakpointLocationList::Dump (Stream *s) const
146{
Jason Molendafd54b362011-09-20 21:44:10 +0000147 s->Printf("%p: ", this);
Greg Claytonded470d2011-03-19 01:12:21 +0000148 //s->Indent();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000149 Mutex::Locker locker (m_mutex);
Daniel Malead01b2952012-11-29 21:49:15 +0000150 s->Printf("BreakpointLocationList with %" PRIu64 " BreakpointLocations:\n", (uint64_t)m_locations.size());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000151 s->IndentMore();
152 collection::const_iterator pos, end = m_locations.end();
153 for (pos = m_locations.begin(); pos != end; ++pos)
154 (*pos).get()->Dump(s);
155 s->IndentLess();
156}
157
158
159BreakpointLocationSP
Greg Claytonc7bece562013-01-25 18:06:21 +0000160BreakpointLocationList::GetByIndex (size_t i)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000161{
162 Mutex::Locker locker (m_mutex);
Greg Claytonc0d34462011-02-05 00:38:04 +0000163 BreakpointLocationSP bp_loc_sp;
Greg Claytonc982c762010-07-09 20:39:50 +0000164 if (i < m_locations.size())
Greg Claytonc0d34462011-02-05 00:38:04 +0000165 bp_loc_sp = m_locations[i];
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000166
Greg Claytonc0d34462011-02-05 00:38:04 +0000167 return bp_loc_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000168}
169
170const BreakpointLocationSP
Greg Claytonc7bece562013-01-25 18:06:21 +0000171BreakpointLocationList::GetByIndex (size_t i) const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000172{
173 Mutex::Locker locker (m_mutex);
Greg Claytonc0d34462011-02-05 00:38:04 +0000174 BreakpointLocationSP bp_loc_sp;
Greg Claytonc982c762010-07-09 20:39:50 +0000175 if (i < m_locations.size())
Greg Claytonc0d34462011-02-05 00:38:04 +0000176 bp_loc_sp = m_locations[i];
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000177
Greg Claytonc0d34462011-02-05 00:38:04 +0000178 return bp_loc_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000179}
180
181void
182BreakpointLocationList::ClearAllBreakpointSites ()
183{
184 Mutex::Locker locker (m_mutex);
185 collection::iterator pos, end = m_locations.end();
186 for (pos = m_locations.begin(); pos != end; ++pos)
187 (*pos)->ClearBreakpointSite();
188}
189
190void
191BreakpointLocationList::ResolveAllBreakpointSites ()
192{
193 Mutex::Locker locker (m_mutex);
194 collection::iterator pos, end = m_locations.end();
195
196 for (pos = m_locations.begin(); pos != end; ++pos)
Jim Inghamd4ce0a12010-10-20 03:36:33 +0000197 {
198 if ((*pos)->IsEnabled())
199 (*pos)->ResolveBreakpointSite();
200 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000201}
202
Greg Clayton9fed0d82010-07-23 23:33:17 +0000203uint32_t
204BreakpointLocationList::GetHitCount () const
205{
206 uint32_t hit_count = 0;
207 Mutex::Locker locker (m_mutex);
208 collection::const_iterator pos, end = m_locations.end();
209 for (pos = m_locations.begin(); pos != end; ++pos)
210 hit_count += (*pos)->GetHitCount();
211 return hit_count;
212}
213
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000214size_t
215BreakpointLocationList::GetNumResolvedLocations() const
216{
217 Mutex::Locker locker (m_mutex);
218 size_t resolve_count = 0;
219 collection::const_iterator pos, end = m_locations.end();
220 for (pos = m_locations.begin(); pos != end; ++pos)
221 {
222 if ((*pos)->IsResolved())
223 ++resolve_count;
224 }
225 return resolve_count;
226}
227
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000228void
229BreakpointLocationList::GetDescription (Stream *s, lldb::DescriptionLevel level)
230{
231 Mutex::Locker locker (m_mutex);
232 collection::iterator pos, end = m_locations.end();
233
234 for (pos = m_locations.begin(); pos != end; ++pos)
235 {
236 s->Printf(" ");
237 (*pos)->GetDescription(s, level);
238 }
239}
240
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000241BreakpointLocationSP
242BreakpointLocationList::AddLocation (const Address &addr, bool *new_location)
243{
244 Mutex::Locker locker (m_mutex);
245
246 if (new_location)
247 *new_location = false;
248 BreakpointLocationSP bp_loc_sp (FindByAddress(addr));
249 if (!bp_loc_sp)
250 {
251 bp_loc_sp = Create (addr);
252 if (bp_loc_sp)
253 {
254 bp_loc_sp->ResolveBreakpointSite();
255
256 if (new_location)
257 *new_location = true;
258 if(m_new_location_recorder)
259 {
260 m_new_location_recorder->Add(bp_loc_sp);
261 }
262 }
263 }
264 return bp_loc_sp;
265}
266
Greg Claytone72dfb32012-02-24 01:59:29 +0000267bool
268BreakpointLocationList::RemoveLocation (const lldb::BreakpointLocationSP &bp_loc_sp)
269{
270 if (bp_loc_sp)
271 {
272 Mutex::Locker locker (m_mutex);
273
274 m_address_to_location.erase (bp_loc_sp->GetAddress());
275
276 collection::iterator pos, end = m_locations.end();
277 for (pos = m_locations.begin(); pos != end; ++pos)
278 {
279 if ((*pos).get() == bp_loc_sp.get())
280 {
281 m_locations.erase (pos);
282 return true;
283 }
284 }
285 }
286 return false;
287}
288
289
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000290
291void
292BreakpointLocationList::StartRecordingNewLocations (BreakpointLocationCollection &new_locations)
293{
294 Mutex::Locker locker (m_mutex);
295 assert (m_new_location_recorder == NULL);
296 m_new_location_recorder = &new_locations;
297}
298
299void
300BreakpointLocationList::StopRecordingNewLocations ()
301{
302 Mutex::Locker locker (m_mutex);
303 m_new_location_recorder = NULL;
304}
305