180814287SRaphael Isemann //===-- SBWatchpoint.cpp --------------------------------------------------===//
21b282f96SGreg Clayton //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
61b282f96SGreg Clayton //
71b282f96SGreg Clayton //===----------------------------------------------------------------------===//
81b282f96SGreg Clayton 
91b282f96SGreg Clayton #include "lldb/API/SBWatchpoint.h"
10d51402acSJonas Devlieghere #include "lldb/Utility/ReproducerInstrumentation.h"
111b282f96SGreg Clayton #include "lldb/API/SBAddress.h"
121b282f96SGreg Clayton #include "lldb/API/SBDebugger.h"
13b9c1b51eSKate Stone #include "lldb/API/SBDefines.h"
141b5792e5SJim Ingham #include "lldb/API/SBEvent.h"
151b282f96SGreg Clayton #include "lldb/API/SBStream.h"
161b282f96SGreg Clayton 
1701a67860SJohnny Chen #include "lldb/Breakpoint/Watchpoint.h"
1801a67860SJohnny Chen #include "lldb/Breakpoint/WatchpointList.h"
191b282f96SGreg Clayton #include "lldb/Core/StreamFile.h"
20306b62b4SJim Ingham #include "lldb/Target/Process.h"
211b282f96SGreg Clayton #include "lldb/Target/Target.h"
22bf9a7730SZachary Turner #include "lldb/Utility/Stream.h"
23b9c1b51eSKate Stone #include "lldb/lldb-defines.h"
24b9c1b51eSKate Stone #include "lldb/lldb-types.h"
251b282f96SGreg Clayton 
261b282f96SGreg Clayton using namespace lldb;
271b282f96SGreg Clayton using namespace lldb_private;
281b282f96SGreg Clayton 
29baf5664fSJonas Devlieghere SBWatchpoint::SBWatchpoint() { LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBWatchpoint); }
301b282f96SGreg Clayton 
31b9c1b51eSKate Stone SBWatchpoint::SBWatchpoint(const lldb::WatchpointSP &wp_sp)
327a1d34beSPavel Labath     : m_opaque_wp(wp_sp) {
33baf5664fSJonas Devlieghere   LLDB_RECORD_CONSTRUCTOR(SBWatchpoint, (const lldb::WatchpointSP &), wp_sp);
341b282f96SGreg Clayton }
351b282f96SGreg Clayton 
36b9c1b51eSKate Stone SBWatchpoint::SBWatchpoint(const SBWatchpoint &rhs)
37baf5664fSJonas Devlieghere     : m_opaque_wp(rhs.m_opaque_wp) {
38baf5664fSJonas Devlieghere   LLDB_RECORD_CONSTRUCTOR(SBWatchpoint, (const lldb::SBWatchpoint &), rhs);
39baf5664fSJonas Devlieghere }
401b282f96SGreg Clayton 
41b9c1b51eSKate Stone const SBWatchpoint &SBWatchpoint::operator=(const SBWatchpoint &rhs) {
42baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(const lldb::SBWatchpoint &,
43baf5664fSJonas Devlieghere                      SBWatchpoint, operator=,(const lldb::SBWatchpoint &), rhs);
44baf5664fSJonas Devlieghere 
457a1d34beSPavel Labath   m_opaque_wp = rhs.m_opaque_wp;
46*d232abc3SJonas Devlieghere   return *this;
471b282f96SGreg Clayton }
481b282f96SGreg Clayton 
49866b7a65SJonas Devlieghere SBWatchpoint::~SBWatchpoint() = default;
501b282f96SGreg Clayton 
51b9c1b51eSKate Stone watch_id_t SBWatchpoint::GetID() {
52baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb::watch_id_t, SBWatchpoint, GetID);
53baf5664fSJonas Devlieghere 
541b282f96SGreg Clayton 
551b282f96SGreg Clayton   watch_id_t watch_id = LLDB_INVALID_WATCH_ID;
5681e871edSGreg Clayton   lldb::WatchpointSP watchpoint_sp(GetSP());
5781e871edSGreg Clayton   if (watchpoint_sp)
5881e871edSGreg Clayton     watch_id = watchpoint_sp->GetID();
591b282f96SGreg Clayton 
601b282f96SGreg Clayton   return watch_id;
611b282f96SGreg Clayton }
621b282f96SGreg Clayton 
63baf5664fSJonas Devlieghere bool SBWatchpoint::IsValid() const {
64baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBWatchpoint, IsValid);
657f5237bcSPavel Labath   return this->operator bool();
667f5237bcSPavel Labath }
677f5237bcSPavel Labath SBWatchpoint::operator bool() const {
687f5237bcSPavel Labath   LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBWatchpoint, operator bool);
69baf5664fSJonas Devlieghere 
70baf5664fSJonas Devlieghere   return bool(m_opaque_wp.lock());
71baf5664fSJonas Devlieghere }
721b282f96SGreg Clayton 
734bc05006SPavel Labath bool SBWatchpoint::operator==(const SBWatchpoint &rhs) const {
744bc05006SPavel Labath   LLDB_RECORD_METHOD_CONST(
754bc05006SPavel Labath       bool, SBWatchpoint, operator==,(const SBWatchpoint &), rhs);
764bc05006SPavel Labath 
774bc05006SPavel Labath   return GetSP() == rhs.GetSP();
784bc05006SPavel Labath }
794bc05006SPavel Labath 
804bc05006SPavel Labath bool SBWatchpoint::operator!=(const SBWatchpoint &rhs) const {
814bc05006SPavel Labath   LLDB_RECORD_METHOD_CONST(
824bc05006SPavel Labath       bool, SBWatchpoint, operator!=,(const SBWatchpoint &), rhs);
834bc05006SPavel Labath 
844bc05006SPavel Labath   return !(*this == rhs);
854bc05006SPavel Labath }
864bc05006SPavel Labath 
87b9c1b51eSKate Stone SBError SBWatchpoint::GetError() {
88baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBError, SBWatchpoint, GetError);
89baf5664fSJonas Devlieghere 
90ef42a6fbSJim Ingham   SBError sb_error;
91ef42a6fbSJim Ingham   lldb::WatchpointSP watchpoint_sp(GetSP());
92b9c1b51eSKate Stone   if (watchpoint_sp) {
93ef42a6fbSJim Ingham     sb_error.SetError(watchpoint_sp->GetError());
94ef42a6fbSJim Ingham   }
95*d232abc3SJonas Devlieghere   return sb_error;
96ef42a6fbSJim Ingham }
97ef42a6fbSJim Ingham 
98b9c1b51eSKate Stone int32_t SBWatchpoint::GetHardwareIndex() {
99baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(int32_t, SBWatchpoint, GetHardwareIndex);
100baf5664fSJonas Devlieghere 
1011b282f96SGreg Clayton   int32_t hw_index = -1;
1021b282f96SGreg Clayton 
10381e871edSGreg Clayton   lldb::WatchpointSP watchpoint_sp(GetSP());
104b9c1b51eSKate Stone   if (watchpoint_sp) {
105b9c1b51eSKate Stone     std::lock_guard<std::recursive_mutex> guard(
106b9c1b51eSKate Stone         watchpoint_sp->GetTarget().GetAPIMutex());
10781e871edSGreg Clayton     hw_index = watchpoint_sp->GetHardwareIndex();
1081b282f96SGreg Clayton   }
1091b282f96SGreg Clayton 
1101b282f96SGreg Clayton   return hw_index;
1111b282f96SGreg Clayton }
1121b282f96SGreg Clayton 
113b9c1b51eSKate Stone addr_t SBWatchpoint::GetWatchAddress() {
114baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(lldb::addr_t, SBWatchpoint, GetWatchAddress);
115baf5664fSJonas Devlieghere 
1161b282f96SGreg Clayton   addr_t ret_addr = LLDB_INVALID_ADDRESS;
1171b282f96SGreg Clayton 
11881e871edSGreg Clayton   lldb::WatchpointSP watchpoint_sp(GetSP());
119b9c1b51eSKate Stone   if (watchpoint_sp) {
120b9c1b51eSKate Stone     std::lock_guard<std::recursive_mutex> guard(
121b9c1b51eSKate Stone         watchpoint_sp->GetTarget().GetAPIMutex());
12281e871edSGreg Clayton     ret_addr = watchpoint_sp->GetLoadAddress();
1231b282f96SGreg Clayton   }
1241b282f96SGreg Clayton 
1251b282f96SGreg Clayton   return ret_addr;
1261b282f96SGreg Clayton }
1271b282f96SGreg Clayton 
128b9c1b51eSKate Stone size_t SBWatchpoint::GetWatchSize() {
129baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(size_t, SBWatchpoint, GetWatchSize);
130baf5664fSJonas Devlieghere 
1311b282f96SGreg Clayton   size_t watch_size = 0;
1321b282f96SGreg Clayton 
13381e871edSGreg Clayton   lldb::WatchpointSP watchpoint_sp(GetSP());
134b9c1b51eSKate Stone   if (watchpoint_sp) {
135b9c1b51eSKate Stone     std::lock_guard<std::recursive_mutex> guard(
136b9c1b51eSKate Stone         watchpoint_sp->GetTarget().GetAPIMutex());
13781e871edSGreg Clayton     watch_size = watchpoint_sp->GetByteSize();
1381b282f96SGreg Clayton   }
1391b282f96SGreg Clayton 
1401b282f96SGreg Clayton   return watch_size;
1411b282f96SGreg Clayton }
1421b282f96SGreg Clayton 
143b9c1b51eSKate Stone void SBWatchpoint::SetEnabled(bool enabled) {
144baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBWatchpoint, SetEnabled, (bool), enabled);
145baf5664fSJonas Devlieghere 
14681e871edSGreg Clayton   lldb::WatchpointSP watchpoint_sp(GetSP());
147b9c1b51eSKate Stone   if (watchpoint_sp) {
148306b62b4SJim Ingham     Target &target = watchpoint_sp->GetTarget();
149306b62b4SJim Ingham     std::lock_guard<std::recursive_mutex> guard(target.GetAPIMutex());
150306b62b4SJim Ingham     ProcessSP process_sp = target.GetProcessSP();
151c76c3f2fSJim Ingham     const bool notify = true;
152306b62b4SJim Ingham     if (process_sp) {
153306b62b4SJim Ingham       if (enabled)
154c76c3f2fSJim Ingham         process_sp->EnableWatchpoint(watchpoint_sp.get(), notify);
155306b62b4SJim Ingham       else
156c76c3f2fSJim Ingham         process_sp->DisableWatchpoint(watchpoint_sp.get(), notify);
157306b62b4SJim Ingham     } else {
158c76c3f2fSJim Ingham       watchpoint_sp->SetEnabled(enabled, notify);
1591b282f96SGreg Clayton     }
1601b282f96SGreg Clayton   }
161306b62b4SJim Ingham }
1621b282f96SGreg Clayton 
163b9c1b51eSKate Stone bool SBWatchpoint::IsEnabled() {
164baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(bool, SBWatchpoint, IsEnabled);
165baf5664fSJonas Devlieghere 
16681e871edSGreg Clayton   lldb::WatchpointSP watchpoint_sp(GetSP());
167b9c1b51eSKate Stone   if (watchpoint_sp) {
168b9c1b51eSKate Stone     std::lock_guard<std::recursive_mutex> guard(
169b9c1b51eSKate Stone         watchpoint_sp->GetTarget().GetAPIMutex());
17081e871edSGreg Clayton     return watchpoint_sp->IsEnabled();
171b9c1b51eSKate Stone   } else
1721b282f96SGreg Clayton     return false;
1731b282f96SGreg Clayton }
1741b282f96SGreg Clayton 
175b9c1b51eSKate Stone uint32_t SBWatchpoint::GetHitCount() {
176baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBWatchpoint, GetHitCount);
177baf5664fSJonas Devlieghere 
1781b282f96SGreg Clayton   uint32_t count = 0;
17981e871edSGreg Clayton   lldb::WatchpointSP watchpoint_sp(GetSP());
180b9c1b51eSKate Stone   if (watchpoint_sp) {
181b9c1b51eSKate Stone     std::lock_guard<std::recursive_mutex> guard(
182b9c1b51eSKate Stone         watchpoint_sp->GetTarget().GetAPIMutex());
18381e871edSGreg Clayton     count = watchpoint_sp->GetHitCount();
1841b282f96SGreg Clayton   }
1851b282f96SGreg Clayton 
1861b282f96SGreg Clayton   return count;
1871b282f96SGreg Clayton }
1881b282f96SGreg Clayton 
189b9c1b51eSKate Stone uint32_t SBWatchpoint::GetIgnoreCount() {
190baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBWatchpoint, GetIgnoreCount);
191baf5664fSJonas Devlieghere 
19281e871edSGreg Clayton   lldb::WatchpointSP watchpoint_sp(GetSP());
193b9c1b51eSKate Stone   if (watchpoint_sp) {
194b9c1b51eSKate Stone     std::lock_guard<std::recursive_mutex> guard(
195b9c1b51eSKate Stone         watchpoint_sp->GetTarget().GetAPIMutex());
19681e871edSGreg Clayton     return watchpoint_sp->GetIgnoreCount();
197b9c1b51eSKate Stone   } else
1981b282f96SGreg Clayton     return 0;
1991b282f96SGreg Clayton }
2001b282f96SGreg Clayton 
201b9c1b51eSKate Stone void SBWatchpoint::SetIgnoreCount(uint32_t n) {
202baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBWatchpoint, SetIgnoreCount, (uint32_t), n);
203baf5664fSJonas Devlieghere 
20481e871edSGreg Clayton   lldb::WatchpointSP watchpoint_sp(GetSP());
205b9c1b51eSKate Stone   if (watchpoint_sp) {
206b9c1b51eSKate Stone     std::lock_guard<std::recursive_mutex> guard(
207b9c1b51eSKate Stone         watchpoint_sp->GetTarget().GetAPIMutex());
20881e871edSGreg Clayton     watchpoint_sp->SetIgnoreCount(n);
2091b282f96SGreg Clayton   }
2101b282f96SGreg Clayton }
2111b282f96SGreg Clayton 
212b9c1b51eSKate Stone const char *SBWatchpoint::GetCondition() {
213baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(const char *, SBWatchpoint, GetCondition);
214baf5664fSJonas Devlieghere 
21581e871edSGreg Clayton   lldb::WatchpointSP watchpoint_sp(GetSP());
216b9c1b51eSKate Stone   if (watchpoint_sp) {
217b9c1b51eSKate Stone     std::lock_guard<std::recursive_mutex> guard(
218b9c1b51eSKate Stone         watchpoint_sp->GetTarget().GetAPIMutex());
21981e871edSGreg Clayton     return watchpoint_sp->GetConditionText();
22016dcf718SJohnny Chen   }
221248a1305SKonrad Kleine   return nullptr;
22216dcf718SJohnny Chen }
22316dcf718SJohnny Chen 
224b9c1b51eSKate Stone void SBWatchpoint::SetCondition(const char *condition) {
225baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBWatchpoint, SetCondition, (const char *),
226baf5664fSJonas Devlieghere                      condition);
227baf5664fSJonas Devlieghere 
22881e871edSGreg Clayton   lldb::WatchpointSP watchpoint_sp(GetSP());
229b9c1b51eSKate Stone   if (watchpoint_sp) {
230b9c1b51eSKate Stone     std::lock_guard<std::recursive_mutex> guard(
231b9c1b51eSKate Stone         watchpoint_sp->GetTarget().GetAPIMutex());
23281e871edSGreg Clayton     watchpoint_sp->SetCondition(condition);
23316dcf718SJohnny Chen   }
23416dcf718SJohnny Chen }
23516dcf718SJohnny Chen 
236b9c1b51eSKate Stone bool SBWatchpoint::GetDescription(SBStream &description,
237b9c1b51eSKate Stone                                   DescriptionLevel level) {
238baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(bool, SBWatchpoint, GetDescription,
239baf5664fSJonas Devlieghere                      (lldb::SBStream &, lldb::DescriptionLevel), description,
240baf5664fSJonas Devlieghere                      level);
241baf5664fSJonas Devlieghere 
242da7bc7d0SGreg Clayton   Stream &strm = description.ref();
243da7bc7d0SGreg Clayton 
24481e871edSGreg Clayton   lldb::WatchpointSP watchpoint_sp(GetSP());
245b9c1b51eSKate Stone   if (watchpoint_sp) {
246b9c1b51eSKate Stone     std::lock_guard<std::recursive_mutex> guard(
247b9c1b51eSKate Stone         watchpoint_sp->GetTarget().GetAPIMutex());
24881e871edSGreg Clayton     watchpoint_sp->GetDescription(&strm, level);
249da7bc7d0SGreg Clayton     strm.EOL();
250b9c1b51eSKate Stone   } else
251da7bc7d0SGreg Clayton     strm.PutCString("No value");
2521b282f96SGreg Clayton 
2531b282f96SGreg Clayton   return true;
2541b282f96SGreg Clayton }
2551b282f96SGreg Clayton 
256baf5664fSJonas Devlieghere void SBWatchpoint::Clear() {
257baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_NO_ARGS(void, SBWatchpoint, Clear);
2581b282f96SGreg Clayton 
259baf5664fSJonas Devlieghere   m_opaque_wp.reset();
260baf5664fSJonas Devlieghere }
26181e871edSGreg Clayton 
262baf5664fSJonas Devlieghere lldb::WatchpointSP SBWatchpoint::GetSP() const {
263baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::WatchpointSP, SBWatchpoint, GetSP);
264baf5664fSJonas Devlieghere 
265*d232abc3SJonas Devlieghere   return m_opaque_wp.lock();
266baf5664fSJonas Devlieghere }
267baf5664fSJonas Devlieghere 
268baf5664fSJonas Devlieghere void SBWatchpoint::SetSP(const lldb::WatchpointSP &sp) {
269baf5664fSJonas Devlieghere   LLDB_RECORD_METHOD(void, SBWatchpoint, SetSP, (const lldb::WatchpointSP &),
270baf5664fSJonas Devlieghere                      sp);
271baf5664fSJonas Devlieghere 
272baf5664fSJonas Devlieghere   m_opaque_wp = sp;
273baf5664fSJonas Devlieghere }
2741b5792e5SJim Ingham 
275b9c1b51eSKate Stone bool SBWatchpoint::EventIsWatchpointEvent(const lldb::SBEvent &event) {
276baf5664fSJonas Devlieghere   LLDB_RECORD_STATIC_METHOD(bool, SBWatchpoint, EventIsWatchpointEvent,
277baf5664fSJonas Devlieghere                             (const lldb::SBEvent &), event);
278baf5664fSJonas Devlieghere 
279b9c1b51eSKate Stone   return Watchpoint::WatchpointEventData::GetEventDataFromEvent(event.get()) !=
280248a1305SKonrad Kleine          nullptr;
2811b5792e5SJim Ingham }
2821b5792e5SJim Ingham 
2831b5792e5SJim Ingham WatchpointEventType
284b9c1b51eSKate Stone SBWatchpoint::GetWatchpointEventTypeFromEvent(const SBEvent &event) {
285baf5664fSJonas Devlieghere   LLDB_RECORD_STATIC_METHOD(lldb::WatchpointEventType, SBWatchpoint,
286baf5664fSJonas Devlieghere                             GetWatchpointEventTypeFromEvent,
287baf5664fSJonas Devlieghere                             (const lldb::SBEvent &), event);
288baf5664fSJonas Devlieghere 
2891b5792e5SJim Ingham   if (event.IsValid())
290b9c1b51eSKate Stone     return Watchpoint::WatchpointEventData::GetWatchpointEventTypeFromEvent(
291b9c1b51eSKate Stone         event.GetSP());
2921b5792e5SJim Ingham   return eWatchpointEventTypeInvalidType;
2931b5792e5SJim Ingham }
2941b5792e5SJim Ingham 
295b9c1b51eSKate Stone SBWatchpoint SBWatchpoint::GetWatchpointFromEvent(const lldb::SBEvent &event) {
296baf5664fSJonas Devlieghere   LLDB_RECORD_STATIC_METHOD(lldb::SBWatchpoint, SBWatchpoint,
297baf5664fSJonas Devlieghere                             GetWatchpointFromEvent, (const lldb::SBEvent &),
298baf5664fSJonas Devlieghere                             event);
299baf5664fSJonas Devlieghere 
3001b5792e5SJim Ingham   SBWatchpoint sb_watchpoint;
3011b5792e5SJim Ingham   if (event.IsValid())
3027a1d34beSPavel Labath     sb_watchpoint =
303b9c1b51eSKate Stone         Watchpoint::WatchpointEventData::GetWatchpointFromEvent(event.GetSP());
304*d232abc3SJonas Devlieghere   return sb_watchpoint;
3051b5792e5SJim Ingham }
306