build as needed
[platform/upstream/binutils.git] / gdb / mi / mi-cmd-break.c
1 /* MI Command Set - breakpoint and watchpoint commands.
2    Copyright (C) 2000-2014 Free Software Foundation, Inc.
3    Contributed by Cygnus Solutions (a Red Hat company).
4
5    This file is part of GDB.
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19
20 #include "defs.h"
21 #include "arch-utils.h"
22 #include "mi-cmds.h"
23 #include "ui-out.h"
24 #include "mi-out.h"
25 #include "breakpoint.h"
26 #include "mi-getopt.h"
27 #include "gdb.h"
28 #include "observer.h"
29 #include "mi-main.h"
30 #include "mi-cmd-break.h"
31 #include "gdb_obstack.h"
32 #include <ctype.h>
33
34 enum
35   {
36     FROM_TTY = 0
37   };
38
39 /* True if MI breakpoint observers have been registered.  */
40
41 static int mi_breakpoint_observers_installed;
42
43 /* Control whether breakpoint_notify may act.  */
44
45 static int mi_can_breakpoint_notify;
46
47 /* Output a single breakpoint, when allowed.  */
48
49 static void
50 breakpoint_notify (struct breakpoint *b)
51 {
52   if (mi_can_breakpoint_notify)
53     gdb_breakpoint_query (current_uiout, b->number, NULL);
54 }
55
56 enum bp_type
57   {
58     REG_BP,
59     HW_BP,
60     REGEXP_BP
61   };
62
63 /* Arrange for all new breakpoints and catchpoints to be reported to
64    CURRENT_UIOUT until the cleanup returned by this function is run.
65
66    Note that MI output will be probably invalid if more than one
67    breakpoint is created inside one MI command.  */
68
69 struct cleanup *
70 setup_breakpoint_reporting (void)
71 {
72   struct cleanup *rev_flag;
73
74   if (! mi_breakpoint_observers_installed)
75     {
76       observer_attach_breakpoint_created (breakpoint_notify);
77       mi_breakpoint_observers_installed = 1;
78     }
79
80   rev_flag = make_cleanup_restore_integer (&mi_can_breakpoint_notify);
81   mi_can_breakpoint_notify = 1;
82
83   return rev_flag;
84 }
85
86
87 /* Convert arguments in ARGV to the string in "format",argv,argv...
88    and return it.  */
89
90 static char *
91 mi_argv_to_format (char **argv, int argc)
92 {
93   int i;
94   struct obstack obstack;
95   char *ret;
96
97   obstack_init (&obstack);
98
99   /* Convert ARGV[OIND + 1] to format string and save to FORMAT.  */
100   obstack_1grow (&obstack, '\"');
101   for (i = 0; i < strlen (argv[0]); i++)
102     {
103       switch (argv[0][i])
104         {
105         case '\\':
106           obstack_grow (&obstack, "\\\\", 2);
107           break;
108         case '\a':
109           obstack_grow (&obstack, "\\a", 2);
110           break;
111         case '\b':
112           obstack_grow (&obstack, "\\b", 2);
113           break;
114         case '\f':
115           obstack_grow (&obstack, "\\f", 2);
116           break;
117         case '\n':
118           obstack_grow (&obstack, "\\n", 2);
119           break;
120         case '\r':
121           obstack_grow (&obstack, "\\r", 2);
122           break;
123         case '\t':
124           obstack_grow (&obstack, "\\t", 2);
125           break;
126         case '\v':
127           obstack_grow (&obstack, "\\v", 2);
128           break;
129         case '"':
130           obstack_grow (&obstack, "\\\"", 2);
131           break;
132         default:
133           if (isprint (argv[0][i]))
134             obstack_grow (&obstack, argv[0] + i, 1);
135           else
136             {
137               char tmp[5];
138
139               xsnprintf (tmp, sizeof (tmp), "\\%o",
140                          (unsigned char) argv[0][i]);
141               obstack_grow (&obstack, tmp, strlen (tmp));
142             }
143           break;
144         }
145     }
146   obstack_1grow (&obstack, '\"');
147
148   /* Apply other argv to FORMAT.  */
149   for (i = 1; i < argc; i++)
150     {
151       obstack_1grow (&obstack, ',');
152       obstack_grow (&obstack, argv[i], strlen (argv[i]));
153     }
154   obstack_1grow (&obstack, '\0');
155
156   ret = xstrdup (obstack_finish (&obstack));
157   obstack_free (&obstack, NULL);
158
159   return ret;
160 }
161
162 /* Insert breakpoint.
163    If dprintf is true, it will insert dprintf.
164    If not, it will insert other type breakpoint.  */
165
166 static void
167 mi_cmd_break_insert_1 (int dprintf, char *command, char **argv, int argc)
168 {
169   char *address = NULL;
170   int hardware = 0;
171   int temp_p = 0;
172   int thread = -1;
173   int ignore_count = 0;
174   char *condition = NULL;
175   int pending = 0;
176   int enabled = 1;
177   int tracepoint = 0;
178   struct cleanup *back_to = make_cleanup (null_cleanup, NULL);
179   enum bptype type_wanted;
180   struct breakpoint_ops *ops;
181   char *extra_string = NULL;
182
183   enum opt
184     {
185       HARDWARE_OPT, TEMP_OPT, CONDITION_OPT,
186       IGNORE_COUNT_OPT, THREAD_OPT, PENDING_OPT, DISABLE_OPT,
187       TRACEPOINT_OPT,
188     };
189   static const struct mi_opt opts[] =
190   {
191     {"h", HARDWARE_OPT, 0},
192     {"t", TEMP_OPT, 0},
193     {"c", CONDITION_OPT, 1},
194     {"i", IGNORE_COUNT_OPT, 1},
195     {"p", THREAD_OPT, 1},
196     {"f", PENDING_OPT, 0},
197     {"d", DISABLE_OPT, 0},
198     {"a", TRACEPOINT_OPT, 0},
199     { 0, 0, 0 }
200   };
201
202   /* Parse arguments. It could be -r or -h or -t, <location> or ``--''
203      to denote the end of the option list. */
204   int oind = 0;
205   char *oarg;
206
207   while (1)
208     {
209       int opt = mi_getopt ("-break-insert", argc, argv,
210                            opts, &oind, &oarg);
211       if (opt < 0)
212         break;
213       switch ((enum opt) opt)
214         {
215         case TEMP_OPT:
216           temp_p = 1;
217           break;
218         case HARDWARE_OPT:
219           hardware = 1;
220           break;
221         case CONDITION_OPT:
222           condition = oarg;
223           break;
224         case IGNORE_COUNT_OPT:
225           ignore_count = atol (oarg);
226           break;
227         case THREAD_OPT:
228           thread = atol (oarg);
229           break;
230         case PENDING_OPT:
231           pending = 1;
232           break;
233         case DISABLE_OPT:
234           enabled = 0;
235           break;
236         case TRACEPOINT_OPT:
237           tracepoint = 1;
238           break;
239         }
240     }
241
242   if (oind >= argc)
243     error (_("-%s-insert: Missing <location>"),
244            dprintf ? "dprintf" : "break");
245   address = argv[oind];
246   if (dprintf)
247     {
248       int format_num = oind + 1;
249
250       if (hardware || tracepoint)
251         error (_("-dprintf-insert: does not support -h or -a"));
252       if (format_num >= argc)
253         error (_("-dprintf-insert: Missing <format>"));
254
255       extra_string = mi_argv_to_format (argv + format_num, argc - format_num);
256       make_cleanup (xfree, extra_string);
257     }
258   else
259     {
260       if (oind < argc - 1)
261         error (_("-break-insert: Garbage following <location>"));
262     }
263
264   /* Now we have what we need, let's insert the breakpoint!  */
265   setup_breakpoint_reporting ();
266
267   if (tracepoint)
268     {
269       /* Note that to request a fast tracepoint, the client uses the
270          "hardware" flag, although there's nothing of hardware related to
271          fast tracepoints -- one can implement slow tracepoints with
272          hardware breakpoints, but fast tracepoints are always software.
273          "fast" is a misnomer, actually, "jump" would be more appropriate.
274          A simulator or an emulator could conceivably implement fast
275          regular non-jump based tracepoints.  */
276       type_wanted = hardware ? bp_fast_tracepoint : bp_tracepoint;
277       ops = &tracepoint_breakpoint_ops;
278     }
279   else if (dprintf)
280     {
281       type_wanted = bp_dprintf;
282       ops = &dprintf_breakpoint_ops;
283     }
284   else
285     {
286       type_wanted = hardware ? bp_hardware_breakpoint : bp_breakpoint;
287       ops = &bkpt_breakpoint_ops;
288     }
289
290   create_breakpoint (get_current_arch (), address, condition, thread,
291                      extra_string,
292                      0 /* condition and thread are valid.  */,
293                      temp_p, type_wanted,
294                      ignore_count,
295                      pending ? AUTO_BOOLEAN_TRUE : AUTO_BOOLEAN_FALSE,
296                      ops, 0, enabled, 0, 0);
297   do_cleanups (back_to);
298 }
299
300 /* Implements the -break-insert command.
301    See the MI manual for the list of possible options.  */
302
303 void
304 mi_cmd_break_insert (char *command, char **argv, int argc)
305 {
306   mi_cmd_break_insert_1 (0, command, argv, argc);
307 }
308
309 /* Implements the -dprintf-insert command.
310    See the MI manual for the list of possible options.  */
311
312 void
313 mi_cmd_dprintf_insert (char *command, char **argv, int argc)
314 {
315   mi_cmd_break_insert_1 (1, command, argv, argc);
316 }
317
318 enum wp_type
319 {
320   REG_WP,
321   READ_WP,
322   ACCESS_WP
323 };
324
325 void
326 mi_cmd_break_passcount (char *command, char **argv, int argc)
327 {
328   int n;
329   int p;
330   struct tracepoint *t;
331
332   if (argc != 2)
333     error (_("Usage: tracepoint-number passcount"));
334
335   n = atoi (argv[0]);
336   p = atoi (argv[1]);
337   t = get_tracepoint (n);
338
339   if (t)
340     {
341       t->pass_count = p;
342       observer_notify_breakpoint_modified (&t->base);
343     }
344   else
345     {
346       error (_("Could not find tracepoint %d"), n);
347     }
348 }
349
350 /* Insert a watchpoint. The type of watchpoint is specified by the
351    first argument: 
352    -break-watch <expr> --> insert a regular wp.  
353    -break-watch -r <expr> --> insert a read watchpoint.
354    -break-watch -a <expr> --> insert an access wp.  */
355
356 void
357 mi_cmd_break_watch (char *command, char **argv, int argc)
358 {
359   char *expr = NULL;
360   enum wp_type type = REG_WP;
361   enum opt
362     {
363       READ_OPT, ACCESS_OPT
364     };
365   static const struct mi_opt opts[] =
366   {
367     {"r", READ_OPT, 0},
368     {"a", ACCESS_OPT, 0},
369     { 0, 0, 0 }
370   };
371
372   /* Parse arguments. */
373   int oind = 0;
374   char *oarg;
375
376   while (1)
377     {
378       int opt = mi_getopt ("-break-watch", argc, argv,
379                            opts, &oind, &oarg);
380
381       if (opt < 0)
382         break;
383       switch ((enum opt) opt)
384         {
385         case READ_OPT:
386           type = READ_WP;
387           break;
388         case ACCESS_OPT:
389           type = ACCESS_WP;
390           break;
391         }
392     }
393   if (oind >= argc)
394     error (_("-break-watch: Missing <expression>"));
395   if (oind < argc - 1)
396     error (_("-break-watch: Garbage following <expression>"));
397   expr = argv[oind];
398
399   /* Now we have what we need, let's insert the watchpoint!  */
400   switch (type)
401     {
402     case REG_WP:
403       watch_command_wrapper (expr, FROM_TTY, 0);
404       break;
405     case READ_WP:
406       rwatch_command_wrapper (expr, FROM_TTY, 0);
407       break;
408     case ACCESS_WP:
409       awatch_command_wrapper (expr, FROM_TTY, 0);
410       break;
411     default:
412       error (_("-break-watch: Unknown watchpoint type."));
413     }
414 }
415
416 /* The mi_read_next_line consults these variable to return successive
417    command lines.  While it would be clearer to use a closure pointer,
418    it is not expected that any future code will use read_command_lines_1,
419    therefore no point of overengineering.  */
420
421 static char **mi_command_line_array;
422 static int mi_command_line_array_cnt;
423 static int mi_command_line_array_ptr;
424
425 static char *
426 mi_read_next_line (void)
427 {
428   if (mi_command_line_array_ptr == mi_command_line_array_cnt)
429     return NULL;
430   else
431     return mi_command_line_array[mi_command_line_array_ptr++];
432 }
433
434 void
435 mi_cmd_break_commands (char *command, char **argv, int argc)
436 {
437   struct command_line *break_command;
438   char *endptr;
439   int bnum;
440   struct breakpoint *b;
441
442   if (argc < 1)
443     error (_("USAGE: %s <BKPT> [<COMMAND> [<COMMAND>...]]"), command);
444
445   bnum = strtol (argv[0], &endptr, 0);
446   if (endptr == argv[0])
447     error (_("breakpoint number argument \"%s\" is not a number."),
448            argv[0]);
449   else if (*endptr != '\0')
450     error (_("junk at the end of breakpoint number argument \"%s\"."),
451            argv[0]);
452
453   b = get_breakpoint (bnum);
454   if (b == NULL)
455     error (_("breakpoint %d not found."), bnum);
456
457   mi_command_line_array = argv;
458   mi_command_line_array_ptr = 1;
459   mi_command_line_array_cnt = argc;
460
461   if (is_tracepoint (b))
462     break_command = read_command_lines_1 (mi_read_next_line, 1,
463                                           check_tracepoint_command, b);
464   else
465     break_command = read_command_lines_1 (mi_read_next_line, 1, 0, 0);
466
467   breakpoint_set_commands (b, break_command);
468 }
469