1 //===-- BreakpointLocationList.h --------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLDB_BREAKPOINT_BREAKPOINTLOCATIONLIST_H
10 #define LLDB_BREAKPOINT_BREAKPOINTLOCATIONLIST_H
11 
12 #include <map>
13 #include <mutex>
14 #include <vector>
15 
16 #include "lldb/Core/Address.h"
17 #include "lldb/Utility/Iterable.h"
18 #include "lldb/lldb-private.h"
19 
20 namespace lldb_private {
21 
22 /// \class BreakpointLocationList BreakpointLocationList.h
23 /// "lldb/Breakpoint/BreakpointLocationList.h" This class is used by
24 /// Breakpoint to manage a list of breakpoint locations, each breakpoint
25 /// location in the list has a unique ID, and is unique by Address as well.
26 class BreakpointLocationList {
27   // Only Breakpoints can make the location list, or add elements to it. This
28   // is not just some random collection of locations.  Rather, the act of
29   // adding the location to this list sets its ID, and implicitly all the
30   // locations have the same breakpoint ID as well.  If you need a generic
31   // container for breakpoint locations, use BreakpointLocationCollection.
32   friend class Breakpoint;
33 
34 public:
35   virtual ~BreakpointLocationList();
36 
37   /// Standard "Dump" method.  At present it does nothing.
38   void Dump(Stream *s) const;
39 
40   /// Returns a shared pointer to the breakpoint location at address \a addr -
41   /// const version.
42   ///
43   /// \param[in] addr
44   ///     The address to look for.
45   ///
46   /// \result
47   ///     A shared pointer to the breakpoint. May contain a nullptr
48   ///     pointer if the breakpoint doesn't exist.
49   const lldb::BreakpointLocationSP FindByAddress(const Address &addr) const;
50 
51   /// Returns a shared pointer to the breakpoint location with id \a breakID,
52   /// const version.
53   ///
54   /// \param[in] breakID
55   ///     The breakpoint location ID to seek for.
56   ///
57   /// \result
58   ///     A shared pointer to the breakpoint. May contain a nullptr
59   ///     pointer if the breakpoint doesn't exist.
60   lldb::BreakpointLocationSP FindByID(lldb::break_id_t breakID) const;
61 
62   /// Returns the breakpoint location id to the breakpoint location at address
63   /// \a addr.
64   ///
65   /// \param[in] addr
66   ///     The address to match.
67   ///
68   /// \result
69   ///     The ID of the breakpoint location, or LLDB_INVALID_BREAK_ID.
70   lldb::break_id_t FindIDByAddress(const Address &addr);
71 
72   /// Returns a breakpoint location list of the breakpoint locations in the
73   /// module \a module.  This list is allocated, and owned by the caller.
74   ///
75   /// \param[in] module
76   ///     The module to seek in.
77   ///
78   /// \param[in] bp_loc_list
79   ///     A breakpoint collection that gets any breakpoint locations
80   ///     that match \a module appended to.
81   ///
82   /// \result
83   ///     The number of matches
84   size_t FindInModule(Module *module,
85                       BreakpointLocationCollection &bp_loc_list);
86 
87   /// Returns a shared pointer to the breakpoint location with index \a i.
88   ///
89   /// \param[in] i
90   ///     The breakpoint location index to seek for.
91   ///
92   /// \result
93   ///     A shared pointer to the breakpoint. May contain a nullptr
94   ///     pointer if the breakpoint doesn't exist.
95   lldb::BreakpointLocationSP GetByIndex(size_t i);
96 
97   /// Returns a shared pointer to the breakpoint location with index \a i,
98   /// const version.
99   ///
100   /// \param[in] i
101   ///     The breakpoint location index to seek for.
102   ///
103   /// \result
104   ///     A shared pointer to the breakpoint. May contain a nullptr
105   ///     pointer if the breakpoint doesn't exist.
106   const lldb::BreakpointLocationSP GetByIndex(size_t i) const;
107 
108   /// Removes all the locations in this list from their breakpoint site owners
109   /// list.
110   void ClearAllBreakpointSites();
111 
112   /// Tells all the breakpoint locations in this list to attempt to resolve
113   /// any possible breakpoint sites.
114   void ResolveAllBreakpointSites();
115 
116   /// Returns the number of breakpoint locations in this list with resolved
117   /// breakpoints.
118   ///
119   /// \result
120   ///     Number of qualifying breakpoint locations.
121   size_t GetNumResolvedLocations() const;
122 
123   /// Returns the number hit count of all locations in this list.
124   ///
125   /// \result
126   ///     Hit count of all locations in this list.
127   uint32_t GetHitCount() const;
128 
129   /// Enquires of the breakpoint location in this list with ID \a breakID
130   /// whether we should stop.
131   ///
132   /// \param[in] context
133   ///     This contains the information about this stop.
134   ///
135   /// \param[in] breakID
136   ///     This break ID that we hit.
137   ///
138   /// \return
139   ///     \b true if we should stop, \b false otherwise.
140   bool ShouldStop(StoppointCallbackContext *context, lldb::break_id_t breakID);
141 
142   /// Returns the number of elements in this breakpoint location list.
143   ///
144   /// \result
145   ///     The number of elements.
146   size_t GetSize() const { return m_locations.size(); }
147 
148   /// Print a description of the breakpoint locations in this list to the
149   /// stream \a s.
150   ///
151   /// \param[in] s
152   ///     The stream to which to print the description.
153   ///
154   /// \param[in] level
155   ///     The description level that indicates the detail level to
156   ///     provide.
157   ///
158   /// \see lldb::DescriptionLevel
159   void GetDescription(Stream *s, lldb::DescriptionLevel level);
160 
161 protected:
162   /// This is the standard constructor.
163   ///
164   /// It creates an empty breakpoint location list. It is protected here
165   /// because only Breakpoints are allowed to create the breakpoint location
166   /// list.
167   BreakpointLocationList(Breakpoint &owner);
168 
169   lldb::BreakpointLocationSP Create(const Address &addr,
170                                     bool resolve_indirect_symbols);
171 
172   void StartRecordingNewLocations(BreakpointLocationCollection &new_locations);
173 
174   void StopRecordingNewLocations();
175 
176   lldb::BreakpointLocationSP AddLocation(const Address &addr,
177                                          bool resolve_indirect_symbols,
178                                          bool *new_location = nullptr);
179 
180   void SwapLocation(lldb::BreakpointLocationSP to_location_sp,
181                     lldb::BreakpointLocationSP from_location_sp);
182 
183   bool RemoveLocation(const lldb::BreakpointLocationSP &bp_loc_sp);
184 
185   void RemoveLocationByIndex(size_t idx);
186 
187   void RemoveInvalidLocations(const ArchSpec &arch);
188 
189   void Compact();
190 
191   typedef std::vector<lldb::BreakpointLocationSP> collection;
192   typedef std::map<lldb_private::Address, lldb::BreakpointLocationSP,
193                    Address::ModulePointerAndOffsetLessThanFunctionObject>
194       addr_map;
195 
196   Breakpoint &m_owner;
197   collection m_locations; // Vector of locations, sorted by ID
198   addr_map m_address_to_location;
199   mutable std::recursive_mutex m_mutex;
200   lldb::break_id_t m_next_id;
201   BreakpointLocationCollection *m_new_location_recorder;
202 
203 public:
204   typedef AdaptedIterable<collection, lldb::BreakpointLocationSP,
205                           vector_adapter>
206       BreakpointLocationIterable;
207 
208   BreakpointLocationIterable BreakpointLocations() {
209     return BreakpointLocationIterable(m_locations);
210   }
211 };
212 
213 } // namespace lldb_private
214 
215 #endif // LLDB_BREAKPOINT_BREAKPOINTLOCATIONLIST_H
216