xref: /openbsd-src/gnu/usr.bin/binutils/gdb/mi/mi-main.c (revision 11efff7f3ac2b3cfeff0c0cddc14294d9b3aca4f)
1b725ae77Skettenis /* MI Command Set.
2b725ae77Skettenis 
3b725ae77Skettenis    Copyright 2000, 2001, 2002, 2003, 2004 Free Software Foundation,
4b725ae77Skettenis    Inc.
5b725ae77Skettenis 
6b725ae77Skettenis    Contributed by Cygnus Solutions (a Red Hat company).
7b725ae77Skettenis 
8b725ae77Skettenis    This file is part of GDB.
9b725ae77Skettenis 
10b725ae77Skettenis    This program is free software; you can redistribute it and/or modify
11b725ae77Skettenis    it under the terms of the GNU General Public License as published by
12b725ae77Skettenis    the Free Software Foundation; either version 2 of the License, or
13b725ae77Skettenis    (at your option) any later version.
14b725ae77Skettenis 
15b725ae77Skettenis    This program is distributed in the hope that it will be useful,
16b725ae77Skettenis    but WITHOUT ANY WARRANTY; without even the implied warranty of
17b725ae77Skettenis    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18b725ae77Skettenis    GNU General Public License for more details.
19b725ae77Skettenis 
20b725ae77Skettenis    You should have received a copy of the GNU General Public License
21b725ae77Skettenis    along with this program; if not, write to the Free Software
22b725ae77Skettenis    Foundation, Inc., 59 Temple Place - Suite 330,
23b725ae77Skettenis    Boston, MA 02111-1307, USA.  */
24b725ae77Skettenis 
25b725ae77Skettenis /* Work in progress */
26b725ae77Skettenis 
27b725ae77Skettenis #include "defs.h"
28b725ae77Skettenis #include "target.h"
29b725ae77Skettenis #include "inferior.h"
30b725ae77Skettenis #include "gdb_string.h"
31b725ae77Skettenis #include "top.h"
32b725ae77Skettenis #include "gdbthread.h"
33b725ae77Skettenis #include "mi-cmds.h"
34b725ae77Skettenis #include "mi-parse.h"
35b725ae77Skettenis #include "mi-getopt.h"
36b725ae77Skettenis #include "mi-console.h"
37b725ae77Skettenis #include "ui-out.h"
38b725ae77Skettenis #include "mi-out.h"
39b725ae77Skettenis #include "interps.h"
40b725ae77Skettenis #include "event-loop.h"
41b725ae77Skettenis #include "event-top.h"
42b725ae77Skettenis #include "gdbcore.h"		/* for write_memory() */
43b725ae77Skettenis #include "value.h"		/* for deprecated_write_register_bytes() */
44b725ae77Skettenis #include "regcache.h"
45b725ae77Skettenis #include "gdb.h"
46b725ae77Skettenis #include "frame.h"
47b725ae77Skettenis #include "mi-main.h"
48b725ae77Skettenis 
49b725ae77Skettenis #include <ctype.h>
50b725ae77Skettenis #include <sys/time.h>
51b725ae77Skettenis 
52b725ae77Skettenis enum
53b725ae77Skettenis   {
54b725ae77Skettenis     FROM_TTY = 0
55b725ae77Skettenis   };
56b725ae77Skettenis 
57b725ae77Skettenis /* Enumerations of the actions that may result from calling
58b725ae77Skettenis    captured_mi_execute_command */
59b725ae77Skettenis 
60b725ae77Skettenis enum captured_mi_execute_command_actions
61b725ae77Skettenis   {
62b725ae77Skettenis     EXECUTE_COMMAND_DISPLAY_PROMPT,
63b725ae77Skettenis     EXECUTE_COMMAND_SUPRESS_PROMPT,
64b725ae77Skettenis     EXECUTE_COMMAND_DISPLAY_ERROR
65b725ae77Skettenis   };
66b725ae77Skettenis 
67b725ae77Skettenis /* This structure is used to pass information from captured_mi_execute_command
68b725ae77Skettenis    to mi_execute_command. */
69b725ae77Skettenis struct captured_mi_execute_command_args
70b725ae77Skettenis {
71b725ae77Skettenis   /* This return result of the MI command (output) */
72b725ae77Skettenis   enum mi_cmd_result rc;
73b725ae77Skettenis 
74b725ae77Skettenis   /* What action to perform when the call is finished (output) */
75b725ae77Skettenis   enum captured_mi_execute_command_actions action;
76b725ae77Skettenis 
77b725ae77Skettenis   /* The command context to be executed (input) */
78b725ae77Skettenis   struct mi_parse *command;
79b725ae77Skettenis };
80b725ae77Skettenis 
81b725ae77Skettenis int mi_debug_p;
82b725ae77Skettenis struct ui_file *raw_stdout;
83b725ae77Skettenis 
84b725ae77Skettenis /* The token of the last asynchronous command */
85b725ae77Skettenis static char *last_async_command;
86b725ae77Skettenis static char *previous_async_command;
87b725ae77Skettenis char *mi_error_message;
88b725ae77Skettenis static char *old_regs;
89b725ae77Skettenis 
90b725ae77Skettenis extern void _initialize_mi_main (void);
91b725ae77Skettenis static enum mi_cmd_result mi_cmd_execute (struct mi_parse *parse);
92b725ae77Skettenis 
93b725ae77Skettenis static void mi_execute_cli_command (const char *cmd, int args_p,
94b725ae77Skettenis 				    const char *args);
95b725ae77Skettenis static enum mi_cmd_result mi_execute_async_cli_command (char *mi, char *args, int from_tty);
96b725ae77Skettenis 
97b725ae77Skettenis static void mi_exec_async_cli_cmd_continuation (struct continuation_arg *arg);
98b725ae77Skettenis 
99b725ae77Skettenis static int register_changed_p (int regnum);
100b725ae77Skettenis static int get_register (int regnum, int format);
101b725ae77Skettenis 
102b725ae77Skettenis /* Command implementations. FIXME: Is this libgdb? No.  This is the MI
103b725ae77Skettenis    layer that calls libgdb.  Any operation used in the below should be
104b725ae77Skettenis    formalized. */
105b725ae77Skettenis 
106b725ae77Skettenis enum mi_cmd_result
mi_cmd_gdb_exit(char * command,char ** argv,int argc)107b725ae77Skettenis mi_cmd_gdb_exit (char *command, char **argv, int argc)
108b725ae77Skettenis {
109b725ae77Skettenis   /* We have to print everything right here because we never return */
110b725ae77Skettenis   if (last_async_command)
111b725ae77Skettenis     fputs_unfiltered (last_async_command, raw_stdout);
112b725ae77Skettenis   fputs_unfiltered ("^exit\n", raw_stdout);
113b725ae77Skettenis   mi_out_put (uiout, raw_stdout);
114b725ae77Skettenis   /* FIXME: The function called is not yet a formal libgdb function */
115b725ae77Skettenis   quit_force (NULL, FROM_TTY);
116b725ae77Skettenis   return MI_CMD_DONE;
117b725ae77Skettenis }
118b725ae77Skettenis 
119b725ae77Skettenis enum mi_cmd_result
mi_cmd_exec_run(char * args,int from_tty)120b725ae77Skettenis mi_cmd_exec_run (char *args, int from_tty)
121b725ae77Skettenis {
122b725ae77Skettenis   /* FIXME: Should call a libgdb function, not a cli wrapper */
123b725ae77Skettenis   return mi_execute_async_cli_command ("run", args, from_tty);
124b725ae77Skettenis }
125b725ae77Skettenis 
126b725ae77Skettenis enum mi_cmd_result
mi_cmd_exec_next(char * args,int from_tty)127b725ae77Skettenis mi_cmd_exec_next (char *args, int from_tty)
128b725ae77Skettenis {
129b725ae77Skettenis   /* FIXME: Should call a libgdb function, not a cli wrapper */
130b725ae77Skettenis   return mi_execute_async_cli_command ("next", args, from_tty);
131b725ae77Skettenis }
132b725ae77Skettenis 
133b725ae77Skettenis enum mi_cmd_result
mi_cmd_exec_next_instruction(char * args,int from_tty)134b725ae77Skettenis mi_cmd_exec_next_instruction (char *args, int from_tty)
135b725ae77Skettenis {
136b725ae77Skettenis   /* FIXME: Should call a libgdb function, not a cli wrapper */
137b725ae77Skettenis   return mi_execute_async_cli_command ("nexti", args, from_tty);
138b725ae77Skettenis }
139b725ae77Skettenis 
140b725ae77Skettenis enum mi_cmd_result
mi_cmd_exec_step(char * args,int from_tty)141b725ae77Skettenis mi_cmd_exec_step (char *args, int from_tty)
142b725ae77Skettenis {
143b725ae77Skettenis   /* FIXME: Should call a libgdb function, not a cli wrapper */
144b725ae77Skettenis   return mi_execute_async_cli_command ("step", args, from_tty);
145b725ae77Skettenis }
146b725ae77Skettenis 
147b725ae77Skettenis enum mi_cmd_result
mi_cmd_exec_step_instruction(char * args,int from_tty)148b725ae77Skettenis mi_cmd_exec_step_instruction (char *args, int from_tty)
149b725ae77Skettenis {
150b725ae77Skettenis   /* FIXME: Should call a libgdb function, not a cli wrapper */
151b725ae77Skettenis   return mi_execute_async_cli_command ("stepi", args, from_tty);
152b725ae77Skettenis }
153b725ae77Skettenis 
154b725ae77Skettenis enum mi_cmd_result
mi_cmd_exec_finish(char * args,int from_tty)155b725ae77Skettenis mi_cmd_exec_finish (char *args, int from_tty)
156b725ae77Skettenis {
157b725ae77Skettenis   /* FIXME: Should call a libgdb function, not a cli wrapper */
158b725ae77Skettenis   return mi_execute_async_cli_command ("finish", args, from_tty);
159b725ae77Skettenis }
160b725ae77Skettenis 
161b725ae77Skettenis enum mi_cmd_result
mi_cmd_exec_until(char * args,int from_tty)162b725ae77Skettenis mi_cmd_exec_until (char *args, int from_tty)
163b725ae77Skettenis {
164b725ae77Skettenis   /* FIXME: Should call a libgdb function, not a cli wrapper */
165b725ae77Skettenis   return mi_execute_async_cli_command ("until", args, from_tty);
166b725ae77Skettenis }
167b725ae77Skettenis 
168b725ae77Skettenis enum mi_cmd_result
mi_cmd_exec_return(char * args,int from_tty)169b725ae77Skettenis mi_cmd_exec_return (char *args, int from_tty)
170b725ae77Skettenis {
171b725ae77Skettenis   /* This command doesn't really execute the target, it just pops the
172b725ae77Skettenis      specified number of frames. */
173b725ae77Skettenis   if (*args)
174b725ae77Skettenis     /* Call return_command with from_tty argument equal to 0 so as to
175b725ae77Skettenis        avoid being queried. */
176b725ae77Skettenis     return_command (args, 0);
177b725ae77Skettenis   else
178b725ae77Skettenis     /* Call return_command with from_tty argument equal to 0 so as to
179b725ae77Skettenis        avoid being queried. */
180b725ae77Skettenis     return_command (NULL, 0);
181b725ae77Skettenis 
182b725ae77Skettenis   /* Because we have called return_command with from_tty = 0, we need
183b725ae77Skettenis      to print the frame here. */
184*11efff7fSkettenis   print_stack_frame (get_selected_frame (), 1, LOC_AND_ADDRESS);
185b725ae77Skettenis 
186b725ae77Skettenis   return MI_CMD_DONE;
187b725ae77Skettenis }
188b725ae77Skettenis 
189b725ae77Skettenis enum mi_cmd_result
mi_cmd_exec_continue(char * args,int from_tty)190b725ae77Skettenis mi_cmd_exec_continue (char *args, int from_tty)
191b725ae77Skettenis {
192b725ae77Skettenis   /* FIXME: Should call a libgdb function, not a cli wrapper */
193b725ae77Skettenis   return mi_execute_async_cli_command ("continue", args, from_tty);
194b725ae77Skettenis }
195b725ae77Skettenis 
196b725ae77Skettenis /* Interrupt the execution of the target. Note how we must play around
197b725ae77Skettenis    with the token varialbes, in order to display the current token in
198b725ae77Skettenis    the result of the interrupt command, and the previous execution
199b725ae77Skettenis    token when the target finally stops. See comments in
200b725ae77Skettenis    mi_cmd_execute. */
201b725ae77Skettenis enum mi_cmd_result
mi_cmd_exec_interrupt(char * args,int from_tty)202b725ae77Skettenis mi_cmd_exec_interrupt (char *args, int from_tty)
203b725ae77Skettenis {
204b725ae77Skettenis   if (!target_executing)
205b725ae77Skettenis     {
206*11efff7fSkettenis       mi_error_message = xstrprintf ("mi_cmd_exec_interrupt: Inferior not executing.");
207b725ae77Skettenis       return MI_CMD_ERROR;
208b725ae77Skettenis     }
209b725ae77Skettenis   interrupt_target_command (args, from_tty);
210b725ae77Skettenis   if (last_async_command)
211b725ae77Skettenis     fputs_unfiltered (last_async_command, raw_stdout);
212b725ae77Skettenis   fputs_unfiltered ("^done", raw_stdout);
213b725ae77Skettenis   xfree (last_async_command);
214b725ae77Skettenis   if (previous_async_command)
215b725ae77Skettenis     last_async_command = xstrdup (previous_async_command);
216b725ae77Skettenis   xfree (previous_async_command);
217b725ae77Skettenis   previous_async_command = NULL;
218b725ae77Skettenis   mi_out_put (uiout, raw_stdout);
219b725ae77Skettenis   mi_out_rewind (uiout);
220b725ae77Skettenis   fputs_unfiltered ("\n", raw_stdout);
221b725ae77Skettenis   return MI_CMD_QUIET;
222b725ae77Skettenis }
223b725ae77Skettenis 
224b725ae77Skettenis enum mi_cmd_result
mi_cmd_thread_select(char * command,char ** argv,int argc)225b725ae77Skettenis mi_cmd_thread_select (char *command, char **argv, int argc)
226b725ae77Skettenis {
227b725ae77Skettenis   enum gdb_rc rc;
228b725ae77Skettenis 
229b725ae77Skettenis   if (argc != 1)
230b725ae77Skettenis     {
231*11efff7fSkettenis       mi_error_message = xstrprintf ("mi_cmd_thread_select: USAGE: threadnum.");
232b725ae77Skettenis       return MI_CMD_ERROR;
233b725ae77Skettenis     }
234b725ae77Skettenis   else
235b725ae77Skettenis     rc = gdb_thread_select (uiout, argv[0]);
236b725ae77Skettenis 
237b725ae77Skettenis   /* RC is enum gdb_rc if it is successful (>=0)
238b725ae77Skettenis      enum return_reason if not (<0). */
239b725ae77Skettenis   if ((int) rc < 0 && (enum return_reason) rc == RETURN_ERROR)
240b725ae77Skettenis     return MI_CMD_CAUGHT_ERROR;
241b725ae77Skettenis   else if ((int) rc >= 0 && rc == GDB_RC_FAIL)
242b725ae77Skettenis     return MI_CMD_ERROR;
243b725ae77Skettenis   else
244b725ae77Skettenis     return MI_CMD_DONE;
245b725ae77Skettenis }
246b725ae77Skettenis 
247b725ae77Skettenis enum mi_cmd_result
mi_cmd_thread_list_ids(char * command,char ** argv,int argc)248b725ae77Skettenis mi_cmd_thread_list_ids (char *command, char **argv, int argc)
249b725ae77Skettenis {
250b725ae77Skettenis   enum gdb_rc rc = MI_CMD_DONE;
251b725ae77Skettenis 
252b725ae77Skettenis   if (argc != 0)
253b725ae77Skettenis     {
254*11efff7fSkettenis       mi_error_message = xstrprintf ("mi_cmd_thread_list_ids: No arguments required.");
255b725ae77Skettenis       return MI_CMD_ERROR;
256b725ae77Skettenis     }
257b725ae77Skettenis   else
258b725ae77Skettenis     rc = gdb_list_thread_ids (uiout);
259b725ae77Skettenis 
260b725ae77Skettenis   if (rc == GDB_RC_FAIL)
261b725ae77Skettenis     return MI_CMD_CAUGHT_ERROR;
262b725ae77Skettenis   else
263b725ae77Skettenis     return MI_CMD_DONE;
264b725ae77Skettenis }
265b725ae77Skettenis 
266b725ae77Skettenis enum mi_cmd_result
mi_cmd_data_list_register_names(char * command,char ** argv,int argc)267b725ae77Skettenis mi_cmd_data_list_register_names (char *command, char **argv, int argc)
268b725ae77Skettenis {
269b725ae77Skettenis   int regnum, numregs;
270b725ae77Skettenis   int i;
271b725ae77Skettenis   struct cleanup *cleanup;
272b725ae77Skettenis 
273b725ae77Skettenis   /* Note that the test for a valid register must include checking the
274b725ae77Skettenis      REGISTER_NAME because NUM_REGS may be allocated for the union of
275b725ae77Skettenis      the register sets within a family of related processors.  In this
276b725ae77Skettenis      case, some entries of REGISTER_NAME will change depending upon
277b725ae77Skettenis      the particular processor being debugged.  */
278b725ae77Skettenis 
279b725ae77Skettenis   numregs = NUM_REGS + NUM_PSEUDO_REGS;
280b725ae77Skettenis 
281b725ae77Skettenis   cleanup = make_cleanup_ui_out_list_begin_end (uiout, "register-names");
282b725ae77Skettenis 
283b725ae77Skettenis   if (argc == 0)		/* No args, just do all the regs */
284b725ae77Skettenis     {
285b725ae77Skettenis       for (regnum = 0;
286b725ae77Skettenis 	   regnum < numregs;
287b725ae77Skettenis 	   regnum++)
288b725ae77Skettenis 	{
289b725ae77Skettenis 	  if (REGISTER_NAME (regnum) == NULL
290b725ae77Skettenis 	      || *(REGISTER_NAME (regnum)) == '\0')
291b725ae77Skettenis 	    ui_out_field_string (uiout, NULL, "");
292b725ae77Skettenis 	  else
293b725ae77Skettenis 	    ui_out_field_string (uiout, NULL, REGISTER_NAME (regnum));
294b725ae77Skettenis 	}
295b725ae77Skettenis     }
296b725ae77Skettenis 
297b725ae77Skettenis   /* Else, list of register #s, just do listed regs */
298b725ae77Skettenis   for (i = 0; i < argc; i++)
299b725ae77Skettenis     {
300b725ae77Skettenis       regnum = atoi (argv[i]);
301b725ae77Skettenis       if (regnum < 0 || regnum >= numregs)
302b725ae77Skettenis 	{
303b725ae77Skettenis 	  do_cleanups (cleanup);
304*11efff7fSkettenis 	  mi_error_message = xstrprintf ("bad register number");
305b725ae77Skettenis 	  return MI_CMD_ERROR;
306b725ae77Skettenis 	}
307b725ae77Skettenis       if (REGISTER_NAME (regnum) == NULL
308b725ae77Skettenis 	  || *(REGISTER_NAME (regnum)) == '\0')
309b725ae77Skettenis 	ui_out_field_string (uiout, NULL, "");
310b725ae77Skettenis       else
311b725ae77Skettenis 	ui_out_field_string (uiout, NULL, REGISTER_NAME (regnum));
312b725ae77Skettenis     }
313b725ae77Skettenis   do_cleanups (cleanup);
314b725ae77Skettenis   return MI_CMD_DONE;
315b725ae77Skettenis }
316b725ae77Skettenis 
317b725ae77Skettenis enum mi_cmd_result
mi_cmd_data_list_changed_registers(char * command,char ** argv,int argc)318b725ae77Skettenis mi_cmd_data_list_changed_registers (char *command, char **argv, int argc)
319b725ae77Skettenis {
320b725ae77Skettenis   int regnum, numregs, changed;
321b725ae77Skettenis   int i;
322b725ae77Skettenis   struct cleanup *cleanup;
323b725ae77Skettenis 
324b725ae77Skettenis   /* Note that the test for a valid register must include checking the
325b725ae77Skettenis      REGISTER_NAME because NUM_REGS may be allocated for the union of
326b725ae77Skettenis      the register sets within a family of related processors.  In this
327b725ae77Skettenis      case, some entries of REGISTER_NAME will change depending upon
328b725ae77Skettenis      the particular processor being debugged.  */
329b725ae77Skettenis 
330*11efff7fSkettenis   numregs = NUM_REGS + NUM_PSEUDO_REGS;
331b725ae77Skettenis 
332b725ae77Skettenis   cleanup = make_cleanup_ui_out_list_begin_end (uiout, "changed-registers");
333b725ae77Skettenis 
334b725ae77Skettenis   if (argc == 0)		/* No args, just do all the regs */
335b725ae77Skettenis     {
336b725ae77Skettenis       for (regnum = 0;
337b725ae77Skettenis 	   regnum < numregs;
338b725ae77Skettenis 	   regnum++)
339b725ae77Skettenis 	{
340b725ae77Skettenis 	  if (REGISTER_NAME (regnum) == NULL
341b725ae77Skettenis 	      || *(REGISTER_NAME (regnum)) == '\0')
342b725ae77Skettenis 	    continue;
343b725ae77Skettenis 	  changed = register_changed_p (regnum);
344b725ae77Skettenis 	  if (changed < 0)
345b725ae77Skettenis 	    {
346b725ae77Skettenis 	      do_cleanups (cleanup);
347*11efff7fSkettenis 	      mi_error_message = xstrprintf ("mi_cmd_data_list_changed_registers: Unable to read register contents.");
348b725ae77Skettenis 	      return MI_CMD_ERROR;
349b725ae77Skettenis 	    }
350b725ae77Skettenis 	  else if (changed)
351b725ae77Skettenis 	    ui_out_field_int (uiout, NULL, regnum);
352b725ae77Skettenis 	}
353b725ae77Skettenis     }
354b725ae77Skettenis 
355b725ae77Skettenis   /* Else, list of register #s, just do listed regs */
356b725ae77Skettenis   for (i = 0; i < argc; i++)
357b725ae77Skettenis     {
358b725ae77Skettenis       regnum = atoi (argv[i]);
359b725ae77Skettenis 
360b725ae77Skettenis       if (regnum >= 0
361b725ae77Skettenis 	  && regnum < numregs
362b725ae77Skettenis 	  && REGISTER_NAME (regnum) != NULL
363b725ae77Skettenis 	  && *REGISTER_NAME (regnum) != '\000')
364b725ae77Skettenis 	{
365b725ae77Skettenis 	  changed = register_changed_p (regnum);
366b725ae77Skettenis 	  if (changed < 0)
367b725ae77Skettenis 	    {
368b725ae77Skettenis 	      do_cleanups (cleanup);
369*11efff7fSkettenis 	      mi_error_message = xstrprintf ("mi_cmd_data_list_register_change: Unable to read register contents.");
370b725ae77Skettenis 	      return MI_CMD_ERROR;
371b725ae77Skettenis 	    }
372b725ae77Skettenis 	  else if (changed)
373b725ae77Skettenis 	    ui_out_field_int (uiout, NULL, regnum);
374b725ae77Skettenis 	}
375b725ae77Skettenis       else
376b725ae77Skettenis 	{
377b725ae77Skettenis 	  do_cleanups (cleanup);
378*11efff7fSkettenis 	  mi_error_message = xstrprintf ("bad register number");
379b725ae77Skettenis 	  return MI_CMD_ERROR;
380b725ae77Skettenis 	}
381b725ae77Skettenis     }
382b725ae77Skettenis   do_cleanups (cleanup);
383b725ae77Skettenis   return MI_CMD_DONE;
384b725ae77Skettenis }
385b725ae77Skettenis 
386b725ae77Skettenis static int
register_changed_p(int regnum)387b725ae77Skettenis register_changed_p (int regnum)
388b725ae77Skettenis {
389b725ae77Skettenis   char raw_buffer[MAX_REGISTER_SIZE];
390b725ae77Skettenis 
391b725ae77Skettenis   if (! frame_register_read (deprecated_selected_frame, regnum, raw_buffer))
392b725ae77Skettenis     return -1;
393b725ae77Skettenis 
394b725ae77Skettenis   if (memcmp (&old_regs[DEPRECATED_REGISTER_BYTE (regnum)], raw_buffer,
395*11efff7fSkettenis 	      register_size (current_gdbarch, regnum)) == 0)
396b725ae77Skettenis     return 0;
397b725ae77Skettenis 
398b725ae77Skettenis   /* Found a changed register. Return 1. */
399b725ae77Skettenis 
400b725ae77Skettenis   memcpy (&old_regs[DEPRECATED_REGISTER_BYTE (regnum)], raw_buffer,
401*11efff7fSkettenis 	  register_size (current_gdbarch, regnum));
402b725ae77Skettenis 
403b725ae77Skettenis   return 1;
404b725ae77Skettenis }
405b725ae77Skettenis 
406b725ae77Skettenis /* Return a list of register number and value pairs. The valid
407b725ae77Skettenis    arguments expected are: a letter indicating the format in which to
408b725ae77Skettenis    display the registers contents. This can be one of: x (hexadecimal), d
409b725ae77Skettenis    (decimal), N (natural), t (binary), o (octal), r (raw).  After the
410b725ae77Skettenis    format argumetn there can be a sequence of numbers, indicating which
411b725ae77Skettenis    registers to fetch the content of. If the format is the only argument,
412b725ae77Skettenis    a list of all the registers with their values is returned. */
413b725ae77Skettenis enum mi_cmd_result
mi_cmd_data_list_register_values(char * command,char ** argv,int argc)414b725ae77Skettenis mi_cmd_data_list_register_values (char *command, char **argv, int argc)
415b725ae77Skettenis {
416b725ae77Skettenis   int regnum, numregs, format, result;
417b725ae77Skettenis   int i;
418b725ae77Skettenis   struct cleanup *list_cleanup, *tuple_cleanup;
419b725ae77Skettenis 
420b725ae77Skettenis   /* Note that the test for a valid register must include checking the
421b725ae77Skettenis      REGISTER_NAME because NUM_REGS may be allocated for the union of
422b725ae77Skettenis      the register sets within a family of related processors.  In this
423b725ae77Skettenis      case, some entries of REGISTER_NAME will change depending upon
424b725ae77Skettenis      the particular processor being debugged.  */
425b725ae77Skettenis 
426*11efff7fSkettenis   numregs = NUM_REGS + NUM_PSEUDO_REGS;
427b725ae77Skettenis 
428b725ae77Skettenis   if (argc == 0)
429b725ae77Skettenis     {
430*11efff7fSkettenis       mi_error_message = xstrprintf ("mi_cmd_data_list_register_values: Usage: -data-list-register-values <format> [<regnum1>...<regnumN>]");
431b725ae77Skettenis       return MI_CMD_ERROR;
432b725ae77Skettenis     }
433b725ae77Skettenis 
434b725ae77Skettenis   format = (int) argv[0][0];
435b725ae77Skettenis 
436b725ae77Skettenis   if (!target_has_registers)
437b725ae77Skettenis     {
438*11efff7fSkettenis       mi_error_message = xstrprintf ("mi_cmd_data_list_register_values: No registers.");
439b725ae77Skettenis       return MI_CMD_ERROR;
440b725ae77Skettenis     }
441b725ae77Skettenis 
442b725ae77Skettenis   list_cleanup = make_cleanup_ui_out_list_begin_end (uiout, "register-values");
443b725ae77Skettenis 
444b725ae77Skettenis   if (argc == 1)		/* No args, beside the format: do all the regs */
445b725ae77Skettenis     {
446b725ae77Skettenis       for (regnum = 0;
447b725ae77Skettenis 	   regnum < numregs;
448b725ae77Skettenis 	   regnum++)
449b725ae77Skettenis 	{
450b725ae77Skettenis 	  if (REGISTER_NAME (regnum) == NULL
451b725ae77Skettenis 	      || *(REGISTER_NAME (regnum)) == '\0')
452b725ae77Skettenis 	    continue;
453b725ae77Skettenis 	  tuple_cleanup = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
454b725ae77Skettenis 	  ui_out_field_int (uiout, "number", regnum);
455b725ae77Skettenis 	  result = get_register (regnum, format);
456b725ae77Skettenis 	  if (result == -1)
457b725ae77Skettenis 	    {
458b725ae77Skettenis 	      do_cleanups (list_cleanup);
459b725ae77Skettenis 	      return MI_CMD_ERROR;
460b725ae77Skettenis 	    }
461b725ae77Skettenis 	  do_cleanups (tuple_cleanup);
462b725ae77Skettenis 	}
463b725ae77Skettenis     }
464b725ae77Skettenis 
465b725ae77Skettenis   /* Else, list of register #s, just do listed regs */
466b725ae77Skettenis   for (i = 1; i < argc; i++)
467b725ae77Skettenis     {
468b725ae77Skettenis       regnum = atoi (argv[i]);
469b725ae77Skettenis 
470b725ae77Skettenis       if (regnum >= 0
471b725ae77Skettenis 	  && regnum < numregs
472b725ae77Skettenis 	  && REGISTER_NAME (regnum) != NULL
473b725ae77Skettenis 	  && *REGISTER_NAME (regnum) != '\000')
474b725ae77Skettenis 	{
475b725ae77Skettenis 	  tuple_cleanup = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
476b725ae77Skettenis 	  ui_out_field_int (uiout, "number", regnum);
477b725ae77Skettenis 	  result = get_register (regnum, format);
478b725ae77Skettenis 	  if (result == -1)
479b725ae77Skettenis 	    {
480b725ae77Skettenis 	      do_cleanups (list_cleanup);
481b725ae77Skettenis 	      return MI_CMD_ERROR;
482b725ae77Skettenis 	    }
483b725ae77Skettenis 	  do_cleanups (tuple_cleanup);
484b725ae77Skettenis 	}
485b725ae77Skettenis       else
486b725ae77Skettenis 	{
487b725ae77Skettenis 	  do_cleanups (list_cleanup);
488*11efff7fSkettenis 	  mi_error_message = xstrprintf ("bad register number");
489b725ae77Skettenis 	  return MI_CMD_ERROR;
490b725ae77Skettenis 	}
491b725ae77Skettenis     }
492b725ae77Skettenis   do_cleanups (list_cleanup);
493b725ae77Skettenis   return MI_CMD_DONE;
494b725ae77Skettenis }
495b725ae77Skettenis 
496b725ae77Skettenis /* Output one register's contents in the desired format. */
497b725ae77Skettenis static int
get_register(int regnum,int format)498b725ae77Skettenis get_register (int regnum, int format)
499b725ae77Skettenis {
500*11efff7fSkettenis   char buffer[MAX_REGISTER_SIZE];
501b725ae77Skettenis   int optim;
502b725ae77Skettenis   int realnum;
503b725ae77Skettenis   CORE_ADDR addr;
504b725ae77Skettenis   enum lval_type lval;
505b725ae77Skettenis   static struct ui_stream *stb = NULL;
506b725ae77Skettenis 
507b725ae77Skettenis   stb = ui_out_stream_new (uiout);
508b725ae77Skettenis 
509b725ae77Skettenis   if (format == 'N')
510b725ae77Skettenis     format = 0;
511b725ae77Skettenis 
512b725ae77Skettenis   frame_register (deprecated_selected_frame, regnum, &optim, &lval, &addr,
513*11efff7fSkettenis 		  &realnum, buffer);
514b725ae77Skettenis 
515b725ae77Skettenis   if (optim)
516b725ae77Skettenis     {
517*11efff7fSkettenis       mi_error_message = xstrprintf ("Optimized out");
518b725ae77Skettenis       return -1;
519b725ae77Skettenis     }
520b725ae77Skettenis 
521b725ae77Skettenis   if (format == 'r')
522b725ae77Skettenis     {
523b725ae77Skettenis       int j;
524b725ae77Skettenis       char *ptr, buf[1024];
525b725ae77Skettenis 
526b725ae77Skettenis       strcpy (buf, "0x");
527b725ae77Skettenis       ptr = buf + 2;
528*11efff7fSkettenis       for (j = 0; j < register_size (current_gdbarch, regnum); j++)
529b725ae77Skettenis 	{
530b725ae77Skettenis 	  int idx = TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? j
531*11efff7fSkettenis 	  : register_size (current_gdbarch, regnum) - 1 - j;
532*11efff7fSkettenis 	  sprintf (ptr, "%02x", (unsigned char) buffer[idx]);
533b725ae77Skettenis 	  ptr += 2;
534b725ae77Skettenis 	}
535b725ae77Skettenis       ui_out_field_string (uiout, "value", buf);
536b725ae77Skettenis       /*fputs_filtered (buf, gdb_stdout); */
537b725ae77Skettenis     }
538b725ae77Skettenis   else
539b725ae77Skettenis     {
540*11efff7fSkettenis       val_print (register_type (current_gdbarch, regnum), buffer, 0, 0,
541b725ae77Skettenis 		 stb->stream, format, 1, 0, Val_pretty_default);
542b725ae77Skettenis       ui_out_field_stream (uiout, "value", stb);
543b725ae77Skettenis       ui_out_stream_delete (stb);
544b725ae77Skettenis     }
545b725ae77Skettenis   return 1;
546b725ae77Skettenis }
547b725ae77Skettenis 
548b725ae77Skettenis /* Write given values into registers. The registers and values are
549b725ae77Skettenis    given as pairs. The corresponding MI command is
550b725ae77Skettenis    -data-write-register-values <format> [<regnum1> <value1>...<regnumN> <valueN>]*/
551b725ae77Skettenis enum mi_cmd_result
mi_cmd_data_write_register_values(char * command,char ** argv,int argc)552b725ae77Skettenis mi_cmd_data_write_register_values (char *command, char **argv, int argc)
553b725ae77Skettenis {
554b725ae77Skettenis   int regnum;
555b725ae77Skettenis   int i;
556b725ae77Skettenis   int numregs;
557b725ae77Skettenis   LONGEST value;
558b725ae77Skettenis   char format;
559b725ae77Skettenis 
560b725ae77Skettenis   /* Note that the test for a valid register must include checking the
561b725ae77Skettenis      REGISTER_NAME because NUM_REGS may be allocated for the union of
562b725ae77Skettenis      the register sets within a family of related processors.  In this
563b725ae77Skettenis      case, some entries of REGISTER_NAME will change depending upon
564b725ae77Skettenis      the particular processor being debugged.  */
565b725ae77Skettenis 
566*11efff7fSkettenis   numregs = NUM_REGS + NUM_PSEUDO_REGS;
567b725ae77Skettenis 
568b725ae77Skettenis   if (argc == 0)
569b725ae77Skettenis     {
570*11efff7fSkettenis       mi_error_message = xstrprintf ("mi_cmd_data_write_register_values: Usage: -data-write-register-values <format> [<regnum1> <value1>...<regnumN> <valueN>]");
571b725ae77Skettenis       return MI_CMD_ERROR;
572b725ae77Skettenis     }
573b725ae77Skettenis 
574b725ae77Skettenis   format = (int) argv[0][0];
575b725ae77Skettenis 
576b725ae77Skettenis   if (!target_has_registers)
577b725ae77Skettenis     {
578*11efff7fSkettenis       mi_error_message = xstrprintf ("mi_cmd_data_write_register_values: No registers.");
579b725ae77Skettenis       return MI_CMD_ERROR;
580b725ae77Skettenis     }
581b725ae77Skettenis 
582b725ae77Skettenis   if (!(argc - 1))
583b725ae77Skettenis     {
584*11efff7fSkettenis       mi_error_message = xstrprintf ("mi_cmd_data_write_register_values: No regs and values specified.");
585b725ae77Skettenis       return MI_CMD_ERROR;
586b725ae77Skettenis     }
587b725ae77Skettenis 
588b725ae77Skettenis   if ((argc - 1) % 2)
589b725ae77Skettenis     {
590*11efff7fSkettenis       mi_error_message = xstrprintf ("mi_cmd_data_write_register_values: Regs and vals are not in pairs.");
591b725ae77Skettenis       return MI_CMD_ERROR;
592b725ae77Skettenis     }
593b725ae77Skettenis 
594b725ae77Skettenis   for (i = 1; i < argc; i = i + 2)
595b725ae77Skettenis     {
596b725ae77Skettenis       regnum = atoi (argv[i]);
597b725ae77Skettenis 
598b725ae77Skettenis       if (regnum >= 0
599b725ae77Skettenis 	  && regnum < numregs
600b725ae77Skettenis 	  && REGISTER_NAME (regnum) != NULL
601b725ae77Skettenis 	  && *REGISTER_NAME (regnum) != '\000')
602b725ae77Skettenis 	{
603b725ae77Skettenis 	  void *buffer;
604b725ae77Skettenis 	  struct cleanup *old_chain;
605b725ae77Skettenis 
606b725ae77Skettenis 	  /* Get the value as a number */
607b725ae77Skettenis 	  value = parse_and_eval_address (argv[i + 1]);
608b725ae77Skettenis 	  /* Get the value into an array */
609b725ae77Skettenis 	  buffer = xmalloc (DEPRECATED_REGISTER_SIZE);
610b725ae77Skettenis 	  old_chain = make_cleanup (xfree, buffer);
611b725ae77Skettenis 	  store_signed_integer (buffer, DEPRECATED_REGISTER_SIZE, value);
612b725ae77Skettenis 	  /* Write it down */
613*11efff7fSkettenis 	  deprecated_write_register_bytes (DEPRECATED_REGISTER_BYTE (regnum), buffer, register_size (current_gdbarch, regnum));
614b725ae77Skettenis 	  /* Free the buffer.  */
615b725ae77Skettenis 	  do_cleanups (old_chain);
616b725ae77Skettenis 	}
617b725ae77Skettenis       else
618b725ae77Skettenis 	{
619*11efff7fSkettenis 	  mi_error_message = xstrprintf ("bad register number");
620b725ae77Skettenis 	  return MI_CMD_ERROR;
621b725ae77Skettenis 	}
622b725ae77Skettenis     }
623b725ae77Skettenis   return MI_CMD_DONE;
624b725ae77Skettenis }
625b725ae77Skettenis 
626b725ae77Skettenis #if 0
627b725ae77Skettenis /*This is commented out because we decided it was not useful. I leave
628b725ae77Skettenis    it, just in case. ezannoni:1999-12-08 */
629b725ae77Skettenis 
630b725ae77Skettenis /* Assign a value to a variable. The expression argument must be in
631b725ae77Skettenis    the form A=2 or "A = 2" (I.e. if there are spaces it needs to be
632b725ae77Skettenis    quoted. */
633b725ae77Skettenis enum mi_cmd_result
634b725ae77Skettenis mi_cmd_data_assign (char *command, char **argv, int argc)
635b725ae77Skettenis {
636b725ae77Skettenis   struct expression *expr;
637b725ae77Skettenis   struct cleanup *old_chain;
638b725ae77Skettenis 
639b725ae77Skettenis   if (argc != 1)
640b725ae77Skettenis     {
641*11efff7fSkettenis       mi_error_message = xstrprintf ("mi_cmd_data_assign: Usage: -data-assign expression");
642b725ae77Skettenis       return MI_CMD_ERROR;
643b725ae77Skettenis     }
644b725ae77Skettenis 
645b725ae77Skettenis   /* NOTE what follows is a clone of set_command(). FIXME: ezannoni
646b725ae77Skettenis      01-12-1999: Need to decide what to do with this for libgdb purposes. */
647b725ae77Skettenis 
648b725ae77Skettenis   expr = parse_expression (argv[0]);
649b725ae77Skettenis   old_chain = make_cleanup (free_current_contents, &expr);
650b725ae77Skettenis   evaluate_expression (expr);
651b725ae77Skettenis   do_cleanups (old_chain);
652b725ae77Skettenis   return MI_CMD_DONE;
653b725ae77Skettenis }
654b725ae77Skettenis #endif
655b725ae77Skettenis 
656b725ae77Skettenis /* Evaluate the value of the argument. The argument is an
657b725ae77Skettenis    expression. If the expression contains spaces it needs to be
658b725ae77Skettenis    included in double quotes. */
659b725ae77Skettenis enum mi_cmd_result
mi_cmd_data_evaluate_expression(char * command,char ** argv,int argc)660b725ae77Skettenis mi_cmd_data_evaluate_expression (char *command, char **argv, int argc)
661b725ae77Skettenis {
662b725ae77Skettenis   struct expression *expr;
663b725ae77Skettenis   struct cleanup *old_chain = NULL;
664b725ae77Skettenis   struct value *val;
665b725ae77Skettenis   struct ui_stream *stb = NULL;
666b725ae77Skettenis 
667b725ae77Skettenis   stb = ui_out_stream_new (uiout);
668b725ae77Skettenis 
669b725ae77Skettenis   if (argc != 1)
670b725ae77Skettenis     {
671*11efff7fSkettenis       mi_error_message = xstrprintf ("mi_cmd_data_evaluate_expression: Usage: -data-evaluate-expression expression");
672b725ae77Skettenis       return MI_CMD_ERROR;
673b725ae77Skettenis     }
674b725ae77Skettenis 
675b725ae77Skettenis   expr = parse_expression (argv[0]);
676b725ae77Skettenis 
677b725ae77Skettenis   old_chain = make_cleanup (free_current_contents, &expr);
678b725ae77Skettenis 
679b725ae77Skettenis   val = evaluate_expression (expr);
680b725ae77Skettenis 
681b725ae77Skettenis   /* Print the result of the expression evaluation. */
682b725ae77Skettenis   val_print (VALUE_TYPE (val), VALUE_CONTENTS (val),
683b725ae77Skettenis 	     VALUE_EMBEDDED_OFFSET (val), VALUE_ADDRESS (val),
684b725ae77Skettenis 	     stb->stream, 0, 0, 0, 0);
685b725ae77Skettenis 
686b725ae77Skettenis   ui_out_field_stream (uiout, "value", stb);
687b725ae77Skettenis   ui_out_stream_delete (stb);
688b725ae77Skettenis 
689b725ae77Skettenis   do_cleanups (old_chain);
690b725ae77Skettenis 
691b725ae77Skettenis   return MI_CMD_DONE;
692b725ae77Skettenis }
693b725ae77Skettenis 
694b725ae77Skettenis enum mi_cmd_result
mi_cmd_target_download(char * args,int from_tty)695b725ae77Skettenis mi_cmd_target_download (char *args, int from_tty)
696b725ae77Skettenis {
697b725ae77Skettenis   char *run;
698b725ae77Skettenis   struct cleanup *old_cleanups = NULL;
699b725ae77Skettenis 
700*11efff7fSkettenis   run = xstrprintf ("load %s", args);
701b725ae77Skettenis   old_cleanups = make_cleanup (xfree, run);
702b725ae77Skettenis   execute_command (run, from_tty);
703b725ae77Skettenis 
704b725ae77Skettenis   do_cleanups (old_cleanups);
705b725ae77Skettenis   return MI_CMD_DONE;
706b725ae77Skettenis }
707b725ae77Skettenis 
708b725ae77Skettenis /* Connect to the remote target. */
709b725ae77Skettenis enum mi_cmd_result
mi_cmd_target_select(char * args,int from_tty)710b725ae77Skettenis mi_cmd_target_select (char *args, int from_tty)
711b725ae77Skettenis {
712b725ae77Skettenis   char *run;
713b725ae77Skettenis   struct cleanup *old_cleanups = NULL;
714b725ae77Skettenis 
715*11efff7fSkettenis   run = xstrprintf ("target %s", args);
716b725ae77Skettenis   old_cleanups = make_cleanup (xfree, run);
717b725ae77Skettenis 
718b725ae77Skettenis   /* target-select is always synchronous.  once the call has returned
719b725ae77Skettenis      we know that we are connected. */
720b725ae77Skettenis   /* NOTE: At present all targets that are connected are also
721b725ae77Skettenis      (implicitly) talking to a halted target.  In the future this may
722b725ae77Skettenis      change. */
723b725ae77Skettenis   execute_command (run, from_tty);
724b725ae77Skettenis 
725b725ae77Skettenis   do_cleanups (old_cleanups);
726b725ae77Skettenis 
727b725ae77Skettenis   /* Issue the completion message here. */
728b725ae77Skettenis   if (last_async_command)
729b725ae77Skettenis     fputs_unfiltered (last_async_command, raw_stdout);
730b725ae77Skettenis   fputs_unfiltered ("^connected", raw_stdout);
731b725ae77Skettenis   mi_out_put (uiout, raw_stdout);
732b725ae77Skettenis   mi_out_rewind (uiout);
733b725ae77Skettenis   fputs_unfiltered ("\n", raw_stdout);
734b725ae77Skettenis   do_exec_cleanups (ALL_CLEANUPS);
735b725ae77Skettenis   return MI_CMD_QUIET;
736b725ae77Skettenis }
737b725ae77Skettenis 
738b725ae77Skettenis /* DATA-MEMORY-READ:
739b725ae77Skettenis 
740b725ae77Skettenis    ADDR: start address of data to be dumped.
741b725ae77Skettenis    WORD-FORMAT: a char indicating format for the ``word''. See
742b725ae77Skettenis    the ``x'' command.
743b725ae77Skettenis    WORD-SIZE: size of each ``word''; 1,2,4, or 8 bytes
744b725ae77Skettenis    NR_ROW: Number of rows.
745b725ae77Skettenis    NR_COL: The number of colums (words per row).
746b725ae77Skettenis    ASCHAR: (OPTIONAL) Append an ascii character dump to each row.  Use
747b725ae77Skettenis    ASCHAR for unprintable characters.
748b725ae77Skettenis 
749b725ae77Skettenis    Reads SIZE*NR_ROW*NR_COL bytes starting at ADDR from memory and
750b725ae77Skettenis    displayes them.  Returns:
751b725ae77Skettenis 
752b725ae77Skettenis    {addr="...",rowN={wordN="..." ,... [,ascii="..."]}, ...}
753b725ae77Skettenis 
754b725ae77Skettenis    Returns:
755b725ae77Skettenis    The number of bytes read is SIZE*ROW*COL. */
756b725ae77Skettenis 
757b725ae77Skettenis enum mi_cmd_result
mi_cmd_data_read_memory(char * command,char ** argv,int argc)758b725ae77Skettenis mi_cmd_data_read_memory (char *command, char **argv, int argc)
759b725ae77Skettenis {
760b725ae77Skettenis   struct cleanup *cleanups = make_cleanup (null_cleanup, NULL);
761b725ae77Skettenis   CORE_ADDR addr;
762b725ae77Skettenis   long total_bytes;
763b725ae77Skettenis   long nr_cols;
764b725ae77Skettenis   long nr_rows;
765b725ae77Skettenis   char word_format;
766b725ae77Skettenis   struct type *word_type;
767b725ae77Skettenis   long word_size;
768b725ae77Skettenis   char word_asize;
769b725ae77Skettenis   char aschar;
770b725ae77Skettenis   char *mbuf;
771b725ae77Skettenis   int nr_bytes;
772b725ae77Skettenis   long offset = 0;
773b725ae77Skettenis   int optind = 0;
774b725ae77Skettenis   char *optarg;
775b725ae77Skettenis   enum opt
776b725ae77Skettenis     {
777b725ae77Skettenis       OFFSET_OPT
778b725ae77Skettenis     };
779b725ae77Skettenis   static struct mi_opt opts[] =
780b725ae77Skettenis   {
781b725ae77Skettenis     {"o", OFFSET_OPT, 1},
782b725ae77Skettenis     0
783b725ae77Skettenis   };
784b725ae77Skettenis 
785b725ae77Skettenis   while (1)
786b725ae77Skettenis     {
787b725ae77Skettenis       int opt = mi_getopt ("mi_cmd_data_read_memory", argc, argv, opts,
788b725ae77Skettenis 			   &optind, &optarg);
789b725ae77Skettenis       if (opt < 0)
790b725ae77Skettenis 	break;
791b725ae77Skettenis       switch ((enum opt) opt)
792b725ae77Skettenis 	{
793b725ae77Skettenis 	case OFFSET_OPT:
794b725ae77Skettenis 	  offset = atol (optarg);
795b725ae77Skettenis 	  break;
796b725ae77Skettenis 	}
797b725ae77Skettenis     }
798b725ae77Skettenis   argv += optind;
799b725ae77Skettenis   argc -= optind;
800b725ae77Skettenis 
801b725ae77Skettenis   if (argc < 5 || argc > 6)
802b725ae77Skettenis     {
803*11efff7fSkettenis       mi_error_message = xstrprintf ("mi_cmd_data_read_memory: Usage: ADDR WORD-FORMAT WORD-SIZE NR-ROWS NR-COLS [ASCHAR].");
804b725ae77Skettenis       return MI_CMD_ERROR;
805b725ae77Skettenis     }
806b725ae77Skettenis 
807b725ae77Skettenis   /* Extract all the arguments. */
808b725ae77Skettenis 
809b725ae77Skettenis   /* Start address of the memory dump. */
810b725ae77Skettenis   addr = parse_and_eval_address (argv[0]) + offset;
811b725ae77Skettenis   /* The format character to use when displaying a memory word. See
812b725ae77Skettenis      the ``x'' command. */
813b725ae77Skettenis   word_format = argv[1][0];
814b725ae77Skettenis   /* The size of the memory word. */
815b725ae77Skettenis   word_size = atol (argv[2]);
816b725ae77Skettenis   switch (word_size)
817b725ae77Skettenis     {
818b725ae77Skettenis     case 1:
819b725ae77Skettenis       word_type = builtin_type_int8;
820b725ae77Skettenis       word_asize = 'b';
821b725ae77Skettenis       break;
822b725ae77Skettenis     case 2:
823b725ae77Skettenis       word_type = builtin_type_int16;
824b725ae77Skettenis       word_asize = 'h';
825b725ae77Skettenis       break;
826b725ae77Skettenis     case 4:
827b725ae77Skettenis       word_type = builtin_type_int32;
828b725ae77Skettenis       word_asize = 'w';
829b725ae77Skettenis       break;
830b725ae77Skettenis     case 8:
831b725ae77Skettenis       word_type = builtin_type_int64;
832b725ae77Skettenis       word_asize = 'g';
833b725ae77Skettenis       break;
834b725ae77Skettenis     default:
835b725ae77Skettenis       word_type = builtin_type_int8;
836b725ae77Skettenis       word_asize = 'b';
837b725ae77Skettenis     }
838b725ae77Skettenis   /* The number of rows */
839b725ae77Skettenis   nr_rows = atol (argv[3]);
840b725ae77Skettenis   if (nr_rows <= 0)
841b725ae77Skettenis     {
842*11efff7fSkettenis       mi_error_message = xstrprintf ("mi_cmd_data_read_memory: invalid number of rows.");
843b725ae77Skettenis       return MI_CMD_ERROR;
844b725ae77Skettenis     }
845b725ae77Skettenis   /* number of bytes per row. */
846b725ae77Skettenis   nr_cols = atol (argv[4]);
847b725ae77Skettenis   if (nr_cols <= 0)
848b725ae77Skettenis     {
849*11efff7fSkettenis       mi_error_message = xstrprintf ("mi_cmd_data_read_memory: invalid number of columns.");
850*11efff7fSkettenis       return MI_CMD_ERROR;
851b725ae77Skettenis     }
852b725ae77Skettenis   /* The un-printable character when printing ascii. */
853b725ae77Skettenis   if (argc == 6)
854b725ae77Skettenis     aschar = *argv[5];
855b725ae77Skettenis   else
856b725ae77Skettenis     aschar = 0;
857b725ae77Skettenis 
858b725ae77Skettenis   /* create a buffer and read it in. */
859b725ae77Skettenis   total_bytes = word_size * nr_rows * nr_cols;
860b725ae77Skettenis   mbuf = xcalloc (total_bytes, 1);
861b725ae77Skettenis   make_cleanup (xfree, mbuf);
862b725ae77Skettenis   nr_bytes = 0;
863b725ae77Skettenis   while (nr_bytes < total_bytes)
864b725ae77Skettenis     {
865b725ae77Skettenis       int error;
866b725ae77Skettenis       long num = target_read_memory_partial (addr + nr_bytes, mbuf + nr_bytes,
867b725ae77Skettenis 					     total_bytes - nr_bytes,
868b725ae77Skettenis 					     &error);
869b725ae77Skettenis       if (num <= 0)
870b725ae77Skettenis 	break;
871b725ae77Skettenis       nr_bytes += num;
872b725ae77Skettenis     }
873b725ae77Skettenis 
874b725ae77Skettenis   /* output the header information. */
875b725ae77Skettenis   ui_out_field_core_addr (uiout, "addr", addr);
876b725ae77Skettenis   ui_out_field_int (uiout, "nr-bytes", nr_bytes);
877b725ae77Skettenis   ui_out_field_int (uiout, "total-bytes", total_bytes);
878b725ae77Skettenis   ui_out_field_core_addr (uiout, "next-row", addr + word_size * nr_cols);
879b725ae77Skettenis   ui_out_field_core_addr (uiout, "prev-row", addr - word_size * nr_cols);
880b725ae77Skettenis   ui_out_field_core_addr (uiout, "next-page", addr + total_bytes);
881b725ae77Skettenis   ui_out_field_core_addr (uiout, "prev-page", addr - total_bytes);
882b725ae77Skettenis 
883b725ae77Skettenis   /* Build the result as a two dimentional table. */
884b725ae77Skettenis   {
885b725ae77Skettenis     struct ui_stream *stream = ui_out_stream_new (uiout);
886b725ae77Skettenis     struct cleanup *cleanup_list_memory;
887b725ae77Skettenis     int row;
888b725ae77Skettenis     int row_byte;
889b725ae77Skettenis     cleanup_list_memory = make_cleanup_ui_out_list_begin_end (uiout, "memory");
890b725ae77Skettenis     for (row = 0, row_byte = 0;
891b725ae77Skettenis 	 row < nr_rows;
892b725ae77Skettenis 	 row++, row_byte += nr_cols * word_size)
893b725ae77Skettenis       {
894b725ae77Skettenis 	int col;
895b725ae77Skettenis 	int col_byte;
896b725ae77Skettenis 	struct cleanup *cleanup_tuple;
897b725ae77Skettenis 	struct cleanup *cleanup_list_data;
898b725ae77Skettenis 	cleanup_tuple = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
899b725ae77Skettenis 	ui_out_field_core_addr (uiout, "addr", addr + row_byte);
900b725ae77Skettenis 	/* ui_out_field_core_addr_symbolic (uiout, "saddr", addr + row_byte); */
901b725ae77Skettenis 	cleanup_list_data = make_cleanup_ui_out_list_begin_end (uiout, "data");
902b725ae77Skettenis 	for (col = 0, col_byte = row_byte;
903b725ae77Skettenis 	     col < nr_cols;
904b725ae77Skettenis 	     col++, col_byte += word_size)
905b725ae77Skettenis 	  {
906b725ae77Skettenis 	    if (col_byte + word_size > nr_bytes)
907b725ae77Skettenis 	      {
908b725ae77Skettenis 		ui_out_field_string (uiout, NULL, "N/A");
909b725ae77Skettenis 	      }
910b725ae77Skettenis 	    else
911b725ae77Skettenis 	      {
912b725ae77Skettenis 		ui_file_rewind (stream->stream);
913b725ae77Skettenis 		print_scalar_formatted (mbuf + col_byte, word_type, word_format,
914b725ae77Skettenis 					word_asize, stream->stream);
915b725ae77Skettenis 		ui_out_field_stream (uiout, NULL, stream);
916b725ae77Skettenis 	      }
917b725ae77Skettenis 	  }
918b725ae77Skettenis 	do_cleanups (cleanup_list_data);
919b725ae77Skettenis 	if (aschar)
920b725ae77Skettenis 	  {
921b725ae77Skettenis 	    int byte;
922b725ae77Skettenis 	    ui_file_rewind (stream->stream);
923b725ae77Skettenis 	    for (byte = row_byte; byte < row_byte + word_size * nr_cols; byte++)
924b725ae77Skettenis 	      {
925b725ae77Skettenis 		if (byte >= nr_bytes)
926b725ae77Skettenis 		  {
927b725ae77Skettenis 		    fputc_unfiltered ('X', stream->stream);
928b725ae77Skettenis 		  }
929b725ae77Skettenis 		else if (mbuf[byte] < 32 || mbuf[byte] > 126)
930b725ae77Skettenis 		  {
931b725ae77Skettenis 		    fputc_unfiltered (aschar, stream->stream);
932b725ae77Skettenis 		  }
933b725ae77Skettenis 		else
934b725ae77Skettenis 		  fputc_unfiltered (mbuf[byte], stream->stream);
935b725ae77Skettenis 	      }
936b725ae77Skettenis 	    ui_out_field_stream (uiout, "ascii", stream);
937b725ae77Skettenis 	  }
938b725ae77Skettenis 	do_cleanups (cleanup_tuple);
939b725ae77Skettenis       }
940b725ae77Skettenis     ui_out_stream_delete (stream);
941b725ae77Skettenis     do_cleanups (cleanup_list_memory);
942b725ae77Skettenis   }
943b725ae77Skettenis   do_cleanups (cleanups);
944b725ae77Skettenis   return MI_CMD_DONE;
945b725ae77Skettenis }
946b725ae77Skettenis 
947b725ae77Skettenis /* DATA-MEMORY-WRITE:
948b725ae77Skettenis 
949b725ae77Skettenis    COLUMN_OFFSET: optional argument. Must be preceeded by '-o'. The
950b725ae77Skettenis    offset from the beginning of the memory grid row where the cell to
951b725ae77Skettenis    be written is.
952b725ae77Skettenis    ADDR: start address of the row in the memory grid where the memory
953b725ae77Skettenis    cell is, if OFFSET_COLUMN is specified. Otherwise, the address of
954b725ae77Skettenis    the location to write to.
955b725ae77Skettenis    FORMAT: a char indicating format for the ``word''. See
956b725ae77Skettenis    the ``x'' command.
957b725ae77Skettenis    WORD_SIZE: size of each ``word''; 1,2,4, or 8 bytes
958b725ae77Skettenis    VALUE: value to be written into the memory address.
959b725ae77Skettenis 
960b725ae77Skettenis    Writes VALUE into ADDR + (COLUMN_OFFSET * WORD_SIZE).
961b725ae77Skettenis 
962b725ae77Skettenis    Prints nothing. */
963b725ae77Skettenis enum mi_cmd_result
mi_cmd_data_write_memory(char * command,char ** argv,int argc)964b725ae77Skettenis mi_cmd_data_write_memory (char *command, char **argv, int argc)
965b725ae77Skettenis {
966b725ae77Skettenis   CORE_ADDR addr;
967b725ae77Skettenis   char word_format;
968b725ae77Skettenis   long word_size;
969b725ae77Skettenis   /* FIXME: ezannoni 2000-02-17 LONGEST could possibly not be big
970b725ae77Skettenis      enough when using a compiler other than GCC. */
971b725ae77Skettenis   LONGEST value;
972b725ae77Skettenis   void *buffer;
973b725ae77Skettenis   struct cleanup *old_chain;
974b725ae77Skettenis   long offset = 0;
975b725ae77Skettenis   int optind = 0;
976b725ae77Skettenis   char *optarg;
977b725ae77Skettenis   enum opt
978b725ae77Skettenis     {
979b725ae77Skettenis       OFFSET_OPT
980b725ae77Skettenis     };
981b725ae77Skettenis   static struct mi_opt opts[] =
982b725ae77Skettenis   {
983b725ae77Skettenis     {"o", OFFSET_OPT, 1},
984b725ae77Skettenis     0
985b725ae77Skettenis   };
986b725ae77Skettenis 
987b725ae77Skettenis   while (1)
988b725ae77Skettenis     {
989b725ae77Skettenis       int opt = mi_getopt ("mi_cmd_data_write_memory", argc, argv, opts,
990b725ae77Skettenis 			   &optind, &optarg);
991b725ae77Skettenis       if (opt < 0)
992b725ae77Skettenis 	break;
993b725ae77Skettenis       switch ((enum opt) opt)
994b725ae77Skettenis 	{
995b725ae77Skettenis 	case OFFSET_OPT:
996b725ae77Skettenis 	  offset = atol (optarg);
997b725ae77Skettenis 	  break;
998b725ae77Skettenis 	}
999b725ae77Skettenis     }
1000b725ae77Skettenis   argv += optind;
1001b725ae77Skettenis   argc -= optind;
1002b725ae77Skettenis 
1003b725ae77Skettenis   if (argc != 4)
1004b725ae77Skettenis     {
1005*11efff7fSkettenis       mi_error_message = xstrprintf ("mi_cmd_data_write_memory: Usage: [-o COLUMN_OFFSET] ADDR FORMAT WORD-SIZE VALUE.");
1006b725ae77Skettenis       return MI_CMD_ERROR;
1007b725ae77Skettenis     }
1008b725ae77Skettenis 
1009b725ae77Skettenis   /* Extract all the arguments. */
1010b725ae77Skettenis   /* Start address of the memory dump. */
1011b725ae77Skettenis   addr = parse_and_eval_address (argv[0]);
1012b725ae77Skettenis   /* The format character to use when displaying a memory word. See
1013b725ae77Skettenis      the ``x'' command. */
1014b725ae77Skettenis   word_format = argv[1][0];
1015b725ae77Skettenis   /* The size of the memory word. */
1016b725ae77Skettenis   word_size = atol (argv[2]);
1017b725ae77Skettenis 
1018b725ae77Skettenis   /* Calculate the real address of the write destination. */
1019b725ae77Skettenis   addr += (offset * word_size);
1020b725ae77Skettenis 
1021b725ae77Skettenis   /* Get the value as a number */
1022b725ae77Skettenis   value = parse_and_eval_address (argv[3]);
1023b725ae77Skettenis   /* Get the value into an array */
1024b725ae77Skettenis   buffer = xmalloc (word_size);
1025b725ae77Skettenis   old_chain = make_cleanup (xfree, buffer);
1026b725ae77Skettenis   store_signed_integer (buffer, word_size, value);
1027b725ae77Skettenis   /* Write it down to memory */
1028b725ae77Skettenis   write_memory (addr, buffer, word_size);
1029b725ae77Skettenis   /* Free the buffer.  */
1030b725ae77Skettenis   do_cleanups (old_chain);
1031b725ae77Skettenis 
1032b725ae77Skettenis   return MI_CMD_DONE;
1033b725ae77Skettenis }
1034b725ae77Skettenis 
1035b725ae77Skettenis /* Execute a command within a safe environment.
1036b725ae77Skettenis    Return <0 for error; >=0 for ok.
1037b725ae77Skettenis 
1038b725ae77Skettenis    args->action will tell mi_execute_command what action
1039b725ae77Skettenis    to perfrom after the given command has executed (display/supress
1040b725ae77Skettenis    prompt, display error). */
1041b725ae77Skettenis 
1042b725ae77Skettenis static int
captured_mi_execute_command(struct ui_out * uiout,void * data)1043b725ae77Skettenis captured_mi_execute_command (struct ui_out *uiout, void *data)
1044b725ae77Skettenis {
1045b725ae77Skettenis   struct captured_mi_execute_command_args *args =
1046b725ae77Skettenis     (struct captured_mi_execute_command_args *) data;
1047b725ae77Skettenis   struct mi_parse *context = args->command;
1048b725ae77Skettenis 
1049b725ae77Skettenis   switch (context->op)
1050b725ae77Skettenis     {
1051b725ae77Skettenis 
1052b725ae77Skettenis     case MI_COMMAND:
1053b725ae77Skettenis       /* A MI command was read from the input stream */
1054b725ae77Skettenis       if (mi_debug_p)
1055b725ae77Skettenis 	/* FIXME: gdb_???? */
1056b725ae77Skettenis 	fprintf_unfiltered (raw_stdout, " token=`%s' command=`%s' args=`%s'\n",
1057b725ae77Skettenis 			    context->token, context->command, context->args);
1058b725ae77Skettenis       /* FIXME: cagney/1999-09-25: Rather than this convoluted
1059b725ae77Skettenis          condition expression, each function should return an
1060b725ae77Skettenis          indication of what action is required and then switch on
1061b725ae77Skettenis          that. */
1062b725ae77Skettenis       args->action = EXECUTE_COMMAND_DISPLAY_PROMPT;
1063b725ae77Skettenis       args->rc = mi_cmd_execute (context);
1064b725ae77Skettenis 
1065b725ae77Skettenis       if (!target_can_async_p () || !target_executing)
1066b725ae77Skettenis 	{
1067b725ae77Skettenis 	  /* print the result if there were no errors
1068b725ae77Skettenis 
1069b725ae77Skettenis 	     Remember that on the way out of executing a command, you have
1070b725ae77Skettenis 	     to directly use the mi_interp's uiout, since the command could
1071b725ae77Skettenis 	     have reset the interpreter, in which case the current uiout
1072b725ae77Skettenis 	     will most likely crash in the mi_out_* routines.  */
1073b725ae77Skettenis 	  if (args->rc == MI_CMD_DONE)
1074b725ae77Skettenis 	    {
1075b725ae77Skettenis 	      fputs_unfiltered (context->token, raw_stdout);
1076b725ae77Skettenis 	      fputs_unfiltered ("^done", raw_stdout);
1077b725ae77Skettenis 	      mi_out_put (uiout, raw_stdout);
1078b725ae77Skettenis 	      mi_out_rewind (uiout);
1079b725ae77Skettenis 	      fputs_unfiltered ("\n", raw_stdout);
1080b725ae77Skettenis 	    }
1081b725ae77Skettenis 	  else if (args->rc == MI_CMD_ERROR)
1082b725ae77Skettenis 	    {
1083b725ae77Skettenis 	      if (mi_error_message)
1084b725ae77Skettenis 		{
1085b725ae77Skettenis 		  fputs_unfiltered (context->token, raw_stdout);
1086b725ae77Skettenis 		  fputs_unfiltered ("^error,msg=\"", raw_stdout);
1087b725ae77Skettenis 		  fputstr_unfiltered (mi_error_message, '"', raw_stdout);
1088b725ae77Skettenis 		  xfree (mi_error_message);
1089b725ae77Skettenis 		  fputs_unfiltered ("\"\n", raw_stdout);
1090b725ae77Skettenis 		}
1091b725ae77Skettenis 	      mi_out_rewind (uiout);
1092b725ae77Skettenis 	    }
1093b725ae77Skettenis 	  else if (args->rc == MI_CMD_CAUGHT_ERROR)
1094b725ae77Skettenis 	    {
1095b725ae77Skettenis 	      mi_out_rewind (uiout);
1096b725ae77Skettenis 	      args->action = EXECUTE_COMMAND_DISPLAY_ERROR;
1097b725ae77Skettenis 	      return 1;
1098b725ae77Skettenis 	    }
1099b725ae77Skettenis 	  else
1100b725ae77Skettenis 	    mi_out_rewind (uiout);
1101b725ae77Skettenis 	}
1102b725ae77Skettenis       else if (sync_execution)
1103b725ae77Skettenis 	{
1104b725ae77Skettenis 	  /* Don't print the prompt. We are executing the target in
1105b725ae77Skettenis 	     synchronous mode. */
1106b725ae77Skettenis 	  args->action = EXECUTE_COMMAND_SUPRESS_PROMPT;
1107b725ae77Skettenis 	  return 1;
1108b725ae77Skettenis 	}
1109b725ae77Skettenis       break;
1110b725ae77Skettenis 
1111b725ae77Skettenis     case CLI_COMMAND:
1112b725ae77Skettenis       /* A CLI command was read from the input stream */
1113b725ae77Skettenis       /* This will be removed as soon as we have a complete set of
1114b725ae77Skettenis          mi commands */
1115b725ae77Skettenis       /* echo the command on the console. */
1116b725ae77Skettenis       fprintf_unfiltered (gdb_stdlog, "%s\n", context->command);
1117b725ae77Skettenis       mi_execute_cli_command (context->command, 0, NULL);
1118b725ae77Skettenis 
1119b725ae77Skettenis       /* If we changed interpreters, DON'T print out anything. */
1120b725ae77Skettenis       if (current_interp_named_p (INTERP_MI)
1121b725ae77Skettenis 	  || current_interp_named_p (INTERP_MI1)
1122b725ae77Skettenis 	  || current_interp_named_p (INTERP_MI2)
1123b725ae77Skettenis 	  || current_interp_named_p (INTERP_MI3))
1124b725ae77Skettenis 	{
1125b725ae77Skettenis 	  /* print the result */
1126b725ae77Skettenis 	  /* FIXME: Check for errors here. */
1127b725ae77Skettenis 	  fputs_unfiltered (context->token, raw_stdout);
1128b725ae77Skettenis 	  fputs_unfiltered ("^done", raw_stdout);
1129b725ae77Skettenis 	  mi_out_put (uiout, raw_stdout);
1130b725ae77Skettenis 	  mi_out_rewind (uiout);
1131b725ae77Skettenis 	  fputs_unfiltered ("\n", raw_stdout);
1132b725ae77Skettenis 	  args->action = EXECUTE_COMMAND_DISPLAY_PROMPT;
1133b725ae77Skettenis 	  args->rc = MI_CMD_DONE;
1134b725ae77Skettenis 	}
1135b725ae77Skettenis       break;
1136b725ae77Skettenis 
1137b725ae77Skettenis     }
1138b725ae77Skettenis 
1139b725ae77Skettenis   return 1;
1140b725ae77Skettenis }
1141b725ae77Skettenis 
1142b725ae77Skettenis 
1143b725ae77Skettenis void
mi_execute_command(char * cmd,int from_tty)1144b725ae77Skettenis mi_execute_command (char *cmd, int from_tty)
1145b725ae77Skettenis {
1146b725ae77Skettenis   struct mi_parse *command;
1147b725ae77Skettenis   struct captured_mi_execute_command_args args;
1148b725ae77Skettenis   struct ui_out *saved_uiout = uiout;
1149b725ae77Skettenis   int result;
1150b725ae77Skettenis 
1151b725ae77Skettenis   /* This is to handle EOF (^D). We just quit gdb. */
1152b725ae77Skettenis   /* FIXME: we should call some API function here. */
1153b725ae77Skettenis   if (cmd == 0)
1154b725ae77Skettenis     quit_force (NULL, from_tty);
1155b725ae77Skettenis 
1156b725ae77Skettenis   command = mi_parse (cmd);
1157b725ae77Skettenis 
1158b725ae77Skettenis   if (command != NULL)
1159b725ae77Skettenis     {
1160b725ae77Skettenis       /* FIXME: cagney/1999-11-04: Can this use of catch_exceptions either
1161b725ae77Skettenis          be pushed even further down or even eliminated? */
1162b725ae77Skettenis       args.command = command;
1163b725ae77Skettenis       result = catch_exceptions (uiout, captured_mi_execute_command, &args, "",
1164b725ae77Skettenis 				 RETURN_MASK_ALL);
1165b725ae77Skettenis 
1166b725ae77Skettenis       if (args.action == EXECUTE_COMMAND_SUPRESS_PROMPT)
1167b725ae77Skettenis 	{
1168b725ae77Skettenis 	  /* The command is executing synchronously.  Bail out early
1169b725ae77Skettenis 	     suppressing the finished prompt. */
1170b725ae77Skettenis 	  mi_parse_free (command);
1171b725ae77Skettenis 	  return;
1172b725ae77Skettenis 	}
1173b725ae77Skettenis       if (args.action == EXECUTE_COMMAND_DISPLAY_ERROR || result < 0)
1174b725ae77Skettenis 	{
1175b725ae77Skettenis 	  char *msg = error_last_message ();
1176b725ae77Skettenis 	  struct cleanup *cleanup = make_cleanup (xfree, msg);
1177b725ae77Skettenis 	  /* The command execution failed and error() was called
1178b725ae77Skettenis 	     somewhere */
1179b725ae77Skettenis 	  fputs_unfiltered (command->token, raw_stdout);
1180b725ae77Skettenis 	  fputs_unfiltered ("^error,msg=\"", raw_stdout);
1181b725ae77Skettenis 	  fputstr_unfiltered (msg, '"', raw_stdout);
1182b725ae77Skettenis 	  fputs_unfiltered ("\"\n", raw_stdout);
1183b725ae77Skettenis 	}
1184b725ae77Skettenis       mi_parse_free (command);
1185b725ae77Skettenis     }
1186b725ae77Skettenis 
1187b725ae77Skettenis   fputs_unfiltered ("(gdb) \n", raw_stdout);
1188b725ae77Skettenis   gdb_flush (raw_stdout);
1189b725ae77Skettenis   /* print any buffered hook code */
1190b725ae77Skettenis   /* ..... */
1191b725ae77Skettenis }
1192b725ae77Skettenis 
1193b725ae77Skettenis static enum mi_cmd_result
mi_cmd_execute(struct mi_parse * parse)1194b725ae77Skettenis mi_cmd_execute (struct mi_parse *parse)
1195b725ae77Skettenis {
1196b725ae77Skettenis   if (parse->cmd->argv_func != NULL
1197b725ae77Skettenis       || parse->cmd->args_func != NULL)
1198b725ae77Skettenis     {
1199b725ae77Skettenis       /* FIXME: We need to save the token because the command executed
1200b725ae77Skettenis          may be asynchronous and need to print the token again.
1201b725ae77Skettenis          In the future we can pass the token down to the func
1202b725ae77Skettenis          and get rid of the last_async_command */
1203b725ae77Skettenis       /* The problem here is to keep the token around when we launch
1204b725ae77Skettenis          the target, and we want to interrupt it later on.  The
1205b725ae77Skettenis          interrupt command will have its own token, but when the
1206b725ae77Skettenis          target stops, we must display the token corresponding to the
1207b725ae77Skettenis          last execution command given. So we have another string where
1208b725ae77Skettenis          we copy the token (previous_async_command), if this was
1209b725ae77Skettenis          indeed the token of an execution command, and when we stop we
1210b725ae77Skettenis          print that one. This is possible because the interrupt
1211b725ae77Skettenis          command, when over, will copy that token back into the
1212b725ae77Skettenis          default token string (last_async_command). */
1213b725ae77Skettenis 
1214b725ae77Skettenis       if (target_executing)
1215b725ae77Skettenis 	{
1216b725ae77Skettenis 	  if (!previous_async_command)
1217b725ae77Skettenis 	    previous_async_command = xstrdup (last_async_command);
1218b725ae77Skettenis 	  if (strcmp (parse->command, "exec-interrupt"))
1219b725ae77Skettenis 	    {
1220b725ae77Skettenis 	      fputs_unfiltered (parse->token, raw_stdout);
1221b725ae77Skettenis 	      fputs_unfiltered ("^error,msg=\"", raw_stdout);
1222b725ae77Skettenis 	      fputs_unfiltered ("Cannot execute command ", raw_stdout);
1223b725ae77Skettenis 	      fputstr_unfiltered (parse->command, '"', raw_stdout);
1224b725ae77Skettenis 	      fputs_unfiltered (" while target running", raw_stdout);
1225b725ae77Skettenis 	      fputs_unfiltered ("\"\n", raw_stdout);
1226b725ae77Skettenis 	      return MI_CMD_ERROR;
1227b725ae77Skettenis 	    }
1228b725ae77Skettenis 	}
1229b725ae77Skettenis       last_async_command = xstrdup (parse->token);
1230b725ae77Skettenis       make_exec_cleanup (free_current_contents, &last_async_command);
1231b725ae77Skettenis       /* FIXME: DELETE THIS! */
1232b725ae77Skettenis       if (parse->cmd->args_func != NULL)
1233b725ae77Skettenis 	return parse->cmd->args_func (parse->args, 0 /*from_tty */ );
1234b725ae77Skettenis       return parse->cmd->argv_func (parse->command, parse->argv, parse->argc);
1235b725ae77Skettenis     }
1236b725ae77Skettenis   else if (parse->cmd->cli.cmd != 0)
1237b725ae77Skettenis     {
1238b725ae77Skettenis       /* FIXME: DELETE THIS. */
1239b725ae77Skettenis       /* The operation is still implemented by a cli command */
1240b725ae77Skettenis       /* Must be a synchronous one */
1241b725ae77Skettenis       mi_execute_cli_command (parse->cmd->cli.cmd, parse->cmd->cli.args_p,
1242b725ae77Skettenis 			      parse->args);
1243b725ae77Skettenis       return MI_CMD_DONE;
1244b725ae77Skettenis     }
1245b725ae77Skettenis   else
1246b725ae77Skettenis     {
1247b725ae77Skettenis       /* FIXME: DELETE THIS. */
1248b725ae77Skettenis       fputs_unfiltered (parse->token, raw_stdout);
1249b725ae77Skettenis       fputs_unfiltered ("^error,msg=\"", raw_stdout);
1250b725ae77Skettenis       fputs_unfiltered ("Undefined mi command: ", raw_stdout);
1251b725ae77Skettenis       fputstr_unfiltered (parse->command, '"', raw_stdout);
1252b725ae77Skettenis       fputs_unfiltered (" (missing implementation)", raw_stdout);
1253b725ae77Skettenis       fputs_unfiltered ("\"\n", raw_stdout);
1254b725ae77Skettenis       return MI_CMD_ERROR;
1255b725ae77Skettenis     }
1256b725ae77Skettenis }
1257b725ae77Skettenis 
1258b725ae77Skettenis /* FIXME: This is just a hack so we can get some extra commands going.
1259b725ae77Skettenis    We don't want to channel things through the CLI, but call libgdb directly */
1260b725ae77Skettenis /* Use only for synchronous commands */
1261b725ae77Skettenis 
1262b725ae77Skettenis void
mi_execute_cli_command(const char * cmd,int args_p,const char * args)1263b725ae77Skettenis mi_execute_cli_command (const char *cmd, int args_p, const char *args)
1264b725ae77Skettenis {
1265b725ae77Skettenis   if (cmd != 0)
1266b725ae77Skettenis     {
1267b725ae77Skettenis       struct cleanup *old_cleanups;
1268b725ae77Skettenis       char *run;
1269b725ae77Skettenis       if (args_p)
1270*11efff7fSkettenis 	run = xstrprintf ("%s %s", cmd, args);
1271b725ae77Skettenis       else
1272b725ae77Skettenis 	run = xstrdup (cmd);
1273b725ae77Skettenis       if (mi_debug_p)
1274b725ae77Skettenis 	/* FIXME: gdb_???? */
1275b725ae77Skettenis 	fprintf_unfiltered (gdb_stdout, "cli=%s run=%s\n",
1276b725ae77Skettenis 			    cmd, run);
1277b725ae77Skettenis       old_cleanups = make_cleanup (xfree, run);
1278b725ae77Skettenis       execute_command ( /*ui */ run, 0 /*from_tty */ );
1279b725ae77Skettenis       do_cleanups (old_cleanups);
1280b725ae77Skettenis       return;
1281b725ae77Skettenis     }
1282b725ae77Skettenis }
1283b725ae77Skettenis 
1284b725ae77Skettenis enum mi_cmd_result
mi_execute_async_cli_command(char * mi,char * args,int from_tty)1285b725ae77Skettenis mi_execute_async_cli_command (char *mi, char *args, int from_tty)
1286b725ae77Skettenis {
1287b725ae77Skettenis   struct cleanup *old_cleanups;
1288b725ae77Skettenis   char *run;
1289b725ae77Skettenis   char *async_args;
1290b725ae77Skettenis 
1291b725ae77Skettenis   if (target_can_async_p ())
1292b725ae77Skettenis     {
1293b725ae77Skettenis       async_args = (char *) xmalloc (strlen (args) + 2);
1294b725ae77Skettenis       make_exec_cleanup (free, async_args);
1295b725ae77Skettenis       strcpy (async_args, args);
1296b725ae77Skettenis       strcat (async_args, "&");
1297*11efff7fSkettenis       run = xstrprintf ("%s %s", mi, async_args);
1298b725ae77Skettenis       make_exec_cleanup (free, run);
1299b725ae77Skettenis       add_continuation (mi_exec_async_cli_cmd_continuation, NULL);
1300b725ae77Skettenis       old_cleanups = NULL;
1301b725ae77Skettenis     }
1302b725ae77Skettenis   else
1303b725ae77Skettenis     {
1304*11efff7fSkettenis       run = xstrprintf ("%s %s", mi, args);
1305b725ae77Skettenis       old_cleanups = make_cleanup (xfree, run);
1306b725ae77Skettenis     }
1307b725ae77Skettenis 
1308b725ae77Skettenis   if (!target_can_async_p ())
1309b725ae77Skettenis     {
1310b725ae77Skettenis       /* NOTE: For synchronous targets asynchronous behavour is faked by
1311b725ae77Skettenis          printing out the GDB prompt before we even try to execute the
1312b725ae77Skettenis          command. */
1313b725ae77Skettenis       if (last_async_command)
1314b725ae77Skettenis 	fputs_unfiltered (last_async_command, raw_stdout);
1315b725ae77Skettenis       fputs_unfiltered ("^running\n", raw_stdout);
1316b725ae77Skettenis       fputs_unfiltered ("(gdb) \n", raw_stdout);
1317b725ae77Skettenis       gdb_flush (raw_stdout);
1318b725ae77Skettenis     }
1319b725ae77Skettenis   else
1320b725ae77Skettenis     {
1321b725ae77Skettenis       /* FIXME: cagney/1999-11-29: Printing this message before
1322b725ae77Skettenis          calling execute_command is wrong.  It should only be printed
1323b725ae77Skettenis          once gdb has confirmed that it really has managed to send a
1324b725ae77Skettenis          run command to the target. */
1325b725ae77Skettenis       if (last_async_command)
1326b725ae77Skettenis 	fputs_unfiltered (last_async_command, raw_stdout);
1327b725ae77Skettenis       fputs_unfiltered ("^running\n", raw_stdout);
1328b725ae77Skettenis     }
1329b725ae77Skettenis 
1330b725ae77Skettenis   execute_command ( /*ui */ run, 0 /*from_tty */ );
1331b725ae77Skettenis 
1332b725ae77Skettenis   if (!target_can_async_p ())
1333b725ae77Skettenis     {
1334b725ae77Skettenis       /* Do this before doing any printing.  It would appear that some
1335b725ae77Skettenis          print code leaves garbage around in the buffer. */
1336b725ae77Skettenis       do_cleanups (old_cleanups);
1337b725ae77Skettenis       /* If the target was doing the operation synchronously we fake
1338b725ae77Skettenis          the stopped message. */
1339b725ae77Skettenis       if (last_async_command)
1340b725ae77Skettenis 	fputs_unfiltered (last_async_command, raw_stdout);
1341b725ae77Skettenis       fputs_unfiltered ("*stopped", raw_stdout);
1342b725ae77Skettenis       mi_out_put (uiout, raw_stdout);
1343b725ae77Skettenis       mi_out_rewind (uiout);
1344b725ae77Skettenis       fputs_unfiltered ("\n", raw_stdout);
1345b725ae77Skettenis       return MI_CMD_QUIET;
1346b725ae77Skettenis     }
1347b725ae77Skettenis   return MI_CMD_DONE;
1348b725ae77Skettenis }
1349b725ae77Skettenis 
1350b725ae77Skettenis void
mi_exec_async_cli_cmd_continuation(struct continuation_arg * arg)1351b725ae77Skettenis mi_exec_async_cli_cmd_continuation (struct continuation_arg *arg)
1352b725ae77Skettenis {
1353b725ae77Skettenis   if (last_async_command)
1354b725ae77Skettenis     fputs_unfiltered (last_async_command, raw_stdout);
1355b725ae77Skettenis   fputs_unfiltered ("*stopped", raw_stdout);
1356b725ae77Skettenis   mi_out_put (uiout, raw_stdout);
1357b725ae77Skettenis   fputs_unfiltered ("\n", raw_stdout);
1358b725ae77Skettenis   fputs_unfiltered ("(gdb) \n", raw_stdout);
1359b725ae77Skettenis   gdb_flush (raw_stdout);
1360b725ae77Skettenis   do_exec_cleanups (ALL_CLEANUPS);
1361b725ae77Skettenis }
1362b725ae77Skettenis 
1363b725ae77Skettenis void
mi_load_progress(const char * section_name,unsigned long sent_so_far,unsigned long total_section,unsigned long total_sent,unsigned long grand_total)1364b725ae77Skettenis mi_load_progress (const char *section_name,
1365b725ae77Skettenis 		  unsigned long sent_so_far,
1366b725ae77Skettenis 		  unsigned long total_section,
1367b725ae77Skettenis 		  unsigned long total_sent,
1368b725ae77Skettenis 		  unsigned long grand_total)
1369b725ae77Skettenis {
1370b725ae77Skettenis   struct timeval time_now, delta, update_threshold;
1371b725ae77Skettenis   static struct timeval last_update;
1372b725ae77Skettenis   static char *previous_sect_name = NULL;
1373b725ae77Skettenis   int new_section;
1374b725ae77Skettenis 
1375b725ae77Skettenis   if (!current_interp_named_p (INTERP_MI)
1376b725ae77Skettenis       && !current_interp_named_p (INTERP_MI1))
1377b725ae77Skettenis     return;
1378b725ae77Skettenis 
1379b725ae77Skettenis   update_threshold.tv_sec = 0;
1380b725ae77Skettenis   update_threshold.tv_usec = 500000;
1381b725ae77Skettenis   gettimeofday (&time_now, NULL);
1382b725ae77Skettenis 
1383b725ae77Skettenis   delta.tv_usec = time_now.tv_usec - last_update.tv_usec;
1384b725ae77Skettenis   delta.tv_sec = time_now.tv_sec - last_update.tv_sec;
1385b725ae77Skettenis 
1386b725ae77Skettenis   if (delta.tv_usec < 0)
1387b725ae77Skettenis     {
1388b725ae77Skettenis       delta.tv_sec -= 1;
1389b725ae77Skettenis       delta.tv_usec += 1000000;
1390b725ae77Skettenis     }
1391b725ae77Skettenis 
1392b725ae77Skettenis   new_section = (previous_sect_name ?
1393b725ae77Skettenis 		 strcmp (previous_sect_name, section_name) : 1);
1394b725ae77Skettenis   if (new_section)
1395b725ae77Skettenis     {
1396b725ae77Skettenis       struct cleanup *cleanup_tuple;
1397b725ae77Skettenis       xfree (previous_sect_name);
1398b725ae77Skettenis       previous_sect_name = xstrdup (section_name);
1399b725ae77Skettenis 
1400b725ae77Skettenis       if (last_async_command)
1401b725ae77Skettenis 	fputs_unfiltered (last_async_command, raw_stdout);
1402b725ae77Skettenis       fputs_unfiltered ("+download", raw_stdout);
1403b725ae77Skettenis       cleanup_tuple = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
1404b725ae77Skettenis       ui_out_field_string (uiout, "section", section_name);
1405b725ae77Skettenis       ui_out_field_int (uiout, "section-size", total_section);
1406b725ae77Skettenis       ui_out_field_int (uiout, "total-size", grand_total);
1407b725ae77Skettenis       do_cleanups (cleanup_tuple);
1408b725ae77Skettenis       mi_out_put (uiout, raw_stdout);
1409b725ae77Skettenis       fputs_unfiltered ("\n", raw_stdout);
1410b725ae77Skettenis       gdb_flush (raw_stdout);
1411b725ae77Skettenis     }
1412b725ae77Skettenis 
1413b725ae77Skettenis   if (delta.tv_sec >= update_threshold.tv_sec &&
1414b725ae77Skettenis       delta.tv_usec >= update_threshold.tv_usec)
1415b725ae77Skettenis     {
1416b725ae77Skettenis       struct cleanup *cleanup_tuple;
1417b725ae77Skettenis       last_update.tv_sec = time_now.tv_sec;
1418b725ae77Skettenis       last_update.tv_usec = time_now.tv_usec;
1419b725ae77Skettenis       if (last_async_command)
1420b725ae77Skettenis 	fputs_unfiltered (last_async_command, raw_stdout);
1421b725ae77Skettenis       fputs_unfiltered ("+download", raw_stdout);
1422b725ae77Skettenis       cleanup_tuple = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
1423b725ae77Skettenis       ui_out_field_string (uiout, "section", section_name);
1424b725ae77Skettenis       ui_out_field_int (uiout, "section-sent", sent_so_far);
1425b725ae77Skettenis       ui_out_field_int (uiout, "section-size", total_section);
1426b725ae77Skettenis       ui_out_field_int (uiout, "total-sent", total_sent);
1427b725ae77Skettenis       ui_out_field_int (uiout, "total-size", grand_total);
1428b725ae77Skettenis       do_cleanups (cleanup_tuple);
1429b725ae77Skettenis       mi_out_put (uiout, raw_stdout);
1430b725ae77Skettenis       fputs_unfiltered ("\n", raw_stdout);
1431b725ae77Skettenis       gdb_flush (raw_stdout);
1432b725ae77Skettenis     }
1433b725ae77Skettenis }
1434b725ae77Skettenis 
1435b725ae77Skettenis void
mi_setup_architecture_data(void)1436b725ae77Skettenis mi_setup_architecture_data (void)
1437b725ae77Skettenis {
1438b725ae77Skettenis   old_regs = xmalloc ((NUM_REGS + NUM_PSEUDO_REGS) * MAX_REGISTER_SIZE + 1);
1439b725ae77Skettenis   memset (old_regs, 0, (NUM_REGS + NUM_PSEUDO_REGS) * MAX_REGISTER_SIZE + 1);
1440b725ae77Skettenis }
1441b725ae77Skettenis 
1442b725ae77Skettenis void
_initialize_mi_main(void)1443b725ae77Skettenis _initialize_mi_main (void)
1444b725ae77Skettenis {
1445b725ae77Skettenis   DEPRECATED_REGISTER_GDBARCH_SWAP (old_regs);
1446b725ae77Skettenis   deprecated_register_gdbarch_swap (NULL, 0, mi_setup_architecture_data);
1447b725ae77Skettenis }
1448