blob: 19e18bb749a07256d55913a830e66e7ecea0767a [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- BreakpointSiteList.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/Breakpoint/BreakpointSiteList.h"
11
12// C Includes
13// C++ Includes
14// Other libraries and framework includes
15// Project includes
16#include "lldb/Core/Stream.h"
17
18using namespace lldb;
19using namespace lldb_private;
20
21BreakpointSiteList::BreakpointSiteList() :
22 m_bp_site_list()
23{
24}
25
26BreakpointSiteList::~BreakpointSiteList()
27{
28}
29
30// Add breakpoint site to the list. However, if the element already exists in the
31// list, then we don't add it, and return LLDB_INVALID_BREAK_ID.
32
33lldb::user_id_t
34BreakpointSiteList::Add(const BreakpointSiteSP &bp)
35{
36 lldb::addr_t bp_site_load_addr = bp->GetLoadAddress();
37 collection::iterator iter = m_bp_site_list.find (bp_site_load_addr);
38
39 if (iter == m_bp_site_list.end())
40 {
41 m_bp_site_list.insert (iter, collection::value_type (bp_site_load_addr, bp));
42 return bp->GetID();
43 }
44 else
45 {
46 return LLDB_INVALID_BREAK_ID;
47 }
48}
49
50bool
51BreakpointSiteList::ShouldStop (StoppointCallbackContext *context, lldb::user_id_t break_id)
52{
53 BreakpointSiteSP bp = FindByID (break_id);
54 if (bp)
55 {
56 // Let the BreakpointSite 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 BreakpointSite isn't valid anymore or it
62 // doesn't exist.
63 return true;
64}
65lldb::user_id_t
66BreakpointSiteList::FindIDByAddress (lldb::addr_t addr)
67{
68 BreakpointSiteSP bp = FindByAddress (addr);
69 if (bp)
70 {
71 //DBLogIf(PD_LOG_BREAKPOINTS, "BreakpointSiteList::%s ( addr = 0x%8.8llx ) => %u", __FUNCTION__, (uint64_t)addr, bp->GetID());
72 return bp.get()->GetID();
73 }
74 //DBLogIf(PD_LOG_BREAKPOINTS, "BreakpointSiteList::%s ( addr = 0x%8.8llx ) => NONE", __FUNCTION__, (uint64_t)addr);
75 return LLDB_INVALID_BREAK_ID;
76}
77
78bool
79BreakpointSiteList::Remove (lldb::user_id_t break_id)
80{
81 collection::iterator pos = GetIDIterator(break_id); // Predicate
82 if (pos != m_bp_site_list.end())
83 {
84 m_bp_site_list.erase(pos);
85 return true;
86 }
87 return false;
88}
89
90bool
91BreakpointSiteList::RemoveByAddress (lldb::addr_t address)
92{
93 collection::iterator pos = m_bp_site_list.find(address);
94 if (pos != m_bp_site_list.end())
95 {
96 m_bp_site_list.erase(pos);
97 return true;
98 }
99 return false;
100}
101
102class BreakpointSiteIDMatches
103{
104public:
105 BreakpointSiteIDMatches (lldb::user_id_t break_id) :
106 m_break_id(break_id)
107 {
108 }
109
110 bool operator() (std::pair <lldb::addr_t, BreakpointSiteSP> val_pair) const
111 {
112 return m_break_id == val_pair.second.get()->GetID();
113 }
114
115private:
116 const lldb::user_id_t m_break_id;
117};
118
119BreakpointSiteList::collection::iterator
120BreakpointSiteList::GetIDIterator (lldb::user_id_t break_id)
121{
122 return std::find_if(m_bp_site_list.begin(), m_bp_site_list.end(), // Search full range
123 BreakpointSiteIDMatches(break_id)); // Predicate
124}
125
126BreakpointSiteList::collection::const_iterator
127BreakpointSiteList::GetIDConstIterator (lldb::user_id_t break_id) const
128{
129 return std::find_if(m_bp_site_list.begin(), m_bp_site_list.end(), // Search full range
130 BreakpointSiteIDMatches(break_id)); // Predicate
131}
132
133BreakpointSiteSP
134BreakpointSiteList::FindByID (lldb::user_id_t break_id)
135{
136 BreakpointSiteSP stop_sp;
137 collection::iterator pos = GetIDIterator(break_id);
138 if (pos != m_bp_site_list.end())
139 stop_sp = pos->second;
140
141 return stop_sp;
142}
143
144const BreakpointSiteSP
145BreakpointSiteList::FindByID (lldb::user_id_t break_id) const
146{
147 BreakpointSiteSP stop_sp;
148 collection::const_iterator pos = GetIDConstIterator(break_id);
149 if (pos != m_bp_site_list.end())
150 stop_sp = pos->second;
151
152 return stop_sp;
153}
154
155BreakpointSiteSP
156BreakpointSiteList::FindByAddress (lldb::addr_t addr)
157{
158 BreakpointSiteSP found_sp;
159
160 collection::iterator iter = m_bp_site_list.find(addr);
161 if (iter != m_bp_site_list.end())
162 found_sp = iter->second;
163 return found_sp;
164}
165
166void
167BreakpointSiteList::Dump (Stream *s) const
168{
169 s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
170 s->Indent();
171 s->Printf("BreakpointSiteList with %u BreakpointSites:\n", (uint32_t)m_bp_site_list.size());
172 s->IndentMore();
173 collection::const_iterator pos;
174 collection::const_iterator end = m_bp_site_list.end();
175 for (pos = m_bp_site_list.begin(); pos != end; ++pos)
176 pos->second.get()->Dump(s);
177 s->IndentLess();
178}
179
180
181BreakpointSiteSP
182BreakpointSiteList::GetByIndex (uint32_t i)
183{
184 BreakpointSiteSP stop_sp;
185 collection::iterator end = m_bp_site_list.end();
186 collection::iterator pos;
187 uint32_t curr_i = 0;
188 for (pos = m_bp_site_list.begin(), curr_i = 0; pos != end; ++pos, ++curr_i)
189 {
190 if (curr_i == i)
191 stop_sp = pos->second;
192 }
193 return stop_sp;
194}
195
196const BreakpointSiteSP
197BreakpointSiteList::GetByIndex (uint32_t i) const
198{
199 BreakpointSiteSP stop_sp;
200 collection::const_iterator end = m_bp_site_list.end();
201 collection::const_iterator pos;
202 uint32_t curr_i = 0;
203 for (pos = m_bp_site_list.begin(), curr_i = 0; pos != end; ++pos, ++curr_i)
204 {
205 if (curr_i == i)
206 stop_sp = pos->second;
207 }
208 return stop_sp;
209}
210
211void
212BreakpointSiteList::SetEnabledForAll (const bool enabled, const lldb::user_id_t except_id)
213{
214 collection::iterator end = m_bp_site_list.end();
215 collection::iterator pos;
216 for (pos = m_bp_site_list.begin(); pos != end; ++pos)
217 {
218 if (except_id != LLDB_INVALID_BREAK_ID && except_id != pos->second->GetID())
219 pos->second->SetEnabled (enabled);
220 else
221 pos->second->SetEnabled (!enabled);
222 }
223}
224
225const BreakpointSiteList::collection *
226BreakpointSiteList::GetMap ()
227{
228 return &m_bp_site_list;
229}