ea6e02de37831dbb8f8e01bb92f3c4cfd4ed3d62
1 /* Copyright (C) 2009-2014 Free Software Foundation, Inc.
3 This file is part of GDB.
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.
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.
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/>. */
23 #include <sys/ptrace.h>
24 #include "mips-linux-watch.h"
26 /* Assuming usable watch registers REGS, return the irw_mask of
30 mips_linux_watch_get_irw_mask (struct pt_watch_regs
*regs
, int n
)
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
;
39 internal_error (__FILE__
, __LINE__
,
40 _("Unrecognized watch register style"));
44 /* Assuming usable watch registers REGS, return the reg_mask of
48 get_reg_mask (struct pt_watch_regs
*regs
, int n
)
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
;
57 internal_error (__FILE__
, __LINE__
,
58 _("Unrecognized watch register style"));
62 /* Assuming usable watch registers REGS, return the num_valid. */
65 mips_linux_watch_get_num_valid (struct pt_watch_regs
*regs
)
69 case pt_watch_style_mips32
:
70 return regs
->mips32
.num_valid
;
71 case pt_watch_style_mips64
:
72 return regs
->mips64
.num_valid
;
74 internal_error (__FILE__
, __LINE__
,
75 _("Unrecognized watch register style"));
79 /* Assuming usable watch registers REGS, return the watchlo of
83 mips_linux_watch_get_watchlo (struct pt_watch_regs
*regs
, int n
)
87 case pt_watch_style_mips32
:
88 return regs
->mips32
.watchlo
[n
];
89 case pt_watch_style_mips64
:
90 return regs
->mips64
.watchlo
[n
];
92 internal_error (__FILE__
, __LINE__
,
93 _("Unrecognized watch register style"));
97 /* Assuming usable watch registers REGS, set watchlo of register N to
101 mips_linux_watch_set_watchlo (struct pt_watch_regs
*regs
, int n
,
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
;
111 case pt_watch_style_mips64
:
112 regs
->mips64
.watchlo
[n
] = value
;
115 internal_error (__FILE__
, __LINE__
,
116 _("Unrecognized watch register style"));
120 /* Assuming usable watch registers REGS, return the watchhi of
124 mips_linux_watch_get_watchhi (struct pt_watch_regs
*regs
, int n
)
128 case pt_watch_style_mips32
:
129 return regs
->mips32
.watchhi
[n
];
130 case pt_watch_style_mips64
:
131 return regs
->mips64
.watchhi
[n
];
133 internal_error (__FILE__
, __LINE__
,
134 _("Unrecognized watch register style"));
138 /* Assuming usable watch registers REGS, set watchhi of register N to
142 mips_linux_watch_set_watchhi (struct pt_watch_regs
*regs
, int n
,
147 case pt_watch_style_mips32
:
148 regs
->mips32
.watchhi
[n
] = value
;
150 case pt_watch_style_mips64
:
151 regs
->mips64
.watchhi
[n
] = value
;
154 internal_error (__FILE__
, __LINE__
,
155 _("Unrecognized watch register style"));
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. */
165 mips_linux_read_watch_registers (long lwpid
,
166 struct pt_watch_regs
*watch_readback
,
167 int *watch_readback_valid
, int force
)
169 if (force
|| *watch_readback_valid
== 0)
171 if (ptrace (PTRACE_GET_WATCH_REGS
, lwpid
, watch_readback
) == -1)
173 *watch_readback_valid
= -1;
176 switch (watch_readback
->style
)
178 case pt_watch_style_mips32
:
179 if (watch_readback
->mips32
.num_valid
== 0)
181 *watch_readback_valid
= -1;
185 case pt_watch_style_mips64
:
186 if (watch_readback
->mips64
.num_valid
== 0)
188 *watch_readback_valid
= -1;
193 *watch_readback_valid
= -1;
196 /* Watch registers appear to be usable. */
197 *watch_readback_valid
= 1;
199 return (*watch_readback_valid
== 1) ? 1 : 0;
202 /* Convert GDB's TYPE to an IRW mask. */
205 mips_linux_watch_type_to_irw (int type
)
214 return (W_MASK
| R_MASK
);
220 /* Set any low order bits in MASK that are not set. */
223 fill_mask (CORE_ADDR mask
)
227 while (f
&& f
< mask
)
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. */
240 mips_linux_watch_try_one_watch (struct pt_watch_regs
*regs
,
241 CORE_ADDR addr
, int len
, uint32_t irw
)
243 CORE_ADDR base_addr
, last_byte
, break_addr
, segment_len
;
244 CORE_ADDR mask_bits
, t_low
;
247 struct pt_watch_regs regs_copy
;
252 last_byte
= addr
+ len
- 1;
253 mask_bits
= fill_mask (addr
^ last_byte
) | IRW_MASK
;
254 base_addr
= addr
& ~mask_bits
;
256 /* Check to see if it is covered by current registers. */
257 for (i
= 0; i
< mips_linux_watch_get_num_valid (regs
); i
++)
259 t_low
= mips_linux_watch_get_watchlo (regs
, i
);
260 if (t_low
!= 0 && irw
== ((uint32_t) t_low
& irw
))
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
))
268 /* Try to find an empty register. */
270 for (i
= 0; i
< mips_linux_watch_get_num_valid (regs
); i
++)
272 t_low
= mips_linux_watch_get_watchlo (regs
, i
);
274 && irw
== (mips_linux_watch_get_irw_mask (regs
, i
) & irw
))
276 if (mask_bits
<= (get_reg_mask (regs
, i
) | IRW_MASK
))
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
);
285 /* It doesn't fit, but has the proper IRW capabilities. */
290 if (free_watches
> 1)
292 /* Try to split it across several registers. */
294 for (i
= 0; i
< mips_linux_watch_get_num_valid (®s_copy
); i
++)
296 t_low
= mips_linux_watch_get_watchlo (®s_copy
, i
);
297 t_hi
= get_reg_mask (®s_copy
, i
) | IRW_MASK
;
298 if (t_low
== 0 && irw
== (t_hi
& irw
))
300 t_low
= addr
& ~(CORE_ADDR
) t_hi
;
301 break_addr
= t_low
+ t_hi
+ 1;
302 if (break_addr
>= addr
+ len
)
305 segment_len
= break_addr
- addr
;
306 mask_bits
= fill_mask (addr
^ (addr
+ segment_len
- 1));
307 mips_linux_watch_set_watchlo (®s_copy
, i
,
308 (addr
& ~mask_bits
) | irw
);
309 mips_linux_watch_set_watchhi (®s_copy
, i
,
310 mask_bits
& ~IRW_MASK
);
311 if (break_addr
>= addr
+ len
)
316 len
= addr
+ len
- break_addr
;
321 /* It didn't fit anywhere, we failed. */
325 /* Fill in the watch registers REGS with the currently cached
326 watches CURRENT_WATCHES. */
329 mips_linux_watch_populate_regs (struct mips_watchpoint
*current_watches
,
330 struct pt_watch_regs
*regs
)
332 struct mips_watchpoint
*w
;
335 /* Clear them out. */
336 for (i
= 0; i
< mips_linux_watch_get_num_valid (regs
); i
++)
338 mips_linux_watch_set_watchlo (regs
, i
, 0);
339 mips_linux_watch_set_watchhi (regs
, i
, 0);
345 uint32_t irw
= mips_linux_watch_type_to_irw (w
->type
);
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
This page took 0.035912 seconds and 4 git commands to generate.