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"
101b282f96SGreg Clayton #include "lldb/API/SBAddress.h"
111b282f96SGreg Clayton #include "lldb/API/SBDebugger.h"
12b9c1b51eSKate Stone #include "lldb/API/SBDefines.h"
131b5792e5SJim Ingham #include "lldb/API/SBEvent.h"
141b282f96SGreg Clayton #include "lldb/API/SBStream.h"
15*1755f5b1SJonas Devlieghere #include "lldb/Utility/Instrumentation.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 
SBWatchpoint()29*1755f5b1SJonas Devlieghere SBWatchpoint::SBWatchpoint() { LLDB_INSTRUMENT_VA(this); }
301b282f96SGreg Clayton 
SBWatchpoint(const lldb::WatchpointSP & wp_sp)31b9c1b51eSKate Stone SBWatchpoint::SBWatchpoint(const lldb::WatchpointSP &wp_sp)
327a1d34beSPavel Labath     : m_opaque_wp(wp_sp) {
33*1755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this, wp_sp);
341b282f96SGreg Clayton }
351b282f96SGreg Clayton 
SBWatchpoint(const SBWatchpoint & rhs)36b9c1b51eSKate Stone SBWatchpoint::SBWatchpoint(const SBWatchpoint &rhs)
37baf5664fSJonas Devlieghere     : m_opaque_wp(rhs.m_opaque_wp) {
38*1755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this, rhs);
39baf5664fSJonas Devlieghere }
401b282f96SGreg Clayton 
operator =(const SBWatchpoint & rhs)41b9c1b51eSKate Stone const SBWatchpoint &SBWatchpoint::operator=(const SBWatchpoint &rhs) {
42*1755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this, rhs);
43baf5664fSJonas Devlieghere 
447a1d34beSPavel Labath   m_opaque_wp = rhs.m_opaque_wp;
45d232abc3SJonas Devlieghere   return *this;
461b282f96SGreg Clayton }
471b282f96SGreg Clayton 
48866b7a65SJonas Devlieghere SBWatchpoint::~SBWatchpoint() = default;
491b282f96SGreg Clayton 
GetID()50b9c1b51eSKate Stone watch_id_t SBWatchpoint::GetID() {
51*1755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this);
521b282f96SGreg Clayton 
531b282f96SGreg Clayton   watch_id_t watch_id = LLDB_INVALID_WATCH_ID;
5481e871edSGreg Clayton   lldb::WatchpointSP watchpoint_sp(GetSP());
5581e871edSGreg Clayton   if (watchpoint_sp)
5681e871edSGreg Clayton     watch_id = watchpoint_sp->GetID();
571b282f96SGreg Clayton 
581b282f96SGreg Clayton   return watch_id;
591b282f96SGreg Clayton }
601b282f96SGreg Clayton 
IsValid() const61baf5664fSJonas Devlieghere bool SBWatchpoint::IsValid() const {
62*1755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this);
637f5237bcSPavel Labath   return this->operator bool();
647f5237bcSPavel Labath }
operator bool() const657f5237bcSPavel Labath SBWatchpoint::operator bool() const {
66*1755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this);
67baf5664fSJonas Devlieghere 
68baf5664fSJonas Devlieghere   return bool(m_opaque_wp.lock());
69baf5664fSJonas Devlieghere }
701b282f96SGreg Clayton 
operator ==(const SBWatchpoint & rhs) const714bc05006SPavel Labath bool SBWatchpoint::operator==(const SBWatchpoint &rhs) const {
72*1755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this, rhs);
734bc05006SPavel Labath 
744bc05006SPavel Labath   return GetSP() == rhs.GetSP();
754bc05006SPavel Labath }
764bc05006SPavel Labath 
operator !=(const SBWatchpoint & rhs) const774bc05006SPavel Labath bool SBWatchpoint::operator!=(const SBWatchpoint &rhs) const {
78*1755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this, rhs);
794bc05006SPavel Labath 
804bc05006SPavel Labath   return !(*this == rhs);
814bc05006SPavel Labath }
824bc05006SPavel Labath 
GetError()83b9c1b51eSKate Stone SBError SBWatchpoint::GetError() {
84*1755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this);
85baf5664fSJonas Devlieghere 
86ef42a6fbSJim Ingham   SBError sb_error;
87ef42a6fbSJim Ingham   lldb::WatchpointSP watchpoint_sp(GetSP());
88b9c1b51eSKate Stone   if (watchpoint_sp) {
89ef42a6fbSJim Ingham     sb_error.SetError(watchpoint_sp->GetError());
90ef42a6fbSJim Ingham   }
91d232abc3SJonas Devlieghere   return sb_error;
92ef42a6fbSJim Ingham }
93ef42a6fbSJim Ingham 
GetHardwareIndex()94b9c1b51eSKate Stone int32_t SBWatchpoint::GetHardwareIndex() {
95*1755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this);
96baf5664fSJonas Devlieghere 
971b282f96SGreg Clayton   int32_t hw_index = -1;
981b282f96SGreg Clayton 
9981e871edSGreg Clayton   lldb::WatchpointSP watchpoint_sp(GetSP());
100b9c1b51eSKate Stone   if (watchpoint_sp) {
101b9c1b51eSKate Stone     std::lock_guard<std::recursive_mutex> guard(
102b9c1b51eSKate Stone         watchpoint_sp->GetTarget().GetAPIMutex());
10381e871edSGreg Clayton     hw_index = watchpoint_sp->GetHardwareIndex();
1041b282f96SGreg Clayton   }
1051b282f96SGreg Clayton 
1061b282f96SGreg Clayton   return hw_index;
1071b282f96SGreg Clayton }
1081b282f96SGreg Clayton 
GetWatchAddress()109b9c1b51eSKate Stone addr_t SBWatchpoint::GetWatchAddress() {
110*1755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this);
111baf5664fSJonas Devlieghere 
1121b282f96SGreg Clayton   addr_t ret_addr = LLDB_INVALID_ADDRESS;
1131b282f96SGreg Clayton 
11481e871edSGreg Clayton   lldb::WatchpointSP watchpoint_sp(GetSP());
115b9c1b51eSKate Stone   if (watchpoint_sp) {
116b9c1b51eSKate Stone     std::lock_guard<std::recursive_mutex> guard(
117b9c1b51eSKate Stone         watchpoint_sp->GetTarget().GetAPIMutex());
11881e871edSGreg Clayton     ret_addr = watchpoint_sp->GetLoadAddress();
1191b282f96SGreg Clayton   }
1201b282f96SGreg Clayton 
1211b282f96SGreg Clayton   return ret_addr;
1221b282f96SGreg Clayton }
1231b282f96SGreg Clayton 
GetWatchSize()124b9c1b51eSKate Stone size_t SBWatchpoint::GetWatchSize() {
125*1755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this);
126baf5664fSJonas Devlieghere 
1271b282f96SGreg Clayton   size_t watch_size = 0;
1281b282f96SGreg Clayton 
12981e871edSGreg Clayton   lldb::WatchpointSP watchpoint_sp(GetSP());
130b9c1b51eSKate Stone   if (watchpoint_sp) {
131b9c1b51eSKate Stone     std::lock_guard<std::recursive_mutex> guard(
132b9c1b51eSKate Stone         watchpoint_sp->GetTarget().GetAPIMutex());
13381e871edSGreg Clayton     watch_size = watchpoint_sp->GetByteSize();
1341b282f96SGreg Clayton   }
1351b282f96SGreg Clayton 
1361b282f96SGreg Clayton   return watch_size;
1371b282f96SGreg Clayton }
1381b282f96SGreg Clayton 
SetEnabled(bool enabled)139b9c1b51eSKate Stone void SBWatchpoint::SetEnabled(bool enabled) {
140*1755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this, enabled);
141baf5664fSJonas Devlieghere 
14281e871edSGreg Clayton   lldb::WatchpointSP watchpoint_sp(GetSP());
143b9c1b51eSKate Stone   if (watchpoint_sp) {
144306b62b4SJim Ingham     Target &target = watchpoint_sp->GetTarget();
145306b62b4SJim Ingham     std::lock_guard<std::recursive_mutex> guard(target.GetAPIMutex());
146306b62b4SJim Ingham     ProcessSP process_sp = target.GetProcessSP();
147c76c3f2fSJim Ingham     const bool notify = true;
148306b62b4SJim Ingham     if (process_sp) {
149306b62b4SJim Ingham       if (enabled)
150c76c3f2fSJim Ingham         process_sp->EnableWatchpoint(watchpoint_sp.get(), notify);
151306b62b4SJim Ingham       else
152c76c3f2fSJim Ingham         process_sp->DisableWatchpoint(watchpoint_sp.get(), notify);
153306b62b4SJim Ingham     } else {
154c76c3f2fSJim Ingham       watchpoint_sp->SetEnabled(enabled, notify);
1551b282f96SGreg Clayton     }
1561b282f96SGreg Clayton   }
157306b62b4SJim Ingham }
1581b282f96SGreg Clayton 
IsEnabled()159b9c1b51eSKate Stone bool SBWatchpoint::IsEnabled() {
160*1755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this);
161baf5664fSJonas Devlieghere 
16281e871edSGreg Clayton   lldb::WatchpointSP watchpoint_sp(GetSP());
163b9c1b51eSKate Stone   if (watchpoint_sp) {
164b9c1b51eSKate Stone     std::lock_guard<std::recursive_mutex> guard(
165b9c1b51eSKate Stone         watchpoint_sp->GetTarget().GetAPIMutex());
16681e871edSGreg Clayton     return watchpoint_sp->IsEnabled();
167b9c1b51eSKate Stone   } else
1681b282f96SGreg Clayton     return false;
1691b282f96SGreg Clayton }
1701b282f96SGreg Clayton 
GetHitCount()171b9c1b51eSKate Stone uint32_t SBWatchpoint::GetHitCount() {
172*1755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this);
173baf5664fSJonas Devlieghere 
1741b282f96SGreg Clayton   uint32_t count = 0;
17581e871edSGreg Clayton   lldb::WatchpointSP watchpoint_sp(GetSP());
176b9c1b51eSKate Stone   if (watchpoint_sp) {
177b9c1b51eSKate Stone     std::lock_guard<std::recursive_mutex> guard(
178b9c1b51eSKate Stone         watchpoint_sp->GetTarget().GetAPIMutex());
17981e871edSGreg Clayton     count = watchpoint_sp->GetHitCount();
1801b282f96SGreg Clayton   }
1811b282f96SGreg Clayton 
1821b282f96SGreg Clayton   return count;
1831b282f96SGreg Clayton }
1841b282f96SGreg Clayton 
GetIgnoreCount()185b9c1b51eSKate Stone uint32_t SBWatchpoint::GetIgnoreCount() {
186*1755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this);
187baf5664fSJonas Devlieghere 
18881e871edSGreg Clayton   lldb::WatchpointSP watchpoint_sp(GetSP());
189b9c1b51eSKate Stone   if (watchpoint_sp) {
190b9c1b51eSKate Stone     std::lock_guard<std::recursive_mutex> guard(
191b9c1b51eSKate Stone         watchpoint_sp->GetTarget().GetAPIMutex());
19281e871edSGreg Clayton     return watchpoint_sp->GetIgnoreCount();
193b9c1b51eSKate Stone   } else
1941b282f96SGreg Clayton     return 0;
1951b282f96SGreg Clayton }
1961b282f96SGreg Clayton 
SetIgnoreCount(uint32_t n)197b9c1b51eSKate Stone void SBWatchpoint::SetIgnoreCount(uint32_t n) {
198*1755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this, n);
199baf5664fSJonas Devlieghere 
20081e871edSGreg Clayton   lldb::WatchpointSP watchpoint_sp(GetSP());
201b9c1b51eSKate Stone   if (watchpoint_sp) {
202b9c1b51eSKate Stone     std::lock_guard<std::recursive_mutex> guard(
203b9c1b51eSKate Stone         watchpoint_sp->GetTarget().GetAPIMutex());
20481e871edSGreg Clayton     watchpoint_sp->SetIgnoreCount(n);
2051b282f96SGreg Clayton   }
2061b282f96SGreg Clayton }
2071b282f96SGreg Clayton 
GetCondition()208b9c1b51eSKate Stone const char *SBWatchpoint::GetCondition() {
209*1755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this);
210baf5664fSJonas Devlieghere 
21181e871edSGreg Clayton   lldb::WatchpointSP watchpoint_sp(GetSP());
212b9c1b51eSKate Stone   if (watchpoint_sp) {
213b9c1b51eSKate Stone     std::lock_guard<std::recursive_mutex> guard(
214b9c1b51eSKate Stone         watchpoint_sp->GetTarget().GetAPIMutex());
21581e871edSGreg Clayton     return watchpoint_sp->GetConditionText();
21616dcf718SJohnny Chen   }
217248a1305SKonrad Kleine   return nullptr;
21816dcf718SJohnny Chen }
21916dcf718SJohnny Chen 
SetCondition(const char * condition)220b9c1b51eSKate Stone void SBWatchpoint::SetCondition(const char *condition) {
221*1755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this, condition);
222baf5664fSJonas Devlieghere 
22381e871edSGreg Clayton   lldb::WatchpointSP watchpoint_sp(GetSP());
224b9c1b51eSKate Stone   if (watchpoint_sp) {
225b9c1b51eSKate Stone     std::lock_guard<std::recursive_mutex> guard(
226b9c1b51eSKate Stone         watchpoint_sp->GetTarget().GetAPIMutex());
22781e871edSGreg Clayton     watchpoint_sp->SetCondition(condition);
22816dcf718SJohnny Chen   }
22916dcf718SJohnny Chen }
23016dcf718SJohnny Chen 
GetDescription(SBStream & description,DescriptionLevel level)231b9c1b51eSKate Stone bool SBWatchpoint::GetDescription(SBStream &description,
232b9c1b51eSKate Stone                                   DescriptionLevel level) {
233*1755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this, description, level);
234baf5664fSJonas Devlieghere 
235da7bc7d0SGreg Clayton   Stream &strm = description.ref();
236da7bc7d0SGreg Clayton 
23781e871edSGreg Clayton   lldb::WatchpointSP watchpoint_sp(GetSP());
238b9c1b51eSKate Stone   if (watchpoint_sp) {
239b9c1b51eSKate Stone     std::lock_guard<std::recursive_mutex> guard(
240b9c1b51eSKate Stone         watchpoint_sp->GetTarget().GetAPIMutex());
24181e871edSGreg Clayton     watchpoint_sp->GetDescription(&strm, level);
242da7bc7d0SGreg Clayton     strm.EOL();
243b9c1b51eSKate Stone   } else
244da7bc7d0SGreg Clayton     strm.PutCString("No value");
2451b282f96SGreg Clayton 
2461b282f96SGreg Clayton   return true;
2471b282f96SGreg Clayton }
2481b282f96SGreg Clayton 
Clear()249baf5664fSJonas Devlieghere void SBWatchpoint::Clear() {
250*1755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this);
2511b282f96SGreg Clayton 
252baf5664fSJonas Devlieghere   m_opaque_wp.reset();
253baf5664fSJonas Devlieghere }
25481e871edSGreg Clayton 
GetSP() const255baf5664fSJonas Devlieghere lldb::WatchpointSP SBWatchpoint::GetSP() const {
256*1755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this);
257baf5664fSJonas Devlieghere 
258d232abc3SJonas Devlieghere   return m_opaque_wp.lock();
259baf5664fSJonas Devlieghere }
260baf5664fSJonas Devlieghere 
SetSP(const lldb::WatchpointSP & sp)261baf5664fSJonas Devlieghere void SBWatchpoint::SetSP(const lldb::WatchpointSP &sp) {
262*1755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(this, sp);
263baf5664fSJonas Devlieghere 
264baf5664fSJonas Devlieghere   m_opaque_wp = sp;
265baf5664fSJonas Devlieghere }
2661b5792e5SJim Ingham 
EventIsWatchpointEvent(const lldb::SBEvent & event)267b9c1b51eSKate Stone bool SBWatchpoint::EventIsWatchpointEvent(const lldb::SBEvent &event) {
268*1755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(event);
269baf5664fSJonas Devlieghere 
270b9c1b51eSKate Stone   return Watchpoint::WatchpointEventData::GetEventDataFromEvent(event.get()) !=
271248a1305SKonrad Kleine          nullptr;
2721b5792e5SJim Ingham }
2731b5792e5SJim Ingham 
2741b5792e5SJim Ingham WatchpointEventType
GetWatchpointEventTypeFromEvent(const SBEvent & event)275b9c1b51eSKate Stone SBWatchpoint::GetWatchpointEventTypeFromEvent(const SBEvent &event) {
276*1755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(event);
277baf5664fSJonas Devlieghere 
2781b5792e5SJim Ingham   if (event.IsValid())
279b9c1b51eSKate Stone     return Watchpoint::WatchpointEventData::GetWatchpointEventTypeFromEvent(
280b9c1b51eSKate Stone         event.GetSP());
2811b5792e5SJim Ingham   return eWatchpointEventTypeInvalidType;
2821b5792e5SJim Ingham }
2831b5792e5SJim Ingham 
GetWatchpointFromEvent(const lldb::SBEvent & event)284b9c1b51eSKate Stone SBWatchpoint SBWatchpoint::GetWatchpointFromEvent(const lldb::SBEvent &event) {
285*1755f5b1SJonas Devlieghere   LLDB_INSTRUMENT_VA(event);
286baf5664fSJonas Devlieghere 
2871b5792e5SJim Ingham   SBWatchpoint sb_watchpoint;
2881b5792e5SJim Ingham   if (event.IsValid())
2897a1d34beSPavel Labath     sb_watchpoint =
290b9c1b51eSKate Stone         Watchpoint::WatchpointEventData::GetWatchpointFromEvent(event.GetSP());
291d232abc3SJonas Devlieghere   return sb_watchpoint;
2921b5792e5SJim Ingham }
293