1ac7ddfbfSEd Maste //===-- SBWatchpoint.cpp --------------------------------*- C++ -*-===//
2ac7ddfbfSEd Maste //
3ac7ddfbfSEd Maste //                     The LLVM Compiler Infrastructure
4ac7ddfbfSEd Maste //
5ac7ddfbfSEd Maste // This file is distributed under the University of Illinois Open Source
6ac7ddfbfSEd Maste // License. See LICENSE.TXT for details.
7ac7ddfbfSEd Maste //
8ac7ddfbfSEd Maste //===----------------------------------------------------------------------===//
9ac7ddfbfSEd Maste 
10ac7ddfbfSEd Maste #include "lldb/API/SBWatchpoint.h"
11ac7ddfbfSEd Maste #include "lldb/API/SBAddress.h"
12ac7ddfbfSEd Maste #include "lldb/API/SBDebugger.h"
13435933ddSDimitry Andric #include "lldb/API/SBDefines.h"
14ac7ddfbfSEd Maste #include "lldb/API/SBEvent.h"
15ac7ddfbfSEd Maste #include "lldb/API/SBStream.h"
16ac7ddfbfSEd Maste 
17ac7ddfbfSEd Maste #include "lldb/Breakpoint/Watchpoint.h"
18ac7ddfbfSEd Maste #include "lldb/Breakpoint/WatchpointList.h"
19ac7ddfbfSEd Maste #include "lldb/Core/StreamFile.h"
20435933ddSDimitry Andric #include "lldb/Target/Process.h"
21ac7ddfbfSEd Maste #include "lldb/Target/Target.h"
22*f678e45dSDimitry Andric #include "lldb/Utility/Log.h"
23*f678e45dSDimitry Andric #include "lldb/Utility/Stream.h"
24435933ddSDimitry Andric #include "lldb/lldb-defines.h"
25435933ddSDimitry Andric #include "lldb/lldb-types.h"
26ac7ddfbfSEd Maste 
27ac7ddfbfSEd Maste using namespace lldb;
28ac7ddfbfSEd Maste using namespace lldb_private;
29ac7ddfbfSEd Maste 
SBWatchpoint()30*f678e45dSDimitry Andric SBWatchpoint::SBWatchpoint() {}
31ac7ddfbfSEd Maste 
SBWatchpoint(const lldb::WatchpointSP & wp_sp)32435933ddSDimitry Andric SBWatchpoint::SBWatchpoint(const lldb::WatchpointSP &wp_sp)
33*f678e45dSDimitry Andric     : m_opaque_wp(wp_sp) {
34ac7ddfbfSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
35ac7ddfbfSEd Maste 
36435933ddSDimitry Andric   if (log) {
37ac7ddfbfSEd Maste     SBStream sstr;
38ac7ddfbfSEd Maste     GetDescription(sstr, lldb::eDescriptionLevelBrief);
39*f678e45dSDimitry Andric     LLDB_LOG(log, "watchpoint = {0} ({1})", wp_sp.get(), sstr.GetData());
40ac7ddfbfSEd Maste   }
41ac7ddfbfSEd Maste }
42ac7ddfbfSEd Maste 
SBWatchpoint(const SBWatchpoint & rhs)43435933ddSDimitry Andric SBWatchpoint::SBWatchpoint(const SBWatchpoint &rhs)
44*f678e45dSDimitry Andric     : m_opaque_wp(rhs.m_opaque_wp) {}
45ac7ddfbfSEd Maste 
operator =(const SBWatchpoint & rhs)46435933ddSDimitry Andric const SBWatchpoint &SBWatchpoint::operator=(const SBWatchpoint &rhs) {
47*f678e45dSDimitry Andric   m_opaque_wp = rhs.m_opaque_wp;
48ac7ddfbfSEd Maste   return *this;
49ac7ddfbfSEd Maste }
50ac7ddfbfSEd Maste 
~SBWatchpoint()51435933ddSDimitry Andric SBWatchpoint::~SBWatchpoint() {}
52ac7ddfbfSEd Maste 
GetID()53435933ddSDimitry Andric watch_id_t SBWatchpoint::GetID() {
54ac7ddfbfSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
55ac7ddfbfSEd Maste 
56ac7ddfbfSEd Maste   watch_id_t watch_id = LLDB_INVALID_WATCH_ID;
57ac7ddfbfSEd Maste   lldb::WatchpointSP watchpoint_sp(GetSP());
58ac7ddfbfSEd Maste   if (watchpoint_sp)
59ac7ddfbfSEd Maste     watch_id = watchpoint_sp->GetID();
60ac7ddfbfSEd Maste 
61435933ddSDimitry Andric   if (log) {
62ac7ddfbfSEd Maste     if (watch_id == LLDB_INVALID_WATCH_ID)
630127ef0fSEd Maste       log->Printf("SBWatchpoint(%p)::GetID () => LLDB_INVALID_WATCH_ID",
640127ef0fSEd Maste                   static_cast<void *>(watchpoint_sp.get()));
65ac7ddfbfSEd Maste     else
660127ef0fSEd Maste       log->Printf("SBWatchpoint(%p)::GetID () => %u",
670127ef0fSEd Maste                   static_cast<void *>(watchpoint_sp.get()), watch_id);
68ac7ddfbfSEd Maste   }
69ac7ddfbfSEd Maste 
70ac7ddfbfSEd Maste   return watch_id;
71ac7ddfbfSEd Maste }
72ac7ddfbfSEd Maste 
IsValid() const73*f678e45dSDimitry Andric bool SBWatchpoint::IsValid() const { return bool(m_opaque_wp.lock()); }
74ac7ddfbfSEd Maste 
GetError()75435933ddSDimitry Andric SBError SBWatchpoint::GetError() {
76ac7ddfbfSEd Maste   SBError sb_error;
77ac7ddfbfSEd Maste   lldb::WatchpointSP watchpoint_sp(GetSP());
78435933ddSDimitry Andric   if (watchpoint_sp) {
79ac7ddfbfSEd Maste     sb_error.SetError(watchpoint_sp->GetError());
80ac7ddfbfSEd Maste   }
81ac7ddfbfSEd Maste   return sb_error;
82ac7ddfbfSEd Maste }
83ac7ddfbfSEd Maste 
GetHardwareIndex()84435933ddSDimitry Andric int32_t SBWatchpoint::GetHardwareIndex() {
85ac7ddfbfSEd Maste   int32_t hw_index = -1;
86ac7ddfbfSEd Maste 
87ac7ddfbfSEd Maste   lldb::WatchpointSP watchpoint_sp(GetSP());
88435933ddSDimitry Andric   if (watchpoint_sp) {
89435933ddSDimitry Andric     std::lock_guard<std::recursive_mutex> guard(
90435933ddSDimitry Andric         watchpoint_sp->GetTarget().GetAPIMutex());
91ac7ddfbfSEd Maste     hw_index = watchpoint_sp->GetHardwareIndex();
92ac7ddfbfSEd Maste   }
93ac7ddfbfSEd Maste 
94ac7ddfbfSEd Maste   return hw_index;
95ac7ddfbfSEd Maste }
96ac7ddfbfSEd Maste 
GetWatchAddress()97435933ddSDimitry Andric addr_t SBWatchpoint::GetWatchAddress() {
98ac7ddfbfSEd Maste   addr_t ret_addr = LLDB_INVALID_ADDRESS;
99ac7ddfbfSEd Maste 
100ac7ddfbfSEd Maste   lldb::WatchpointSP watchpoint_sp(GetSP());
101435933ddSDimitry Andric   if (watchpoint_sp) {
102435933ddSDimitry Andric     std::lock_guard<std::recursive_mutex> guard(
103435933ddSDimitry Andric         watchpoint_sp->GetTarget().GetAPIMutex());
104ac7ddfbfSEd Maste     ret_addr = watchpoint_sp->GetLoadAddress();
105ac7ddfbfSEd Maste   }
106ac7ddfbfSEd Maste 
107ac7ddfbfSEd Maste   return ret_addr;
108ac7ddfbfSEd Maste }
109ac7ddfbfSEd Maste 
GetWatchSize()110435933ddSDimitry Andric size_t SBWatchpoint::GetWatchSize() {
111ac7ddfbfSEd Maste   size_t watch_size = 0;
112ac7ddfbfSEd Maste 
113ac7ddfbfSEd Maste   lldb::WatchpointSP watchpoint_sp(GetSP());
114435933ddSDimitry Andric   if (watchpoint_sp) {
115435933ddSDimitry Andric     std::lock_guard<std::recursive_mutex> guard(
116435933ddSDimitry Andric         watchpoint_sp->GetTarget().GetAPIMutex());
117ac7ddfbfSEd Maste     watch_size = watchpoint_sp->GetByteSize();
118ac7ddfbfSEd Maste   }
119ac7ddfbfSEd Maste 
120ac7ddfbfSEd Maste   return watch_size;
121ac7ddfbfSEd Maste }
122ac7ddfbfSEd Maste 
SetEnabled(bool enabled)123435933ddSDimitry Andric void SBWatchpoint::SetEnabled(bool enabled) {
124ac7ddfbfSEd Maste   lldb::WatchpointSP watchpoint_sp(GetSP());
125435933ddSDimitry Andric   if (watchpoint_sp) {
126435933ddSDimitry Andric     Target &target = watchpoint_sp->GetTarget();
127435933ddSDimitry Andric     std::lock_guard<std::recursive_mutex> guard(target.GetAPIMutex());
128435933ddSDimitry Andric     ProcessSP process_sp = target.GetProcessSP();
129435933ddSDimitry Andric     const bool notify = true;
130435933ddSDimitry Andric     if (process_sp) {
131435933ddSDimitry Andric       if (enabled)
132435933ddSDimitry Andric         process_sp->EnableWatchpoint(watchpoint_sp.get(), notify);
133435933ddSDimitry Andric       else
134435933ddSDimitry Andric         process_sp->DisableWatchpoint(watchpoint_sp.get(), notify);
135435933ddSDimitry Andric     } else {
136435933ddSDimitry Andric       watchpoint_sp->SetEnabled(enabled, notify);
137435933ddSDimitry Andric     }
138ac7ddfbfSEd Maste   }
139ac7ddfbfSEd Maste }
140ac7ddfbfSEd Maste 
IsEnabled()141435933ddSDimitry Andric bool SBWatchpoint::IsEnabled() {
142ac7ddfbfSEd Maste   lldb::WatchpointSP watchpoint_sp(GetSP());
143435933ddSDimitry Andric   if (watchpoint_sp) {
144435933ddSDimitry Andric     std::lock_guard<std::recursive_mutex> guard(
145435933ddSDimitry Andric         watchpoint_sp->GetTarget().GetAPIMutex());
146ac7ddfbfSEd Maste     return watchpoint_sp->IsEnabled();
147435933ddSDimitry Andric   } else
148ac7ddfbfSEd Maste     return false;
149ac7ddfbfSEd Maste }
150ac7ddfbfSEd Maste 
GetHitCount()151435933ddSDimitry Andric uint32_t SBWatchpoint::GetHitCount() {
152ac7ddfbfSEd Maste   uint32_t count = 0;
153ac7ddfbfSEd Maste   lldb::WatchpointSP watchpoint_sp(GetSP());
154435933ddSDimitry Andric   if (watchpoint_sp) {
155435933ddSDimitry Andric     std::lock_guard<std::recursive_mutex> guard(
156435933ddSDimitry Andric         watchpoint_sp->GetTarget().GetAPIMutex());
157ac7ddfbfSEd Maste     count = watchpoint_sp->GetHitCount();
158ac7ddfbfSEd Maste   }
159ac7ddfbfSEd Maste 
160ac7ddfbfSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
161ac7ddfbfSEd Maste   if (log)
1620127ef0fSEd Maste     log->Printf("SBWatchpoint(%p)::GetHitCount () => %u",
1630127ef0fSEd Maste                 static_cast<void *>(watchpoint_sp.get()), count);
164ac7ddfbfSEd Maste 
165ac7ddfbfSEd Maste   return count;
166ac7ddfbfSEd Maste }
167ac7ddfbfSEd Maste 
GetIgnoreCount()168435933ddSDimitry Andric uint32_t SBWatchpoint::GetIgnoreCount() {
169ac7ddfbfSEd Maste   lldb::WatchpointSP watchpoint_sp(GetSP());
170435933ddSDimitry Andric   if (watchpoint_sp) {
171435933ddSDimitry Andric     std::lock_guard<std::recursive_mutex> guard(
172435933ddSDimitry Andric         watchpoint_sp->GetTarget().GetAPIMutex());
173ac7ddfbfSEd Maste     return watchpoint_sp->GetIgnoreCount();
174435933ddSDimitry Andric   } else
175ac7ddfbfSEd Maste     return 0;
176ac7ddfbfSEd Maste }
177ac7ddfbfSEd Maste 
SetIgnoreCount(uint32_t n)178435933ddSDimitry Andric void SBWatchpoint::SetIgnoreCount(uint32_t n) {
179ac7ddfbfSEd Maste   lldb::WatchpointSP watchpoint_sp(GetSP());
180435933ddSDimitry Andric   if (watchpoint_sp) {
181435933ddSDimitry Andric     std::lock_guard<std::recursive_mutex> guard(
182435933ddSDimitry Andric         watchpoint_sp->GetTarget().GetAPIMutex());
183ac7ddfbfSEd Maste     watchpoint_sp->SetIgnoreCount(n);
184ac7ddfbfSEd Maste   }
185ac7ddfbfSEd Maste }
186ac7ddfbfSEd Maste 
GetCondition()187435933ddSDimitry Andric const char *SBWatchpoint::GetCondition() {
188ac7ddfbfSEd Maste   lldb::WatchpointSP watchpoint_sp(GetSP());
189435933ddSDimitry Andric   if (watchpoint_sp) {
190435933ddSDimitry Andric     std::lock_guard<std::recursive_mutex> guard(
191435933ddSDimitry Andric         watchpoint_sp->GetTarget().GetAPIMutex());
192ac7ddfbfSEd Maste     return watchpoint_sp->GetConditionText();
193ac7ddfbfSEd Maste   }
194ac7ddfbfSEd Maste   return NULL;
195ac7ddfbfSEd Maste }
196ac7ddfbfSEd Maste 
SetCondition(const char * condition)197435933ddSDimitry Andric void SBWatchpoint::SetCondition(const char *condition) {
198ac7ddfbfSEd Maste   lldb::WatchpointSP watchpoint_sp(GetSP());
199435933ddSDimitry Andric   if (watchpoint_sp) {
200435933ddSDimitry Andric     std::lock_guard<std::recursive_mutex> guard(
201435933ddSDimitry Andric         watchpoint_sp->GetTarget().GetAPIMutex());
202ac7ddfbfSEd Maste     watchpoint_sp->SetCondition(condition);
203ac7ddfbfSEd Maste   }
204ac7ddfbfSEd Maste }
205ac7ddfbfSEd Maste 
GetDescription(SBStream & description,DescriptionLevel level)206435933ddSDimitry Andric bool SBWatchpoint::GetDescription(SBStream &description,
207435933ddSDimitry Andric                                   DescriptionLevel level) {
208ac7ddfbfSEd Maste   Stream &strm = description.ref();
209ac7ddfbfSEd Maste 
210ac7ddfbfSEd Maste   lldb::WatchpointSP watchpoint_sp(GetSP());
211435933ddSDimitry Andric   if (watchpoint_sp) {
212435933ddSDimitry Andric     std::lock_guard<std::recursive_mutex> guard(
213435933ddSDimitry Andric         watchpoint_sp->GetTarget().GetAPIMutex());
214ac7ddfbfSEd Maste     watchpoint_sp->GetDescription(&strm, level);
215ac7ddfbfSEd Maste     strm.EOL();
216435933ddSDimitry Andric   } else
217ac7ddfbfSEd Maste     strm.PutCString("No value");
218ac7ddfbfSEd Maste 
219ac7ddfbfSEd Maste   return true;
220ac7ddfbfSEd Maste }
221ac7ddfbfSEd Maste 
Clear()222*f678e45dSDimitry Andric void SBWatchpoint::Clear() { m_opaque_wp.reset(); }
223ac7ddfbfSEd Maste 
GetSP() const224*f678e45dSDimitry Andric lldb::WatchpointSP SBWatchpoint::GetSP() const { return m_opaque_wp.lock(); }
225ac7ddfbfSEd Maste 
SetSP(const lldb::WatchpointSP & sp)226*f678e45dSDimitry Andric void SBWatchpoint::SetSP(const lldb::WatchpointSP &sp) { m_opaque_wp = sp; }
227ac7ddfbfSEd Maste 
EventIsWatchpointEvent(const lldb::SBEvent & event)228435933ddSDimitry Andric bool SBWatchpoint::EventIsWatchpointEvent(const lldb::SBEvent &event) {
229435933ddSDimitry Andric   return Watchpoint::WatchpointEventData::GetEventDataFromEvent(event.get()) !=
230435933ddSDimitry Andric          NULL;
231ac7ddfbfSEd Maste }
232ac7ddfbfSEd Maste 
233ac7ddfbfSEd Maste WatchpointEventType
GetWatchpointEventTypeFromEvent(const SBEvent & event)234435933ddSDimitry Andric SBWatchpoint::GetWatchpointEventTypeFromEvent(const SBEvent &event) {
235ac7ddfbfSEd Maste   if (event.IsValid())
236435933ddSDimitry Andric     return Watchpoint::WatchpointEventData::GetWatchpointEventTypeFromEvent(
237435933ddSDimitry Andric         event.GetSP());
238ac7ddfbfSEd Maste   return eWatchpointEventTypeInvalidType;
239ac7ddfbfSEd Maste }
240ac7ddfbfSEd Maste 
GetWatchpointFromEvent(const lldb::SBEvent & event)241435933ddSDimitry Andric SBWatchpoint SBWatchpoint::GetWatchpointFromEvent(const lldb::SBEvent &event) {
242ac7ddfbfSEd Maste   SBWatchpoint sb_watchpoint;
243ac7ddfbfSEd Maste   if (event.IsValid())
244*f678e45dSDimitry Andric     sb_watchpoint =
245435933ddSDimitry Andric         Watchpoint::WatchpointEventData::GetWatchpointFromEvent(event.GetSP());
246ac7ddfbfSEd Maste   return sb_watchpoint;
247ac7ddfbfSEd Maste }
248