1 //===-- WatchpointResourceList.cpp ----------------------------------------===//
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 #include "lldb/Breakpoint/WatchpointResourceList.h"
10 #include "lldb/Breakpoint/WatchpointResource.h"
11 #include "lldb/Utility/LLDBLog.h"
12 #include "lldb/Utility/Log.h"
13 
14 using namespace lldb;
15 using namespace lldb_private;
16 
17 WatchpointResourceList::WatchpointResourceList() : m_resources(), m_mutex() {}
18 
19 WatchpointResourceList::~WatchpointResourceList() { Clear(); }
20 
21 wp_resource_id_t
22 WatchpointResourceList::Add(const WatchpointResourceSP &wp_res_sp) {
23   Log *log = GetLog(LLDBLog::Watchpoints);
24   std::lock_guard<std::mutex> guard(m_mutex);
25   LLDB_LOGF(log, "WatchpointResourceList::Add(addr 0x%" PRIx64 " size %zu)",
26             wp_res_sp->GetLoadAddress(), wp_res_sp->GetByteSize());
27 
28   m_resources.push_back(wp_res_sp);
29   return wp_res_sp->GetID();
30 }
31 
32 bool WatchpointResourceList::Remove(wp_resource_id_t id) {
33   std::lock_guard<std::mutex> guard(m_mutex);
34   Log *log = GetLog(LLDBLog::Watchpoints);
35   for (collection::iterator pos = m_resources.begin(); pos != m_resources.end();
36        ++pos) {
37     if ((*pos)->GetID() == id) {
38       LLDB_LOGF(log,
39                 "WatchpointResourceList::Remove(addr 0x%" PRIx64 " size %zu)",
40                 (*pos)->GetLoadAddress(), (*pos)->GetByteSize());
41       m_resources.erase(pos);
42       return true;
43     }
44   }
45   return false;
46 }
47 
48 bool WatchpointResourceList::RemoveByAddress(addr_t addr) {
49   std::lock_guard<std::mutex> guard(m_mutex);
50   Log *log = GetLog(LLDBLog::Watchpoints);
51   for (collection::iterator pos = m_resources.begin(); pos != m_resources.end();
52        ++pos) {
53     if ((*pos)->Contains(addr)) {
54       LLDB_LOGF(log,
55                 "WatchpointResourceList::RemoveByAddress(addr 0x%" PRIx64
56                 " size %zu)",
57                 (*pos)->GetLoadAddress(), (*pos)->GetByteSize());
58       m_resources.erase(pos);
59       return true;
60     }
61   }
62   return false;
63 }
64 
65 WatchpointResourceSP WatchpointResourceList::FindByAddress(addr_t addr) {
66   std::lock_guard<std::mutex> guard(m_mutex);
67   for (WatchpointResourceSP wp_res_sp : m_resources)
68     if (wp_res_sp->Contains(addr))
69       return wp_res_sp;
70   return {};
71 }
72 
73 WatchpointResourceSP
74 WatchpointResourceList::FindByWatchpointSP(WatchpointSP &wp_sp) {
75   return FindByWatchpoint(wp_sp.get());
76 }
77 
78 WatchpointResourceSP
79 WatchpointResourceList::FindByWatchpoint(const Watchpoint *wp) {
80   std::lock_guard<std::mutex> guard(m_mutex);
81   for (WatchpointResourceSP wp_res_sp : m_resources)
82     if (wp_res_sp->ConstituentsContains(wp))
83       return wp_res_sp;
84   return {};
85 }
86 
87 WatchpointResourceSP WatchpointResourceList::FindByID(wp_resource_id_t id) {
88   std::lock_guard<std::mutex> guard(m_mutex);
89   for (WatchpointResourceSP wp_res_sp : m_resources)
90     if (wp_res_sp->GetID() == id)
91       return wp_res_sp;
92   return {};
93 }
94 
95 uint32_t WatchpointResourceList::GetSize() {
96   std::lock_guard<std::mutex> guard(m_mutex);
97   return m_resources.size();
98 }
99 
100 lldb::WatchpointResourceSP
101 WatchpointResourceList::GetResourceAtIndex(uint32_t idx) {
102   std::lock_guard<std::mutex> guard(m_mutex);
103   if (idx < m_resources.size())
104     return m_resources[idx];
105 
106   return {};
107 }
108 
109 void WatchpointResourceList::Clear() {
110   std::lock_guard<std::mutex> guard(m_mutex);
111   m_resources.clear();
112 }
113 
114 std::mutex &WatchpointResourceList::GetMutex() { return m_mutex; }
115