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