1 //===-- Watchpoint.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/Breakpoint/Watchpoint.h"
11 
12 // C Includes
13 // C++ Includes
14 // Other libraries and framework includes
15 // Project includes
16 #include "lldb/Core/Stream.h"
17 
18 using namespace lldb;
19 using namespace lldb_private;
20 
21 Watchpoint::Watchpoint (lldb::addr_t addr, size_t size, bool hardware) :
22     StoppointLocation (GetNextID(), addr, size, hardware),
23     m_target(NULL),
24     m_enabled(0),
25     m_is_hardware(hardware),
26     m_watch_read(0),
27     m_watch_write(0),
28     m_watch_was_read(0),
29     m_watch_was_written(0),
30     m_ignore_count(0),
31     m_callback(NULL),
32     m_callback_baton(NULL),
33     m_decl_str(),
34     m_error()
35 {
36 }
37 
38 Watchpoint::~Watchpoint()
39 {
40 }
41 
42 break_id_t
43 Watchpoint::GetNextID()
44 {
45     static break_id_t g_next_ID = 0;
46     return ++g_next_ID;
47 }
48 
49 bool
50 Watchpoint::SetCallback (WatchpointHitCallback callback, void *callback_baton)
51 {
52     m_callback = callback;
53     m_callback_baton = callback_baton;
54     return true;
55 }
56 
57 void
58 Watchpoint::SetDeclInfo (std::string &str)
59 {
60     m_decl_str = str;
61     return;
62 }
63 
64 
65 bool
66 Watchpoint::IsHardware () const
67 {
68     return m_is_hardware;
69 }
70 
71 // RETURNS - true if we should stop at this breakpoint, false if we
72 // should continue.
73 
74 bool
75 Watchpoint::ShouldStop (StoppointCallbackContext *context)
76 {
77     ++m_hit_count;
78 
79     if (!IsEnabled())
80         return false;
81 
82     if (m_hit_count <= GetIgnoreCount())
83         return false;
84 
85     uint32_t access = 0;
86     if (m_watch_was_read)
87         access |= LLDB_WATCH_TYPE_READ;
88     if (m_watch_was_written)
89         access |= LLDB_WATCH_TYPE_WRITE;
90 
91     if (m_callback)
92         return m_callback(m_callback_baton, context, GetID(), access);
93     else
94         return true;
95 }
96 
97 void
98 Watchpoint::GetDescription (Stream *s, lldb::DescriptionLevel level)
99 {
100     DumpWithLevel(s, level);
101     return;
102 }
103 
104 void
105 Watchpoint::Dump(Stream *s) const
106 {
107     DumpWithLevel(s, lldb::eDescriptionLevelBrief);
108 }
109 
110 void
111 Watchpoint::DumpWithLevel(Stream *s, lldb::DescriptionLevel description_level) const
112 {
113     if (s == NULL)
114         return;
115 
116     assert(description_level >= lldb::eDescriptionLevelBrief &&
117            description_level <= lldb::eDescriptionLevelVerbose);
118 
119     s->Printf("Watchpoint %u: addr = 0x%8.8llx size = %zu state = %s type = %s%s",
120               GetID(),
121               (uint64_t)m_addr,
122               m_byte_size,
123               m_enabled ? "enabled" : "disabled",
124               m_watch_read ? "r" : "",
125               m_watch_write ? "w" : "");
126 
127     if (description_level >= lldb::eDescriptionLevelFull)
128         s->Printf("\n    declare @ '%s'", m_decl_str.c_str());
129 
130     if (description_level >= lldb::eDescriptionLevelVerbose)
131         if (m_callback)
132             s->Printf("\n    hw_index = %i  hit_count = %-4u  ignore_count = %-4u  callback = %8p baton = %8p",
133                       GetHardwareIndex(),
134                       GetHitCount(),
135                       GetIgnoreCount(),
136                       m_callback,
137                       m_callback_baton);
138         else
139             s->Printf("\n    hw_index = %i  hit_count = %-4u  ignore_count = %-4u",
140                       GetHardwareIndex(),
141                       GetHitCount(),
142                       GetIgnoreCount());
143 }
144 
145 bool
146 Watchpoint::IsEnabled() const
147 {
148     return m_enabled;
149 }
150 
151 void
152 Watchpoint::SetEnabled(bool enabled)
153 {
154     if (!enabled)
155         SetHardwareIndex(LLDB_INVALID_INDEX32);
156     m_enabled = enabled;
157 }
158 
159 void
160 Watchpoint::SetWatchpointType (uint32_t type)
161 {
162     m_watch_read = (type & LLDB_WATCH_TYPE_READ) != 0;
163     m_watch_write = (type & LLDB_WATCH_TYPE_WRITE) != 0;
164 }
165 
166 bool
167 Watchpoint::WatchpointRead () const
168 {
169     return m_watch_read != 0;
170 }
171 bool
172 Watchpoint::WatchpointWrite () const
173 {
174     return m_watch_write != 0;
175 }
176 uint32_t
177 Watchpoint::GetIgnoreCount () const
178 {
179     return m_ignore_count;
180 }
181 
182 void
183 Watchpoint::SetIgnoreCount (uint32_t n)
184 {
185     m_ignore_count = n;
186 }
187