]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Breakpoint/BreakpointList.cpp
Merge OpenSSL 1.1.1a.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Breakpoint / BreakpointList.cpp
1 //===-- BreakpointList.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/BreakpointList.h"
11
12 // C Includes
13 // C++ Includes
14 // Other libraries and framework includes
15 // Project includes
16 #include "lldb/Target/Target.h"
17
18 using namespace lldb;
19 using namespace lldb_private;
20
21 BreakpointList::BreakpointList(bool is_internal)
22     : m_mutex(), m_breakpoints(), m_next_break_id(0),
23       m_is_internal(is_internal) {}
24
25 BreakpointList::~BreakpointList() {}
26
27 break_id_t BreakpointList::Add(BreakpointSP &bp_sp, bool notify) {
28   std::lock_guard<std::recursive_mutex> guard(m_mutex);
29   // Internal breakpoint IDs are negative, normal ones are positive
30   bp_sp->SetID(m_is_internal ? --m_next_break_id : ++m_next_break_id);
31
32   m_breakpoints.push_back(bp_sp);
33   if (notify) {
34     if (bp_sp->GetTarget().EventTypeHasListeners(
35             Target::eBroadcastBitBreakpointChanged))
36       bp_sp->GetTarget().BroadcastEvent(Target::eBroadcastBitBreakpointChanged,
37                                         new Breakpoint::BreakpointEventData(
38                                             eBreakpointEventTypeAdded, bp_sp));
39   }
40   return bp_sp->GetID();
41 }
42
43 bool BreakpointList::Remove(break_id_t break_id, bool notify) {
44   std::lock_guard<std::recursive_mutex> guard(m_mutex);
45   bp_collection::iterator pos = GetBreakpointIDIterator(break_id); // Predicate
46   if (pos != m_breakpoints.end()) {
47     BreakpointSP bp_sp(*pos);
48     m_breakpoints.erase(pos);
49     if (notify) {
50       if (bp_sp->GetTarget().EventTypeHasListeners(
51               Target::eBroadcastBitBreakpointChanged))
52         bp_sp->GetTarget().BroadcastEvent(
53             Target::eBroadcastBitBreakpointChanged,
54             new Breakpoint::BreakpointEventData(eBreakpointEventTypeRemoved,
55                                                 bp_sp));
56     }
57     return true;
58   }
59   return false;
60 }
61
62 void BreakpointList::RemoveInvalidLocations(const ArchSpec &arch) {
63   std::lock_guard<std::recursive_mutex> guard(m_mutex);
64   for (const auto &bp_sp : m_breakpoints)
65     bp_sp->RemoveInvalidLocations(arch);
66 }
67
68 void BreakpointList::SetEnabledAll(bool enabled) {
69   std::lock_guard<std::recursive_mutex> guard(m_mutex);
70   for (const auto &bp_sp : m_breakpoints)
71     bp_sp->SetEnabled(enabled);
72 }
73
74 void BreakpointList::SetEnabledAllowed(bool enabled) {
75   std::lock_guard<std::recursive_mutex> guard(m_mutex);
76   for (const auto &bp_sp : m_breakpoints)
77     if (bp_sp->AllowDisable())
78       bp_sp->SetEnabled(enabled);
79 }
80
81 void BreakpointList::RemoveAll(bool notify) {
82   std::lock_guard<std::recursive_mutex> guard(m_mutex);
83   ClearAllBreakpointSites();
84
85   if (notify) {
86     bp_collection::iterator pos, end = m_breakpoints.end();
87     for (pos = m_breakpoints.begin(); pos != end; ++pos) {
88       if ((*pos)->GetTarget().EventTypeHasListeners(
89               Target::eBroadcastBitBreakpointChanged)) {
90         (*pos)->GetTarget().BroadcastEvent(
91             Target::eBroadcastBitBreakpointChanged,
92             new Breakpoint::BreakpointEventData(eBreakpointEventTypeRemoved,
93                                                 *pos));
94       }
95     }
96   }
97   m_breakpoints.erase(m_breakpoints.begin(), m_breakpoints.end());
98 }
99
100 void BreakpointList::RemoveAllowed(bool notify) {
101   std::lock_guard<std::recursive_mutex> guard(m_mutex);
102   
103   bp_collection::iterator pos, end = m_breakpoints.end();
104   if (notify) {
105     for (pos = m_breakpoints.begin(); pos != end; ++pos) {
106       if(!(*pos)->AllowDelete())
107         continue;
108       if ((*pos)->GetTarget().EventTypeHasListeners(
109               Target::eBroadcastBitBreakpointChanged)) {
110         (*pos)->GetTarget().BroadcastEvent(
111             Target::eBroadcastBitBreakpointChanged,
112             new Breakpoint::BreakpointEventData(eBreakpointEventTypeRemoved,
113                                                 *pos));
114       }
115     }
116   }
117   pos = m_breakpoints.begin();
118   while ( pos != end) {
119       if((*pos)->AllowDelete())
120         pos = m_breakpoints.erase(pos);
121       else
122         pos++;
123   }
124 }
125
126 class BreakpointIDMatches {
127 public:
128   BreakpointIDMatches(break_id_t break_id) : m_break_id(break_id) {}
129
130   bool operator()(const BreakpointSP &bp) const {
131     return m_break_id == bp->GetID();
132   }
133
134 private:
135   const break_id_t m_break_id;
136 };
137
138 BreakpointList::bp_collection::iterator
139 BreakpointList::GetBreakpointIDIterator(break_id_t break_id) {
140   return std::find_if(m_breakpoints.begin(),
141                       m_breakpoints.end(),            // Search full range
142                       BreakpointIDMatches(break_id)); // Predicate
143 }
144
145 BreakpointList::bp_collection::const_iterator
146 BreakpointList::GetBreakpointIDConstIterator(break_id_t break_id) const {
147   return std::find_if(m_breakpoints.begin(),
148                       m_breakpoints.end(),            // Search full range
149                       BreakpointIDMatches(break_id)); // Predicate
150 }
151
152 BreakpointSP BreakpointList::FindBreakpointByID(break_id_t break_id) {
153   std::lock_guard<std::recursive_mutex> guard(m_mutex);
154   BreakpointSP stop_sp;
155   bp_collection::iterator pos = GetBreakpointIDIterator(break_id);
156   if (pos != m_breakpoints.end())
157     stop_sp = *pos;
158
159   return stop_sp;
160 }
161
162 const BreakpointSP
163 BreakpointList::FindBreakpointByID(break_id_t break_id) const {
164   std::lock_guard<std::recursive_mutex> guard(m_mutex);
165   BreakpointSP stop_sp;
166   bp_collection::const_iterator pos = GetBreakpointIDConstIterator(break_id);
167   if (pos != m_breakpoints.end())
168     stop_sp = *pos;
169
170   return stop_sp;
171 }
172
173 bool BreakpointList::FindBreakpointsByName(const char *name,
174                                            BreakpointList &matching_bps) {
175   Status error;
176   if (!name)
177     return false;
178
179   if (!BreakpointID::StringIsBreakpointName(llvm::StringRef(name), error))
180     return false;
181
182   for (BreakpointSP bkpt_sp : Breakpoints()) {
183     if (bkpt_sp->MatchesName(name)) {
184       matching_bps.Add(bkpt_sp, false);
185     }
186   }
187   return true;
188 }
189
190 void BreakpointList::Dump(Stream *s) const {
191   std::lock_guard<std::recursive_mutex> guard(m_mutex);
192   s->Printf("%p: ", static_cast<const void *>(this));
193   s->Indent();
194   s->Printf("BreakpointList with %u Breakpoints:\n",
195             (uint32_t)m_breakpoints.size());
196   s->IndentMore();
197   for (const auto &bp_sp : m_breakpoints)
198     bp_sp->Dump(s);
199   s->IndentLess();
200 }
201
202 BreakpointSP BreakpointList::GetBreakpointAtIndex(size_t i) {
203   std::lock_guard<std::recursive_mutex> guard(m_mutex);
204   BreakpointSP stop_sp;
205   bp_collection::iterator end = m_breakpoints.end();
206   bp_collection::iterator pos;
207   size_t curr_i = 0;
208   for (pos = m_breakpoints.begin(), curr_i = 0; pos != end; ++pos, ++curr_i) {
209     if (curr_i == i)
210       stop_sp = *pos;
211   }
212   return stop_sp;
213 }
214
215 const BreakpointSP BreakpointList::GetBreakpointAtIndex(size_t i) const {
216   std::lock_guard<std::recursive_mutex> guard(m_mutex);
217   BreakpointSP stop_sp;
218   bp_collection::const_iterator end = m_breakpoints.end();
219   bp_collection::const_iterator pos;
220   size_t curr_i = 0;
221   for (pos = m_breakpoints.begin(), curr_i = 0; pos != end; ++pos, ++curr_i) {
222     if (curr_i == i)
223       stop_sp = *pos;
224   }
225   return stop_sp;
226 }
227
228 void BreakpointList::UpdateBreakpoints(ModuleList &module_list, bool added,
229                                        bool delete_locations) {
230   std::lock_guard<std::recursive_mutex> guard(m_mutex);
231   for (const auto &bp_sp : m_breakpoints)
232     bp_sp->ModulesChanged(module_list, added, delete_locations);
233 }
234
235 void BreakpointList::UpdateBreakpointsWhenModuleIsReplaced(
236     ModuleSP old_module_sp, ModuleSP new_module_sp) {
237   std::lock_guard<std::recursive_mutex> guard(m_mutex);
238   for (const auto &bp_sp : m_breakpoints)
239     bp_sp->ModuleReplaced(old_module_sp, new_module_sp);
240 }
241
242 void BreakpointList::ClearAllBreakpointSites() {
243   std::lock_guard<std::recursive_mutex> guard(m_mutex);
244   for (const auto &bp_sp : m_breakpoints)
245     bp_sp->ClearAllBreakpointSites();
246 }
247
248 void BreakpointList::GetListMutex(
249     std::unique_lock<std::recursive_mutex> &lock) {
250   lock = std::unique_lock<std::recursive_mutex>(m_mutex);
251 }