15796c8dcSSimon Schubert /* MI Command Set.
25796c8dcSSimon Schubert
3a45ae5f8SJohn Marino Copyright (C) 2000-2013 Free Software Foundation, Inc.
45796c8dcSSimon Schubert
55796c8dcSSimon Schubert Contributed by Cygnus Solutions (a Red Hat company).
65796c8dcSSimon Schubert
75796c8dcSSimon Schubert This file is part of GDB.
85796c8dcSSimon Schubert
95796c8dcSSimon Schubert This program is free software; you can redistribute it and/or modify
105796c8dcSSimon Schubert it under the terms of the GNU General Public License as published by
115796c8dcSSimon Schubert the Free Software Foundation; either version 3 of the License, or
125796c8dcSSimon Schubert (at your option) any later version.
135796c8dcSSimon Schubert
145796c8dcSSimon Schubert This program is distributed in the hope that it will be useful,
155796c8dcSSimon Schubert but WITHOUT ANY WARRANTY; without even the implied warranty of
165796c8dcSSimon Schubert MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
175796c8dcSSimon Schubert GNU General Public License for more details.
185796c8dcSSimon Schubert
195796c8dcSSimon Schubert You should have received a copy of the GNU General Public License
205796c8dcSSimon Schubert along with this program. If not, see <http://www.gnu.org/licenses/>. */
215796c8dcSSimon Schubert
225796c8dcSSimon Schubert #include "defs.h"
235796c8dcSSimon Schubert #include "arch-utils.h"
245796c8dcSSimon Schubert #include "target.h"
255796c8dcSSimon Schubert #include "inferior.h"
265796c8dcSSimon Schubert #include "gdb_string.h"
275796c8dcSSimon Schubert #include "exceptions.h"
285796c8dcSSimon Schubert #include "top.h"
295796c8dcSSimon Schubert #include "gdbthread.h"
305796c8dcSSimon Schubert #include "mi-cmds.h"
315796c8dcSSimon Schubert #include "mi-parse.h"
325796c8dcSSimon Schubert #include "mi-getopt.h"
335796c8dcSSimon Schubert #include "mi-console.h"
345796c8dcSSimon Schubert #include "ui-out.h"
355796c8dcSSimon Schubert #include "mi-out.h"
365796c8dcSSimon Schubert #include "interps.h"
375796c8dcSSimon Schubert #include "event-loop.h"
385796c8dcSSimon Schubert #include "event-top.h"
395796c8dcSSimon Schubert #include "gdbcore.h" /* For write_memory(). */
405796c8dcSSimon Schubert #include "value.h"
415796c8dcSSimon Schubert #include "regcache.h"
425796c8dcSSimon Schubert #include "gdb.h"
435796c8dcSSimon Schubert #include "frame.h"
445796c8dcSSimon Schubert #include "mi-main.h"
455796c8dcSSimon Schubert #include "mi-common.h"
465796c8dcSSimon Schubert #include "language.h"
475796c8dcSSimon Schubert #include "valprint.h"
485796c8dcSSimon Schubert #include "inferior.h"
495796c8dcSSimon Schubert #include "osdata.h"
505796c8dcSSimon Schubert #include "splay-tree.h"
515796c8dcSSimon Schubert #include "tracepoint.h"
52cf7f2e2dSJohn Marino #include "ada-lang.h"
53cf7f2e2dSJohn Marino #include "linespec.h"
54a45ae5f8SJohn Marino
55a45ae5f8SJohn Marino #include <ctype.h>
565796c8dcSSimon Schubert #include <sys/time.h>
575796c8dcSSimon Schubert
585796c8dcSSimon Schubert #if defined HAVE_SYS_RESOURCE_H
595796c8dcSSimon Schubert #include <sys/resource.h>
605796c8dcSSimon Schubert #endif
615796c8dcSSimon Schubert
625796c8dcSSimon Schubert #ifdef HAVE_GETRUSAGE
635796c8dcSSimon Schubert struct rusage rusage;
645796c8dcSSimon Schubert #endif
655796c8dcSSimon Schubert
665796c8dcSSimon Schubert enum
675796c8dcSSimon Schubert {
685796c8dcSSimon Schubert FROM_TTY = 0
695796c8dcSSimon Schubert };
705796c8dcSSimon Schubert
715796c8dcSSimon Schubert int mi_debug_p;
725796c8dcSSimon Schubert
735796c8dcSSimon Schubert struct ui_file *raw_stdout;
745796c8dcSSimon Schubert
755796c8dcSSimon Schubert /* This is used to pass the current command timestamp down to
765796c8dcSSimon Schubert continuation routines. */
775796c8dcSSimon Schubert static struct mi_timestamp *current_command_ts;
785796c8dcSSimon Schubert
795796c8dcSSimon Schubert static int do_timings = 0;
805796c8dcSSimon Schubert
815796c8dcSSimon Schubert char *current_token;
825796c8dcSSimon Schubert /* Few commands would like to know if options like --thread-group were
83cf7f2e2dSJohn Marino explicitly specified. This variable keeps the current parsed
84cf7f2e2dSJohn Marino command including all option, and make it possible. */
85cf7f2e2dSJohn Marino static struct mi_parse *current_context;
86cf7f2e2dSJohn Marino
87cf7f2e2dSJohn Marino int running_result_record_printed = 1;
885796c8dcSSimon Schubert
895796c8dcSSimon Schubert /* Flag indicating that the target has proceeded since the last
905796c8dcSSimon Schubert command was issued. */
915796c8dcSSimon Schubert int mi_proceeded;
925796c8dcSSimon Schubert
935796c8dcSSimon Schubert extern void _initialize_mi_main (void);
945796c8dcSSimon Schubert static void mi_cmd_execute (struct mi_parse *parse);
955796c8dcSSimon Schubert
965796c8dcSSimon Schubert static void mi_execute_cli_command (const char *cmd, int args_p,
975796c8dcSSimon Schubert const char *args);
985796c8dcSSimon Schubert static void mi_execute_async_cli_command (char *cli_command,
995796c8dcSSimon Schubert char **argv, int argc);
1005796c8dcSSimon Schubert static int register_changed_p (int regnum, struct regcache *,
1015796c8dcSSimon Schubert struct regcache *);
1025796c8dcSSimon Schubert static void get_register (struct frame_info *, int regnum, int format);
1035796c8dcSSimon Schubert
1045796c8dcSSimon Schubert /* Command implementations. FIXME: Is this libgdb? No. This is the MI
1055796c8dcSSimon Schubert layer that calls libgdb. Any operation used in the below should be
1065796c8dcSSimon Schubert formalized. */
1075796c8dcSSimon Schubert
1085796c8dcSSimon Schubert static void timestamp (struct mi_timestamp *tv);
1095796c8dcSSimon Schubert
1105796c8dcSSimon Schubert static void print_diff_now (struct mi_timestamp *start);
1115796c8dcSSimon Schubert static void print_diff (struct mi_timestamp *start, struct mi_timestamp *end);
1125796c8dcSSimon Schubert
1135796c8dcSSimon Schubert void
mi_cmd_gdb_exit(char * command,char ** argv,int argc)1145796c8dcSSimon Schubert mi_cmd_gdb_exit (char *command, char **argv, int argc)
1155796c8dcSSimon Schubert {
1165796c8dcSSimon Schubert /* We have to print everything right here because we never return. */
1175796c8dcSSimon Schubert if (current_token)
1185796c8dcSSimon Schubert fputs_unfiltered (current_token, raw_stdout);
1195796c8dcSSimon Schubert fputs_unfiltered ("^exit\n", raw_stdout);
1205796c8dcSSimon Schubert mi_out_put (current_uiout, raw_stdout);
121a45ae5f8SJohn Marino gdb_flush (raw_stdout);
122cf7f2e2dSJohn Marino /* FIXME: The function called is not yet a formal libgdb function. */
1235796c8dcSSimon Schubert quit_force (NULL, FROM_TTY);
1245796c8dcSSimon Schubert }
1255796c8dcSSimon Schubert
1265796c8dcSSimon Schubert void
mi_cmd_exec_next(char * command,char ** argv,int argc)1275796c8dcSSimon Schubert mi_cmd_exec_next (char *command, char **argv, int argc)
1285796c8dcSSimon Schubert {
1295796c8dcSSimon Schubert /* FIXME: Should call a libgdb function, not a cli wrapper. */
1305796c8dcSSimon Schubert if (argc > 0 && strcmp(argv[0], "--reverse") == 0)
131cf7f2e2dSJohn Marino mi_execute_async_cli_command ("reverse-next", argv + 1, argc - 1);
132cf7f2e2dSJohn Marino else
133cf7f2e2dSJohn Marino mi_execute_async_cli_command ("next", argv, argc);
1345796c8dcSSimon Schubert }
1355796c8dcSSimon Schubert
1365796c8dcSSimon Schubert void
mi_cmd_exec_next_instruction(char * command,char ** argv,int argc)1375796c8dcSSimon Schubert mi_cmd_exec_next_instruction (char *command, char **argv, int argc)
1385796c8dcSSimon Schubert {
1395796c8dcSSimon Schubert /* FIXME: Should call a libgdb function, not a cli wrapper. */
1405796c8dcSSimon Schubert if (argc > 0 && strcmp(argv[0], "--reverse") == 0)
141cf7f2e2dSJohn Marino mi_execute_async_cli_command ("reverse-nexti", argv + 1, argc - 1);
142cf7f2e2dSJohn Marino else
143cf7f2e2dSJohn Marino mi_execute_async_cli_command ("nexti", argv, argc);
1445796c8dcSSimon Schubert }
1455796c8dcSSimon Schubert
1465796c8dcSSimon Schubert void
mi_cmd_exec_step(char * command,char ** argv,int argc)1475796c8dcSSimon Schubert mi_cmd_exec_step (char *command, char **argv, int argc)
1485796c8dcSSimon Schubert {
1495796c8dcSSimon Schubert /* FIXME: Should call a libgdb function, not a cli wrapper. */
1505796c8dcSSimon Schubert if (argc > 0 && strcmp(argv[0], "--reverse") == 0)
151cf7f2e2dSJohn Marino mi_execute_async_cli_command ("reverse-step", argv + 1, argc - 1);
152cf7f2e2dSJohn Marino else
153cf7f2e2dSJohn Marino mi_execute_async_cli_command ("step", argv, argc);
1545796c8dcSSimon Schubert }
1555796c8dcSSimon Schubert
1565796c8dcSSimon Schubert void
mi_cmd_exec_step_instruction(char * command,char ** argv,int argc)1575796c8dcSSimon Schubert mi_cmd_exec_step_instruction (char *command, char **argv, int argc)
1585796c8dcSSimon Schubert {
1595796c8dcSSimon Schubert /* FIXME: Should call a libgdb function, not a cli wrapper. */
1605796c8dcSSimon Schubert if (argc > 0 && strcmp(argv[0], "--reverse") == 0)
161cf7f2e2dSJohn Marino mi_execute_async_cli_command ("reverse-stepi", argv + 1, argc - 1);
162cf7f2e2dSJohn Marino else
163cf7f2e2dSJohn Marino mi_execute_async_cli_command ("stepi", argv, argc);
1645796c8dcSSimon Schubert }
1655796c8dcSSimon Schubert
1665796c8dcSSimon Schubert void
mi_cmd_exec_finish(char * command,char ** argv,int argc)1675796c8dcSSimon Schubert mi_cmd_exec_finish (char *command, char **argv, int argc)
1685796c8dcSSimon Schubert {
1695796c8dcSSimon Schubert /* FIXME: Should call a libgdb function, not a cli wrapper. */
1705796c8dcSSimon Schubert if (argc > 0 && strcmp(argv[0], "--reverse") == 0)
171cf7f2e2dSJohn Marino mi_execute_async_cli_command ("reverse-finish", argv + 1, argc - 1);
172cf7f2e2dSJohn Marino else
173cf7f2e2dSJohn Marino mi_execute_async_cli_command ("finish", argv, argc);
1745796c8dcSSimon Schubert }
1755796c8dcSSimon Schubert
1765796c8dcSSimon Schubert void
mi_cmd_exec_return(char * command,char ** argv,int argc)1775796c8dcSSimon Schubert mi_cmd_exec_return (char *command, char **argv, int argc)
1785796c8dcSSimon Schubert {
1795796c8dcSSimon Schubert /* This command doesn't really execute the target, it just pops the
1805796c8dcSSimon Schubert specified number of frames. */
1815796c8dcSSimon Schubert if (argc)
1825796c8dcSSimon Schubert /* Call return_command with from_tty argument equal to 0 so as to
1835796c8dcSSimon Schubert avoid being queried. */
1845796c8dcSSimon Schubert return_command (*argv, 0);
1855796c8dcSSimon Schubert else
1865796c8dcSSimon Schubert /* Call return_command with from_tty argument equal to 0 so as to
1875796c8dcSSimon Schubert avoid being queried. */
1885796c8dcSSimon Schubert return_command (NULL, 0);
1895796c8dcSSimon Schubert
1905796c8dcSSimon Schubert /* Because we have called return_command with from_tty = 0, we need
1915796c8dcSSimon Schubert to print the frame here. */
1925796c8dcSSimon Schubert print_stack_frame (get_selected_frame (NULL), 1, LOC_AND_ADDRESS);
1935796c8dcSSimon Schubert }
1945796c8dcSSimon Schubert
1955796c8dcSSimon Schubert void
mi_cmd_exec_jump(char * args,char ** argv,int argc)1965796c8dcSSimon Schubert mi_cmd_exec_jump (char *args, char **argv, int argc)
1975796c8dcSSimon Schubert {
1985796c8dcSSimon Schubert /* FIXME: Should call a libgdb function, not a cli wrapper. */
1995796c8dcSSimon Schubert mi_execute_async_cli_command ("jump", argv, argc);
200cf7f2e2dSJohn Marino }
2015796c8dcSSimon Schubert
2025796c8dcSSimon Schubert static void
proceed_thread(struct thread_info * thread,int pid)203cf7f2e2dSJohn Marino proceed_thread (struct thread_info *thread, int pid)
204cf7f2e2dSJohn Marino {
205cf7f2e2dSJohn Marino if (!is_stopped (thread->ptid))
206cf7f2e2dSJohn Marino return;
207cf7f2e2dSJohn Marino
208cf7f2e2dSJohn Marino if (pid != 0 && PIDGET (thread->ptid) != pid)
209cf7f2e2dSJohn Marino return;
210cf7f2e2dSJohn Marino
211cf7f2e2dSJohn Marino switch_to_thread (thread->ptid);
212cf7f2e2dSJohn Marino clear_proceed_status ();
213cf7f2e2dSJohn Marino proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT, 0);
214cf7f2e2dSJohn Marino }
215cf7f2e2dSJohn Marino
216cf7f2e2dSJohn Marino static int
proceed_thread_callback(struct thread_info * thread,void * arg)217cf7f2e2dSJohn Marino proceed_thread_callback (struct thread_info *thread, void *arg)
2185796c8dcSSimon Schubert {
2195796c8dcSSimon Schubert int pid = *(int *)arg;
2205796c8dcSSimon Schubert
2215796c8dcSSimon Schubert proceed_thread (thread, pid);
2225796c8dcSSimon Schubert return 0;
223cf7f2e2dSJohn Marino }
2245796c8dcSSimon Schubert
225cf7f2e2dSJohn Marino static void
exec_continue(char ** argv,int argc)2265796c8dcSSimon Schubert exec_continue (char **argv, int argc)
227cf7f2e2dSJohn Marino {
228cf7f2e2dSJohn Marino if (non_stop)
229cf7f2e2dSJohn Marino {
230cf7f2e2dSJohn Marino /* In non-stop mode, 'resume' always resumes a single thread.
231cf7f2e2dSJohn Marino Therefore, to resume all threads of the current inferior, or
232cf7f2e2dSJohn Marino all threads in all inferiors, we need to iterate over
233cf7f2e2dSJohn Marino threads.
234cf7f2e2dSJohn Marino
2355796c8dcSSimon Schubert See comment on infcmd.c:proceed_thread_callback for rationale. */
236cf7f2e2dSJohn Marino if (current_context->all || current_context->thread_group != -1)
237cf7f2e2dSJohn Marino {
238cf7f2e2dSJohn Marino int pid = 0;
239cf7f2e2dSJohn Marino struct cleanup *back_to = make_cleanup_restore_current_thread ();
240cf7f2e2dSJohn Marino
241cf7f2e2dSJohn Marino if (!current_context->all)
242cf7f2e2dSJohn Marino {
243cf7f2e2dSJohn Marino struct inferior *inf
244c50c785cSJohn Marino = find_inferior_id (current_context->thread_group);
245c50c785cSJohn Marino
246c50c785cSJohn Marino pid = inf->pid;
247cf7f2e2dSJohn Marino }
248cf7f2e2dSJohn Marino iterate_over_threads (proceed_thread_callback, &pid);
249cf7f2e2dSJohn Marino do_cleanups (back_to);
250cf7f2e2dSJohn Marino }
251cf7f2e2dSJohn Marino else
252cf7f2e2dSJohn Marino {
253cf7f2e2dSJohn Marino continue_1 (0);
254cf7f2e2dSJohn Marino }
255cf7f2e2dSJohn Marino }
256cf7f2e2dSJohn Marino else
257cf7f2e2dSJohn Marino {
258cf7f2e2dSJohn Marino struct cleanup *back_to = make_cleanup_restore_integer (&sched_multi);
259cf7f2e2dSJohn Marino
260cf7f2e2dSJohn Marino if (current_context->all)
261cf7f2e2dSJohn Marino {
262cf7f2e2dSJohn Marino sched_multi = 1;
263cf7f2e2dSJohn Marino continue_1 (0);
264cf7f2e2dSJohn Marino }
265cf7f2e2dSJohn Marino else
266cf7f2e2dSJohn Marino {
267cf7f2e2dSJohn Marino /* In all-stop mode, -exec-continue traditionally resumed
268cf7f2e2dSJohn Marino either all threads, or one thread, depending on the
269cf7f2e2dSJohn Marino 'scheduler-locking' variable. Let's continue to do the
270cf7f2e2dSJohn Marino same. */
271cf7f2e2dSJohn Marino continue_1 (1);
272cf7f2e2dSJohn Marino }
273cf7f2e2dSJohn Marino do_cleanups (back_to);
274cf7f2e2dSJohn Marino }
275cf7f2e2dSJohn Marino }
276cf7f2e2dSJohn Marino
277cf7f2e2dSJohn Marino static void
exec_direction_forward(void * notused)278cf7f2e2dSJohn Marino exec_direction_forward (void *notused)
279cf7f2e2dSJohn Marino {
280cf7f2e2dSJohn Marino execution_direction = EXEC_FORWARD;
281cf7f2e2dSJohn Marino }
282cf7f2e2dSJohn Marino
283cf7f2e2dSJohn Marino static void
exec_reverse_continue(char ** argv,int argc)284cf7f2e2dSJohn Marino exec_reverse_continue (char **argv, int argc)
285cf7f2e2dSJohn Marino {
286cf7f2e2dSJohn Marino enum exec_direction_kind dir = execution_direction;
287cf7f2e2dSJohn Marino struct cleanup *old_chain;
288cf7f2e2dSJohn Marino
289cf7f2e2dSJohn Marino if (dir == EXEC_REVERSE)
290cf7f2e2dSJohn Marino error (_("Already in reverse mode."));
291cf7f2e2dSJohn Marino
292cf7f2e2dSJohn Marino if (!target_can_execute_reverse)
293cf7f2e2dSJohn Marino error (_("Target %s does not support this command."), target_shortname);
294cf7f2e2dSJohn Marino
295cf7f2e2dSJohn Marino old_chain = make_cleanup (exec_direction_forward, NULL);
296cf7f2e2dSJohn Marino execution_direction = EXEC_REVERSE;
297cf7f2e2dSJohn Marino exec_continue (argv, argc);
298cf7f2e2dSJohn Marino do_cleanups (old_chain);
2995796c8dcSSimon Schubert }
3005796c8dcSSimon Schubert
3015796c8dcSSimon Schubert void
mi_cmd_exec_continue(char * command,char ** argv,int argc)3025796c8dcSSimon Schubert mi_cmd_exec_continue (char *command, char **argv, int argc)
3035796c8dcSSimon Schubert {
304cf7f2e2dSJohn Marino if (argc > 0 && strcmp (argv[0], "--reverse") == 0)
305cf7f2e2dSJohn Marino exec_reverse_continue (argv + 1, argc - 1);
3065796c8dcSSimon Schubert else
307cf7f2e2dSJohn Marino exec_continue (argv, argc);
3085796c8dcSSimon Schubert }
3095796c8dcSSimon Schubert
3105796c8dcSSimon Schubert static int
interrupt_thread_callback(struct thread_info * thread,void * arg)3115796c8dcSSimon Schubert interrupt_thread_callback (struct thread_info *thread, void *arg)
3125796c8dcSSimon Schubert {
3135796c8dcSSimon Schubert int pid = *(int *)arg;
3145796c8dcSSimon Schubert
3155796c8dcSSimon Schubert if (!is_running (thread->ptid))
3165796c8dcSSimon Schubert return 0;
3175796c8dcSSimon Schubert
3185796c8dcSSimon Schubert if (PIDGET (thread->ptid) != pid)
3195796c8dcSSimon Schubert return 0;
3205796c8dcSSimon Schubert
3215796c8dcSSimon Schubert target_stop (thread->ptid);
3225796c8dcSSimon Schubert return 0;
3235796c8dcSSimon Schubert }
3245796c8dcSSimon Schubert
3255796c8dcSSimon Schubert /* Interrupt the execution of the target. Note how we must play
3265796c8dcSSimon Schubert around with the token variables, in order to display the current
3275796c8dcSSimon Schubert token in the result of the interrupt command, and the previous
3285796c8dcSSimon Schubert execution token when the target finally stops. See comments in
3295796c8dcSSimon Schubert mi_cmd_execute. */
3305796c8dcSSimon Schubert
3315796c8dcSSimon Schubert void
mi_cmd_exec_interrupt(char * command,char ** argv,int argc)3325796c8dcSSimon Schubert mi_cmd_exec_interrupt (char *command, char **argv, int argc)
333cf7f2e2dSJohn Marino {
334cf7f2e2dSJohn Marino /* In all-stop mode, everything stops, so we don't need to try
335cf7f2e2dSJohn Marino anything specific. */
3365796c8dcSSimon Schubert if (!non_stop)
3375796c8dcSSimon Schubert {
338cf7f2e2dSJohn Marino interrupt_target_1 (0);
3395796c8dcSSimon Schubert return;
3405796c8dcSSimon Schubert }
341cf7f2e2dSJohn Marino
342cf7f2e2dSJohn Marino if (current_context->all)
343cf7f2e2dSJohn Marino {
3445796c8dcSSimon Schubert /* This will interrupt all threads in all inferiors. */
3455796c8dcSSimon Schubert interrupt_target_1 (1);
346cf7f2e2dSJohn Marino }
3475796c8dcSSimon Schubert else if (current_context->thread_group != -1)
348cf7f2e2dSJohn Marino {
3495796c8dcSSimon Schubert struct inferior *inf = find_inferior_id (current_context->thread_group);
350cf7f2e2dSJohn Marino
3515796c8dcSSimon Schubert iterate_over_threads (interrupt_thread_callback, &inf->pid);
3525796c8dcSSimon Schubert }
353cf7f2e2dSJohn Marino else
354cf7f2e2dSJohn Marino {
355cf7f2e2dSJohn Marino /* Interrupt just the current thread -- either explicitly
356cf7f2e2dSJohn Marino specified via --thread or whatever was current before
357cf7f2e2dSJohn Marino MI command was sent. */
3585796c8dcSSimon Schubert interrupt_target_1 (0);
359cf7f2e2dSJohn Marino }
360cf7f2e2dSJohn Marino }
361cf7f2e2dSJohn Marino
362cf7f2e2dSJohn Marino static int
run_one_inferior(struct inferior * inf,void * arg)363cf7f2e2dSJohn Marino run_one_inferior (struct inferior *inf, void *arg)
364*74a8b0f5SJohn Marino {
365cf7f2e2dSJohn Marino if (inf->pid != 0)
366cf7f2e2dSJohn Marino {
367cf7f2e2dSJohn Marino if (inf->pid != ptid_get_pid (inferior_ptid))
368cf7f2e2dSJohn Marino {
369cf7f2e2dSJohn Marino struct thread_info *tp;
370cf7f2e2dSJohn Marino
371cf7f2e2dSJohn Marino tp = any_thread_of_process (inf->pid);
372cf7f2e2dSJohn Marino if (!tp)
373cf7f2e2dSJohn Marino error (_("Inferior has no threads."));
374cf7f2e2dSJohn Marino
375cf7f2e2dSJohn Marino switch_to_thread (tp->ptid);
376cf7f2e2dSJohn Marino }
377cf7f2e2dSJohn Marino }
378cf7f2e2dSJohn Marino else
379cf7f2e2dSJohn Marino {
380cf7f2e2dSJohn Marino set_current_inferior (inf);
381cf7f2e2dSJohn Marino switch_to_thread (null_ptid);
382cf7f2e2dSJohn Marino set_current_program_space (inf->pspace);
383cf7f2e2dSJohn Marino }
384cf7f2e2dSJohn Marino mi_execute_cli_command ("run", target_can_async_p (),
385cf7f2e2dSJohn Marino target_can_async_p () ? "&" : NULL);
386cf7f2e2dSJohn Marino return 0;
387cf7f2e2dSJohn Marino }
388cf7f2e2dSJohn Marino
389cf7f2e2dSJohn Marino void
mi_cmd_exec_run(char * command,char ** argv,int argc)390cf7f2e2dSJohn Marino mi_cmd_exec_run (char *command, char **argv, int argc)
391cf7f2e2dSJohn Marino {
392cf7f2e2dSJohn Marino if (current_context->all)
393cf7f2e2dSJohn Marino {
394cf7f2e2dSJohn Marino struct cleanup *back_to = save_current_space_and_thread ();
395cf7f2e2dSJohn Marino
396cf7f2e2dSJohn Marino iterate_over_inferiors (run_one_inferior, NULL);
397cf7f2e2dSJohn Marino do_cleanups (back_to);
398cf7f2e2dSJohn Marino }
399cf7f2e2dSJohn Marino else
400cf7f2e2dSJohn Marino {
401cf7f2e2dSJohn Marino mi_execute_cli_command ("run", target_can_async_p (),
402cf7f2e2dSJohn Marino target_can_async_p () ? "&" : NULL);
403cf7f2e2dSJohn Marino }
404cf7f2e2dSJohn Marino }
4055796c8dcSSimon Schubert
4065796c8dcSSimon Schubert
4075796c8dcSSimon Schubert static int
find_thread_of_process(struct thread_info * ti,void * p)4085796c8dcSSimon Schubert find_thread_of_process (struct thread_info *ti, void *p)
4095796c8dcSSimon Schubert {
410cf7f2e2dSJohn Marino int pid = *(int *)p;
4115796c8dcSSimon Schubert
4125796c8dcSSimon Schubert if (PIDGET (ti->ptid) == pid && !is_exited (ti->ptid))
4135796c8dcSSimon Schubert return 1;
4145796c8dcSSimon Schubert
4155796c8dcSSimon Schubert return 0;
4165796c8dcSSimon Schubert }
4175796c8dcSSimon Schubert
4185796c8dcSSimon Schubert void
mi_cmd_target_detach(char * command,char ** argv,int argc)4195796c8dcSSimon Schubert mi_cmd_target_detach (char *command, char **argv, int argc)
4205796c8dcSSimon Schubert {
421c50c785cSJohn Marino if (argc != 0 && argc != 1)
4225796c8dcSSimon Schubert error (_("Usage: -target-detach [pid | thread-group]"));
4235796c8dcSSimon Schubert
4245796c8dcSSimon Schubert if (argc == 1)
4255796c8dcSSimon Schubert {
4265796c8dcSSimon Schubert struct thread_info *tp;
427c50c785cSJohn Marino char *end = argv[0];
428c50c785cSJohn Marino int pid;
429c50c785cSJohn Marino
430c50c785cSJohn Marino /* First see if we are dealing with a thread-group id. */
431c50c785cSJohn Marino if (*argv[0] == 'i')
432c50c785cSJohn Marino {
433c50c785cSJohn Marino struct inferior *inf;
434cf7f2e2dSJohn Marino int id = strtoul (argv[0] + 1, &end, 0);
4355796c8dcSSimon Schubert
436c50c785cSJohn Marino if (*end != '\0')
437c50c785cSJohn Marino error (_("Invalid syntax of thread-group id '%s'"), argv[0]);
438c50c785cSJohn Marino
439c50c785cSJohn Marino inf = find_inferior_id (id);
440c50c785cSJohn Marino if (!inf)
441c50c785cSJohn Marino error (_("Non-existent thread-group id '%d'"), id);
442c50c785cSJohn Marino
443c50c785cSJohn Marino pid = inf->pid;
444c50c785cSJohn Marino }
445c50c785cSJohn Marino else
446c50c785cSJohn Marino {
447c50c785cSJohn Marino /* We must be dealing with a pid. */
448c50c785cSJohn Marino pid = strtol (argv[0], &end, 10);
449c50c785cSJohn Marino
450c50c785cSJohn Marino if (*end != '\0')
451c50c785cSJohn Marino error (_("Invalid identifier '%s'"), argv[0]);
4525796c8dcSSimon Schubert }
4535796c8dcSSimon Schubert
454c50c785cSJohn Marino /* Pick any thread in the desired process. Current
4555796c8dcSSimon Schubert target_detach detaches from the parent of inferior_ptid. */
4565796c8dcSSimon Schubert tp = iterate_over_threads (find_thread_of_process, &pid);
4575796c8dcSSimon Schubert if (!tp)
4585796c8dcSSimon Schubert error (_("Thread group is empty"));
4595796c8dcSSimon Schubert
4605796c8dcSSimon Schubert switch_to_thread (tp->ptid);
4615796c8dcSSimon Schubert }
4625796c8dcSSimon Schubert
4635796c8dcSSimon Schubert detach_command (NULL, 0);
4645796c8dcSSimon Schubert }
4655796c8dcSSimon Schubert
4665796c8dcSSimon Schubert void
mi_cmd_thread_select(char * command,char ** argv,int argc)4675796c8dcSSimon Schubert mi_cmd_thread_select (char *command, char **argv, int argc)
4685796c8dcSSimon Schubert {
4695796c8dcSSimon Schubert enum gdb_rc rc;
4705796c8dcSSimon Schubert char *mi_error_message;
4715796c8dcSSimon Schubert
472c50c785cSJohn Marino if (argc != 1)
4735796c8dcSSimon Schubert error (_("-thread-select: USAGE: threadnum."));
474a45ae5f8SJohn Marino
4755796c8dcSSimon Schubert rc = gdb_thread_select (current_uiout, argv[0], &mi_error_message);
4765796c8dcSSimon Schubert
4775796c8dcSSimon Schubert if (rc == GDB_RC_FAIL)
4785796c8dcSSimon Schubert {
4795796c8dcSSimon Schubert make_cleanup (xfree, mi_error_message);
4805796c8dcSSimon Schubert error ("%s", mi_error_message);
4815796c8dcSSimon Schubert }
4825796c8dcSSimon Schubert }
4835796c8dcSSimon Schubert
4845796c8dcSSimon Schubert void
mi_cmd_thread_list_ids(char * command,char ** argv,int argc)4855796c8dcSSimon Schubert mi_cmd_thread_list_ids (char *command, char **argv, int argc)
4865796c8dcSSimon Schubert {
4875796c8dcSSimon Schubert enum gdb_rc rc;
4885796c8dcSSimon Schubert char *mi_error_message;
4895796c8dcSSimon Schubert
490c50c785cSJohn Marino if (argc != 0)
4915796c8dcSSimon Schubert error (_("-thread-list-ids: No arguments required."));
492a45ae5f8SJohn Marino
4935796c8dcSSimon Schubert rc = gdb_list_thread_ids (current_uiout, &mi_error_message);
4945796c8dcSSimon Schubert
4955796c8dcSSimon Schubert if (rc == GDB_RC_FAIL)
4965796c8dcSSimon Schubert {
4975796c8dcSSimon Schubert make_cleanup (xfree, mi_error_message);
4985796c8dcSSimon Schubert error ("%s", mi_error_message);
4995796c8dcSSimon Schubert }
5005796c8dcSSimon Schubert }
5015796c8dcSSimon Schubert
5025796c8dcSSimon Schubert void
mi_cmd_thread_info(char * command,char ** argv,int argc)5035796c8dcSSimon Schubert mi_cmd_thread_info (char *command, char **argv, int argc)
5045796c8dcSSimon Schubert {
505c50c785cSJohn Marino if (argc != 0 && argc != 1)
5065796c8dcSSimon Schubert error (_("Invalid MI command"));
507a45ae5f8SJohn Marino
5085796c8dcSSimon Schubert print_thread_info (current_uiout, argv[0], -1);
5095796c8dcSSimon Schubert }
510cf7f2e2dSJohn Marino
5115796c8dcSSimon Schubert DEF_VEC_I(int);
512cf7f2e2dSJohn Marino
5135796c8dcSSimon Schubert struct collect_cores_data
514cf7f2e2dSJohn Marino {
515cf7f2e2dSJohn Marino int pid;
5165796c8dcSSimon Schubert
517cf7f2e2dSJohn Marino VEC (int) *cores;
518cf7f2e2dSJohn Marino };
519cf7f2e2dSJohn Marino
520cf7f2e2dSJohn Marino static int
collect_cores(struct thread_info * ti,void * xdata)521cf7f2e2dSJohn Marino collect_cores (struct thread_info *ti, void *xdata)
522cf7f2e2dSJohn Marino {
523cf7f2e2dSJohn Marino struct collect_cores_data *data = xdata;
524cf7f2e2dSJohn Marino
525cf7f2e2dSJohn Marino if (ptid_get_pid (ti->ptid) == data->pid)
526cf7f2e2dSJohn Marino {
527cf7f2e2dSJohn Marino int core = target_core_of_thread (ti->ptid);
528cf7f2e2dSJohn Marino
529cf7f2e2dSJohn Marino if (core != -1)
5305796c8dcSSimon Schubert VEC_safe_push (int, data->cores, core);
5315796c8dcSSimon Schubert }
5325796c8dcSSimon Schubert
533cf7f2e2dSJohn Marino return 0;
534cf7f2e2dSJohn Marino }
5355796c8dcSSimon Schubert
536cf7f2e2dSJohn Marino static int *
unique(int * b,int * e)5375796c8dcSSimon Schubert unique (int *b, int *e)
538cf7f2e2dSJohn Marino {
539cf7f2e2dSJohn Marino int *d = b;
540cf7f2e2dSJohn Marino
541cf7f2e2dSJohn Marino while (++b != e)
5425796c8dcSSimon Schubert if (*d != *b)
5435796c8dcSSimon Schubert *++d = *b;
544cf7f2e2dSJohn Marino return ++d;
5455796c8dcSSimon Schubert }
546cf7f2e2dSJohn Marino
547cf7f2e2dSJohn Marino struct print_one_inferior_data
548cf7f2e2dSJohn Marino {
549cf7f2e2dSJohn Marino int recurse;
550cf7f2e2dSJohn Marino VEC (int) *inferiors;
551cf7f2e2dSJohn Marino };
552cf7f2e2dSJohn Marino
553cf7f2e2dSJohn Marino static int
print_one_inferior(struct inferior * inferior,void * xdata)554a45ae5f8SJohn Marino print_one_inferior (struct inferior *inferior, void *xdata)
555cf7f2e2dSJohn Marino {
556cf7f2e2dSJohn Marino struct print_one_inferior_data *top_data = xdata;
557cf7f2e2dSJohn Marino struct ui_out *uiout = current_uiout;
558cf7f2e2dSJohn Marino
559cf7f2e2dSJohn Marino if (VEC_empty (int, top_data->inferiors)
560cf7f2e2dSJohn Marino || bsearch (&(inferior->pid), VEC_address (int, top_data->inferiors),
561cf7f2e2dSJohn Marino VEC_length (int, top_data->inferiors), sizeof (int),
562cf7f2e2dSJohn Marino compare_positive_ints))
563cf7f2e2dSJohn Marino {
564cf7f2e2dSJohn Marino struct collect_cores_data data;
565cf7f2e2dSJohn Marino struct cleanup *back_to
566cf7f2e2dSJohn Marino = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
567*74a8b0f5SJohn Marino
568cf7f2e2dSJohn Marino ui_out_field_fmt (uiout, "id", "i%d", inferior->num);
569cf7f2e2dSJohn Marino ui_out_field_string (uiout, "type", "process");
570cf7f2e2dSJohn Marino if (inferior->pid != 0)
571cf7f2e2dSJohn Marino ui_out_field_int (uiout, "pid", inferior->pid);
572cf7f2e2dSJohn Marino
573cf7f2e2dSJohn Marino if (inferior->pspace->pspace_exec_filename != NULL)
5745796c8dcSSimon Schubert {
575cf7f2e2dSJohn Marino ui_out_field_string (uiout, "executable",
576cf7f2e2dSJohn Marino inferior->pspace->pspace_exec_filename);
577*74a8b0f5SJohn Marino }
578cf7f2e2dSJohn Marino
579cf7f2e2dSJohn Marino data.cores = 0;
580cf7f2e2dSJohn Marino if (inferior->pid != 0)
581cf7f2e2dSJohn Marino {
582cf7f2e2dSJohn Marino data.pid = inferior->pid;
583cf7f2e2dSJohn Marino iterate_over_threads (collect_cores, &data);
584cf7f2e2dSJohn Marino }
585cf7f2e2dSJohn Marino
586cf7f2e2dSJohn Marino if (!VEC_empty (int, data.cores))
587cf7f2e2dSJohn Marino {
588cf7f2e2dSJohn Marino int *b, *e;
589cf7f2e2dSJohn Marino struct cleanup *back_to_2 =
590cf7f2e2dSJohn Marino make_cleanup_ui_out_list_begin_end (uiout, "cores");
591cf7f2e2dSJohn Marino
592cf7f2e2dSJohn Marino qsort (VEC_address (int, data.cores),
593cf7f2e2dSJohn Marino VEC_length (int, data.cores), sizeof (int),
594cf7f2e2dSJohn Marino compare_positive_ints);
595cf7f2e2dSJohn Marino
596cf7f2e2dSJohn Marino b = VEC_address (int, data.cores);
597cf7f2e2dSJohn Marino e = b + VEC_length (int, data.cores);
598cf7f2e2dSJohn Marino e = unique (b, e);
599cf7f2e2dSJohn Marino
600cf7f2e2dSJohn Marino for (; b != e; ++b)
601cf7f2e2dSJohn Marino ui_out_field_int (uiout, NULL, *b);
602cf7f2e2dSJohn Marino
603cf7f2e2dSJohn Marino do_cleanups (back_to_2);
604c50c785cSJohn Marino }
605cf7f2e2dSJohn Marino
606cf7f2e2dSJohn Marino if (top_data->recurse)
607cf7f2e2dSJohn Marino print_thread_info (uiout, NULL, inferior->pid);
608cf7f2e2dSJohn Marino
609cf7f2e2dSJohn Marino do_cleanups (back_to);
610cf7f2e2dSJohn Marino }
611cf7f2e2dSJohn Marino
612cf7f2e2dSJohn Marino return 0;
613cf7f2e2dSJohn Marino }
614cf7f2e2dSJohn Marino
615cf7f2e2dSJohn Marino /* Output a field named 'cores' with a list as the value. The
616cf7f2e2dSJohn Marino elements of the list are obtained by splitting 'cores' on
617cf7f2e2dSJohn Marino comma. */
618cf7f2e2dSJohn Marino
619cf7f2e2dSJohn Marino static void
output_cores(struct ui_out * uiout,const char * field_name,const char * xcores)620cf7f2e2dSJohn Marino output_cores (struct ui_out *uiout, const char *field_name, const char *xcores)
621cf7f2e2dSJohn Marino {
622cf7f2e2dSJohn Marino struct cleanup *back_to = make_cleanup_ui_out_list_begin_end (uiout,
623cf7f2e2dSJohn Marino field_name);
624cf7f2e2dSJohn Marino char *cores = xstrdup (xcores);
625cf7f2e2dSJohn Marino char *p = cores;
626cf7f2e2dSJohn Marino
627cf7f2e2dSJohn Marino make_cleanup (xfree, cores);
628cf7f2e2dSJohn Marino
629cf7f2e2dSJohn Marino for (p = strtok (p, ","); p; p = strtok (NULL, ","))
630cf7f2e2dSJohn Marino ui_out_field_string (uiout, NULL, p);
631cf7f2e2dSJohn Marino
632cf7f2e2dSJohn Marino do_cleanups (back_to);
633cf7f2e2dSJohn Marino }
634cf7f2e2dSJohn Marino
635cf7f2e2dSJohn Marino static void
free_vector_of_ints(void * xvector)636cf7f2e2dSJohn Marino free_vector_of_ints (void *xvector)
637cf7f2e2dSJohn Marino {
638cf7f2e2dSJohn Marino VEC (int) **vector = xvector;
639cf7f2e2dSJohn Marino
640cf7f2e2dSJohn Marino VEC_free (int, *vector);
641cf7f2e2dSJohn Marino }
642cf7f2e2dSJohn Marino
643cf7f2e2dSJohn Marino static void
do_nothing(splay_tree_key k)644cf7f2e2dSJohn Marino do_nothing (splay_tree_key k)
645cf7f2e2dSJohn Marino {
646cf7f2e2dSJohn Marino }
647cf7f2e2dSJohn Marino
648cf7f2e2dSJohn Marino static void
free_vector_of_osdata_items(splay_tree_value xvalue)649cf7f2e2dSJohn Marino free_vector_of_osdata_items (splay_tree_value xvalue)
650cf7f2e2dSJohn Marino {
651cf7f2e2dSJohn Marino VEC (osdata_item_s) *value = (VEC (osdata_item_s) *) xvalue;
652cf7f2e2dSJohn Marino
653cf7f2e2dSJohn Marino /* We don't free the items itself, it will be done separately. */
654cf7f2e2dSJohn Marino VEC_free (osdata_item_s, value);
655cf7f2e2dSJohn Marino }
656cf7f2e2dSJohn Marino
657cf7f2e2dSJohn Marino static int
splay_tree_int_comparator(splay_tree_key xa,splay_tree_key xb)658cf7f2e2dSJohn Marino splay_tree_int_comparator (splay_tree_key xa, splay_tree_key xb)
659cf7f2e2dSJohn Marino {
660cf7f2e2dSJohn Marino int a = xa;
661cf7f2e2dSJohn Marino int b = xb;
662cf7f2e2dSJohn Marino
663cf7f2e2dSJohn Marino return a - b;
664cf7f2e2dSJohn Marino }
665cf7f2e2dSJohn Marino
666cf7f2e2dSJohn Marino static void
free_splay_tree(void * xt)667cf7f2e2dSJohn Marino free_splay_tree (void *xt)
668cf7f2e2dSJohn Marino {
669cf7f2e2dSJohn Marino splay_tree t = xt;
670cf7f2e2dSJohn Marino splay_tree_delete (t);
6715796c8dcSSimon Schubert }
6725796c8dcSSimon Schubert
6735796c8dcSSimon Schubert static void
list_available_thread_groups(VEC (int)* ids,int recurse)6745796c8dcSSimon Schubert list_available_thread_groups (VEC (int) *ids, int recurse)
675a45ae5f8SJohn Marino {
6765796c8dcSSimon Schubert struct osdata *data;
677cf7f2e2dSJohn Marino struct osdata_item *item;
678cf7f2e2dSJohn Marino int ix_items;
679cf7f2e2dSJohn Marino struct ui_out *uiout = current_uiout;
680cf7f2e2dSJohn Marino
681cf7f2e2dSJohn Marino /* This keeps a map from integer (pid) to VEC (struct osdata_item *)*
682cf7f2e2dSJohn Marino The vector contains information about all threads for the given pid.
683cf7f2e2dSJohn Marino This is assigned an initial value to avoid "may be used uninitialized"
6845796c8dcSSimon Schubert warning from gcc. */
6855796c8dcSSimon Schubert splay_tree tree = NULL;
6865796c8dcSSimon Schubert
687cf7f2e2dSJohn Marino /* get_osdata will throw if it cannot return data. */
688cf7f2e2dSJohn Marino data = get_osdata ("processes");
689cf7f2e2dSJohn Marino make_cleanup_osdata_free (data);
690cf7f2e2dSJohn Marino
691cf7f2e2dSJohn Marino if (recurse)
692cf7f2e2dSJohn Marino {
693cf7f2e2dSJohn Marino struct osdata *threads = get_osdata ("threads");
694cf7f2e2dSJohn Marino
695cf7f2e2dSJohn Marino make_cleanup_osdata_free (threads);
696cf7f2e2dSJohn Marino tree = splay_tree_new (splay_tree_int_comparator,
697cf7f2e2dSJohn Marino do_nothing,
698cf7f2e2dSJohn Marino free_vector_of_osdata_items);
699cf7f2e2dSJohn Marino make_cleanup (free_splay_tree, tree);
700cf7f2e2dSJohn Marino
701cf7f2e2dSJohn Marino for (ix_items = 0;
702cf7f2e2dSJohn Marino VEC_iterate (osdata_item_s, threads->items,
703cf7f2e2dSJohn Marino ix_items, item);
704cf7f2e2dSJohn Marino ix_items++)
705cf7f2e2dSJohn Marino {
706cf7f2e2dSJohn Marino const char *pid = get_osdata_column (item, "pid");
707cf7f2e2dSJohn Marino int pid_i = strtoul (pid, NULL, 0);
708cf7f2e2dSJohn Marino VEC (osdata_item_s) *vec = 0;
709cf7f2e2dSJohn Marino
710cf7f2e2dSJohn Marino splay_tree_node n = splay_tree_lookup (tree, pid_i);
711cf7f2e2dSJohn Marino if (!n)
712cf7f2e2dSJohn Marino {
713cf7f2e2dSJohn Marino VEC_safe_push (osdata_item_s, vec, item);
714cf7f2e2dSJohn Marino splay_tree_insert (tree, pid_i, (splay_tree_value)vec);
715cf7f2e2dSJohn Marino }
716cf7f2e2dSJohn Marino else
717cf7f2e2dSJohn Marino {
718cf7f2e2dSJohn Marino vec = (VEC (osdata_item_s) *) n->value;
719cf7f2e2dSJohn Marino VEC_safe_push (osdata_item_s, vec, item);
720cf7f2e2dSJohn Marino n->value = (splay_tree_value) vec;
7215796c8dcSSimon Schubert }
7225796c8dcSSimon Schubert }
7235796c8dcSSimon Schubert }
7245796c8dcSSimon Schubert
7255796c8dcSSimon Schubert make_cleanup_ui_out_list_begin_end (uiout, "groups");
7265796c8dcSSimon Schubert
7275796c8dcSSimon Schubert for (ix_items = 0;
728cf7f2e2dSJohn Marino VEC_iterate (osdata_item_s, data->items,
7295796c8dcSSimon Schubert ix_items, item);
7305796c8dcSSimon Schubert ix_items++)
7315796c8dcSSimon Schubert {
7325796c8dcSSimon Schubert struct cleanup *back_to;
733cf7f2e2dSJohn Marino
734cf7f2e2dSJohn Marino const char *pid = get_osdata_column (item, "pid");
735cf7f2e2dSJohn Marino const char *cmd = get_osdata_column (item, "command");
736cf7f2e2dSJohn Marino const char *user = get_osdata_column (item, "user");
737cf7f2e2dSJohn Marino const char *cores = get_osdata_column (item, "cores");
738cf7f2e2dSJohn Marino
739cf7f2e2dSJohn Marino int pid_i = strtoul (pid, NULL, 0);
740cf7f2e2dSJohn Marino
741cf7f2e2dSJohn Marino /* At present, the target will return all available processes
742cf7f2e2dSJohn Marino and if information about specific ones was required, we filter
743cf7f2e2dSJohn Marino undesired processes here. */
744cf7f2e2dSJohn Marino if (ids && bsearch (&pid_i, VEC_address (int, ids),
745cf7f2e2dSJohn Marino VEC_length (int, ids),
746cf7f2e2dSJohn Marino sizeof (int), compare_positive_ints) == NULL)
7475796c8dcSSimon Schubert continue;
7485796c8dcSSimon Schubert
7495796c8dcSSimon Schubert
7505796c8dcSSimon Schubert back_to = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
7515796c8dcSSimon Schubert
7525796c8dcSSimon Schubert ui_out_field_fmt (uiout, "id", "%s", pid);
7535796c8dcSSimon Schubert ui_out_field_string (uiout, "type", "process");
754cf7f2e2dSJohn Marino if (cmd)
755cf7f2e2dSJohn Marino ui_out_field_string (uiout, "description", cmd);
756cf7f2e2dSJohn Marino if (user)
757cf7f2e2dSJohn Marino ui_out_field_string (uiout, "user", user);
758cf7f2e2dSJohn Marino if (cores)
759cf7f2e2dSJohn Marino output_cores (uiout, "cores", cores);
760cf7f2e2dSJohn Marino
761cf7f2e2dSJohn Marino if (recurse)
762cf7f2e2dSJohn Marino {
763cf7f2e2dSJohn Marino splay_tree_node n = splay_tree_lookup (tree, pid_i);
764cf7f2e2dSJohn Marino if (n)
765cf7f2e2dSJohn Marino {
766cf7f2e2dSJohn Marino VEC (osdata_item_s) *children = (VEC (osdata_item_s) *) n->value;
767cf7f2e2dSJohn Marino struct osdata_item *child;
768cf7f2e2dSJohn Marino int ix_child;
769cf7f2e2dSJohn Marino
770cf7f2e2dSJohn Marino make_cleanup_ui_out_list_begin_end (uiout, "threads");
771cf7f2e2dSJohn Marino
772cf7f2e2dSJohn Marino for (ix_child = 0;
773cf7f2e2dSJohn Marino VEC_iterate (osdata_item_s, children, ix_child, child);
774cf7f2e2dSJohn Marino ++ix_child)
775cf7f2e2dSJohn Marino {
776cf7f2e2dSJohn Marino struct cleanup *back_to_2 =
777cf7f2e2dSJohn Marino make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
778cf7f2e2dSJohn Marino const char *tid = get_osdata_column (child, "tid");
779cf7f2e2dSJohn Marino const char *tcore = get_osdata_column (child, "core");
780cf7f2e2dSJohn Marino
781cf7f2e2dSJohn Marino ui_out_field_string (uiout, "id", tid);
782cf7f2e2dSJohn Marino if (tcore)
783cf7f2e2dSJohn Marino ui_out_field_string (uiout, "core", tcore);
784cf7f2e2dSJohn Marino
7855796c8dcSSimon Schubert do_cleanups (back_to_2);
7865796c8dcSSimon Schubert }
7875796c8dcSSimon Schubert }
7885796c8dcSSimon Schubert }
789cf7f2e2dSJohn Marino
790cf7f2e2dSJohn Marino do_cleanups (back_to);
791cf7f2e2dSJohn Marino }
7925796c8dcSSimon Schubert }
793a45ae5f8SJohn Marino
794cf7f2e2dSJohn Marino void
mi_cmd_list_thread_groups(char * command,char ** argv,int argc)795cf7f2e2dSJohn Marino mi_cmd_list_thread_groups (char *command, char **argv, int argc)
796cf7f2e2dSJohn Marino {
797cf7f2e2dSJohn Marino struct ui_out *uiout = current_uiout;
798cf7f2e2dSJohn Marino struct cleanup *back_to;
799cf7f2e2dSJohn Marino int available = 0;
800cf7f2e2dSJohn Marino int recurse = 0;
801cf7f2e2dSJohn Marino VEC (int) *ids = 0;
802cf7f2e2dSJohn Marino
803a45ae5f8SJohn Marino enum opt
804cf7f2e2dSJohn Marino {
805cf7f2e2dSJohn Marino AVAILABLE_OPT, RECURSE_OPT
806cf7f2e2dSJohn Marino };
807cf7f2e2dSJohn Marino static const struct mi_opt opts[] =
808cf7f2e2dSJohn Marino {
809cf7f2e2dSJohn Marino {"-available", AVAILABLE_OPT, 0},
810cf7f2e2dSJohn Marino {"-recurse", RECURSE_OPT, 1},
811cf7f2e2dSJohn Marino { 0, 0, 0 }
812cf7f2e2dSJohn Marino };
813cf7f2e2dSJohn Marino
814cf7f2e2dSJohn Marino int oind = 0;
815cf7f2e2dSJohn Marino char *oarg;
816cf7f2e2dSJohn Marino
817cf7f2e2dSJohn Marino while (1)
818cf7f2e2dSJohn Marino {
819cf7f2e2dSJohn Marino int opt = mi_getopt ("-list-thread-groups", argc, argv, opts,
820cf7f2e2dSJohn Marino &oind, &oarg);
821cf7f2e2dSJohn Marino
822cf7f2e2dSJohn Marino if (opt < 0)
823cf7f2e2dSJohn Marino break;
824cf7f2e2dSJohn Marino switch ((enum opt) opt)
825cf7f2e2dSJohn Marino {
826cf7f2e2dSJohn Marino case AVAILABLE_OPT:
827cf7f2e2dSJohn Marino available = 1;
828cf7f2e2dSJohn Marino break;
829cf7f2e2dSJohn Marino case RECURSE_OPT:
830cf7f2e2dSJohn Marino if (strcmp (oarg, "0") == 0)
831c50c785cSJohn Marino ;
832c50c785cSJohn Marino else if (strcmp (oarg, "1") == 0)
833cf7f2e2dSJohn Marino recurse = 1;
834cf7f2e2dSJohn Marino else
835cf7f2e2dSJohn Marino error (_("only '0' and '1' are valid values "
836cf7f2e2dSJohn Marino "for the '--recurse' option"));
837cf7f2e2dSJohn Marino break;
838cf7f2e2dSJohn Marino }
839cf7f2e2dSJohn Marino }
840cf7f2e2dSJohn Marino
841cf7f2e2dSJohn Marino for (; oind < argc; ++oind)
842cf7f2e2dSJohn Marino {
843c50c785cSJohn Marino char *end;
844cf7f2e2dSJohn Marino int inf;
845cf7f2e2dSJohn Marino
846cf7f2e2dSJohn Marino if (*(argv[oind]) != 'i')
847cf7f2e2dSJohn Marino error (_("invalid syntax of group id '%s'"), argv[oind]);
848c50c785cSJohn Marino
849cf7f2e2dSJohn Marino inf = strtoul (argv[oind] + 1, &end, 0);
850cf7f2e2dSJohn Marino
851cf7f2e2dSJohn Marino if (*end != '\0')
852cf7f2e2dSJohn Marino error (_("invalid syntax of group id '%s'"), argv[oind]);
853cf7f2e2dSJohn Marino VEC_safe_push (int, ids, inf);
854cf7f2e2dSJohn Marino }
855cf7f2e2dSJohn Marino if (VEC_length (int, ids) > 1)
856cf7f2e2dSJohn Marino qsort (VEC_address (int, ids),
857cf7f2e2dSJohn Marino VEC_length (int, ids),
858cf7f2e2dSJohn Marino sizeof (int), compare_positive_ints);
859cf7f2e2dSJohn Marino
860cf7f2e2dSJohn Marino back_to = make_cleanup (free_vector_of_ints, &ids);
861cf7f2e2dSJohn Marino
862cf7f2e2dSJohn Marino if (available)
863cf7f2e2dSJohn Marino {
864cf7f2e2dSJohn Marino list_available_thread_groups (ids, recurse);
865cf7f2e2dSJohn Marino }
866cf7f2e2dSJohn Marino else if (VEC_length (int, ids) == 1)
867cf7f2e2dSJohn Marino {
868cf7f2e2dSJohn Marino /* Local thread groups, single id. */
869c50c785cSJohn Marino int id = *VEC_address (int, ids);
870cf7f2e2dSJohn Marino struct inferior *inf = find_inferior_id (id);
871c50c785cSJohn Marino
8725796c8dcSSimon Schubert if (!inf)
8735796c8dcSSimon Schubert error (_("Non-existent thread group id '%d'"), id);
8745796c8dcSSimon Schubert
875cf7f2e2dSJohn Marino print_thread_info (uiout, NULL, inf->pid);
876cf7f2e2dSJohn Marino }
877cf7f2e2dSJohn Marino else
878cf7f2e2dSJohn Marino {
879cf7f2e2dSJohn Marino struct print_one_inferior_data data;
880cf7f2e2dSJohn Marino
881cf7f2e2dSJohn Marino data.recurse = recurse;
882cf7f2e2dSJohn Marino data.inferiors = ids;
883cf7f2e2dSJohn Marino
8845796c8dcSSimon Schubert /* Local thread groups. Either no explicit ids -- and we
885cf7f2e2dSJohn Marino print everything, or several explicit ids. In both cases,
886cf7f2e2dSJohn Marino we print more than one group, and have to use 'groups'
8875796c8dcSSimon Schubert as the top-level element. */
8885796c8dcSSimon Schubert make_cleanup_ui_out_list_begin_end (uiout, "groups");
8895796c8dcSSimon Schubert update_thread_list ();
8905796c8dcSSimon Schubert iterate_over_inferiors (print_one_inferior, &data);
8915796c8dcSSimon Schubert }
8925796c8dcSSimon Schubert
8935796c8dcSSimon Schubert do_cleanups (back_to);
8945796c8dcSSimon Schubert }
8955796c8dcSSimon Schubert
896a45ae5f8SJohn Marino void
mi_cmd_data_list_register_names(char * command,char ** argv,int argc)8975796c8dcSSimon Schubert mi_cmd_data_list_register_names (char *command, char **argv, int argc)
8985796c8dcSSimon Schubert {
8995796c8dcSSimon Schubert struct gdbarch *gdbarch;
9005796c8dcSSimon Schubert struct ui_out *uiout = current_uiout;
9015796c8dcSSimon Schubert int regnum, numregs;
9025796c8dcSSimon Schubert int i;
9035796c8dcSSimon Schubert struct cleanup *cleanup;
9045796c8dcSSimon Schubert
9055796c8dcSSimon Schubert /* Note that the test for a valid register must include checking the
9065796c8dcSSimon Schubert gdbarch_register_name because gdbarch_num_regs may be allocated
907cf7f2e2dSJohn Marino for the union of the register sets within a family of related
9085796c8dcSSimon Schubert processors. In this case, some entries of gdbarch_register_name
9095796c8dcSSimon Schubert will change depending upon the particular processor being
9105796c8dcSSimon Schubert debugged. */
9115796c8dcSSimon Schubert
9125796c8dcSSimon Schubert gdbarch = get_current_arch ();
9135796c8dcSSimon Schubert numregs = gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch);
9145796c8dcSSimon Schubert
9155796c8dcSSimon Schubert cleanup = make_cleanup_ui_out_list_begin_end (uiout, "register-names");
9165796c8dcSSimon Schubert
9175796c8dcSSimon Schubert if (argc == 0) /* No args, just do all the regs. */
9185796c8dcSSimon Schubert {
9195796c8dcSSimon Schubert for (regnum = 0;
9205796c8dcSSimon Schubert regnum < numregs;
9215796c8dcSSimon Schubert regnum++)
9225796c8dcSSimon Schubert {
9235796c8dcSSimon Schubert if (gdbarch_register_name (gdbarch, regnum) == NULL
9245796c8dcSSimon Schubert || *(gdbarch_register_name (gdbarch, regnum)) == '\0')
9255796c8dcSSimon Schubert ui_out_field_string (uiout, NULL, "");
9265796c8dcSSimon Schubert else
9275796c8dcSSimon Schubert ui_out_field_string (uiout, NULL,
9285796c8dcSSimon Schubert gdbarch_register_name (gdbarch, regnum));
9295796c8dcSSimon Schubert }
9305796c8dcSSimon Schubert }
9315796c8dcSSimon Schubert
932c50c785cSJohn Marino /* Else, list of register #s, just do listed regs. */
9335796c8dcSSimon Schubert for (i = 0; i < argc; i++)
9345796c8dcSSimon Schubert {
9355796c8dcSSimon Schubert regnum = atoi (argv[i]);
9365796c8dcSSimon Schubert if (regnum < 0 || regnum >= numregs)
9375796c8dcSSimon Schubert error (_("bad register number"));
9385796c8dcSSimon Schubert
9395796c8dcSSimon Schubert if (gdbarch_register_name (gdbarch, regnum) == NULL
9405796c8dcSSimon Schubert || *(gdbarch_register_name (gdbarch, regnum)) == '\0')
9415796c8dcSSimon Schubert ui_out_field_string (uiout, NULL, "");
9425796c8dcSSimon Schubert else
9435796c8dcSSimon Schubert ui_out_field_string (uiout, NULL,
9445796c8dcSSimon Schubert gdbarch_register_name (gdbarch, regnum));
9455796c8dcSSimon Schubert }
9465796c8dcSSimon Schubert do_cleanups (cleanup);
9475796c8dcSSimon Schubert }
948a45ae5f8SJohn Marino
9495796c8dcSSimon Schubert void
mi_cmd_data_list_changed_registers(char * command,char ** argv,int argc)9505796c8dcSSimon Schubert mi_cmd_data_list_changed_registers (char *command, char **argv, int argc)
9515796c8dcSSimon Schubert {
9525796c8dcSSimon Schubert static struct regcache *this_regs = NULL;
9535796c8dcSSimon Schubert struct ui_out *uiout = current_uiout;
9545796c8dcSSimon Schubert struct regcache *prev_regs;
9555796c8dcSSimon Schubert struct gdbarch *gdbarch;
9565796c8dcSSimon Schubert int regnum, numregs, changed;
9575796c8dcSSimon Schubert int i;
9585796c8dcSSimon Schubert struct cleanup *cleanup;
9595796c8dcSSimon Schubert
9605796c8dcSSimon Schubert /* The last time we visited this function, the current frame's
9615796c8dcSSimon Schubert register contents were saved in THIS_REGS. Move THIS_REGS over
9625796c8dcSSimon Schubert to PREV_REGS, and refresh THIS_REGS with the now-current register
9635796c8dcSSimon Schubert contents. */
9645796c8dcSSimon Schubert
9655796c8dcSSimon Schubert prev_regs = this_regs;
9665796c8dcSSimon Schubert this_regs = frame_save_as_regcache (get_selected_frame (NULL));
9675796c8dcSSimon Schubert cleanup = make_cleanup_regcache_xfree (prev_regs);
9685796c8dcSSimon Schubert
9695796c8dcSSimon Schubert /* Note that the test for a valid register must include checking the
9705796c8dcSSimon Schubert gdbarch_register_name because gdbarch_num_regs may be allocated
9715796c8dcSSimon Schubert for the union of the register sets within a family of related
9725796c8dcSSimon Schubert processors. In this case, some entries of gdbarch_register_name
9735796c8dcSSimon Schubert will change depending upon the particular processor being
9745796c8dcSSimon Schubert debugged. */
9755796c8dcSSimon Schubert
9765796c8dcSSimon Schubert gdbarch = get_regcache_arch (this_regs);
9775796c8dcSSimon Schubert numregs = gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch);
9785796c8dcSSimon Schubert
9795796c8dcSSimon Schubert make_cleanup_ui_out_list_begin_end (uiout, "changed-registers");
9805796c8dcSSimon Schubert
9815796c8dcSSimon Schubert if (argc == 0)
9825796c8dcSSimon Schubert {
9835796c8dcSSimon Schubert /* No args, just do all the regs. */
9845796c8dcSSimon Schubert for (regnum = 0;
985c50c785cSJohn Marino regnum < numregs;
986c50c785cSJohn Marino regnum++)
9875796c8dcSSimon Schubert {
9885796c8dcSSimon Schubert if (gdbarch_register_name (gdbarch, regnum) == NULL
9895796c8dcSSimon Schubert || *(gdbarch_register_name (gdbarch, regnum)) == '\0')
9905796c8dcSSimon Schubert continue;
9915796c8dcSSimon Schubert changed = register_changed_p (regnum, prev_regs, this_regs);
9925796c8dcSSimon Schubert if (changed < 0)
9935796c8dcSSimon Schubert error (_("-data-list-changed-registers: "
9945796c8dcSSimon Schubert "Unable to read register contents."));
9955796c8dcSSimon Schubert else if (changed)
9965796c8dcSSimon Schubert ui_out_field_int (uiout, NULL, regnum);
9975796c8dcSSimon Schubert }
9985796c8dcSSimon Schubert }
9995796c8dcSSimon Schubert
10005796c8dcSSimon Schubert /* Else, list of register #s, just do listed regs. */
10015796c8dcSSimon Schubert for (i = 0; i < argc; i++)
10025796c8dcSSimon Schubert {
10035796c8dcSSimon Schubert regnum = atoi (argv[i]);
1004c50c785cSJohn Marino
1005c50c785cSJohn Marino if (regnum >= 0
10065796c8dcSSimon Schubert && regnum < numregs
10075796c8dcSSimon Schubert && gdbarch_register_name (gdbarch, regnum) != NULL
10085796c8dcSSimon Schubert && *gdbarch_register_name (gdbarch, regnum) != '\000')
10095796c8dcSSimon Schubert {
1010c50c785cSJohn Marino changed = register_changed_p (regnum, prev_regs, this_regs);
10115796c8dcSSimon Schubert if (changed < 0)
10125796c8dcSSimon Schubert error (_("-data-list-changed-registers: "
10135796c8dcSSimon Schubert "Unable to read register contents."));
10145796c8dcSSimon Schubert else if (changed)
10155796c8dcSSimon Schubert ui_out_field_int (uiout, NULL, regnum);
10165796c8dcSSimon Schubert }
10175796c8dcSSimon Schubert else
10185796c8dcSSimon Schubert error (_("bad register number"));
10195796c8dcSSimon Schubert }
10205796c8dcSSimon Schubert do_cleanups (cleanup);
10215796c8dcSSimon Schubert }
1022c50c785cSJohn Marino
1023c50c785cSJohn Marino static int
register_changed_p(int regnum,struct regcache * prev_regs,struct regcache * this_regs)10245796c8dcSSimon Schubert register_changed_p (int regnum, struct regcache *prev_regs,
1025c50c785cSJohn Marino struct regcache *this_regs)
1026c50c785cSJohn Marino {
1027c50c785cSJohn Marino struct gdbarch *gdbarch = get_regcache_arch (this_regs);
10285796c8dcSSimon Schubert gdb_byte prev_buffer[MAX_REGISTER_SIZE];
10295796c8dcSSimon Schubert gdb_byte this_buffer[MAX_REGISTER_SIZE];
10305796c8dcSSimon Schubert enum register_status prev_status;
1031c50c785cSJohn Marino enum register_status this_status;
1032c50c785cSJohn Marino
10335796c8dcSSimon Schubert /* First time through or after gdbarch change consider all registers
1034c50c785cSJohn Marino as changed. */
1035c50c785cSJohn Marino if (!prev_regs || get_regcache_arch (prev_regs) != gdbarch)
1036c50c785cSJohn Marino return 1;
10375796c8dcSSimon Schubert
10385796c8dcSSimon Schubert /* Get register contents and compare. */
1039c50c785cSJohn Marino prev_status = regcache_cooked_read (prev_regs, regnum, prev_buffer);
1040c50c785cSJohn Marino this_status = regcache_cooked_read (this_regs, regnum, this_buffer);
10415796c8dcSSimon Schubert
10425796c8dcSSimon Schubert if (this_status != prev_status)
10435796c8dcSSimon Schubert return 1;
10445796c8dcSSimon Schubert else if (this_status == REG_VALID)
10455796c8dcSSimon Schubert return memcmp (prev_buffer, this_buffer,
10465796c8dcSSimon Schubert register_size (gdbarch, regnum)) != 0;
10475796c8dcSSimon Schubert else
10485796c8dcSSimon Schubert return 0;
10495796c8dcSSimon Schubert }
10505796c8dcSSimon Schubert
10515796c8dcSSimon Schubert /* Return a list of register number and value pairs. The valid
10525796c8dcSSimon Schubert arguments expected are: a letter indicating the format in which to
1053a45ae5f8SJohn Marino display the registers contents. This can be one of: x
10545796c8dcSSimon Schubert (hexadecimal), d (decimal), N (natural), t (binary), o (octal), r
10555796c8dcSSimon Schubert (raw). After the format argument there can be a sequence of
10565796c8dcSSimon Schubert numbers, indicating which registers to fetch the content of. If
10575796c8dcSSimon Schubert the format is the only argument, a list of all the registers with
10585796c8dcSSimon Schubert their values is returned. */
10595796c8dcSSimon Schubert
10605796c8dcSSimon Schubert void
mi_cmd_data_list_register_values(char * command,char ** argv,int argc)10615796c8dcSSimon Schubert mi_cmd_data_list_register_values (char *command, char **argv, int argc)
10625796c8dcSSimon Schubert {
10635796c8dcSSimon Schubert struct ui_out *uiout = current_uiout;
10645796c8dcSSimon Schubert struct frame_info *frame;
10655796c8dcSSimon Schubert struct gdbarch *gdbarch;
10665796c8dcSSimon Schubert int regnum, numregs, format;
1067c50c785cSJohn Marino int i;
1068c50c785cSJohn Marino struct cleanup *list_cleanup, *tuple_cleanup;
10695796c8dcSSimon Schubert
10705796c8dcSSimon Schubert /* Note that the test for a valid register must include checking the
10715796c8dcSSimon Schubert gdbarch_register_name because gdbarch_num_regs may be allocated
10725796c8dcSSimon Schubert for the union of the register sets within a family of related
10735796c8dcSSimon Schubert processors. In this case, some entries of gdbarch_register_name
10745796c8dcSSimon Schubert will change depending upon the particular processor being
10755796c8dcSSimon Schubert debugged. */
10765796c8dcSSimon Schubert
10775796c8dcSSimon Schubert if (argc == 0)
10785796c8dcSSimon Schubert error (_("-data-list-register-values: Usage: "
10795796c8dcSSimon Schubert "-data-list-register-values <format> [<regnum1>...<regnumN>]"));
10805796c8dcSSimon Schubert
10815796c8dcSSimon Schubert format = (int) argv[0][0];
10825796c8dcSSimon Schubert
10835796c8dcSSimon Schubert frame = get_selected_frame (NULL);
10845796c8dcSSimon Schubert gdbarch = get_frame_arch (frame);
10855796c8dcSSimon Schubert numregs = gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch);
10865796c8dcSSimon Schubert
10875796c8dcSSimon Schubert list_cleanup = make_cleanup_ui_out_list_begin_end (uiout, "register-values");
10885796c8dcSSimon Schubert
10895796c8dcSSimon Schubert if (argc == 1)
10905796c8dcSSimon Schubert {
10915796c8dcSSimon Schubert /* No args, beside the format: do all the regs. */
10925796c8dcSSimon Schubert for (regnum = 0;
10935796c8dcSSimon Schubert regnum < numregs;
10945796c8dcSSimon Schubert regnum++)
10955796c8dcSSimon Schubert {
10965796c8dcSSimon Schubert if (gdbarch_register_name (gdbarch, regnum) == NULL
10975796c8dcSSimon Schubert || *(gdbarch_register_name (gdbarch, regnum)) == '\0')
10985796c8dcSSimon Schubert continue;
10995796c8dcSSimon Schubert tuple_cleanup = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
11005796c8dcSSimon Schubert ui_out_field_int (uiout, "number", regnum);
11015796c8dcSSimon Schubert get_register (frame, regnum, format);
11025796c8dcSSimon Schubert do_cleanups (tuple_cleanup);
11035796c8dcSSimon Schubert }
11045796c8dcSSimon Schubert }
11055796c8dcSSimon Schubert
11065796c8dcSSimon Schubert /* Else, list of register #s, just do listed regs. */
11075796c8dcSSimon Schubert for (i = 1; i < argc; i++)
11085796c8dcSSimon Schubert {
11095796c8dcSSimon Schubert regnum = atoi (argv[i]);
1110c50c785cSJohn Marino
11115796c8dcSSimon Schubert if (regnum >= 0
11125796c8dcSSimon Schubert && regnum < numregs
11135796c8dcSSimon Schubert && gdbarch_register_name (gdbarch, regnum) != NULL
11145796c8dcSSimon Schubert && *gdbarch_register_name (gdbarch, regnum) != '\000')
11155796c8dcSSimon Schubert {
11165796c8dcSSimon Schubert tuple_cleanup = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
11175796c8dcSSimon Schubert ui_out_field_int (uiout, "number", regnum);
11185796c8dcSSimon Schubert get_register (frame, regnum, format);
11195796c8dcSSimon Schubert do_cleanups (tuple_cleanup);
1120a45ae5f8SJohn Marino }
11215796c8dcSSimon Schubert else
11225796c8dcSSimon Schubert error (_("bad register number"));
1123a45ae5f8SJohn Marino }
1124c50c785cSJohn Marino do_cleanups (list_cleanup);
11255796c8dcSSimon Schubert }
11265796c8dcSSimon Schubert
11275796c8dcSSimon Schubert /* Output one register's contents in the desired format. */
11285796c8dcSSimon Schubert
11295796c8dcSSimon Schubert static void
get_register(struct frame_info * frame,int regnum,int format)11305796c8dcSSimon Schubert get_register (struct frame_info *frame, int regnum, int format)
1131c50c785cSJohn Marino {
11325796c8dcSSimon Schubert struct gdbarch *gdbarch = get_frame_arch (frame);
1133c50c785cSJohn Marino struct ui_out *uiout = current_uiout;
1134c50c785cSJohn Marino struct value *val;
11355796c8dcSSimon Schubert
11365796c8dcSSimon Schubert if (format == 'N')
11375796c8dcSSimon Schubert format = 0;
11385796c8dcSSimon Schubert
11395796c8dcSSimon Schubert val = get_frame_register_value (frame, regnum);
1140c50c785cSJohn Marino
11415796c8dcSSimon Schubert if (value_optimized_out (val))
11425796c8dcSSimon Schubert error (_("Optimized out"));
11435796c8dcSSimon Schubert
11445796c8dcSSimon Schubert if (format == 'r')
11455796c8dcSSimon Schubert {
11465796c8dcSSimon Schubert int j;
11475796c8dcSSimon Schubert char *ptr, buf[1024];
1148cf7f2e2dSJohn Marino const gdb_byte *valaddr = value_contents_for_printing (val);
1149c50c785cSJohn Marino
11505796c8dcSSimon Schubert strcpy (buf, "0x");
11515796c8dcSSimon Schubert ptr = buf + 2;
11525796c8dcSSimon Schubert for (j = 0; j < register_size (gdbarch, regnum); j++)
11535796c8dcSSimon Schubert {
11545796c8dcSSimon Schubert int idx = gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG ?
11555796c8dcSSimon Schubert j : register_size (gdbarch, regnum) - 1 - j;
11565796c8dcSSimon Schubert
11575796c8dcSSimon Schubert sprintf (ptr, "%02x", (unsigned char) valaddr[idx]);
1158cf7f2e2dSJohn Marino ptr += 2;
11595796c8dcSSimon Schubert }
11605796c8dcSSimon Schubert ui_out_field_string (uiout, "value", buf);
1161c50c785cSJohn Marino }
1162c50c785cSJohn Marino else
1163c50c785cSJohn Marino {
1164c50c785cSJohn Marino struct value_print_options opts;
11655796c8dcSSimon Schubert struct ui_file *stb;
11665796c8dcSSimon Schubert struct cleanup *old_chain;
11675796c8dcSSimon Schubert
11685796c8dcSSimon Schubert stb = mem_fileopen ();
11695796c8dcSSimon Schubert old_chain = make_cleanup_ui_file_delete (stb);
11705796c8dcSSimon Schubert
11715796c8dcSSimon Schubert get_formatted_print_options (&opts, format);
1172c50c785cSJohn Marino opts.deref_ref = 1;
1173c50c785cSJohn Marino val_print (value_type (val),
11745796c8dcSSimon Schubert value_contents_for_printing (val),
11755796c8dcSSimon Schubert value_embedded_offset (val), 0,
11765796c8dcSSimon Schubert stb, 0, val, &opts, current_language);
11775796c8dcSSimon Schubert ui_out_field_stream (uiout, "value", stb);
11785796c8dcSSimon Schubert do_cleanups (old_chain);
11795796c8dcSSimon Schubert }
11805796c8dcSSimon Schubert }
11815796c8dcSSimon Schubert
11825796c8dcSSimon Schubert /* Write given values into registers. The registers and values are
11835796c8dcSSimon Schubert given as pairs. The corresponding MI command is
11845796c8dcSSimon Schubert -data-write-register-values <format>
11855796c8dcSSimon Schubert [<regnum1> <value1>...<regnumN> <valueN>] */
11865796c8dcSSimon Schubert void
mi_cmd_data_write_register_values(char * command,char ** argv,int argc)11875796c8dcSSimon Schubert mi_cmd_data_write_register_values (char *command, char **argv, int argc)
11885796c8dcSSimon Schubert {
11895796c8dcSSimon Schubert struct regcache *regcache;
11905796c8dcSSimon Schubert struct gdbarch *gdbarch;
11915796c8dcSSimon Schubert int numregs, i;
11925796c8dcSSimon Schubert
1193c50c785cSJohn Marino /* Note that the test for a valid register must include checking the
1194c50c785cSJohn Marino gdbarch_register_name because gdbarch_num_regs may be allocated
11955796c8dcSSimon Schubert for the union of the register sets within a family of related
11965796c8dcSSimon Schubert processors. In this case, some entries of gdbarch_register_name
11975796c8dcSSimon Schubert will change depending upon the particular processor being
11985796c8dcSSimon Schubert debugged. */
1199c50c785cSJohn Marino
12005796c8dcSSimon Schubert regcache = get_current_regcache ();
12015796c8dcSSimon Schubert gdbarch = get_regcache_arch (regcache);
1202c50c785cSJohn Marino numregs = gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch);
12035796c8dcSSimon Schubert
12045796c8dcSSimon Schubert if (argc == 0)
1205c50c785cSJohn Marino error (_("-data-write-register-values: Usage: -data-write-register-"
1206c50c785cSJohn Marino "values <format> [<regnum1> <value1>...<regnumN> <valueN>]"));
12075796c8dcSSimon Schubert
12085796c8dcSSimon Schubert if (!target_has_registers)
12095796c8dcSSimon Schubert error (_("-data-write-register-values: No registers."));
12105796c8dcSSimon Schubert
12115796c8dcSSimon Schubert if (!(argc - 1))
12125796c8dcSSimon Schubert error (_("-data-write-register-values: No regs and values specified."));
12135796c8dcSSimon Schubert
12145796c8dcSSimon Schubert if ((argc - 1) % 2)
12155796c8dcSSimon Schubert error (_("-data-write-register-values: "
12165796c8dcSSimon Schubert "Regs and vals are not in pairs."));
12175796c8dcSSimon Schubert
12185796c8dcSSimon Schubert for (i = 1; i < argc; i = i + 2)
12195796c8dcSSimon Schubert {
12205796c8dcSSimon Schubert int regnum = atoi (argv[i]);
12215796c8dcSSimon Schubert
12225796c8dcSSimon Schubert if (regnum >= 0 && regnum < numregs
12235796c8dcSSimon Schubert && gdbarch_register_name (gdbarch, regnum)
12245796c8dcSSimon Schubert && *gdbarch_register_name (gdbarch, regnum))
1225c50c785cSJohn Marino {
12265796c8dcSSimon Schubert LONGEST value;
12275796c8dcSSimon Schubert
12285796c8dcSSimon Schubert /* Get the value as a number. */
12295796c8dcSSimon Schubert value = parse_and_eval_address (argv[i + 1]);
12305796c8dcSSimon Schubert
12315796c8dcSSimon Schubert /* Write it down. */
12325796c8dcSSimon Schubert regcache_cooked_write_signed (regcache, regnum, value);
12335796c8dcSSimon Schubert }
12345796c8dcSSimon Schubert else
12355796c8dcSSimon Schubert error (_("bad register number"));
12365796c8dcSSimon Schubert }
12375796c8dcSSimon Schubert }
12385796c8dcSSimon Schubert
12395796c8dcSSimon Schubert /* Evaluate the value of the argument. The argument is an
1240a45ae5f8SJohn Marino expression. If the expression contains spaces it needs to be
12415796c8dcSSimon Schubert included in double quotes. */
12425796c8dcSSimon Schubert
12435796c8dcSSimon Schubert void
mi_cmd_data_evaluate_expression(char * command,char ** argv,int argc)12445796c8dcSSimon Schubert mi_cmd_data_evaluate_expression (char *command, char **argv, int argc)
12455796c8dcSSimon Schubert {
12465796c8dcSSimon Schubert struct expression *expr;
1247c50c785cSJohn Marino struct cleanup *old_chain;
1248c50c785cSJohn Marino struct value *val;
12495796c8dcSSimon Schubert struct ui_file *stb;
12505796c8dcSSimon Schubert struct value_print_options opts;
12515796c8dcSSimon Schubert struct ui_out *uiout = current_uiout;
12525796c8dcSSimon Schubert
12535796c8dcSSimon Schubert stb = mem_fileopen ();
12545796c8dcSSimon Schubert old_chain = make_cleanup_ui_file_delete (stb);
12555796c8dcSSimon Schubert
12565796c8dcSSimon Schubert if (argc != 1)
12575796c8dcSSimon Schubert error (_("-data-evaluate-expression: "
12585796c8dcSSimon Schubert "Usage: -data-evaluate-expression expression"));
12595796c8dcSSimon Schubert
1260cf7f2e2dSJohn Marino expr = parse_expression (argv[0]);
12615796c8dcSSimon Schubert
12625796c8dcSSimon Schubert make_cleanup (free_current_contents, &expr);
12635796c8dcSSimon Schubert
12645796c8dcSSimon Schubert val = evaluate_expression (expr);
12655796c8dcSSimon Schubert
12665796c8dcSSimon Schubert /* Print the result of the expression evaluation. */
12675796c8dcSSimon Schubert get_user_print_options (&opts);
12685796c8dcSSimon Schubert opts.deref_ref = 0;
12695796c8dcSSimon Schubert common_val_print (val, stb, 0, &opts, current_language);
12705796c8dcSSimon Schubert
12715796c8dcSSimon Schubert ui_out_field_stream (uiout, "value", stb);
12725796c8dcSSimon Schubert
12735796c8dcSSimon Schubert do_cleanups (old_chain);
12745796c8dcSSimon Schubert }
12755796c8dcSSimon Schubert
12765796c8dcSSimon Schubert /* This is the -data-read-memory command.
12775796c8dcSSimon Schubert
12785796c8dcSSimon Schubert ADDR: start address of data to be dumped.
12795796c8dcSSimon Schubert WORD-FORMAT: a char indicating format for the ``word''. See
12805796c8dcSSimon Schubert the ``x'' command.
12815796c8dcSSimon Schubert WORD-SIZE: size of each ``word''; 1,2,4, or 8 bytes.
12825796c8dcSSimon Schubert NR_ROW: Number of rows.
12835796c8dcSSimon Schubert NR_COL: The number of colums (words per row).
12845796c8dcSSimon Schubert ASCHAR: (OPTIONAL) Append an ascii character dump to each row. Use
12855796c8dcSSimon Schubert ASCHAR for unprintable characters.
12865796c8dcSSimon Schubert
12875796c8dcSSimon Schubert Reads SIZE*NR_ROW*NR_COL bytes starting at ADDR from memory and
12885796c8dcSSimon Schubert displayes them. Returns:
12895796c8dcSSimon Schubert
12905796c8dcSSimon Schubert {addr="...",rowN={wordN="..." ,... [,ascii="..."]}, ...}
1291a45ae5f8SJohn Marino
12925796c8dcSSimon Schubert Returns:
12935796c8dcSSimon Schubert The number of bytes read is SIZE*ROW*COL. */
12945796c8dcSSimon Schubert
12955796c8dcSSimon Schubert void
mi_cmd_data_read_memory(char * command,char ** argv,int argc)12965796c8dcSSimon Schubert mi_cmd_data_read_memory (char *command, char **argv, int argc)
12975796c8dcSSimon Schubert {
12985796c8dcSSimon Schubert struct gdbarch *gdbarch = get_current_arch ();
12995796c8dcSSimon Schubert struct ui_out *uiout = current_uiout;
13005796c8dcSSimon Schubert struct cleanup *cleanups = make_cleanup (null_cleanup, NULL);
13015796c8dcSSimon Schubert CORE_ADDR addr;
13025796c8dcSSimon Schubert long total_bytes, nr_cols, nr_rows;
13035796c8dcSSimon Schubert char word_format;
13045796c8dcSSimon Schubert struct type *word_type;
13055796c8dcSSimon Schubert long word_size;
13065796c8dcSSimon Schubert char word_asize;
13075796c8dcSSimon Schubert char aschar;
13085796c8dcSSimon Schubert gdb_byte *mbuf;
13095796c8dcSSimon Schubert int nr_bytes;
13105796c8dcSSimon Schubert long offset = 0;
1311a45ae5f8SJohn Marino int oind = 0;
13125796c8dcSSimon Schubert char *oarg;
13135796c8dcSSimon Schubert enum opt
13145796c8dcSSimon Schubert {
13155796c8dcSSimon Schubert OFFSET_OPT
13165796c8dcSSimon Schubert };
13175796c8dcSSimon Schubert static const struct mi_opt opts[] =
13185796c8dcSSimon Schubert {
1319c50c785cSJohn Marino {"o", OFFSET_OPT, 1},
13205796c8dcSSimon Schubert { 0, 0, 0 }
1321cf7f2e2dSJohn Marino };
13225796c8dcSSimon Schubert
13235796c8dcSSimon Schubert while (1)
13245796c8dcSSimon Schubert {
13255796c8dcSSimon Schubert int opt = mi_getopt ("-data-read-memory", argc, argv, opts,
13265796c8dcSSimon Schubert &oind, &oarg);
13275796c8dcSSimon Schubert
13285796c8dcSSimon Schubert if (opt < 0)
13295796c8dcSSimon Schubert break;
13305796c8dcSSimon Schubert switch ((enum opt) opt)
13315796c8dcSSimon Schubert {
13325796c8dcSSimon Schubert case OFFSET_OPT:
13335796c8dcSSimon Schubert offset = atol (oarg);
13345796c8dcSSimon Schubert break;
1335c50c785cSJohn Marino }
1336c50c785cSJohn Marino }
13375796c8dcSSimon Schubert argv += oind;
13385796c8dcSSimon Schubert argc -= oind;
13395796c8dcSSimon Schubert
13405796c8dcSSimon Schubert if (argc < 5 || argc > 6)
13415796c8dcSSimon Schubert error (_("-data-read-memory: Usage: "
13425796c8dcSSimon Schubert "ADDR WORD-FORMAT WORD-SIZE NR-ROWS NR-COLS [ASCHAR]."));
13435796c8dcSSimon Schubert
13445796c8dcSSimon Schubert /* Extract all the arguments. */
13455796c8dcSSimon Schubert
13465796c8dcSSimon Schubert /* Start address of the memory dump. */
13475796c8dcSSimon Schubert addr = parse_and_eval_address (argv[0]) + offset;
13485796c8dcSSimon Schubert /* The format character to use when displaying a memory word. See
13495796c8dcSSimon Schubert the ``x'' command. */
13505796c8dcSSimon Schubert word_format = argv[1][0];
13515796c8dcSSimon Schubert /* The size of the memory word. */
13525796c8dcSSimon Schubert word_size = atol (argv[2]);
13535796c8dcSSimon Schubert switch (word_size)
13545796c8dcSSimon Schubert {
13555796c8dcSSimon Schubert case 1:
13565796c8dcSSimon Schubert word_type = builtin_type (gdbarch)->builtin_int8;
13575796c8dcSSimon Schubert word_asize = 'b';
13585796c8dcSSimon Schubert break;
13595796c8dcSSimon Schubert case 2:
13605796c8dcSSimon Schubert word_type = builtin_type (gdbarch)->builtin_int16;
13615796c8dcSSimon Schubert word_asize = 'h';
13625796c8dcSSimon Schubert break;
13635796c8dcSSimon Schubert case 4:
13645796c8dcSSimon Schubert word_type = builtin_type (gdbarch)->builtin_int32;
13655796c8dcSSimon Schubert word_asize = 'w';
13665796c8dcSSimon Schubert break;
13675796c8dcSSimon Schubert case 8:
13685796c8dcSSimon Schubert word_type = builtin_type (gdbarch)->builtin_int64;
13695796c8dcSSimon Schubert word_asize = 'g';
13705796c8dcSSimon Schubert break;
13715796c8dcSSimon Schubert default:
1372c50c785cSJohn Marino word_type = builtin_type (gdbarch)->builtin_int8;
13735796c8dcSSimon Schubert word_asize = 'b';
13745796c8dcSSimon Schubert }
13755796c8dcSSimon Schubert /* The number of rows. */
13765796c8dcSSimon Schubert nr_rows = atol (argv[3]);
1377c50c785cSJohn Marino if (nr_rows <= 0)
13785796c8dcSSimon Schubert error (_("-data-read-memory: invalid number of rows."));
13795796c8dcSSimon Schubert
13805796c8dcSSimon Schubert /* Number of bytes per row. */
13815796c8dcSSimon Schubert nr_cols = atol (argv[4]);
13825796c8dcSSimon Schubert if (nr_cols <= 0)
13835796c8dcSSimon Schubert error (_("-data-read-memory: invalid number of columns."));
13845796c8dcSSimon Schubert
13855796c8dcSSimon Schubert /* The un-printable character when printing ascii. */
13865796c8dcSSimon Schubert if (argc == 6)
13875796c8dcSSimon Schubert aschar = *argv[5];
13885796c8dcSSimon Schubert else
13895796c8dcSSimon Schubert aschar = 0;
13905796c8dcSSimon Schubert
13915796c8dcSSimon Schubert /* Create a buffer and read it in. */
1392c50c785cSJohn Marino total_bytes = word_size * nr_rows * nr_cols;
13935796c8dcSSimon Schubert mbuf = xcalloc (total_bytes, 1);
13945796c8dcSSimon Schubert make_cleanup (xfree, mbuf);
13955796c8dcSSimon Schubert
1396c50c785cSJohn Marino /* Dispatch memory reads to the topmost target, not the flattened
13975796c8dcSSimon Schubert current_target. */
13985796c8dcSSimon Schubert nr_bytes = target_read (current_target.beneath,
13995796c8dcSSimon Schubert TARGET_OBJECT_MEMORY, NULL, mbuf,
14005796c8dcSSimon Schubert addr, total_bytes);
14015796c8dcSSimon Schubert if (nr_bytes <= 0)
14025796c8dcSSimon Schubert error (_("Unable to read memory."));
14035796c8dcSSimon Schubert
14045796c8dcSSimon Schubert /* Output the header information. */
14055796c8dcSSimon Schubert ui_out_field_core_addr (uiout, "addr", gdbarch, addr);
14065796c8dcSSimon Schubert ui_out_field_int (uiout, "nr-bytes", nr_bytes);
14075796c8dcSSimon Schubert ui_out_field_int (uiout, "total-bytes", total_bytes);
14085796c8dcSSimon Schubert ui_out_field_core_addr (uiout, "next-row",
14095796c8dcSSimon Schubert gdbarch, addr + word_size * nr_cols);
14105796c8dcSSimon Schubert ui_out_field_core_addr (uiout, "prev-row",
14115796c8dcSSimon Schubert gdbarch, addr - word_size * nr_cols);
14125796c8dcSSimon Schubert ui_out_field_core_addr (uiout, "next-page", gdbarch, addr + total_bytes);
14135796c8dcSSimon Schubert ui_out_field_core_addr (uiout, "prev-page", gdbarch, addr - total_bytes);
14145796c8dcSSimon Schubert
1415cf7f2e2dSJohn Marino /* Build the result as a two dimentional table. */
14165796c8dcSSimon Schubert {
14175796c8dcSSimon Schubert struct ui_file *stream;
14185796c8dcSSimon Schubert struct cleanup *cleanup_stream;
14195796c8dcSSimon Schubert int row;
14205796c8dcSSimon Schubert int row_byte;
14215796c8dcSSimon Schubert
14225796c8dcSSimon Schubert stream = mem_fileopen ();
14235796c8dcSSimon Schubert cleanup_stream = make_cleanup_ui_file_delete (stream);
14245796c8dcSSimon Schubert
14255796c8dcSSimon Schubert make_cleanup_ui_out_list_begin_end (uiout, "memory");
14265796c8dcSSimon Schubert for (row = 0, row_byte = 0;
14275796c8dcSSimon Schubert row < nr_rows;
14285796c8dcSSimon Schubert row++, row_byte += nr_cols * word_size)
1429c50c785cSJohn Marino {
1430c50c785cSJohn Marino int col;
14315796c8dcSSimon Schubert int col_byte;
14325796c8dcSSimon Schubert struct cleanup *cleanup_tuple;
14335796c8dcSSimon Schubert struct cleanup *cleanup_list_data;
14345796c8dcSSimon Schubert struct value_print_options opts;
14355796c8dcSSimon Schubert
14365796c8dcSSimon Schubert cleanup_tuple = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
14375796c8dcSSimon Schubert ui_out_field_core_addr (uiout, "addr", gdbarch, addr + row_byte);
14385796c8dcSSimon Schubert /* ui_out_field_core_addr_symbolic (uiout, "saddr", addr +
14395796c8dcSSimon Schubert row_byte); */
14405796c8dcSSimon Schubert cleanup_list_data = make_cleanup_ui_out_list_begin_end (uiout, "data");
14415796c8dcSSimon Schubert get_formatted_print_options (&opts, word_format);
14425796c8dcSSimon Schubert for (col = 0, col_byte = row_byte;
14435796c8dcSSimon Schubert col < nr_cols;
14445796c8dcSSimon Schubert col++, col_byte += word_size)
14455796c8dcSSimon Schubert {
14465796c8dcSSimon Schubert if (col_byte + word_size > nr_bytes)
14475796c8dcSSimon Schubert {
14485796c8dcSSimon Schubert ui_out_field_string (uiout, NULL, "N/A");
14495796c8dcSSimon Schubert }
14505796c8dcSSimon Schubert else
14515796c8dcSSimon Schubert {
14525796c8dcSSimon Schubert ui_file_rewind (stream);
1453cf7f2e2dSJohn Marino print_scalar_formatted (mbuf + col_byte, word_type, &opts,
14545796c8dcSSimon Schubert word_asize, stream);
1455c50c785cSJohn Marino ui_out_field_stream (uiout, NULL, stream);
1456c50c785cSJohn Marino }
14575796c8dcSSimon Schubert }
14585796c8dcSSimon Schubert do_cleanups (cleanup_list_data);
14595796c8dcSSimon Schubert if (aschar)
14605796c8dcSSimon Schubert {
14615796c8dcSSimon Schubert int byte;
14625796c8dcSSimon Schubert
14635796c8dcSSimon Schubert ui_file_rewind (stream);
14645796c8dcSSimon Schubert for (byte = row_byte;
14655796c8dcSSimon Schubert byte < row_byte + word_size * nr_cols; byte++)
14665796c8dcSSimon Schubert {
14675796c8dcSSimon Schubert if (byte >= nr_bytes)
14685796c8dcSSimon Schubert fputc_unfiltered ('X', stream);
14695796c8dcSSimon Schubert else if (mbuf[byte] < 32 || mbuf[byte] > 126)
14705796c8dcSSimon Schubert fputc_unfiltered (aschar, stream);
14715796c8dcSSimon Schubert else
14725796c8dcSSimon Schubert fputc_unfiltered (mbuf[byte], stream);
14735796c8dcSSimon Schubert }
14745796c8dcSSimon Schubert ui_out_field_stream (uiout, "ascii", stream);
14755796c8dcSSimon Schubert }
14765796c8dcSSimon Schubert do_cleanups (cleanup_tuple);
14775796c8dcSSimon Schubert }
14785796c8dcSSimon Schubert do_cleanups (cleanup_stream);
1479c50c785cSJohn Marino }
1480c50c785cSJohn Marino do_cleanups (cleanups);
1481c50c785cSJohn Marino }
1482c50c785cSJohn Marino
1483a45ae5f8SJohn Marino void
mi_cmd_data_read_memory_bytes(char * command,char ** argv,int argc)1484c50c785cSJohn Marino mi_cmd_data_read_memory_bytes (char *command, char **argv, int argc)
1485c50c785cSJohn Marino {
1486c50c785cSJohn Marino struct gdbarch *gdbarch = get_current_arch ();
1487c50c785cSJohn Marino struct ui_out *uiout = current_uiout;
1488c50c785cSJohn Marino struct cleanup *cleanups;
1489c50c785cSJohn Marino CORE_ADDR addr;
1490c50c785cSJohn Marino LONGEST length;
1491c50c785cSJohn Marino memory_read_result_s *read_result;
1492c50c785cSJohn Marino int ix;
1493c50c785cSJohn Marino VEC(memory_read_result_s) *result;
1494c50c785cSJohn Marino long offset = 0;
1495c50c785cSJohn Marino int oind = 0;
1496c50c785cSJohn Marino char *oarg;
1497a45ae5f8SJohn Marino enum opt
1498c50c785cSJohn Marino {
1499c50c785cSJohn Marino OFFSET_OPT
1500c50c785cSJohn Marino };
1501c50c785cSJohn Marino static const struct mi_opt opts[] =
1502c50c785cSJohn Marino {
1503c50c785cSJohn Marino {"o", OFFSET_OPT, 1},
1504c50c785cSJohn Marino { 0, 0, 0 }
1505c50c785cSJohn Marino };
1506c50c785cSJohn Marino
1507c50c785cSJohn Marino while (1)
1508c50c785cSJohn Marino {
1509c50c785cSJohn Marino int opt = mi_getopt ("-data-read-memory-bytes", argc, argv, opts,
1510c50c785cSJohn Marino &oind, &oarg);
1511c50c785cSJohn Marino if (opt < 0)
1512c50c785cSJohn Marino break;
1513c50c785cSJohn Marino switch ((enum opt) opt)
1514c50c785cSJohn Marino {
1515c50c785cSJohn Marino case OFFSET_OPT:
1516c50c785cSJohn Marino offset = atol (oarg);
1517c50c785cSJohn Marino break;
1518c50c785cSJohn Marino }
1519c50c785cSJohn Marino }
1520c50c785cSJohn Marino argv += oind;
1521c50c785cSJohn Marino argc -= oind;
1522c50c785cSJohn Marino
1523c50c785cSJohn Marino if (argc != 2)
1524c50c785cSJohn Marino error (_("Usage: [ -o OFFSET ] ADDR LENGTH."));
1525c50c785cSJohn Marino
1526c50c785cSJohn Marino addr = parse_and_eval_address (argv[0]) + offset;
1527c50c785cSJohn Marino length = atol (argv[1]);
1528c50c785cSJohn Marino
1529c50c785cSJohn Marino result = read_memory_robust (current_target.beneath, addr, length);
1530c50c785cSJohn Marino
1531c50c785cSJohn Marino cleanups = make_cleanup (free_memory_read_result_vector, result);
1532c50c785cSJohn Marino
1533c50c785cSJohn Marino if (VEC_length (memory_read_result_s, result) == 0)
1534c50c785cSJohn Marino error (_("Unable to read memory."));
1535c50c785cSJohn Marino
1536c50c785cSJohn Marino make_cleanup_ui_out_list_begin_end (uiout, "memory");
1537c50c785cSJohn Marino for (ix = 0;
1538c50c785cSJohn Marino VEC_iterate (memory_read_result_s, result, ix, read_result);
1539c50c785cSJohn Marino ++ix)
1540c50c785cSJohn Marino {
1541c50c785cSJohn Marino struct cleanup *t = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
1542c50c785cSJohn Marino char *data, *p;
1543c50c785cSJohn Marino int i;
1544c50c785cSJohn Marino
1545c50c785cSJohn Marino ui_out_field_core_addr (uiout, "begin", gdbarch, read_result->begin);
1546c50c785cSJohn Marino ui_out_field_core_addr (uiout, "offset", gdbarch, read_result->begin
1547c50c785cSJohn Marino - addr);
1548c50c785cSJohn Marino ui_out_field_core_addr (uiout, "end", gdbarch, read_result->end);
1549c50c785cSJohn Marino
1550c50c785cSJohn Marino data = xmalloc ((read_result->end - read_result->begin) * 2 + 1);
1551c50c785cSJohn Marino
1552c50c785cSJohn Marino for (i = 0, p = data;
1553c50c785cSJohn Marino i < (read_result->end - read_result->begin);
1554c50c785cSJohn Marino ++i, p += 2)
1555c50c785cSJohn Marino {
1556c50c785cSJohn Marino sprintf (p, "%02x", read_result->data[i]);
1557c50c785cSJohn Marino }
1558c50c785cSJohn Marino ui_out_field_string (uiout, "contents", data);
1559c50c785cSJohn Marino xfree (data);
1560c50c785cSJohn Marino do_cleanups (t);
1561c50c785cSJohn Marino }
15625796c8dcSSimon Schubert do_cleanups (cleanups);
15635796c8dcSSimon Schubert }
1564a45ae5f8SJohn Marino
15655796c8dcSSimon Schubert /* Implementation of the -data-write_memory command.
15665796c8dcSSimon Schubert
15675796c8dcSSimon Schubert COLUMN_OFFSET: optional argument. Must be preceded by '-o'. The
15685796c8dcSSimon Schubert offset from the beginning of the memory grid row where the cell to
15695796c8dcSSimon Schubert be written is.
15705796c8dcSSimon Schubert ADDR: start address of the row in the memory grid where the memory
15715796c8dcSSimon Schubert cell is, if OFFSET_COLUMN is specified. Otherwise, the address of
15725796c8dcSSimon Schubert the location to write to.
15735796c8dcSSimon Schubert FORMAT: a char indicating format for the ``word''. See
15745796c8dcSSimon Schubert the ``x'' command.
15755796c8dcSSimon Schubert WORD_SIZE: size of each ``word''; 1,2,4, or 8 bytes
15765796c8dcSSimon Schubert VALUE: value to be written into the memory address.
15775796c8dcSSimon Schubert
15785796c8dcSSimon Schubert Writes VALUE into ADDR + (COLUMN_OFFSET * WORD_SIZE).
15795796c8dcSSimon Schubert
15805796c8dcSSimon Schubert Prints nothing. */
15815796c8dcSSimon Schubert
15825796c8dcSSimon Schubert void
mi_cmd_data_write_memory(char * command,char ** argv,int argc)15835796c8dcSSimon Schubert mi_cmd_data_write_memory (char *command, char **argv, int argc)
15845796c8dcSSimon Schubert {
15855796c8dcSSimon Schubert struct gdbarch *gdbarch = get_current_arch ();
15865796c8dcSSimon Schubert enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
15875796c8dcSSimon Schubert CORE_ADDR addr;
15885796c8dcSSimon Schubert long word_size;
15895796c8dcSSimon Schubert /* FIXME: ezannoni 2000-02-17 LONGEST could possibly not be big
15905796c8dcSSimon Schubert enough when using a compiler other than GCC. */
15915796c8dcSSimon Schubert LONGEST value;
15925796c8dcSSimon Schubert void *buffer;
15935796c8dcSSimon Schubert struct cleanup *old_chain;
15945796c8dcSSimon Schubert long offset = 0;
15955796c8dcSSimon Schubert int oind = 0;
15965796c8dcSSimon Schubert char *oarg;
15975796c8dcSSimon Schubert enum opt
1598a45ae5f8SJohn Marino {
15995796c8dcSSimon Schubert OFFSET_OPT
16005796c8dcSSimon Schubert };
16015796c8dcSSimon Schubert static const struct mi_opt opts[] =
16025796c8dcSSimon Schubert {
16035796c8dcSSimon Schubert {"o", OFFSET_OPT, 1},
16045796c8dcSSimon Schubert { 0, 0, 0 }
16055796c8dcSSimon Schubert };
1606c50c785cSJohn Marino
16075796c8dcSSimon Schubert while (1)
1608cf7f2e2dSJohn Marino {
16095796c8dcSSimon Schubert int opt = mi_getopt ("-data-write-memory", argc, argv, opts,
16105796c8dcSSimon Schubert &oind, &oarg);
16115796c8dcSSimon Schubert
16125796c8dcSSimon Schubert if (opt < 0)
16135796c8dcSSimon Schubert break;
16145796c8dcSSimon Schubert switch ((enum opt) opt)
16155796c8dcSSimon Schubert {
16165796c8dcSSimon Schubert case OFFSET_OPT:
16175796c8dcSSimon Schubert offset = atol (oarg);
16185796c8dcSSimon Schubert break;
16195796c8dcSSimon Schubert }
16205796c8dcSSimon Schubert }
16215796c8dcSSimon Schubert argv += oind;
1622c50c785cSJohn Marino argc -= oind;
1623c50c785cSJohn Marino
16245796c8dcSSimon Schubert if (argc != 4)
16255796c8dcSSimon Schubert error (_("-data-write-memory: Usage: "
16265796c8dcSSimon Schubert "[-o COLUMN_OFFSET] ADDR FORMAT WORD-SIZE VALUE."));
16275796c8dcSSimon Schubert
16285796c8dcSSimon Schubert /* Extract all the arguments. */
16295796c8dcSSimon Schubert /* Start address of the memory dump. */
16305796c8dcSSimon Schubert addr = parse_and_eval_address (argv[0]);
16315796c8dcSSimon Schubert /* The size of the memory word. */
16325796c8dcSSimon Schubert word_size = atol (argv[2]);
16335796c8dcSSimon Schubert
16345796c8dcSSimon Schubert /* Calculate the real address of the write destination. */
16355796c8dcSSimon Schubert addr += (offset * word_size);
16365796c8dcSSimon Schubert
16375796c8dcSSimon Schubert /* Get the value as a number. */
16385796c8dcSSimon Schubert value = parse_and_eval_address (argv[3]);
16395796c8dcSSimon Schubert /* Get the value into an array. */
16405796c8dcSSimon Schubert buffer = xmalloc (word_size);
16415796c8dcSSimon Schubert old_chain = make_cleanup (xfree, buffer);
16425796c8dcSSimon Schubert store_signed_integer (buffer, word_size, byte_order, value);
16435796c8dcSSimon Schubert /* Write it down to memory. */
16445796c8dcSSimon Schubert write_memory_with_notification (addr, buffer, word_size);
16455796c8dcSSimon Schubert /* Free the buffer. */
16465796c8dcSSimon Schubert do_cleanups (old_chain);
16475796c8dcSSimon Schubert }
16485796c8dcSSimon Schubert
1649c50c785cSJohn Marino /* Implementation of the -data-write-memory-bytes command.
1650c50c785cSJohn Marino
1651c50c785cSJohn Marino ADDR: start address
1652c50c785cSJohn Marino DATA: string of bytes to write at that address
1653c50c785cSJohn Marino COUNT: number of bytes to be filled (decimal integer). */
1654c50c785cSJohn Marino
1655c50c785cSJohn Marino void
mi_cmd_data_write_memory_bytes(char * command,char ** argv,int argc)1656c50c785cSJohn Marino mi_cmd_data_write_memory_bytes (char *command, char **argv, int argc)
1657c50c785cSJohn Marino {
1658c50c785cSJohn Marino CORE_ADDR addr;
1659c50c785cSJohn Marino char *cdata;
1660c50c785cSJohn Marino gdb_byte *data;
1661c50c785cSJohn Marino gdb_byte *databuf;
1662c50c785cSJohn Marino size_t len, i, steps, remainder;
1663c50c785cSJohn Marino long int count, j;
1664c50c785cSJohn Marino struct cleanup *back_to;
1665c50c785cSJohn Marino
1666c50c785cSJohn Marino if (argc != 2 && argc != 3)
1667c50c785cSJohn Marino error (_("Usage: ADDR DATA [COUNT]."));
1668c50c785cSJohn Marino
1669c50c785cSJohn Marino addr = parse_and_eval_address (argv[0]);
1670c50c785cSJohn Marino cdata = argv[1];
1671c50c785cSJohn Marino if (strlen (cdata) % 2)
1672c50c785cSJohn Marino error (_("Hex-encoded '%s' must have an even number of characters."),
1673c50c785cSJohn Marino cdata);
1674c50c785cSJohn Marino
1675c50c785cSJohn Marino len = strlen (cdata)/2;
1676c50c785cSJohn Marino if (argc == 3)
1677c50c785cSJohn Marino count = strtoul (argv[2], NULL, 10);
1678c50c785cSJohn Marino else
1679c50c785cSJohn Marino count = len;
1680c50c785cSJohn Marino
1681c50c785cSJohn Marino databuf = xmalloc (len * sizeof (gdb_byte));
1682c50c785cSJohn Marino back_to = make_cleanup (xfree, databuf);
1683c50c785cSJohn Marino
1684c50c785cSJohn Marino for (i = 0; i < len; ++i)
1685c50c785cSJohn Marino {
1686c50c785cSJohn Marino int x;
16875796c8dcSSimon Schubert if (sscanf (cdata + i * 2, "%02x", &x) != 1)
16885796c8dcSSimon Schubert error (_("Invalid argument"));
16895796c8dcSSimon Schubert databuf[i] = (gdb_byte) x;
16905796c8dcSSimon Schubert }
16915796c8dcSSimon Schubert
16925796c8dcSSimon Schubert if (len < count)
16935796c8dcSSimon Schubert {
16945796c8dcSSimon Schubert /* Pattern is made of less bytes than count:
16955796c8dcSSimon Schubert repeat pattern to fill memory. */
16965796c8dcSSimon Schubert data = xmalloc (count);
16975796c8dcSSimon Schubert make_cleanup (xfree, data);
16985796c8dcSSimon Schubert
16995796c8dcSSimon Schubert steps = count / len;
17005796c8dcSSimon Schubert remainder = count % len;
17015796c8dcSSimon Schubert for (j = 0; j < steps; j++)
17025796c8dcSSimon Schubert memcpy (data + j * len, databuf, len);
17035796c8dcSSimon Schubert
17045796c8dcSSimon Schubert if (remainder > 0)
17055796c8dcSSimon Schubert memcpy (data + steps * len, databuf, remainder);
17065796c8dcSSimon Schubert }
1707c50c785cSJohn Marino else
17085796c8dcSSimon Schubert {
17095796c8dcSSimon Schubert /* Pattern is longer than or equal to count:
17105796c8dcSSimon Schubert just copy len bytes. */
17115796c8dcSSimon Schubert data = databuf;
17125796c8dcSSimon Schubert }
17135796c8dcSSimon Schubert
17145796c8dcSSimon Schubert write_memory_with_notification (addr, data, count);
17155796c8dcSSimon Schubert
1716a45ae5f8SJohn Marino do_cleanups (back_to);
17175796c8dcSSimon Schubert }
1718cf7f2e2dSJohn Marino
17195796c8dcSSimon Schubert void
mi_cmd_enable_timings(char * command,char ** argv,int argc)17205796c8dcSSimon Schubert mi_cmd_enable_timings (char *command, char **argv, int argc)
17215796c8dcSSimon Schubert {
1722c50c785cSJohn Marino if (argc == 0)
1723a45ae5f8SJohn Marino do_timings = 1;
1724a45ae5f8SJohn Marino else if (argc == 1)
17255796c8dcSSimon Schubert {
17265796c8dcSSimon Schubert if (strcmp (argv[0], "yes") == 0)
17275796c8dcSSimon Schubert do_timings = 1;
17285796c8dcSSimon Schubert else if (strcmp (argv[0], "no") == 0)
17295796c8dcSSimon Schubert do_timings = 0;
17305796c8dcSSimon Schubert else
17315796c8dcSSimon Schubert goto usage_error;
17325796c8dcSSimon Schubert }
17335796c8dcSSimon Schubert else
1734c50c785cSJohn Marino goto usage_error;
17355796c8dcSSimon Schubert
17365796c8dcSSimon Schubert return;
17375796c8dcSSimon Schubert
17385796c8dcSSimon Schubert usage_error:
17395796c8dcSSimon Schubert error (_("-enable-timings: Usage: %s {yes|no}"), command);
17405796c8dcSSimon Schubert }
17415796c8dcSSimon Schubert
17425796c8dcSSimon Schubert void
mi_cmd_list_features(char * command,char ** argv,int argc)1743a45ae5f8SJohn Marino mi_cmd_list_features (char *command, char **argv, int argc)
17445796c8dcSSimon Schubert {
1745cf7f2e2dSJohn Marino if (argc == 0)
17465796c8dcSSimon Schubert {
17475796c8dcSSimon Schubert struct cleanup *cleanup = NULL;
1748cf7f2e2dSJohn Marino struct ui_out *uiout = current_uiout;
1749cf7f2e2dSJohn Marino
17505796c8dcSSimon Schubert cleanup = make_cleanup_ui_out_list_begin_end (uiout, "features");
17515796c8dcSSimon Schubert ui_out_field_string (uiout, NULL, "frozen-varobjs");
17525796c8dcSSimon Schubert ui_out_field_string (uiout, NULL, "pending-breakpoints");
17535796c8dcSSimon Schubert ui_out_field_string (uiout, NULL, "thread-info");
17545796c8dcSSimon Schubert ui_out_field_string (uiout, NULL, "data-read-memory-bytes");
1755c50c785cSJohn Marino ui_out_field_string (uiout, NULL, "breakpoint-notifications");
17565796c8dcSSimon Schubert ui_out_field_string (uiout, NULL, "ada-task-info");
17575796c8dcSSimon Schubert
1758cf7f2e2dSJohn Marino #if HAVE_PYTHON
1759cf7f2e2dSJohn Marino ui_out_field_string (uiout, NULL, "python");
1760cf7f2e2dSJohn Marino #endif
1761cf7f2e2dSJohn Marino
1762cf7f2e2dSJohn Marino do_cleanups (cleanup);
1763cf7f2e2dSJohn Marino return;
1764cf7f2e2dSJohn Marino }
1765cf7f2e2dSJohn Marino
1766cf7f2e2dSJohn Marino error (_("-list-features should be passed no arguments"));
1767cf7f2e2dSJohn Marino }
1768a45ae5f8SJohn Marino
1769cf7f2e2dSJohn Marino void
mi_cmd_list_target_features(char * command,char ** argv,int argc)1770cf7f2e2dSJohn Marino mi_cmd_list_target_features (char *command, char **argv, int argc)
1771c50c785cSJohn Marino {
1772c50c785cSJohn Marino if (argc == 0)
1773c50c785cSJohn Marino {
1774c50c785cSJohn Marino struct cleanup *cleanup = NULL;
1775c50c785cSJohn Marino struct ui_out *uiout = current_uiout;
1776c50c785cSJohn Marino
1777c50c785cSJohn Marino cleanup = make_cleanup_ui_out_list_begin_end (uiout, "features");
1778c50c785cSJohn Marino if (target_can_async_p ())
1779c50c785cSJohn Marino ui_out_field_string (uiout, NULL, "async");
1780c50c785cSJohn Marino if (target_can_execute_reverse)
1781c50c785cSJohn Marino ui_out_field_string (uiout, NULL, "reverse");
1782c50c785cSJohn Marino
1783cf7f2e2dSJohn Marino do_cleanups (cleanup);
1784cf7f2e2dSJohn Marino return;
1785cf7f2e2dSJohn Marino }
1786cf7f2e2dSJohn Marino
1787cf7f2e2dSJohn Marino error (_("-list-target-features should be passed no arguments"));
1788cf7f2e2dSJohn Marino }
1789cf7f2e2dSJohn Marino
1790c50c785cSJohn Marino void
mi_cmd_add_inferior(char * command,char ** argv,int argc)1791cf7f2e2dSJohn Marino mi_cmd_add_inferior (char *command, char **argv, int argc)
1792cf7f2e2dSJohn Marino {
1793c50c785cSJohn Marino struct inferior *inf;
1794cf7f2e2dSJohn Marino
1795cf7f2e2dSJohn Marino if (argc != 0)
1796cf7f2e2dSJohn Marino error (_("-add-inferior should be passed no arguments"));
1797c50c785cSJohn Marino
1798c50c785cSJohn Marino inf = add_inferior_with_spaces ();
1799*74a8b0f5SJohn Marino
1800c50c785cSJohn Marino ui_out_field_fmt (current_uiout, "inferior", "i%d", inf->num);
1801c50c785cSJohn Marino }
1802c50c785cSJohn Marino
1803c50c785cSJohn Marino /* Callback used to find the first inferior other than the current
1804c50c785cSJohn Marino one. */
1805c50c785cSJohn Marino
1806c50c785cSJohn Marino static int
get_other_inferior(struct inferior * inf,void * arg)1807c50c785cSJohn Marino get_other_inferior (struct inferior *inf, void *arg)
1808c50c785cSJohn Marino {
1809c50c785cSJohn Marino if (inf == current_inferior ())
1810c50c785cSJohn Marino return 0;
1811c50c785cSJohn Marino
1812*74a8b0f5SJohn Marino return 1;
1813c50c785cSJohn Marino }
1814c50c785cSJohn Marino
1815c50c785cSJohn Marino void
mi_cmd_remove_inferior(char * command,char ** argv,int argc)1816c50c785cSJohn Marino mi_cmd_remove_inferior (char *command, char **argv, int argc)
1817cf7f2e2dSJohn Marino {
1818cf7f2e2dSJohn Marino int id;
1819cf7f2e2dSJohn Marino struct inferior *inf;
1820cf7f2e2dSJohn Marino
1821cf7f2e2dSJohn Marino if (argc != 1)
1822cf7f2e2dSJohn Marino error (_("-remove-inferior should be passed a single argument"));
18235796c8dcSSimon Schubert
18245796c8dcSSimon Schubert if (sscanf (argv[0], "i%d", &id) != 1)
18255796c8dcSSimon Schubert error (_("the thread group id is syntactically invalid"));
18265796c8dcSSimon Schubert
18275796c8dcSSimon Schubert inf = find_inferior_id (id);
18285796c8dcSSimon Schubert if (!inf)
18295796c8dcSSimon Schubert error (_("the specified thread group does not exist"));
18305796c8dcSSimon Schubert
1831a45ae5f8SJohn Marino if (inf->pid != 0)
18325796c8dcSSimon Schubert error (_("cannot remove an active inferior"));
18335796c8dcSSimon Schubert
18345796c8dcSSimon Schubert if (inf == current_inferior ())
18355796c8dcSSimon Schubert {
18365796c8dcSSimon Schubert struct thread_info *tp = 0;
18375796c8dcSSimon Schubert struct inferior *new_inferior
18385796c8dcSSimon Schubert = iterate_over_inferiors (get_other_inferior, NULL);
18395796c8dcSSimon Schubert
18405796c8dcSSimon Schubert if (new_inferior == NULL)
18415796c8dcSSimon Schubert error (_("Cannot remove last inferior"));
18425796c8dcSSimon Schubert
18435796c8dcSSimon Schubert set_current_inferior (new_inferior);
18445796c8dcSSimon Schubert if (new_inferior->pid != 0)
18455796c8dcSSimon Schubert tp = any_thread_of_process (new_inferior->pid);
18465796c8dcSSimon Schubert switch_to_thread (tp ? tp->ptid : null_ptid);
18475796c8dcSSimon Schubert set_current_program_space (new_inferior->pspace);
18485796c8dcSSimon Schubert }
18495796c8dcSSimon Schubert
18505796c8dcSSimon Schubert delete_inferior_1 (inf, 1 /* silent */);
18515796c8dcSSimon Schubert }
18525796c8dcSSimon Schubert
18535796c8dcSSimon Schubert
18545796c8dcSSimon Schubert
18555796c8dcSSimon Schubert /* Execute a command within a safe environment.
18565796c8dcSSimon Schubert Return <0 for error; >=0 for ok.
18575796c8dcSSimon Schubert
18585796c8dcSSimon Schubert args->action will tell mi_execute_command what action
18595796c8dcSSimon Schubert to perfrom after the given command has executed (display/suppress
18605796c8dcSSimon Schubert prompt, display error). */
18615796c8dcSSimon Schubert
18625796c8dcSSimon Schubert static void
captured_mi_execute_command(struct ui_out * uiout,struct mi_parse * context)18635796c8dcSSimon Schubert captured_mi_execute_command (struct ui_out *uiout, struct mi_parse *context)
18645796c8dcSSimon Schubert {
18655796c8dcSSimon Schubert struct cleanup *cleanup;
18665796c8dcSSimon Schubert
18675796c8dcSSimon Schubert if (do_timings)
18685796c8dcSSimon Schubert current_command_ts = context->cmd_start;
18695796c8dcSSimon Schubert
18705796c8dcSSimon Schubert current_token = xstrdup (context->token);
18715796c8dcSSimon Schubert cleanup = make_cleanup (free_current_contents, ¤t_token);
18725796c8dcSSimon Schubert
18735796c8dcSSimon Schubert running_result_record_printed = 0;
18745796c8dcSSimon Schubert mi_proceeded = 0;
18755796c8dcSSimon Schubert switch (context->op)
18765796c8dcSSimon Schubert {
18775796c8dcSSimon Schubert case MI_COMMAND:
18785796c8dcSSimon Schubert /* A MI command was read from the input stream. */
18795796c8dcSSimon Schubert if (mi_debug_p)
18805796c8dcSSimon Schubert /* FIXME: gdb_???? */
18815796c8dcSSimon Schubert fprintf_unfiltered (raw_stdout, " token=`%s' command=`%s' args=`%s'\n",
18825796c8dcSSimon Schubert context->token, context->command, context->args);
1883cf7f2e2dSJohn Marino
18845796c8dcSSimon Schubert mi_cmd_execute (context);
18855796c8dcSSimon Schubert
18865796c8dcSSimon Schubert /* Print the result if there were no errors.
18875796c8dcSSimon Schubert
18885796c8dcSSimon Schubert Remember that on the way out of executing a command, you have
18895796c8dcSSimon Schubert to directly use the mi_interp's uiout, since the command
18905796c8dcSSimon Schubert could have reset the interpreter, in which case the current
18915796c8dcSSimon Schubert uiout will most likely crash in the mi_out_* routines. */
18925796c8dcSSimon Schubert if (!running_result_record_printed)
18935796c8dcSSimon Schubert {
18945796c8dcSSimon Schubert fputs_unfiltered (context->token, raw_stdout);
18955796c8dcSSimon Schubert /* There's no particularly good reason why target-connect results
18965796c8dcSSimon Schubert in not ^done. Should kill ^connected for MI3. */
18975796c8dcSSimon Schubert fputs_unfiltered (strcmp (context->command, "target-select") == 0
18985796c8dcSSimon Schubert ? "^connected" : "^done", raw_stdout);
18995796c8dcSSimon Schubert mi_out_put (uiout, raw_stdout);
19005796c8dcSSimon Schubert mi_out_rewind (uiout);
19015796c8dcSSimon Schubert mi_print_timing_maybe ();
19025796c8dcSSimon Schubert fputs_unfiltered ("\n", raw_stdout);
19035796c8dcSSimon Schubert }
19045796c8dcSSimon Schubert else
19055796c8dcSSimon Schubert /* The command does not want anything to be printed. In that
19065796c8dcSSimon Schubert case, the command probably should not have written anything
19075796c8dcSSimon Schubert to uiout, but in case it has written something, discard it. */
19085796c8dcSSimon Schubert mi_out_rewind (uiout);
19095796c8dcSSimon Schubert break;
19105796c8dcSSimon Schubert
19115796c8dcSSimon Schubert case CLI_COMMAND:
19125796c8dcSSimon Schubert {
19135796c8dcSSimon Schubert char *argv[2];
19145796c8dcSSimon Schubert
19155796c8dcSSimon Schubert /* A CLI command was read from the input stream. */
19165796c8dcSSimon Schubert /* This "feature" will be removed as soon as we have a
19175796c8dcSSimon Schubert complete set of mi commands. */
19185796c8dcSSimon Schubert /* Echo the command on the console. */
19195796c8dcSSimon Schubert fprintf_unfiltered (gdb_stdlog, "%s\n", context->command);
19205796c8dcSSimon Schubert /* Call the "console" interpreter. */
19215796c8dcSSimon Schubert argv[0] = "console";
1922c50c785cSJohn Marino argv[1] = context->command;
1923c50c785cSJohn Marino mi_cmd_interpreter_exec ("-interpreter-exec", argv, 2);
1924c50c785cSJohn Marino
1925c50c785cSJohn Marino /* If we changed interpreters, DON'T print out anything. */
1926c50c785cSJohn Marino if (current_interp_named_p (INTERP_MI)
1927c50c785cSJohn Marino || current_interp_named_p (INTERP_MI1)
1928c50c785cSJohn Marino || current_interp_named_p (INTERP_MI2)
1929c50c785cSJohn Marino || current_interp_named_p (INTERP_MI3))
1930c50c785cSJohn Marino {
1931c50c785cSJohn Marino if (!running_result_record_printed)
1932c50c785cSJohn Marino {
1933c50c785cSJohn Marino fputs_unfiltered (context->token, raw_stdout);
1934c50c785cSJohn Marino fputs_unfiltered ("^done", raw_stdout);
19355796c8dcSSimon Schubert mi_out_put (uiout, raw_stdout);
19365796c8dcSSimon Schubert mi_out_rewind (uiout);
19375796c8dcSSimon Schubert mi_print_timing_maybe ();
19385796c8dcSSimon Schubert fputs_unfiltered ("\n", raw_stdout);
1939c50c785cSJohn Marino }
1940c50c785cSJohn Marino else
1941c50c785cSJohn Marino mi_out_rewind (uiout);
19425796c8dcSSimon Schubert }
19435796c8dcSSimon Schubert break;
19445796c8dcSSimon Schubert }
19455796c8dcSSimon Schubert }
19465796c8dcSSimon Schubert
19475796c8dcSSimon Schubert do_cleanups (cleanup);
1948cf7f2e2dSJohn Marino }
1949cf7f2e2dSJohn Marino
1950c50c785cSJohn Marino /* Print a gdb exception to the MI output stream. */
1951c50c785cSJohn Marino
1952c50c785cSJohn Marino static void
mi_print_exception(const char * token,struct gdb_exception exception)1953c50c785cSJohn Marino mi_print_exception (const char *token, struct gdb_exception exception)
1954c50c785cSJohn Marino {
1955c50c785cSJohn Marino fputs_unfiltered (token, raw_stdout);
1956c50c785cSJohn Marino fputs_unfiltered ("^error,msg=\"", raw_stdout);
1957c50c785cSJohn Marino if (exception.message == NULL)
1958c50c785cSJohn Marino fputs_unfiltered ("unknown error", raw_stdout);
1959c50c785cSJohn Marino else
19605796c8dcSSimon Schubert fputstr_unfiltered (exception.message, '"', raw_stdout);
1961a45ae5f8SJohn Marino fputs_unfiltered ("\"\n", raw_stdout);
19625796c8dcSSimon Schubert }
19635796c8dcSSimon Schubert
1964c50c785cSJohn Marino void
mi_execute_command(const char * cmd,int from_tty)1965c50c785cSJohn Marino mi_execute_command (const char *cmd, int from_tty)
19665796c8dcSSimon Schubert {
19675796c8dcSSimon Schubert char *token;
19685796c8dcSSimon Schubert struct mi_parse *command = NULL;
19695796c8dcSSimon Schubert volatile struct gdb_exception exception;
19705796c8dcSSimon Schubert
19715796c8dcSSimon Schubert /* This is to handle EOF (^D). We just quit gdb. */
19725796c8dcSSimon Schubert /* FIXME: we should call some API function here. */
1973a45ae5f8SJohn Marino if (cmd == 0)
1974a45ae5f8SJohn Marino quit_force (NULL, from_tty);
1975a45ae5f8SJohn Marino
1976a45ae5f8SJohn Marino target_log_command (cmd);
19775796c8dcSSimon Schubert
19785796c8dcSSimon Schubert TRY_CATCH (exception, RETURN_MASK_ALL)
19795796c8dcSSimon Schubert {
19805796c8dcSSimon Schubert command = mi_parse (cmd, &token);
1981c50c785cSJohn Marino }
1982a45ae5f8SJohn Marino if (exception.reason < 0)
19835796c8dcSSimon Schubert {
19845796c8dcSSimon Schubert mi_print_exception (token, exception);
1985cf7f2e2dSJohn Marino xfree (token);
1986cf7f2e2dSJohn Marino }
19875796c8dcSSimon Schubert else
19885796c8dcSSimon Schubert {
19895796c8dcSSimon Schubert volatile struct gdb_exception result;
19905796c8dcSSimon Schubert ptid_t previous_ptid = inferior_ptid;
19915796c8dcSSimon Schubert
19925796c8dcSSimon Schubert command->token = token;
19935796c8dcSSimon Schubert
19945796c8dcSSimon Schubert if (do_timings)
19955796c8dcSSimon Schubert {
19965796c8dcSSimon Schubert command->cmd_start = (struct mi_timestamp *)
19975796c8dcSSimon Schubert xmalloc (sizeof (struct mi_timestamp));
19985796c8dcSSimon Schubert timestamp (command->cmd_start);
19995796c8dcSSimon Schubert }
20005796c8dcSSimon Schubert
20015796c8dcSSimon Schubert TRY_CATCH (result, RETURN_MASK_ALL)
20025796c8dcSSimon Schubert {
20035796c8dcSSimon Schubert captured_mi_execute_command (current_uiout, command);
20045796c8dcSSimon Schubert }
20055796c8dcSSimon Schubert if (result.reason < 0)
20065796c8dcSSimon Schubert {
20075796c8dcSSimon Schubert /* The command execution failed and error() was called
20085796c8dcSSimon Schubert somewhere. */
20095796c8dcSSimon Schubert mi_print_exception (command->token, result);
2010cf7f2e2dSJohn Marino mi_out_rewind (current_uiout);
20115796c8dcSSimon Schubert }
20125796c8dcSSimon Schubert
20135796c8dcSSimon Schubert bpstat_do_actions ();
20145796c8dcSSimon Schubert
20155796c8dcSSimon Schubert if (/* The notifications are only output when the top-level
20165796c8dcSSimon Schubert interpreter (specified on the command line) is MI. */
2017cf7f2e2dSJohn Marino ui_out_is_mi_like_p (interp_ui_out (top_level_interpreter ()))
20185796c8dcSSimon Schubert /* Don't try report anything if there are no threads --
20195796c8dcSSimon Schubert the program is dead. */
20205796c8dcSSimon Schubert && thread_count () != 0
20215796c8dcSSimon Schubert /* -thread-select explicitly changes thread. If frontend uses that
20225796c8dcSSimon Schubert internally, we don't want to emit =thread-selected, since
20235796c8dcSSimon Schubert =thread-selected is supposed to indicate user's intentions. */
20245796c8dcSSimon Schubert && strcmp (command->command, "thread-select") != 0)
20255796c8dcSSimon Schubert {
20265796c8dcSSimon Schubert struct mi_interp *mi = top_level_interpreter_data ();
20275796c8dcSSimon Schubert int report_change = 0;
20285796c8dcSSimon Schubert
20295796c8dcSSimon Schubert if (command->thread == -1)
20305796c8dcSSimon Schubert {
20315796c8dcSSimon Schubert report_change = (!ptid_equal (previous_ptid, null_ptid)
20325796c8dcSSimon Schubert && !ptid_equal (inferior_ptid, previous_ptid)
20335796c8dcSSimon Schubert && !ptid_equal (inferior_ptid, null_ptid));
20345796c8dcSSimon Schubert }
20355796c8dcSSimon Schubert else if (!ptid_equal (inferior_ptid, null_ptid))
20365796c8dcSSimon Schubert {
20375796c8dcSSimon Schubert struct thread_info *ti = inferior_thread ();
20385796c8dcSSimon Schubert
20395796c8dcSSimon Schubert report_change = (ti->num != command->thread);
2040a45ae5f8SJohn Marino }
20415796c8dcSSimon Schubert
2042cf7f2e2dSJohn Marino if (report_change)
2043cf7f2e2dSJohn Marino {
2044cf7f2e2dSJohn Marino struct thread_info *ti = inferior_thread ();
2045cf7f2e2dSJohn Marino
2046cf7f2e2dSJohn Marino target_terminal_ours ();
2047cf7f2e2dSJohn Marino fprintf_unfiltered (mi->event_channel,
2048cf7f2e2dSJohn Marino "thread-selected,id=\"%d\"",
2049cf7f2e2dSJohn Marino ti->num);
2050cf7f2e2dSJohn Marino gdb_flush (mi->event_channel);
20515796c8dcSSimon Schubert }
20525796c8dcSSimon Schubert }
20535796c8dcSSimon Schubert
2054cf7f2e2dSJohn Marino mi_parse_free (command);
2055cf7f2e2dSJohn Marino }
2056cf7f2e2dSJohn Marino }
2057cf7f2e2dSJohn Marino
2058cf7f2e2dSJohn Marino static void
mi_cmd_execute(struct mi_parse * parse)2059cf7f2e2dSJohn Marino mi_cmd_execute (struct mi_parse *parse)
2060cf7f2e2dSJohn Marino {
2061cf7f2e2dSJohn Marino struct cleanup *cleanup;
2062cf7f2e2dSJohn Marino
2063cf7f2e2dSJohn Marino cleanup = prepare_execute_command ();
2064cf7f2e2dSJohn Marino
2065cf7f2e2dSJohn Marino if (parse->all && parse->thread_group != -1)
2066cf7f2e2dSJohn Marino error (_("Cannot specify --thread-group together with --all"));
2067*74a8b0f5SJohn Marino
2068a45ae5f8SJohn Marino if (parse->all && parse->thread != -1)
2069cf7f2e2dSJohn Marino error (_("Cannot specify --thread together with --all"));
2070cf7f2e2dSJohn Marino
2071cf7f2e2dSJohn Marino if (parse->thread_group != -1 && parse->thread != -1)
2072cf7f2e2dSJohn Marino error (_("Cannot specify --thread together with --thread-group"));
20735796c8dcSSimon Schubert
20745796c8dcSSimon Schubert if (parse->frame != -1 && parse->thread == -1)
20755796c8dcSSimon Schubert error (_("Cannot specify --frame without --thread"));
2076cf7f2e2dSJohn Marino
20775796c8dcSSimon Schubert if (parse->thread_group != -1)
20785796c8dcSSimon Schubert {
20795796c8dcSSimon Schubert struct inferior *inf = find_inferior_id (parse->thread_group);
20805796c8dcSSimon Schubert struct thread_info *tp = 0;
20815796c8dcSSimon Schubert
20825796c8dcSSimon Schubert if (!inf)
20835796c8dcSSimon Schubert error (_("Invalid thread group for the --thread-group option"));
20845796c8dcSSimon Schubert
20855796c8dcSSimon Schubert set_current_inferior (inf);
20865796c8dcSSimon Schubert /* This behaviour means that if --thread-group option identifies
20875796c8dcSSimon Schubert an inferior with multiple threads, then a random one will be
20885796c8dcSSimon Schubert picked. This is not a problem -- frontend should always
20895796c8dcSSimon Schubert provide --thread if it wishes to operate on a specific
2090cf7f2e2dSJohn Marino thread. */
20915796c8dcSSimon Schubert if (inf->pid != 0)
20925796c8dcSSimon Schubert tp = any_live_thread_of_process (inf->pid);
20935796c8dcSSimon Schubert switch_to_thread (tp ? tp->ptid : null_ptid);
20945796c8dcSSimon Schubert set_current_program_space (inf->pspace);
20955796c8dcSSimon Schubert }
20965796c8dcSSimon Schubert
20975796c8dcSSimon Schubert if (parse->thread != -1)
20985796c8dcSSimon Schubert {
2099cf7f2e2dSJohn Marino struct thread_info *tp = find_thread_id (parse->thread);
2100cf7f2e2dSJohn Marino
2101a45ae5f8SJohn Marino if (!tp)
2102a45ae5f8SJohn Marino error (_("Invalid thread id: %d"), parse->thread);
2103a45ae5f8SJohn Marino
2104a45ae5f8SJohn Marino if (is_exited (tp->ptid))
2105a45ae5f8SJohn Marino error (_("Thread id: %d has terminated"), parse->thread);
2106a45ae5f8SJohn Marino
21075796c8dcSSimon Schubert switch_to_thread (tp->ptid);
2108a45ae5f8SJohn Marino }
21095796c8dcSSimon Schubert
2110a45ae5f8SJohn Marino if (parse->frame != -1)
21115796c8dcSSimon Schubert {
21125796c8dcSSimon Schubert struct frame_info *fid;
21135796c8dcSSimon Schubert int frame = parse->frame;
21145796c8dcSSimon Schubert
21155796c8dcSSimon Schubert fid = find_relative_frame (get_current_frame (), &frame);
21165796c8dcSSimon Schubert if (frame == 0)
21175796c8dcSSimon Schubert /* find_relative_frame was successful */
21185796c8dcSSimon Schubert select_frame (fid);
21195796c8dcSSimon Schubert else
21205796c8dcSSimon Schubert error (_("Invalid frame id: %d"), frame);
21215796c8dcSSimon Schubert }
21225796c8dcSSimon Schubert
21235796c8dcSSimon Schubert current_context = parse;
21245796c8dcSSimon Schubert
21255796c8dcSSimon Schubert if (parse->cmd->suppress_notification != NULL)
21265796c8dcSSimon Schubert {
21275796c8dcSSimon Schubert make_cleanup_restore_integer (parse->cmd->suppress_notification);
21285796c8dcSSimon Schubert *parse->cmd->suppress_notification = 1;
21295796c8dcSSimon Schubert }
21305796c8dcSSimon Schubert
21315796c8dcSSimon Schubert if (parse->cmd->argv_func != NULL)
21325796c8dcSSimon Schubert {
21335796c8dcSSimon Schubert parse->cmd->argv_func (parse->command, parse->argv, parse->argc);
21345796c8dcSSimon Schubert }
21355796c8dcSSimon Schubert else if (parse->cmd->cli.cmd != 0)
21365796c8dcSSimon Schubert {
21375796c8dcSSimon Schubert /* FIXME: DELETE THIS. */
21385796c8dcSSimon Schubert /* The operation is still implemented by a cli command. */
21395796c8dcSSimon Schubert /* Must be a synchronous one. */
21405796c8dcSSimon Schubert mi_execute_cli_command (parse->cmd->cli.cmd, parse->cmd->cli.args_p,
21415796c8dcSSimon Schubert parse->args);
21425796c8dcSSimon Schubert }
21435796c8dcSSimon Schubert else
21445796c8dcSSimon Schubert {
21455796c8dcSSimon Schubert /* FIXME: DELETE THIS. */
21465796c8dcSSimon Schubert struct ui_file *stb;
2147cf7f2e2dSJohn Marino
21485796c8dcSSimon Schubert stb = mem_fileopen ();
21495796c8dcSSimon Schubert
21505796c8dcSSimon Schubert fputs_unfiltered ("Undefined mi command: ", stb);
21515796c8dcSSimon Schubert fputstr_unfiltered (parse->command, '"', stb);
21525796c8dcSSimon Schubert fputs_unfiltered (" (missing implementation)", stb);
21535796c8dcSSimon Schubert
21545796c8dcSSimon Schubert make_cleanup_ui_file_delete (stb);
21555796c8dcSSimon Schubert error_stream (stb);
21565796c8dcSSimon Schubert }
21575796c8dcSSimon Schubert do_cleanups (cleanup);
21585796c8dcSSimon Schubert }
21595796c8dcSSimon Schubert
21605796c8dcSSimon Schubert /* FIXME: This is just a hack so we can get some extra commands going.
21615796c8dcSSimon Schubert We don't want to channel things through the CLI, but call libgdb directly.
21625796c8dcSSimon Schubert Use only for synchronous commands. */
21635796c8dcSSimon Schubert
21645796c8dcSSimon Schubert void
mi_execute_cli_command(const char * cmd,int args_p,const char * args)21655796c8dcSSimon Schubert mi_execute_cli_command (const char *cmd, int args_p, const char *args)
21665796c8dcSSimon Schubert {
21675796c8dcSSimon Schubert if (cmd != 0)
21685796c8dcSSimon Schubert {
21695796c8dcSSimon Schubert struct cleanup *old_cleanups;
21705796c8dcSSimon Schubert char *run;
21715796c8dcSSimon Schubert
21725796c8dcSSimon Schubert if (args_p)
21735796c8dcSSimon Schubert run = xstrprintf ("%s %s", cmd, args);
21745796c8dcSSimon Schubert else
21755796c8dcSSimon Schubert run = xstrdup (cmd);
21765796c8dcSSimon Schubert if (mi_debug_p)
21775796c8dcSSimon Schubert /* FIXME: gdb_???? */
21785796c8dcSSimon Schubert fprintf_unfiltered (gdb_stdout, "cli=%s run=%s\n",
21795796c8dcSSimon Schubert cmd, run);
21805796c8dcSSimon Schubert old_cleanups = make_cleanup (xfree, run);
21815796c8dcSSimon Schubert execute_command (run, 0 /* from_tty */ );
21825796c8dcSSimon Schubert do_cleanups (old_cleanups);
21835796c8dcSSimon Schubert return;
21845796c8dcSSimon Schubert }
21855796c8dcSSimon Schubert }
21865796c8dcSSimon Schubert
21875796c8dcSSimon Schubert void
mi_execute_async_cli_command(char * cli_command,char ** argv,int argc)21885796c8dcSSimon Schubert mi_execute_async_cli_command (char *cli_command, char **argv, int argc)
21895796c8dcSSimon Schubert {
21905796c8dcSSimon Schubert struct cleanup *old_cleanups;
21915796c8dcSSimon Schubert char *run;
21925796c8dcSSimon Schubert
21935796c8dcSSimon Schubert if (target_can_async_p ())
2194a45ae5f8SJohn Marino run = xstrprintf ("%s %s&", cli_command, argc ? *argv : "");
21955796c8dcSSimon Schubert else
21965796c8dcSSimon Schubert run = xstrprintf ("%s %s", cli_command, argc ? *argv : "");
21975796c8dcSSimon Schubert old_cleanups = make_cleanup (xfree, run);
21985796c8dcSSimon Schubert
2199a45ae5f8SJohn Marino execute_command (run, 0 /* from_tty */ );
22005796c8dcSSimon Schubert
22015796c8dcSSimon Schubert /* Do this before doing any printing. It would appear that some
22025796c8dcSSimon Schubert print code leaves garbage around in the buffer. */
2203a45ae5f8SJohn Marino do_cleanups (old_cleanups);
22045796c8dcSSimon Schubert }
2205a45ae5f8SJohn Marino
22065796c8dcSSimon Schubert 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)2207a45ae5f8SJohn Marino mi_load_progress (const char *section_name,
22085796c8dcSSimon Schubert unsigned long sent_so_far,
22095796c8dcSSimon Schubert unsigned long total_section,
22105796c8dcSSimon Schubert unsigned long total_sent,
2211a45ae5f8SJohn Marino unsigned long grand_total)
2212a45ae5f8SJohn Marino {
22135796c8dcSSimon Schubert struct timeval time_now, delta, update_threshold;
22145796c8dcSSimon Schubert static struct timeval last_update;
22155796c8dcSSimon Schubert static char *previous_sect_name = NULL;
22165796c8dcSSimon Schubert int new_section;
22175796c8dcSSimon Schubert struct ui_out *saved_uiout;
22185796c8dcSSimon Schubert struct ui_out *uiout;
22195796c8dcSSimon Schubert
22205796c8dcSSimon Schubert /* This function is called through deprecated_show_load_progress
22215796c8dcSSimon Schubert which means uiout may not be correct. Fix it for the duration
22225796c8dcSSimon Schubert of this function. */
22235796c8dcSSimon Schubert saved_uiout = current_uiout;
22245796c8dcSSimon Schubert
22255796c8dcSSimon Schubert if (current_interp_named_p (INTERP_MI)
22265796c8dcSSimon Schubert || current_interp_named_p (INTERP_MI2))
22275796c8dcSSimon Schubert current_uiout = mi_out_new (2);
22285796c8dcSSimon Schubert else if (current_interp_named_p (INTERP_MI1))
22295796c8dcSSimon Schubert current_uiout = mi_out_new (1);
22305796c8dcSSimon Schubert else if (current_interp_named_p (INTERP_MI3))
2231cf7f2e2dSJohn Marino current_uiout = mi_out_new (3);
22325796c8dcSSimon Schubert else
22335796c8dcSSimon Schubert return;
22345796c8dcSSimon Schubert
22355796c8dcSSimon Schubert uiout = current_uiout;
22365796c8dcSSimon Schubert
22375796c8dcSSimon Schubert update_threshold.tv_sec = 0;
22385796c8dcSSimon Schubert update_threshold.tv_usec = 500000;
22395796c8dcSSimon Schubert gettimeofday (&time_now, NULL);
22405796c8dcSSimon Schubert
22415796c8dcSSimon Schubert delta.tv_usec = time_now.tv_usec - last_update.tv_usec;
22425796c8dcSSimon Schubert delta.tv_sec = time_now.tv_sec - last_update.tv_sec;
22435796c8dcSSimon Schubert
22445796c8dcSSimon Schubert if (delta.tv_usec < 0)
22455796c8dcSSimon Schubert {
22465796c8dcSSimon Schubert delta.tv_sec -= 1;
22475796c8dcSSimon Schubert delta.tv_usec += 1000000L;
22485796c8dcSSimon Schubert }
22495796c8dcSSimon Schubert
22505796c8dcSSimon Schubert new_section = (previous_sect_name ?
22515796c8dcSSimon Schubert strcmp (previous_sect_name, section_name) : 1);
2252cf7f2e2dSJohn Marino if (new_section)
22535796c8dcSSimon Schubert {
22545796c8dcSSimon Schubert struct cleanup *cleanup_tuple;
22555796c8dcSSimon Schubert
22565796c8dcSSimon Schubert xfree (previous_sect_name);
22575796c8dcSSimon Schubert previous_sect_name = xstrdup (section_name);
22585796c8dcSSimon Schubert
22595796c8dcSSimon Schubert if (current_token)
22605796c8dcSSimon Schubert fputs_unfiltered (current_token, raw_stdout);
22615796c8dcSSimon Schubert fputs_unfiltered ("+download", raw_stdout);
22625796c8dcSSimon Schubert cleanup_tuple = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
22635796c8dcSSimon Schubert ui_out_field_string (uiout, "section", section_name);
22645796c8dcSSimon Schubert ui_out_field_int (uiout, "section-size", total_section);
22655796c8dcSSimon Schubert ui_out_field_int (uiout, "total-size", grand_total);
22665796c8dcSSimon Schubert do_cleanups (cleanup_tuple);
22675796c8dcSSimon Schubert mi_out_put (uiout, raw_stdout);
22685796c8dcSSimon Schubert fputs_unfiltered ("\n", raw_stdout);
22695796c8dcSSimon Schubert gdb_flush (raw_stdout);
22705796c8dcSSimon Schubert }
2271a45ae5f8SJohn Marino
22725796c8dcSSimon Schubert if (delta.tv_sec >= update_threshold.tv_sec &&
22735796c8dcSSimon Schubert delta.tv_usec >= update_threshold.tv_usec)
22745796c8dcSSimon Schubert {
22755796c8dcSSimon Schubert struct cleanup *cleanup_tuple;
22765796c8dcSSimon Schubert
22775796c8dcSSimon Schubert last_update.tv_sec = time_now.tv_sec;
22785796c8dcSSimon Schubert last_update.tv_usec = time_now.tv_usec;
22795796c8dcSSimon Schubert if (current_token)
22805796c8dcSSimon Schubert fputs_unfiltered (current_token, raw_stdout);
22815796c8dcSSimon Schubert fputs_unfiltered ("+download", raw_stdout);
22825796c8dcSSimon Schubert cleanup_tuple = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
22835796c8dcSSimon Schubert ui_out_field_string (uiout, "section", section_name);
22845796c8dcSSimon Schubert ui_out_field_int (uiout, "section-sent", sent_so_far);
2285cf7f2e2dSJohn Marino ui_out_field_int (uiout, "section-size", total_section);
2286cf7f2e2dSJohn Marino ui_out_field_int (uiout, "total-sent", total_sent);
2287cf7f2e2dSJohn Marino ui_out_field_int (uiout, "total-size", grand_total);
22885796c8dcSSimon Schubert do_cleanups (cleanup_tuple);
22895796c8dcSSimon Schubert mi_out_put (uiout, raw_stdout);
22905796c8dcSSimon Schubert fputs_unfiltered ("\n", raw_stdout);
22915796c8dcSSimon Schubert gdb_flush (raw_stdout);
2292cf7f2e2dSJohn Marino }
22935796c8dcSSimon Schubert
22945796c8dcSSimon Schubert xfree (uiout);
22955796c8dcSSimon Schubert current_uiout = saved_uiout;
22965796c8dcSSimon Schubert }
22975796c8dcSSimon Schubert
22985796c8dcSSimon Schubert static void
timestamp(struct mi_timestamp * tv)22995796c8dcSSimon Schubert timestamp (struct mi_timestamp *tv)
2300cf7f2e2dSJohn Marino {
23015796c8dcSSimon Schubert gettimeofday (&tv->wallclock, NULL);
23025796c8dcSSimon Schubert #ifdef HAVE_GETRUSAGE
23035796c8dcSSimon Schubert getrusage (RUSAGE_SELF, &rusage);
23045796c8dcSSimon Schubert tv->utime.tv_sec = rusage.ru_utime.tv_sec;
23055796c8dcSSimon Schubert tv->utime.tv_usec = rusage.ru_utime.tv_usec;
23065796c8dcSSimon Schubert tv->stime.tv_sec = rusage.ru_stime.tv_sec;
23075796c8dcSSimon Schubert tv->stime.tv_usec = rusage.ru_stime.tv_usec;
23085796c8dcSSimon Schubert #else
23095796c8dcSSimon Schubert {
23105796c8dcSSimon Schubert long usec = get_run_time ();
23115796c8dcSSimon Schubert
23125796c8dcSSimon Schubert tv->utime.tv_sec = usec/1000000L;
23135796c8dcSSimon Schubert tv->utime.tv_usec = usec - 1000000L*tv->utime.tv_sec;
23145796c8dcSSimon Schubert tv->stime.tv_sec = 0;
23155796c8dcSSimon Schubert tv->stime.tv_usec = 0;
23165796c8dcSSimon Schubert }
23175796c8dcSSimon Schubert #endif
23185796c8dcSSimon Schubert }
23195796c8dcSSimon Schubert
23205796c8dcSSimon Schubert static void
print_diff_now(struct mi_timestamp * start)23215796c8dcSSimon Schubert print_diff_now (struct mi_timestamp *start)
23225796c8dcSSimon Schubert {
23235796c8dcSSimon Schubert struct mi_timestamp now;
23245796c8dcSSimon Schubert
23255796c8dcSSimon Schubert timestamp (&now);
23265796c8dcSSimon Schubert print_diff (start, &now);
23275796c8dcSSimon Schubert }
23285796c8dcSSimon Schubert
23295796c8dcSSimon Schubert void
mi_print_timing_maybe(void)23305796c8dcSSimon Schubert mi_print_timing_maybe (void)
2331cf7f2e2dSJohn Marino {
2332cf7f2e2dSJohn Marino /* If the command is -enable-timing then do_timings may be true
2333cf7f2e2dSJohn Marino whilst current_command_ts is not initialized. */
2334cf7f2e2dSJohn Marino if (do_timings && current_command_ts)
2335cf7f2e2dSJohn Marino print_diff_now (current_command_ts);
2336cf7f2e2dSJohn Marino }
2337cf7f2e2dSJohn Marino
2338cf7f2e2dSJohn Marino static long
timeval_diff(struct timeval start,struct timeval end)2339cf7f2e2dSJohn Marino timeval_diff (struct timeval start, struct timeval end)
2340cf7f2e2dSJohn Marino {
2341cf7f2e2dSJohn Marino return ((end.tv_sec - start.tv_sec) * 1000000L)
2342cf7f2e2dSJohn Marino + (end.tv_usec - start.tv_usec);
2343cf7f2e2dSJohn Marino }
2344cf7f2e2dSJohn Marino
2345cf7f2e2dSJohn Marino static void
print_diff(struct mi_timestamp * start,struct mi_timestamp * end)2346cf7f2e2dSJohn Marino print_diff (struct mi_timestamp *start, struct mi_timestamp *end)
2347cf7f2e2dSJohn Marino {
2348cf7f2e2dSJohn Marino fprintf_unfiltered
2349cf7f2e2dSJohn Marino (raw_stdout,
2350cf7f2e2dSJohn Marino ",time={wallclock=\"%0.5f\",user=\"%0.5f\",system=\"%0.5f\"}",
2351cf7f2e2dSJohn Marino timeval_diff (start->wallclock, end->wallclock) / 1000000.0,
2352cf7f2e2dSJohn Marino timeval_diff (start->utime, end->utime) / 1000000.0,
2353cf7f2e2dSJohn Marino timeval_diff (start->stime, end->stime) / 1000000.0);
2354cf7f2e2dSJohn Marino }
2355cf7f2e2dSJohn Marino
2356cf7f2e2dSJohn Marino void
mi_cmd_trace_define_variable(char * command,char ** argv,int argc)2357cf7f2e2dSJohn Marino mi_cmd_trace_define_variable (char *command, char **argv, int argc)
2358cf7f2e2dSJohn Marino {
2359cf7f2e2dSJohn Marino struct expression *expr;
2360cf7f2e2dSJohn Marino LONGEST initval = 0;
2361cf7f2e2dSJohn Marino struct trace_state_variable *tsv;
2362cf7f2e2dSJohn Marino char *name = 0;
2363cf7f2e2dSJohn Marino
2364cf7f2e2dSJohn Marino if (argc != 1 && argc != 2)
2365cf7f2e2dSJohn Marino error (_("Usage: -trace-define-variable VARIABLE [VALUE]"));
2366cf7f2e2dSJohn Marino
2367cf7f2e2dSJohn Marino name = argv[0];
2368cf7f2e2dSJohn Marino if (*name++ != '$')
2369cf7f2e2dSJohn Marino error (_("Name of trace variable should start with '$'"));
2370cf7f2e2dSJohn Marino
2371cf7f2e2dSJohn Marino validate_trace_state_variable_name (name);
2372cf7f2e2dSJohn Marino
2373cf7f2e2dSJohn Marino tsv = find_trace_state_variable (name);
2374cf7f2e2dSJohn Marino if (!tsv)
2375cf7f2e2dSJohn Marino tsv = create_trace_state_variable (name);
2376cf7f2e2dSJohn Marino
2377cf7f2e2dSJohn Marino if (argc == 2)
2378cf7f2e2dSJohn Marino initval = value_as_long (parse_and_eval (argv[1]));
2379cf7f2e2dSJohn Marino
2380cf7f2e2dSJohn Marino tsv->initial_value = initval;
2381cf7f2e2dSJohn Marino }
2382cf7f2e2dSJohn Marino
2383cf7f2e2dSJohn Marino void
mi_cmd_trace_list_variables(char * command,char ** argv,int argc)2384cf7f2e2dSJohn Marino mi_cmd_trace_list_variables (char *command, char **argv, int argc)
2385cf7f2e2dSJohn Marino {
2386cf7f2e2dSJohn Marino if (argc != 0)
2387cf7f2e2dSJohn Marino error (_("-trace-list-variables: no arguments allowed"));
2388cf7f2e2dSJohn Marino
2389cf7f2e2dSJohn Marino tvariables_info_1 ();
2390cf7f2e2dSJohn Marino }
2391cf7f2e2dSJohn Marino
2392cf7f2e2dSJohn Marino void
mi_cmd_trace_find(char * command,char ** argv,int argc)2393cf7f2e2dSJohn Marino mi_cmd_trace_find (char *command, char **argv, int argc)
2394cf7f2e2dSJohn Marino {
2395cf7f2e2dSJohn Marino char *mode;
2396cf7f2e2dSJohn Marino
2397cf7f2e2dSJohn Marino if (argc == 0)
2398cf7f2e2dSJohn Marino error (_("trace selection mode is required"));
2399cf7f2e2dSJohn Marino
2400cf7f2e2dSJohn Marino mode = argv[0];
2401cf7f2e2dSJohn Marino
2402cf7f2e2dSJohn Marino if (strcmp (mode, "none") == 0)
2403cf7f2e2dSJohn Marino {
2404cf7f2e2dSJohn Marino tfind_1 (tfind_number, -1, 0, 0, 0);
2405cf7f2e2dSJohn Marino return;
2406cf7f2e2dSJohn Marino }
2407cf7f2e2dSJohn Marino
2408cf7f2e2dSJohn Marino if (current_trace_status ()->running)
2409cf7f2e2dSJohn Marino error (_("May not look at trace frames while trace is running."));
2410cf7f2e2dSJohn Marino
2411cf7f2e2dSJohn Marino if (strcmp (mode, "frame-number") == 0)
2412cf7f2e2dSJohn Marino {
2413cf7f2e2dSJohn Marino if (argc != 2)
2414cf7f2e2dSJohn Marino error (_("frame number is required"));
2415cf7f2e2dSJohn Marino tfind_1 (tfind_number, atoi (argv[1]), 0, 0, 0);
2416cf7f2e2dSJohn Marino }
2417cf7f2e2dSJohn Marino else if (strcmp (mode, "tracepoint-number") == 0)
2418cf7f2e2dSJohn Marino {
2419cf7f2e2dSJohn Marino if (argc != 2)
2420cf7f2e2dSJohn Marino error (_("tracepoint number is required"));
2421cf7f2e2dSJohn Marino tfind_1 (tfind_tp, atoi (argv[1]), 0, 0, 0);
2422cf7f2e2dSJohn Marino }
2423cf7f2e2dSJohn Marino else if (strcmp (mode, "pc") == 0)
2424cf7f2e2dSJohn Marino {
2425cf7f2e2dSJohn Marino if (argc != 2)
2426cf7f2e2dSJohn Marino error (_("PC is required"));
2427cf7f2e2dSJohn Marino tfind_1 (tfind_pc, 0, parse_and_eval_address (argv[1]), 0, 0);
2428cf7f2e2dSJohn Marino }
2429cf7f2e2dSJohn Marino else if (strcmp (mode, "pc-inside-range") == 0)
2430cf7f2e2dSJohn Marino {
2431cf7f2e2dSJohn Marino if (argc != 3)
2432cf7f2e2dSJohn Marino error (_("Start and end PC are required"));
2433cf7f2e2dSJohn Marino tfind_1 (tfind_range, 0, parse_and_eval_address (argv[1]),
2434cf7f2e2dSJohn Marino parse_and_eval_address (argv[2]), 0);
2435cf7f2e2dSJohn Marino }
2436cf7f2e2dSJohn Marino else if (strcmp (mode, "pc-outside-range") == 0)
2437cf7f2e2dSJohn Marino {
2438cf7f2e2dSJohn Marino if (argc != 3)
2439cf7f2e2dSJohn Marino error (_("Start and end PC are required"));
2440a45ae5f8SJohn Marino tfind_1 (tfind_outside, 0, parse_and_eval_address (argv[1]),
2441cf7f2e2dSJohn Marino parse_and_eval_address (argv[2]), 0);
2442cf7f2e2dSJohn Marino }
2443cf7f2e2dSJohn Marino else if (strcmp (mode, "line") == 0)
2444cf7f2e2dSJohn Marino {
2445cf7f2e2dSJohn Marino struct symtabs_and_lines sals;
2446cf7f2e2dSJohn Marino struct symtab_and_line sal;
2447cf7f2e2dSJohn Marino static CORE_ADDR start_pc, end_pc;
2448cf7f2e2dSJohn Marino struct cleanup *back_to;
2449cf7f2e2dSJohn Marino
2450cf7f2e2dSJohn Marino if (argc != 2)
2451cf7f2e2dSJohn Marino error (_("Line is required"));
2452cf7f2e2dSJohn Marino
2453cf7f2e2dSJohn Marino sals = decode_line_with_current_source (argv[1],
2454cf7f2e2dSJohn Marino DECODE_LINE_FUNFIRSTLINE);
2455cf7f2e2dSJohn Marino back_to = make_cleanup (xfree, sals.sals);
2456cf7f2e2dSJohn Marino
2457cf7f2e2dSJohn Marino sal = sals.sals[0];
2458cf7f2e2dSJohn Marino
2459cf7f2e2dSJohn Marino if (sal.symtab == 0)
2460cf7f2e2dSJohn Marino error (_("Could not find the specified line"));
2461cf7f2e2dSJohn Marino
2462cf7f2e2dSJohn Marino if (sal.line > 0 && find_line_pc_range (sal, &start_pc, &end_pc))
2463cf7f2e2dSJohn Marino tfind_1 (tfind_range, 0, start_pc, end_pc - 1, 0);
2464cf7f2e2dSJohn Marino else
2465cf7f2e2dSJohn Marino error (_("Could not find the specified line"));
2466cf7f2e2dSJohn Marino
2467cf7f2e2dSJohn Marino do_cleanups (back_to);
2468cf7f2e2dSJohn Marino }
2469cf7f2e2dSJohn Marino else
2470cf7f2e2dSJohn Marino error (_("Invalid mode '%s'"), mode);
2471cf7f2e2dSJohn Marino
2472cf7f2e2dSJohn Marino if (has_stack_frames () || get_traceframe_number () >= 0)
2473cf7f2e2dSJohn Marino print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC);
2474cf7f2e2dSJohn Marino }
2475cf7f2e2dSJohn Marino
2476cf7f2e2dSJohn Marino void
mi_cmd_trace_save(char * command,char ** argv,int argc)2477cf7f2e2dSJohn Marino mi_cmd_trace_save (char *command, char **argv, int argc)
2478cf7f2e2dSJohn Marino {
2479cf7f2e2dSJohn Marino int target_saves = 0;
2480cf7f2e2dSJohn Marino char *filename;
2481cf7f2e2dSJohn Marino
2482cf7f2e2dSJohn Marino if (argc != 1 && argc != 2)
2483cf7f2e2dSJohn Marino error (_("Usage: -trace-save [-r] filename"));
2484cf7f2e2dSJohn Marino
2485cf7f2e2dSJohn Marino if (argc == 2)
2486cf7f2e2dSJohn Marino {
2487cf7f2e2dSJohn Marino filename = argv[1];
2488cf7f2e2dSJohn Marino if (strcmp (argv[0], "-r") == 0)
2489cf7f2e2dSJohn Marino target_saves = 1;
2490cf7f2e2dSJohn Marino else
2491cf7f2e2dSJohn Marino error (_("Invalid option: %s"), argv[0]);
2492cf7f2e2dSJohn Marino }
2493a45ae5f8SJohn Marino else
2494cf7f2e2dSJohn Marino {
2495cf7f2e2dSJohn Marino filename = argv[0];
2496cf7f2e2dSJohn Marino }
2497cf7f2e2dSJohn Marino
2498cf7f2e2dSJohn Marino trace_save (filename, target_saves);
2499cf7f2e2dSJohn Marino }
2500cf7f2e2dSJohn Marino
2501cf7f2e2dSJohn Marino void
mi_cmd_trace_start(char * command,char ** argv,int argc)2502cf7f2e2dSJohn Marino mi_cmd_trace_start (char *command, char **argv, int argc)
2503cf7f2e2dSJohn Marino {
2504cf7f2e2dSJohn Marino start_tracing (NULL);
2505a45ae5f8SJohn Marino }
2506cf7f2e2dSJohn Marino
2507cf7f2e2dSJohn Marino void
mi_cmd_trace_status(char * command,char ** argv,int argc)2508a45ae5f8SJohn Marino mi_cmd_trace_status (char *command, char **argv, int argc)
2509a45ae5f8SJohn Marino {
2510a45ae5f8SJohn Marino trace_status_mi (0);
2511a45ae5f8SJohn Marino }
2512a45ae5f8SJohn Marino
2513a45ae5f8SJohn Marino void
mi_cmd_trace_stop(char * command,char ** argv,int argc)2514a45ae5f8SJohn Marino mi_cmd_trace_stop (char *command, char **argv, int argc)
2515a45ae5f8SJohn Marino {
2516a45ae5f8SJohn Marino stop_tracing (NULL);
2517a45ae5f8SJohn Marino trace_status_mi (1);
2518a45ae5f8SJohn Marino }
2519
2520 /* Implement the "-ada-task-info" command. */
2521
2522 void
mi_cmd_ada_task_info(char * command,char ** argv,int argc)2523 mi_cmd_ada_task_info (char *command, char **argv, int argc)
2524 {
2525 if (argc != 0 && argc != 1)
2526 error (_("Invalid MI command"));
2527
2528 print_ada_task_info (current_uiout, argv[0], current_inferior ());
2529 }
2530