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