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
18namespace lldb_private {
19
20class WatchpointResource
21    : public std::enable_shared_from_this<WatchpointResource> {
22
23public:
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.
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
136protected:
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
144private:
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