ea6e02de37831dbb8f8e01bb92f3c4cfd4ed3d62
[deliverable/binutils-gdb.git] / gdb / nat / mips-linux-watch.c
1 /* Copyright (C) 2009-2014 Free Software Foundation, Inc.
2
3 This file is part of GDB.
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */
17
18 #ifdef GDBSERVER
19 #include "server.h"
20 #else
21 #include "defs.h"
22 #endif
23 #include <sys/ptrace.h>
24 #include "mips-linux-watch.h"
25
26 /* Assuming usable watch registers REGS, return the irw_mask of
27 register N. */
28
29 uint32_t
30 mips_linux_watch_get_irw_mask (struct pt_watch_regs *regs, int n)
31 {
32 switch (regs->style)
33 {
34 case pt_watch_style_mips32:
35 return regs->mips32.watch_masks[n] & IRW_MASK;
36 case pt_watch_style_mips64:
37 return regs->mips64.watch_masks[n] & IRW_MASK;
38 default:
39 internal_error (__FILE__, __LINE__,
40 _("Unrecognized watch register style"));
41 }
42 }
43
44 /* Assuming usable watch registers REGS, return the reg_mask of
45 register N. */
46
47 static uint32_t
48 get_reg_mask (struct pt_watch_regs *regs, int n)
49 {
50 switch (regs->style)
51 {
52 case pt_watch_style_mips32:
53 return regs->mips32.watch_masks[n] & ~IRW_MASK;
54 case pt_watch_style_mips64:
55 return regs->mips64.watch_masks[n] & ~IRW_MASK;
56 default:
57 internal_error (__FILE__, __LINE__,
58 _("Unrecognized watch register style"));
59 }
60 }
61
62 /* Assuming usable watch registers REGS, return the num_valid. */
63
64 uint32_t
65 mips_linux_watch_get_num_valid (struct pt_watch_regs *regs)
66 {
67 switch (regs->style)
68 {
69 case pt_watch_style_mips32:
70 return regs->mips32.num_valid;
71 case pt_watch_style_mips64:
72 return regs->mips64.num_valid;
73 default:
74 internal_error (__FILE__, __LINE__,
75 _("Unrecognized watch register style"));
76 }
77 }
78
79 /* Assuming usable watch registers REGS, return the watchlo of
80 register N. */
81
82 CORE_ADDR
83 mips_linux_watch_get_watchlo (struct pt_watch_regs *regs, int n)
84 {
85 switch (regs->style)
86 {
87 case pt_watch_style_mips32:
88 return regs->mips32.watchlo[n];
89 case pt_watch_style_mips64:
90 return regs->mips64.watchlo[n];
91 default:
92 internal_error (__FILE__, __LINE__,
93 _("Unrecognized watch register style"));
94 }
95 }
96
97 /* Assuming usable watch registers REGS, set watchlo of register N to
98 VALUE. */
99
100 void
101 mips_linux_watch_set_watchlo (struct pt_watch_regs *regs, int n,
102 CORE_ADDR value)
103 {
104 switch (regs->style)
105 {
106 case pt_watch_style_mips32:
107 /* The cast will never throw away bits as 64 bit addresses can
108 never be used on a 32 bit kernel. */
109 regs->mips32.watchlo[n] = (uint32_t) value;
110 break;
111 case pt_watch_style_mips64:
112 regs->mips64.watchlo[n] = value;
113 break;
114 default:
115 internal_error (__FILE__, __LINE__,
116 _("Unrecognized watch register style"));
117 }
118 }
119
120 /* Assuming usable watch registers REGS, return the watchhi of
121 register N. */
122
123 uint32_t
124 mips_linux_watch_get_watchhi (struct pt_watch_regs *regs, int n)
125 {
126 switch (regs->style)
127 {
128 case pt_watch_style_mips32:
129 return regs->mips32.watchhi[n];
130 case pt_watch_style_mips64:
131 return regs->mips64.watchhi[n];
132 default:
133 internal_error (__FILE__, __LINE__,
134 _("Unrecognized watch register style"));
135 }
136 }
137
138 /* Assuming usable watch registers REGS, set watchhi of register N to
139 VALUE. */
140
141 void
142 mips_linux_watch_set_watchhi (struct pt_watch_regs *regs, int n,
143 uint16_t value)
144 {
145 switch (regs->style)
146 {
147 case pt_watch_style_mips32:
148 regs->mips32.watchhi[n] = value;
149 break;
150 case pt_watch_style_mips64:
151 regs->mips64.watchhi[n] = value;
152 break;
153 default:
154 internal_error (__FILE__, __LINE__,
155 _("Unrecognized watch register style"));
156 }
157 }
158
159 /* Read the watch registers of process LWPID and store it in
160 WATCH_READBACK. Save true to *WATCH_READBACK_VALID if watch
161 registers are valid. Return 1 if watch registers are usable.
162 Cached information is used unless FORCE is true. */
163
164 int
165 mips_linux_read_watch_registers (long lwpid,
166 struct pt_watch_regs *watch_readback,
167 int *watch_readback_valid, int force)
168 {
169 if (force || *watch_readback_valid == 0)
170 {
171 if (ptrace (PTRACE_GET_WATCH_REGS, lwpid, watch_readback) == -1)
172 {
173 *watch_readback_valid = -1;
174 return 0;
175 }
176 switch (watch_readback->style)
177 {
178 case pt_watch_style_mips32:
179 if (watch_readback->mips32.num_valid == 0)
180 {
181 *watch_readback_valid = -1;
182 return 0;
183 }
184 break;
185 case pt_watch_style_mips64:
186 if (watch_readback->mips64.num_valid == 0)
187 {
188 *watch_readback_valid = -1;
189 return 0;
190 }
191 break;
192 default:
193 *watch_readback_valid = -1;
194 return 0;
195 }
196 /* Watch registers appear to be usable. */
197 *watch_readback_valid = 1;
198 }
199 return (*watch_readback_valid == 1) ? 1 : 0;
200 }
201
202 /* Convert GDB's TYPE to an IRW mask. */
203
204 uint32_t
205 mips_linux_watch_type_to_irw (int type)
206 {
207 switch (type)
208 {
209 case hw_write:
210 return W_MASK;
211 case hw_read:
212 return R_MASK;
213 case hw_access:
214 return (W_MASK | R_MASK);
215 default:
216 return 0;
217 }
218 }
219
220 /* Set any low order bits in MASK that are not set. */
221
222 static CORE_ADDR
223 fill_mask (CORE_ADDR mask)
224 {
225 CORE_ADDR f = 1;
226
227 while (f && f < mask)
228 {
229 mask |= f;
230 f <<= 1;
231 }
232 return mask;
233 }
234
235 /* Try to add a single watch to the specified registers REGS. The
236 address of added watch is ADDR, the length is LEN, and the mask
237 is IRW. Return 1 on success, 0 on failure. */
238
239 int
240 mips_linux_watch_try_one_watch (struct pt_watch_regs *regs,
241 CORE_ADDR addr, int len, uint32_t irw)
242 {
243 CORE_ADDR base_addr, last_byte, break_addr, segment_len;
244 CORE_ADDR mask_bits, t_low;
245 uint16_t t_hi;
246 int i, free_watches;
247 struct pt_watch_regs regs_copy;
248
249 if (len <= 0)
250 return 0;
251
252 last_byte = addr + len - 1;
253 mask_bits = fill_mask (addr ^ last_byte) | IRW_MASK;
254 base_addr = addr & ~mask_bits;
255
256 /* Check to see if it is covered by current registers. */
257 for (i = 0; i < mips_linux_watch_get_num_valid (regs); i++)
258 {
259 t_low = mips_linux_watch_get_watchlo (regs, i);
260 if (t_low != 0 && irw == ((uint32_t) t_low & irw))
261 {
262 t_hi = mips_linux_watch_get_watchhi (regs, i) | IRW_MASK;
263 t_low &= ~(CORE_ADDR) t_hi;
264 if (addr >= t_low && last_byte <= (t_low + t_hi))
265 return 1;
266 }
267 }
268 /* Try to find an empty register. */
269 free_watches = 0;
270 for (i = 0; i < mips_linux_watch_get_num_valid (regs); i++)
271 {
272 t_low = mips_linux_watch_get_watchlo (regs, i);
273 if (t_low == 0
274 && irw == (mips_linux_watch_get_irw_mask (regs, i) & irw))
275 {
276 if (mask_bits <= (get_reg_mask (regs, i) | IRW_MASK))
277 {
278 /* It fits, we'll take it. */
279 mips_linux_watch_set_watchlo (regs, i, base_addr | irw);
280 mips_linux_watch_set_watchhi (regs, i, mask_bits & ~IRW_MASK);
281 return 1;
282 }
283 else
284 {
285 /* It doesn't fit, but has the proper IRW capabilities. */
286 free_watches++;
287 }
288 }
289 }
290 if (free_watches > 1)
291 {
292 /* Try to split it across several registers. */
293 regs_copy = *regs;
294 for (i = 0; i < mips_linux_watch_get_num_valid (&regs_copy); i++)
295 {
296 t_low = mips_linux_watch_get_watchlo (&regs_copy, i);
297 t_hi = get_reg_mask (&regs_copy, i) | IRW_MASK;
298 if (t_low == 0 && irw == (t_hi & irw))
299 {
300 t_low = addr & ~(CORE_ADDR) t_hi;
301 break_addr = t_low + t_hi + 1;
302 if (break_addr >= addr + len)
303 segment_len = len;
304 else
305 segment_len = break_addr - addr;
306 mask_bits = fill_mask (addr ^ (addr + segment_len - 1));
307 mips_linux_watch_set_watchlo (&regs_copy, i,
308 (addr & ~mask_bits) | irw);
309 mips_linux_watch_set_watchhi (&regs_copy, i,
310 mask_bits & ~IRW_MASK);
311 if (break_addr >= addr + len)
312 {
313 *regs = regs_copy;
314 return 1;
315 }
316 len = addr + len - break_addr;
317 addr = break_addr;
318 }
319 }
320 }
321 /* It didn't fit anywhere, we failed. */
322 return 0;
323 }
324
325 /* Fill in the watch registers REGS with the currently cached
326 watches CURRENT_WATCHES. */
327
328 void
329 mips_linux_watch_populate_regs (struct mips_watchpoint *current_watches,
330 struct pt_watch_regs *regs)
331 {
332 struct mips_watchpoint *w;
333 int i;
334
335 /* Clear them out. */
336 for (i = 0; i < mips_linux_watch_get_num_valid (regs); i++)
337 {
338 mips_linux_watch_set_watchlo (regs, i, 0);
339 mips_linux_watch_set_watchhi (regs, i, 0);
340 }
341
342 w = current_watches;
343 while (w)
344 {
345 uint32_t irw = mips_linux_watch_type_to_irw (w->type);
346
347 i = mips_linux_watch_try_one_watch (regs, w->addr, w->len, irw);
348 /* They must all fit, because we previously calculated that they
349 would. */
350 gdb_assert (i);
351 w = w->next;
352 }
353 }
This page took 0.035912 seconds and 4 git commands to generate.