1 //===-- SBWatchpoint.cpp --------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "lldb/API/SBWatchpoint.h"
11 #include "lldb/API/SBAddress.h"
12 #include "lldb/API/SBDebugger.h"
13 #include "lldb/API/SBDefines.h"
14 #include "lldb/API/SBEvent.h"
15 #include "lldb/API/SBStream.h"
16 
17 #include "lldb/Breakpoint/Watchpoint.h"
18 #include "lldb/Breakpoint/WatchpointList.h"
19 #include "lldb/Core/Log.h"
20 #include "lldb/Core/Stream.h"
21 #include "lldb/Core/StreamFile.h"
22 #include "lldb/Target/Target.h"
23 #include "lldb/lldb-defines.h"
24 #include "lldb/lldb-types.h"
25 
26 using namespace lldb;
27 using namespace lldb_private;
28 
29 SBWatchpoint::SBWatchpoint() : m_opaque_sp() {}
30 
31 SBWatchpoint::SBWatchpoint(const lldb::WatchpointSP &wp_sp)
32     : m_opaque_sp(wp_sp) {
33   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
34 
35   if (log) {
36     SBStream sstr;
37     GetDescription(sstr, lldb::eDescriptionLevelBrief);
38     log->Printf("SBWatchpoint::SBWatchpoint (const lldb::WatchpointSP &wp_sp"
39                 "=%p)  => this.sp = %p (%s)",
40                 static_cast<void *>(wp_sp.get()),
41                 static_cast<void *>(m_opaque_sp.get()), sstr.GetData());
42   }
43 }
44 
45 SBWatchpoint::SBWatchpoint(const SBWatchpoint &rhs)
46     : m_opaque_sp(rhs.m_opaque_sp) {}
47 
48 const SBWatchpoint &SBWatchpoint::operator=(const SBWatchpoint &rhs) {
49   if (this != &rhs)
50     m_opaque_sp = rhs.m_opaque_sp;
51   return *this;
52 }
53 
54 SBWatchpoint::~SBWatchpoint() {}
55 
56 watch_id_t SBWatchpoint::GetID() {
57   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
58 
59   watch_id_t watch_id = LLDB_INVALID_WATCH_ID;
60   lldb::WatchpointSP watchpoint_sp(GetSP());
61   if (watchpoint_sp)
62     watch_id = watchpoint_sp->GetID();
63 
64   if (log) {
65     if (watch_id == LLDB_INVALID_WATCH_ID)
66       log->Printf("SBWatchpoint(%p)::GetID () => LLDB_INVALID_WATCH_ID",
67                   static_cast<void *>(watchpoint_sp.get()));
68     else
69       log->Printf("SBWatchpoint(%p)::GetID () => %u",
70                   static_cast<void *>(watchpoint_sp.get()), watch_id);
71   }
72 
73   return watch_id;
74 }
75 
76 bool SBWatchpoint::IsValid() const { return (bool)m_opaque_sp; }
77 
78 SBError SBWatchpoint::GetError() {
79   SBError sb_error;
80   lldb::WatchpointSP watchpoint_sp(GetSP());
81   if (watchpoint_sp) {
82     sb_error.SetError(watchpoint_sp->GetError());
83   }
84   return sb_error;
85 }
86 
87 int32_t SBWatchpoint::GetHardwareIndex() {
88   int32_t hw_index = -1;
89 
90   lldb::WatchpointSP watchpoint_sp(GetSP());
91   if (watchpoint_sp) {
92     std::lock_guard<std::recursive_mutex> guard(
93         watchpoint_sp->GetTarget().GetAPIMutex());
94     hw_index = watchpoint_sp->GetHardwareIndex();
95   }
96 
97   return hw_index;
98 }
99 
100 addr_t SBWatchpoint::GetWatchAddress() {
101   addr_t ret_addr = LLDB_INVALID_ADDRESS;
102 
103   lldb::WatchpointSP watchpoint_sp(GetSP());
104   if (watchpoint_sp) {
105     std::lock_guard<std::recursive_mutex> guard(
106         watchpoint_sp->GetTarget().GetAPIMutex());
107     ret_addr = watchpoint_sp->GetLoadAddress();
108   }
109 
110   return ret_addr;
111 }
112 
113 size_t SBWatchpoint::GetWatchSize() {
114   size_t watch_size = 0;
115 
116   lldb::WatchpointSP watchpoint_sp(GetSP());
117   if (watchpoint_sp) {
118     std::lock_guard<std::recursive_mutex> guard(
119         watchpoint_sp->GetTarget().GetAPIMutex());
120     watch_size = watchpoint_sp->GetByteSize();
121   }
122 
123   return watch_size;
124 }
125 
126 void SBWatchpoint::SetEnabled(bool enabled) {
127   lldb::WatchpointSP watchpoint_sp(GetSP());
128   if (watchpoint_sp) {
129     std::lock_guard<std::recursive_mutex> guard(
130         watchpoint_sp->GetTarget().GetAPIMutex());
131     watchpoint_sp->SetEnabled(enabled);
132   }
133 }
134 
135 bool SBWatchpoint::IsEnabled() {
136   lldb::WatchpointSP watchpoint_sp(GetSP());
137   if (watchpoint_sp) {
138     std::lock_guard<std::recursive_mutex> guard(
139         watchpoint_sp->GetTarget().GetAPIMutex());
140     return watchpoint_sp->IsEnabled();
141   } else
142     return false;
143 }
144 
145 uint32_t SBWatchpoint::GetHitCount() {
146   uint32_t count = 0;
147   lldb::WatchpointSP watchpoint_sp(GetSP());
148   if (watchpoint_sp) {
149     std::lock_guard<std::recursive_mutex> guard(
150         watchpoint_sp->GetTarget().GetAPIMutex());
151     count = watchpoint_sp->GetHitCount();
152   }
153 
154   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
155   if (log)
156     log->Printf("SBWatchpoint(%p)::GetHitCount () => %u",
157                 static_cast<void *>(watchpoint_sp.get()), count);
158 
159   return count;
160 }
161 
162 uint32_t SBWatchpoint::GetIgnoreCount() {
163   lldb::WatchpointSP watchpoint_sp(GetSP());
164   if (watchpoint_sp) {
165     std::lock_guard<std::recursive_mutex> guard(
166         watchpoint_sp->GetTarget().GetAPIMutex());
167     return watchpoint_sp->GetIgnoreCount();
168   } else
169     return 0;
170 }
171 
172 void SBWatchpoint::SetIgnoreCount(uint32_t n) {
173   lldb::WatchpointSP watchpoint_sp(GetSP());
174   if (watchpoint_sp) {
175     std::lock_guard<std::recursive_mutex> guard(
176         watchpoint_sp->GetTarget().GetAPIMutex());
177     watchpoint_sp->SetIgnoreCount(n);
178   }
179 }
180 
181 const char *SBWatchpoint::GetCondition() {
182   lldb::WatchpointSP watchpoint_sp(GetSP());
183   if (watchpoint_sp) {
184     std::lock_guard<std::recursive_mutex> guard(
185         watchpoint_sp->GetTarget().GetAPIMutex());
186     return watchpoint_sp->GetConditionText();
187   }
188   return NULL;
189 }
190 
191 void SBWatchpoint::SetCondition(const char *condition) {
192   lldb::WatchpointSP watchpoint_sp(GetSP());
193   if (watchpoint_sp) {
194     std::lock_guard<std::recursive_mutex> guard(
195         watchpoint_sp->GetTarget().GetAPIMutex());
196     watchpoint_sp->SetCondition(condition);
197   }
198 }
199 
200 bool SBWatchpoint::GetDescription(SBStream &description,
201                                   DescriptionLevel level) {
202   Stream &strm = description.ref();
203 
204   lldb::WatchpointSP watchpoint_sp(GetSP());
205   if (watchpoint_sp) {
206     std::lock_guard<std::recursive_mutex> guard(
207         watchpoint_sp->GetTarget().GetAPIMutex());
208     watchpoint_sp->GetDescription(&strm, level);
209     strm.EOL();
210   } else
211     strm.PutCString("No value");
212 
213   return true;
214 }
215 
216 void SBWatchpoint::Clear() { m_opaque_sp.reset(); }
217 
218 lldb::WatchpointSP SBWatchpoint::GetSP() const { return m_opaque_sp; }
219 
220 void SBWatchpoint::SetSP(const lldb::WatchpointSP &sp) { m_opaque_sp = sp; }
221 
222 bool SBWatchpoint::EventIsWatchpointEvent(const lldb::SBEvent &event) {
223   return Watchpoint::WatchpointEventData::GetEventDataFromEvent(event.get()) !=
224          NULL;
225 }
226 
227 WatchpointEventType
228 SBWatchpoint::GetWatchpointEventTypeFromEvent(const SBEvent &event) {
229   if (event.IsValid())
230     return Watchpoint::WatchpointEventData::GetWatchpointEventTypeFromEvent(
231         event.GetSP());
232   return eWatchpointEventTypeInvalidType;
233 }
234 
235 SBWatchpoint SBWatchpoint::GetWatchpointFromEvent(const lldb::SBEvent &event) {
236   SBWatchpoint sb_watchpoint;
237   if (event.IsValid())
238     sb_watchpoint.m_opaque_sp =
239         Watchpoint::WatchpointEventData::GetWatchpointFromEvent(event.GetSP());
240   return sb_watchpoint;
241 }
242