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