1b725ae77Skettenis /* MI Command Set - breakpoint and watchpoint commands.
2b725ae77Skettenis    Copyright 2000, 2001, 2002 Free Software Foundation, Inc.
3b725ae77Skettenis    Contributed by Cygnus Solutions (a Red Hat company).
4b725ae77Skettenis 
5b725ae77Skettenis    This file is part of GDB.
6b725ae77Skettenis 
7b725ae77Skettenis    This program is free software; you can redistribute it and/or modify
8b725ae77Skettenis    it under the terms of the GNU General Public License as published by
9b725ae77Skettenis    the Free Software Foundation; either version 2 of the License, or
10b725ae77Skettenis    (at your option) any later version.
11b725ae77Skettenis 
12b725ae77Skettenis    This program is distributed in the hope that it will be useful,
13b725ae77Skettenis    but WITHOUT ANY WARRANTY; without even the implied warranty of
14b725ae77Skettenis    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15b725ae77Skettenis    GNU General Public License for more details.
16b725ae77Skettenis 
17b725ae77Skettenis    You should have received a copy of the GNU General Public License
18b725ae77Skettenis    along with this program; if not, write to the Free Software
19b725ae77Skettenis    Foundation, Inc., 59 Temple Place - Suite 330,
20b725ae77Skettenis    Boston, MA 02111-1307, USA.  */
21b725ae77Skettenis 
22b725ae77Skettenis #include "defs.h"
23b725ae77Skettenis #include "mi-cmds.h"
24b725ae77Skettenis #include "ui-out.h"
25b725ae77Skettenis #include "mi-out.h"
26b725ae77Skettenis #include "breakpoint.h"
27b725ae77Skettenis #include "gdb_string.h"
28b725ae77Skettenis #include "mi-getopt.h"
29b725ae77Skettenis #include "gdb-events.h"
30b725ae77Skettenis #include "gdb.h"
31b725ae77Skettenis 
32b725ae77Skettenis enum
33b725ae77Skettenis   {
34b725ae77Skettenis     FROM_TTY = 0
35b725ae77Skettenis   };
36b725ae77Skettenis 
37b725ae77Skettenis /* Output a single breakpoint. */
38b725ae77Skettenis 
39b725ae77Skettenis static void
breakpoint_notify(int b)40b725ae77Skettenis breakpoint_notify (int b)
41b725ae77Skettenis {
42b725ae77Skettenis   gdb_breakpoint_query (uiout, b);
43b725ae77Skettenis }
44b725ae77Skettenis 
45b725ae77Skettenis 
46b725ae77Skettenis struct gdb_events breakpoint_hooks =
47b725ae77Skettenis {
48b725ae77Skettenis   breakpoint_notify,
49b725ae77Skettenis   breakpoint_notify,
50b725ae77Skettenis   breakpoint_notify,
51b725ae77Skettenis };
52b725ae77Skettenis 
53b725ae77Skettenis 
54b725ae77Skettenis enum bp_type
55b725ae77Skettenis   {
56b725ae77Skettenis     REG_BP,
57b725ae77Skettenis     HW_BP,
58b725ae77Skettenis     REGEXP_BP
59b725ae77Skettenis   };
60b725ae77Skettenis 
61b725ae77Skettenis /* Insert a breakpoint. The type of breakpoint is specified by the
62b725ae77Skettenis    first argument: -break-insert <location> --> insert a regular
63b725ae77Skettenis    breakpoint.  -break-insert -t <location> --> insert a temporary
64b725ae77Skettenis    breakpoint.  -break-insert -h <location> --> insert an hardware
65b725ae77Skettenis    breakpoint.  -break-insert -t -h <location> --> insert a temporary
66b725ae77Skettenis    hw bp.
67b725ae77Skettenis    -break-insert -r <regexp> --> insert a bp at functions matching
68b725ae77Skettenis    <regexp> */
69b725ae77Skettenis 
70b725ae77Skettenis enum mi_cmd_result
mi_cmd_break_insert(char * command,char ** argv,int argc)71b725ae77Skettenis mi_cmd_break_insert (char *command, char **argv, int argc)
72b725ae77Skettenis {
73b725ae77Skettenis   char *address = NULL;
74b725ae77Skettenis   enum bp_type type = REG_BP;
75b725ae77Skettenis   int temp_p = 0;
76b725ae77Skettenis   int thread = -1;
77b725ae77Skettenis   int ignore_count = 0;
78b725ae77Skettenis   char *condition = NULL;
79b725ae77Skettenis   enum gdb_rc rc;
80b725ae77Skettenis   struct gdb_events *old_hooks;
81b725ae77Skettenis   enum opt
82b725ae77Skettenis     {
83b725ae77Skettenis       HARDWARE_OPT, TEMP_OPT /*, REGEXP_OPT */ , CONDITION_OPT,
84b725ae77Skettenis       IGNORE_COUNT_OPT, THREAD_OPT
85b725ae77Skettenis     };
86b725ae77Skettenis   static struct mi_opt opts[] =
87b725ae77Skettenis   {
88b725ae77Skettenis     {"h", HARDWARE_OPT, 0},
89b725ae77Skettenis     {"t", TEMP_OPT, 0},
90b725ae77Skettenis     {"c", CONDITION_OPT, 1},
91b725ae77Skettenis     {"i", IGNORE_COUNT_OPT, 1},
92b725ae77Skettenis     {"p", THREAD_OPT, 1},
93b725ae77Skettenis     0
94b725ae77Skettenis   };
95b725ae77Skettenis 
96b725ae77Skettenis   /* Parse arguments. It could be -r or -h or -t, <location> or ``--''
97b725ae77Skettenis      to denote the end of the option list. */
98b725ae77Skettenis   int optind = 0;
99b725ae77Skettenis   char *optarg;
100b725ae77Skettenis   while (1)
101b725ae77Skettenis     {
102b725ae77Skettenis       int opt = mi_getopt ("mi_cmd_break_insert", argc, argv, opts, &optind, &optarg);
103b725ae77Skettenis       if (opt < 0)
104b725ae77Skettenis 	break;
105b725ae77Skettenis       switch ((enum opt) opt)
106b725ae77Skettenis 	{
107b725ae77Skettenis 	case TEMP_OPT:
108b725ae77Skettenis 	  temp_p = 1;
109b725ae77Skettenis 	  break;
110b725ae77Skettenis 	case HARDWARE_OPT:
111b725ae77Skettenis 	  type = HW_BP;
112b725ae77Skettenis 	  break;
113b725ae77Skettenis #if 0
114b725ae77Skettenis 	case REGEXP_OPT:
115b725ae77Skettenis 	  type = REGEXP_BP;
116b725ae77Skettenis 	  break;
117b725ae77Skettenis #endif
118b725ae77Skettenis 	case CONDITION_OPT:
119b725ae77Skettenis 	  condition = optarg;
120b725ae77Skettenis 	  break;
121b725ae77Skettenis 	case IGNORE_COUNT_OPT:
122b725ae77Skettenis 	  ignore_count = atol (optarg);
123b725ae77Skettenis 	  break;
124b725ae77Skettenis 	case THREAD_OPT:
125b725ae77Skettenis 	  thread = atol (optarg);
126b725ae77Skettenis 	  break;
127b725ae77Skettenis 	}
128b725ae77Skettenis     }
129b725ae77Skettenis 
130b725ae77Skettenis   if (optind >= argc)
131b725ae77Skettenis     error ("mi_cmd_break_insert: Missing <location>");
132b725ae77Skettenis   if (optind < argc - 1)
133b725ae77Skettenis     error ("mi_cmd_break_insert: Garbage following <location>");
134b725ae77Skettenis   address = argv[optind];
135b725ae77Skettenis 
136b725ae77Skettenis   /* Now we have what we need, let's insert the breakpoint! */
137*11efff7fSkettenis   old_hooks = deprecated_set_gdb_event_hooks (&breakpoint_hooks);
138b725ae77Skettenis   switch (type)
139b725ae77Skettenis     {
140b725ae77Skettenis     case REG_BP:
141b725ae77Skettenis       rc = gdb_breakpoint (address, condition,
142b725ae77Skettenis 			   0 /*hardwareflag */ , temp_p,
143b725ae77Skettenis 			   thread, ignore_count);
144b725ae77Skettenis       break;
145b725ae77Skettenis     case HW_BP:
146b725ae77Skettenis       rc = gdb_breakpoint (address, condition,
147b725ae77Skettenis 			   1 /*hardwareflag */ , temp_p,
148b725ae77Skettenis 			   thread, ignore_count);
149b725ae77Skettenis       break;
150b725ae77Skettenis #if 0
151b725ae77Skettenis     case REGEXP_BP:
152b725ae77Skettenis       if (temp_p)
153b725ae77Skettenis 	error ("mi_cmd_break_insert: Unsupported tempoary regexp breakpoint");
154b725ae77Skettenis       else
155b725ae77Skettenis 	rbreak_command_wrapper (address, FROM_TTY);
156b725ae77Skettenis       return MI_CMD_DONE;
157b725ae77Skettenis       break;
158b725ae77Skettenis #endif
159b725ae77Skettenis     default:
160b725ae77Skettenis       internal_error (__FILE__, __LINE__,
161b725ae77Skettenis 		      "mi_cmd_break_insert: Bad switch.");
162b725ae77Skettenis     }
163*11efff7fSkettenis   deprecated_set_gdb_event_hooks (old_hooks);
164b725ae77Skettenis 
165b725ae77Skettenis   if (rc == GDB_RC_FAIL)
166b725ae77Skettenis     return MI_CMD_CAUGHT_ERROR;
167b725ae77Skettenis   else
168b725ae77Skettenis     return MI_CMD_DONE;
169b725ae77Skettenis }
170b725ae77Skettenis 
171b725ae77Skettenis enum wp_type
172b725ae77Skettenis {
173b725ae77Skettenis   REG_WP,
174b725ae77Skettenis   READ_WP,
175b725ae77Skettenis   ACCESS_WP
176b725ae77Skettenis };
177b725ae77Skettenis 
178b725ae77Skettenis /* Insert a watchpoint. The type of watchpoint is specified by the
179b725ae77Skettenis    first argument:
180b725ae77Skettenis    -break-watch <expr> --> insert a regular wp.
181b725ae77Skettenis    -break-watch -r <expr> --> insert a read watchpoint.
182b725ae77Skettenis    -break-watch -a <expr> --> insert an access wp. */
183b725ae77Skettenis 
184b725ae77Skettenis enum mi_cmd_result
mi_cmd_break_watch(char * command,char ** argv,int argc)185b725ae77Skettenis mi_cmd_break_watch (char *command, char **argv, int argc)
186b725ae77Skettenis {
187b725ae77Skettenis   char *expr = NULL;
188b725ae77Skettenis   enum wp_type type = REG_WP;
189b725ae77Skettenis   enum opt
190b725ae77Skettenis     {
191b725ae77Skettenis       READ_OPT, ACCESS_OPT
192b725ae77Skettenis     };
193b725ae77Skettenis   static struct mi_opt opts[] =
194b725ae77Skettenis   {
195b725ae77Skettenis     {"r", READ_OPT, 0},
196b725ae77Skettenis     {"a", ACCESS_OPT, 0},
197b725ae77Skettenis     0
198b725ae77Skettenis   };
199b725ae77Skettenis 
200b725ae77Skettenis   /* Parse arguments. */
201b725ae77Skettenis   int optind = 0;
202b725ae77Skettenis   char *optarg;
203b725ae77Skettenis   while (1)
204b725ae77Skettenis     {
205b725ae77Skettenis       int opt = mi_getopt ("mi_cmd_break_watch", argc, argv, opts, &optind, &optarg);
206b725ae77Skettenis       if (opt < 0)
207b725ae77Skettenis 	break;
208b725ae77Skettenis       switch ((enum opt) opt)
209b725ae77Skettenis 	{
210b725ae77Skettenis 	case READ_OPT:
211b725ae77Skettenis 	  type = READ_WP;
212b725ae77Skettenis 	  break;
213b725ae77Skettenis 	case ACCESS_OPT:
214b725ae77Skettenis 	  type = ACCESS_WP;
215b725ae77Skettenis 	  break;
216b725ae77Skettenis 	}
217b725ae77Skettenis     }
218b725ae77Skettenis   if (optind >= argc)
219b725ae77Skettenis     error ("mi_cmd_break_watch: Missing <expression>");
220b725ae77Skettenis   if (optind < argc - 1)
221b725ae77Skettenis     error ("mi_cmd_break_watch: Garbage following <expression>");
222b725ae77Skettenis   expr = argv[optind];
223b725ae77Skettenis 
224b725ae77Skettenis   /* Now we have what we need, let's insert the watchpoint! */
225b725ae77Skettenis   switch (type)
226b725ae77Skettenis     {
227b725ae77Skettenis     case REG_WP:
228b725ae77Skettenis       watch_command_wrapper (expr, FROM_TTY);
229b725ae77Skettenis       break;
230b725ae77Skettenis     case READ_WP:
231b725ae77Skettenis       rwatch_command_wrapper (expr, FROM_TTY);
232b725ae77Skettenis       break;
233b725ae77Skettenis     case ACCESS_WP:
234b725ae77Skettenis       awatch_command_wrapper (expr, FROM_TTY);
235b725ae77Skettenis       break;
236b725ae77Skettenis     default:
237b725ae77Skettenis       error ("mi_cmd_break_watch: Unknown watchpoint type.");
238b725ae77Skettenis     }
239b725ae77Skettenis   return MI_CMD_DONE;
240b725ae77Skettenis }
241