xref: /freebsd-src/contrib/llvm-project/lldb/include/lldb/Breakpoint/WatchpointResource.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1*5f757f3fSDimitry Andric //===-- WatchpointResource.h ------------------------------------*- C++ -*-===//
2*5f757f3fSDimitry Andric //
3*5f757f3fSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*5f757f3fSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*5f757f3fSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*5f757f3fSDimitry Andric //
7*5f757f3fSDimitry Andric //===----------------------------------------------------------------------===//
8*5f757f3fSDimitry Andric 
9*5f757f3fSDimitry Andric #ifndef LLDB_BREAKPOINT_WATCHPOINTRESOURCE_H
10*5f757f3fSDimitry Andric #define LLDB_BREAKPOINT_WATCHPOINTRESOURCE_H
11*5f757f3fSDimitry Andric 
12*5f757f3fSDimitry Andric #include "lldb/Utility/Iterable.h"
13*5f757f3fSDimitry Andric #include "lldb/lldb-public.h"
14*5f757f3fSDimitry Andric 
15*5f757f3fSDimitry Andric #include <mutex>
16*5f757f3fSDimitry Andric #include <vector>
17*5f757f3fSDimitry Andric 
18*5f757f3fSDimitry Andric namespace lldb_private {
19*5f757f3fSDimitry Andric 
20*5f757f3fSDimitry Andric class WatchpointResource
21*5f757f3fSDimitry Andric     : public std::enable_shared_from_this<WatchpointResource> {
22*5f757f3fSDimitry Andric 
23*5f757f3fSDimitry Andric public:
24*5f757f3fSDimitry Andric   WatchpointResource(lldb::addr_t addr, size_t size, bool read, bool write);
25*5f757f3fSDimitry Andric 
26*5f757f3fSDimitry Andric   ~WatchpointResource();
27*5f757f3fSDimitry Andric 
28*5f757f3fSDimitry Andric   typedef lldb::wp_resource_id_t SiteID;
29*5f757f3fSDimitry Andric   typedef lldb::watch_id_t ConstituentID;
30*5f757f3fSDimitry Andric 
31*5f757f3fSDimitry Andric   lldb::addr_t GetLoadAddress() const;
32*5f757f3fSDimitry Andric 
33*5f757f3fSDimitry Andric   size_t GetByteSize() const;
34*5f757f3fSDimitry Andric 
35*5f757f3fSDimitry Andric   bool WatchpointResourceRead() const;
36*5f757f3fSDimitry Andric 
37*5f757f3fSDimitry Andric   bool WatchpointResourceWrite() const;
38*5f757f3fSDimitry Andric 
39*5f757f3fSDimitry Andric   void SetType(bool read, bool write);
40*5f757f3fSDimitry Andric 
41*5f757f3fSDimitry Andric   typedef std::vector<lldb::WatchpointSP> WatchpointCollection;
42*5f757f3fSDimitry Andric   typedef LockingAdaptedIterable<WatchpointCollection, lldb::WatchpointSP,
43*5f757f3fSDimitry Andric                                  vector_adapter, std::mutex>
44*5f757f3fSDimitry Andric       WatchpointIterable;
45*5f757f3fSDimitry Andric 
46*5f757f3fSDimitry Andric   /// Iterate over the watchpoint constituents for this resource
47*5f757f3fSDimitry Andric   ///
48*5f757f3fSDimitry Andric   /// \return
49*5f757f3fSDimitry Andric   ///     An Iterable object which can be used to loop over the watchpoints
50*5f757f3fSDimitry Andric   ///     that are constituents of this resource.
51*5f757f3fSDimitry Andric   WatchpointIterable Constituents() {
52*5f757f3fSDimitry Andric     return WatchpointIterable(m_constituents, m_constituents_mutex);
53*5f757f3fSDimitry Andric   }
54*5f757f3fSDimitry Andric 
55*5f757f3fSDimitry Andric   /// Enquires of the atchpoints that produced this watchpoint resource
56*5f757f3fSDimitry Andric   /// whether we should stop at this location.
57*5f757f3fSDimitry Andric   ///
58*5f757f3fSDimitry Andric   /// \param[in] context
59*5f757f3fSDimitry Andric   ///    This contains the information about this stop.
60*5f757f3fSDimitry Andric   ///
61*5f757f3fSDimitry Andric   /// \return
62*5f757f3fSDimitry Andric   ///    \b true if we should stop, \b false otherwise.
63*5f757f3fSDimitry Andric   bool ShouldStop(StoppointCallbackContext *context);
64*5f757f3fSDimitry Andric 
65*5f757f3fSDimitry Andric   /// Standard Dump method
66*5f757f3fSDimitry Andric   void Dump(Stream *s) const;
67*5f757f3fSDimitry Andric 
68*5f757f3fSDimitry Andric   /// The "Constituents" are the watchpoints that share this resource.
69*5f757f3fSDimitry Andric   /// The method adds the \a constituent to this resource's constituent list.
70*5f757f3fSDimitry Andric   ///
71*5f757f3fSDimitry Andric   /// \param[in] constituent
72*5f757f3fSDimitry Andric   ///    \a constituent is the Wachpoint to add.
73*5f757f3fSDimitry Andric   void AddConstituent(const lldb::WatchpointSP &constituent);
74*5f757f3fSDimitry Andric 
75*5f757f3fSDimitry Andric   /// The method removes the constituent at \a constituent from this watchpoint
76*5f757f3fSDimitry Andric   /// resource.
77*5f757f3fSDimitry Andric   void RemoveConstituent(lldb::WatchpointSP &constituent);
78*5f757f3fSDimitry Andric 
79*5f757f3fSDimitry Andric   /// This method returns the number of Watchpoints currently using
80*5f757f3fSDimitry Andric   /// watchpoint resource.
81*5f757f3fSDimitry Andric   ///
82*5f757f3fSDimitry Andric   /// \return
83*5f757f3fSDimitry Andric   ///    The number of constituents.
84*5f757f3fSDimitry Andric   size_t GetNumberOfConstituents();
85*5f757f3fSDimitry Andric 
86*5f757f3fSDimitry Andric   /// This method returns the Watchpoint at index \a index using this
87*5f757f3fSDimitry Andric   /// Resource.  The constituents are listed ordinally from 0 to
88*5f757f3fSDimitry Andric   /// GetNumberOfConstituents() - 1 so you can use this method to iterate over
89*5f757f3fSDimitry Andric   /// the constituents.
90*5f757f3fSDimitry Andric   ///
91*5f757f3fSDimitry Andric   /// \param[in] idx
92*5f757f3fSDimitry Andric   ///     The index in the list of constituents for which you wish the
93*5f757f3fSDimitry Andric   ///     constituent location.
94*5f757f3fSDimitry Andric   ///
95*5f757f3fSDimitry Andric   /// \return
96*5f757f3fSDimitry Andric   ///    The Watchpoint at that index.
97*5f757f3fSDimitry Andric   lldb::WatchpointSP GetConstituentAtIndex(size_t idx);
98*5f757f3fSDimitry Andric 
99*5f757f3fSDimitry Andric   /// Check if the constituents includes a watchpoint.
100*5f757f3fSDimitry Andric   ///
101*5f757f3fSDimitry Andric   /// \param[in] wp_sp
102*5f757f3fSDimitry Andric   ///     The WatchpointSP to search for.
103*5f757f3fSDimitry Andric   ///
104*5f757f3fSDimitry Andric   /// \result
105*5f757f3fSDimitry Andric   ///     true if this resource's constituents includes the watchpoint.
106*5f757f3fSDimitry Andric   bool ConstituentsContains(const lldb::WatchpointSP &wp_sp);
107*5f757f3fSDimitry Andric 
108*5f757f3fSDimitry Andric   /// Check if the constituents includes a watchpoint.
109*5f757f3fSDimitry Andric   ///
110*5f757f3fSDimitry Andric   /// \param[in] wp
111*5f757f3fSDimitry Andric   ///     The Watchpoint to search for.
112*5f757f3fSDimitry Andric   ///
113*5f757f3fSDimitry Andric   /// \result
114*5f757f3fSDimitry Andric   ///     true if this resource's constituents includes the watchpoint.
115*5f757f3fSDimitry Andric   bool ConstituentsContains(const lldb_private::Watchpoint *wp);
116*5f757f3fSDimitry Andric 
117*5f757f3fSDimitry Andric   /// This method copies the watchpoint resource's constituents into a new
118*5f757f3fSDimitry Andric   /// collection. It does this while the constituents mutex is locked.
119*5f757f3fSDimitry Andric   ///
120*5f757f3fSDimitry Andric   /// \return
121*5f757f3fSDimitry Andric   ///    A copy of the Watchpoints which own this resource.
122*5f757f3fSDimitry Andric   WatchpointCollection CopyConstituentsList();
123*5f757f3fSDimitry Andric 
124*5f757f3fSDimitry Andric   lldb::wp_resource_id_t GetID() const;
125*5f757f3fSDimitry Andric 
126*5f757f3fSDimitry Andric   bool Contains(lldb::addr_t addr);
127*5f757f3fSDimitry Andric 
128*5f757f3fSDimitry Andric protected:
129*5f757f3fSDimitry Andric   // The StopInfoWatchpoint knows when it is processing a hit for a thread for
130*5f757f3fSDimitry Andric   // a site, so let it be the one to manage setting the location hit count once
131*5f757f3fSDimitry Andric   // and only once.
132*5f757f3fSDimitry Andric   friend class StopInfoWatchpoint;
133*5f757f3fSDimitry Andric 
134*5f757f3fSDimitry Andric   void BumpHitCounts();
135*5f757f3fSDimitry Andric 
136*5f757f3fSDimitry Andric private:
137*5f757f3fSDimitry Andric   static lldb::wp_resource_id_t GetNextID();
138*5f757f3fSDimitry Andric 
139*5f757f3fSDimitry Andric   lldb::wp_resource_id_t m_id;
140*5f757f3fSDimitry Andric 
141*5f757f3fSDimitry Andric   // Start address & size aligned & expanded to be a valid watchpoint
142*5f757f3fSDimitry Andric   // memory granule on this target.
143*5f757f3fSDimitry Andric   lldb::addr_t m_addr;
144*5f757f3fSDimitry Andric   size_t m_size;
145*5f757f3fSDimitry Andric 
146*5f757f3fSDimitry Andric   bool m_watch_read;
147*5f757f3fSDimitry Andric   bool m_watch_write;
148*5f757f3fSDimitry Andric 
149*5f757f3fSDimitry Andric   /// The Watchpoints which own this resource.
150*5f757f3fSDimitry Andric   WatchpointCollection m_constituents;
151*5f757f3fSDimitry Andric 
152*5f757f3fSDimitry Andric   /// This mutex protects the constituents collection.
153*5f757f3fSDimitry Andric   std::mutex m_constituents_mutex;
154*5f757f3fSDimitry Andric 
155*5f757f3fSDimitry Andric   WatchpointResource(const WatchpointResource &) = delete;
156*5f757f3fSDimitry Andric   const WatchpointResource &operator=(const WatchpointResource &) = delete;
157*5f757f3fSDimitry Andric };
158*5f757f3fSDimitry Andric 
159*5f757f3fSDimitry Andric } // namespace lldb_private
160*5f757f3fSDimitry Andric 
161*5f757f3fSDimitry Andric #endif // LLDB_BREAKPOINT_WATCHPOINTRESOURCE_H
162