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