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