dcb7ed99a86893429a60a813f5f08ec7da873b15
[platform/upstream/binutils.git] / gdb / mi / mi-cmd-break.c
1 /* MI Command Set - breakpoint and watchpoint commands.
2    Copyright (C) 2000, 2001, 2002, 2007, 2008, 2009, 2010
3    Free Software Foundation, Inc.
4    Contributed by Cygnus Solutions (a Red Hat company).
5
6    This file is part of GDB.
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
20
21 #include "defs.h"
22 #include "arch-utils.h"
23 #include "mi-cmds.h"
24 #include "ui-out.h"
25 #include "mi-out.h"
26 #include "breakpoint.h"
27 #include "gdb_string.h"
28 #include "mi-getopt.h"
29 #include "gdb.h"
30 #include "exceptions.h"
31 #include "observer.h"
32
33 enum
34   {
35     FROM_TTY = 0
36   };
37
38 /* True if MI breakpoint observers have been registered.  */
39
40 static int mi_breakpoint_observers_installed;
41
42 /* Control whether breakpoint_notify may act.  */
43
44 static int mi_can_breakpoint_notify;
45
46 /* Output a single breakpoint, when allowed. */
47
48 static void
49 breakpoint_notify (int b)
50 {
51   if (mi_can_breakpoint_notify)
52     gdb_breakpoint_query (uiout, b, NULL);
53 }
54
55 enum bp_type
56   {
57     REG_BP,
58     HW_BP,
59     REGEXP_BP
60   };
61
62 /* Implements the -break-insert command.
63    See the MI manual for the list of possible options.  */
64
65 void
66 mi_cmd_break_insert (char *command, char **argv, int argc)
67 {
68   char *address = NULL;
69   int hardware = 0;
70   int temp_p = 0;
71   int thread = -1;
72   int ignore_count = 0;
73   char *condition = NULL;
74   int pending = 0;
75   int enabled = 1;
76   int tracepoint = 0;
77   struct cleanup *back_to;
78
79   enum opt
80     {
81       HARDWARE_OPT, TEMP_OPT, CONDITION_OPT,
82       IGNORE_COUNT_OPT, THREAD_OPT, PENDING_OPT, DISABLE_OPT,
83       TRACEPOINT_OPT,
84     };
85   static struct mi_opt opts[] =
86   {
87     {"h", HARDWARE_OPT, 0},
88     {"t", TEMP_OPT, 0},
89     {"c", CONDITION_OPT, 1},
90     {"i", IGNORE_COUNT_OPT, 1},
91     {"p", THREAD_OPT, 1},
92     {"f", PENDING_OPT, 0},
93     {"d", DISABLE_OPT, 0},
94     {"a", TRACEPOINT_OPT, 0},
95     { 0, 0, 0 }
96   };
97
98   /* Parse arguments. It could be -r or -h or -t, <location> or ``--''
99      to denote the end of the option list. */
100   int optind = 0;
101   char *optarg;
102   while (1)
103     {
104       int opt = mi_getopt ("mi_cmd_break_insert", argc, argv, opts, &optind, &optarg);
105       if (opt < 0)
106         break;
107       switch ((enum opt) opt)
108         {
109         case TEMP_OPT:
110           temp_p = 1;
111           break;
112         case HARDWARE_OPT:
113           hardware = 1;
114           break;
115         case CONDITION_OPT:
116           condition = optarg;
117           break;
118         case IGNORE_COUNT_OPT:
119           ignore_count = atol (optarg);
120           break;
121         case THREAD_OPT:
122           thread = atol (optarg);
123           break;
124         case PENDING_OPT:
125           pending = 1;
126           break;
127         case DISABLE_OPT:
128           enabled = 0;
129           break;
130         case TRACEPOINT_OPT:
131           tracepoint = 1;
132           break;
133         }
134     }
135
136   if (optind >= argc)
137     error (_("mi_cmd_break_insert: Missing <location>"));
138   if (optind < argc - 1)
139     error (_("mi_cmd_break_insert: Garbage following <location>"));
140   address = argv[optind];
141
142   /* Now we have what we need, let's insert the breakpoint! */
143   if (! mi_breakpoint_observers_installed)
144     {
145       observer_attach_breakpoint_created (breakpoint_notify);
146       observer_attach_breakpoint_modified (breakpoint_notify);
147       observer_attach_breakpoint_deleted (breakpoint_notify);
148       mi_breakpoint_observers_installed = 1;
149     }
150
151   back_to = make_cleanup_restore_integer (&mi_can_breakpoint_notify);
152   mi_can_breakpoint_notify = 1;
153   create_breakpoint (get_current_arch (), address, condition, thread,
154                      0 /* condition and thread are valid.  */,
155                      temp_p, hardware, tracepoint,
156                      ignore_count,
157                      pending ? AUTO_BOOLEAN_TRUE : AUTO_BOOLEAN_FALSE,
158                      NULL, 0, enabled);
159   do_cleanups (back_to);
160
161 }
162
163 enum wp_type
164 {
165   REG_WP,
166   READ_WP,
167   ACCESS_WP
168 };
169
170 void
171 mi_cmd_break_passcount (char *command, char **argv, int argc)
172 {
173   int n;
174   int p;
175   struct breakpoint *t;
176
177   if (argc != 2)
178     error (_("Usage: tracepoint-number passcount"));
179
180   n = atoi (argv[0]);
181   p = atoi (argv[1]);
182   t = get_tracepoint (n);
183
184   if (t)
185     {
186       t->pass_count = p;
187       observer_notify_tracepoint_modified (n);
188     }
189   else
190     {
191       error (_("Cound not find tracepoint %d"), n);
192     }
193 }
194
195 /* Insert a watchpoint. The type of watchpoint is specified by the
196    first argument: 
197    -break-watch <expr> --> insert a regular wp.  
198    -break-watch -r <expr> --> insert a read watchpoint.
199    -break-watch -a <expr> --> insert an access wp. */
200
201 void
202 mi_cmd_break_watch (char *command, char **argv, int argc)
203 {
204   char *expr = NULL;
205   enum wp_type type = REG_WP;
206   enum opt
207     {
208       READ_OPT, ACCESS_OPT
209     };
210   static struct mi_opt opts[] =
211   {
212     {"r", READ_OPT, 0},
213     {"a", ACCESS_OPT, 0},
214     { 0, 0, 0 }
215   };
216
217   /* Parse arguments. */
218   int optind = 0;
219   char *optarg;
220   while (1)
221     {
222       int opt = mi_getopt ("mi_cmd_break_watch", argc, argv, opts, &optind, &optarg);
223       if (opt < 0)
224         break;
225       switch ((enum opt) opt)
226         {
227         case READ_OPT:
228           type = READ_WP;
229           break;
230         case ACCESS_OPT:
231           type = ACCESS_WP;
232           break;
233         }
234     }
235   if (optind >= argc)
236     error (_("mi_cmd_break_watch: Missing <expression>"));
237   if (optind < argc - 1)
238     error (_("mi_cmd_break_watch: Garbage following <expression>"));
239   expr = argv[optind];
240
241   /* Now we have what we need, let's insert the watchpoint! */
242   switch (type)
243     {
244     case REG_WP:
245       watch_command_wrapper (expr, FROM_TTY);
246       break;
247     case READ_WP:
248       rwatch_command_wrapper (expr, FROM_TTY);
249       break;
250     case ACCESS_WP:
251       awatch_command_wrapper (expr, FROM_TTY);
252       break;
253     default:
254       error (_("mi_cmd_break_watch: Unknown watchpoint type."));
255     }
256 }
257
258 /* The mi_read_next_line consults these variable to return successive
259    command lines.  While it would be clearer to use a closure pointer,
260    it is not expected that any future code will use read_command_lines_1,
261    therefore no point of overengineering.  */
262
263 static char **mi_command_line_array;
264 static int mi_command_line_array_cnt;
265 static int mi_command_line_array_ptr;
266
267 static char *
268 mi_read_next_line (void)
269 {
270   if (mi_command_line_array_ptr == mi_command_line_array_cnt)
271     return NULL;
272   else
273     return mi_command_line_array[mi_command_line_array_ptr++];
274 }
275
276 void
277 mi_cmd_break_commands (char *command, char **argv, int argc)
278 {
279   struct command_line *break_command;
280   char *endptr;
281   int bnum;
282   struct breakpoint *b;
283
284   if (argc < 1)
285     error ("USAGE: %s <BKPT> [<COMMAND> [<COMMAND>...]]", command);
286
287   bnum = strtol (argv[0], &endptr, 0);
288   if (endptr == argv[0])
289     error ("breakpoint number argument \"%s\" is not a number.",
290            argv[0]);
291   else if (*endptr != '\0')
292     error ("junk at the end of breakpoint number argument \"%s\".",
293            argv[0]);
294
295   b = get_breakpoint (bnum);
296   if (b == NULL)
297     error ("breakpoint %d not found.", bnum);
298
299   mi_command_line_array = argv;
300   mi_command_line_array_ptr = 1;
301   mi_command_line_array_cnt = argc;
302
303   if (is_tracepoint (b))
304     break_command = read_command_lines_1 (mi_read_next_line, 1,
305                                           check_tracepoint_command, b);
306   else
307     break_command = read_command_lines_1 (mi_read_next_line, 1, 0, 0);
308
309   breakpoint_set_commands (b, break_command);
310 }
311