xref: /dragonfly/contrib/gdb-7/gdb/mi/mi-interp.c (revision 74a8b0f5)
15796c8dcSSimon Schubert /* MI Interpreter Definitions and Commands for GDB, the GNU debugger.
25796c8dcSSimon Schubert 
3a45ae5f8SJohn Marino    Copyright (C) 2002-2013 Free Software Foundation, Inc.
45796c8dcSSimon Schubert 
55796c8dcSSimon Schubert    This file is part of GDB.
65796c8dcSSimon Schubert 
75796c8dcSSimon Schubert    This program is free software; you can redistribute it and/or modify
85796c8dcSSimon Schubert    it under the terms of the GNU General Public License as published by
95796c8dcSSimon Schubert    the Free Software Foundation; either version 3 of the License, or
105796c8dcSSimon Schubert    (at your option) any later version.
115796c8dcSSimon Schubert 
125796c8dcSSimon Schubert    This program is distributed in the hope that it will be useful,
135796c8dcSSimon Schubert    but WITHOUT ANY WARRANTY; without even the implied warranty of
145796c8dcSSimon Schubert    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
155796c8dcSSimon Schubert    GNU General Public License for more details.
165796c8dcSSimon Schubert 
175796c8dcSSimon Schubert    You should have received a copy of the GNU General Public License
185796c8dcSSimon Schubert    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
195796c8dcSSimon Schubert 
205796c8dcSSimon Schubert #include "defs.h"
215796c8dcSSimon Schubert #include "gdb_string.h"
225796c8dcSSimon Schubert #include "interps.h"
235796c8dcSSimon Schubert #include "event-top.h"
245796c8dcSSimon Schubert #include "event-loop.h"
255796c8dcSSimon Schubert #include "inferior.h"
265796c8dcSSimon Schubert #include "ui-out.h"
275796c8dcSSimon Schubert #include "top.h"
285796c8dcSSimon Schubert #include "exceptions.h"
295796c8dcSSimon Schubert #include "mi-main.h"
305796c8dcSSimon Schubert #include "mi-cmds.h"
315796c8dcSSimon Schubert #include "mi-out.h"
325796c8dcSSimon Schubert #include "mi-console.h"
335796c8dcSSimon Schubert #include "mi-common.h"
345796c8dcSSimon Schubert #include "observer.h"
355796c8dcSSimon Schubert #include "gdbthread.h"
365796c8dcSSimon Schubert #include "solist.h"
37a45ae5f8SJohn Marino #include "gdb.h"
385796c8dcSSimon Schubert #include "objfiles.h"
395796c8dcSSimon Schubert #include "tracepoint.h"
405796c8dcSSimon Schubert 
415796c8dcSSimon Schubert /* These are the interpreter setup, etc. functions for the MI
425796c8dcSSimon Schubert    interpreter.  */
435796c8dcSSimon Schubert 
445796c8dcSSimon Schubert static void mi_execute_command_wrapper (const char *cmd);
455796c8dcSSimon Schubert static void mi_execute_command_input_handler (char *cmd);
465796c8dcSSimon Schubert static void mi_command_loop (int mi_version);
47cf7f2e2dSJohn Marino 
485796c8dcSSimon Schubert /* These are hooks that we put in place while doing interpreter_exec
495796c8dcSSimon Schubert    so we can report interesting things that happened "behind the MI's
505796c8dcSSimon Schubert    back" in this command.  */
515796c8dcSSimon Schubert 
525796c8dcSSimon Schubert static int mi_interp_query_hook (const char *ctlstr, va_list ap)
535796c8dcSSimon Schubert   ATTRIBUTE_PRINTF (1, 0);
545796c8dcSSimon Schubert 
555796c8dcSSimon Schubert static void mi3_command_loop (void);
565796c8dcSSimon Schubert static void mi2_command_loop (void);
575796c8dcSSimon Schubert static void mi1_command_loop (void);
585796c8dcSSimon Schubert 
59cf7f2e2dSJohn Marino static void mi_insert_notify_hooks (void);
60cf7f2e2dSJohn Marino static void mi_remove_notify_hooks (void);
61cf7f2e2dSJohn Marino static void mi_on_normal_stop (struct bpstats *bs, int print_frame);
62cf7f2e2dSJohn Marino 
635796c8dcSSimon Schubert static void mi_new_thread (struct thread_info *t);
645796c8dcSSimon Schubert static void mi_thread_exit (struct thread_info *t, int silent);
655796c8dcSSimon Schubert static void mi_record_changed (struct inferior*, int);
665796c8dcSSimon Schubert static void mi_inferior_added (struct inferior *inf);
67a45ae5f8SJohn Marino static void mi_inferior_appeared (struct inferior *inf);
68a45ae5f8SJohn Marino static void mi_inferior_exit (struct inferior *inf);
69a45ae5f8SJohn Marino static void mi_inferior_removed (struct inferior *inf);
705796c8dcSSimon Schubert static void mi_on_resume (ptid_t ptid);
71cf7f2e2dSJohn Marino static void mi_solib_loaded (struct so_list *solib);
72cf7f2e2dSJohn Marino static void mi_solib_unloaded (struct so_list *solib);
735796c8dcSSimon Schubert static void mi_about_to_proceed (void);
74a45ae5f8SJohn Marino static void mi_traceframe_changed (int tfnum, int tpnum);
755796c8dcSSimon Schubert static void mi_tsv_created (const struct trace_state_variable *tsv);
765796c8dcSSimon Schubert static void mi_tsv_deleted (const struct trace_state_variable *tsv);
77a45ae5f8SJohn Marino static void mi_tsv_modified (const struct trace_state_variable *tsv);
78a45ae5f8SJohn Marino static void mi_breakpoint_created (struct breakpoint *b);
795796c8dcSSimon Schubert static void mi_breakpoint_deleted (struct breakpoint *b);
805796c8dcSSimon Schubert static void mi_breakpoint_modified (struct breakpoint *b);
815796c8dcSSimon Schubert static void mi_command_param_changed (const char *param, const char *value);
825796c8dcSSimon Schubert static void mi_memory_changed (struct inferior *inf, CORE_ADDR memaddr,
835796c8dcSSimon Schubert 			       ssize_t len, const bfd_byte *myaddr);
845796c8dcSSimon Schubert 
855796c8dcSSimon Schubert static int report_initial_inferior (struct inferior *inf, void *closure);
865796c8dcSSimon Schubert 
875796c8dcSSimon Schubert static void *
mi_interpreter_init(struct interp * interp,int top_level)885796c8dcSSimon Schubert mi_interpreter_init (struct interp *interp, int top_level)
895796c8dcSSimon Schubert {
905796c8dcSSimon Schubert   struct mi_interp *mi = XMALLOC (struct mi_interp);
915796c8dcSSimon Schubert   const char *name;
925796c8dcSSimon Schubert   int mi_version;
935796c8dcSSimon Schubert 
94a45ae5f8SJohn Marino   /* Assign the output channel created at startup to its own global,
95a45ae5f8SJohn Marino      so that we can create a console channel that encapsulates and
96a45ae5f8SJohn Marino      prefixes all gdb_output-type bits coming from the rest of the
97a45ae5f8SJohn Marino      debugger.  */
98a45ae5f8SJohn Marino 
99a45ae5f8SJohn Marino   raw_stdout = gdb_stdout;
100a45ae5f8SJohn Marino 
101a45ae5f8SJohn Marino   /* Create MI console channels, each with a different prefix so they
102a45ae5f8SJohn Marino      can be distinguished.  */
103a45ae5f8SJohn Marino   mi->out = mi_console_file_new (raw_stdout, "~", '"');
104a45ae5f8SJohn Marino   mi->err = mi_console_file_new (raw_stdout, "&", '"');
105a45ae5f8SJohn Marino   mi->log = mi->err;
106a45ae5f8SJohn Marino   mi->targ = mi_console_file_new (raw_stdout, "@", '"');
107a45ae5f8SJohn Marino   mi->event_channel = mi_console_file_new (raw_stdout, "=", 0);
108a45ae5f8SJohn Marino 
109a45ae5f8SJohn Marino   name = interp_name (interp);
1105796c8dcSSimon Schubert   /* INTERP_MI selects the most recent released version.  "mi2" was
1115796c8dcSSimon Schubert      released as part of GDB 6.0.  */
1125796c8dcSSimon Schubert   if (strcmp (name, INTERP_MI) == 0)
1135796c8dcSSimon Schubert     mi_version = 2;
114cf7f2e2dSJohn Marino   else if (strcmp (name, INTERP_MI1) == 0)
115cf7f2e2dSJohn Marino     mi_version = 1;
1165796c8dcSSimon Schubert   else if (strcmp (name, INTERP_MI2) == 0)
117cf7f2e2dSJohn Marino     mi_version = 2;
1185796c8dcSSimon Schubert   else if (strcmp (name, INTERP_MI3) == 0)
1195796c8dcSSimon Schubert     mi_version = 3;
1205796c8dcSSimon Schubert   else
1215796c8dcSSimon Schubert     gdb_assert_not_reached ("unhandled MI version");
1225796c8dcSSimon Schubert 
123a45ae5f8SJohn Marino   mi->uiout = mi_out_new (mi_version);
124a45ae5f8SJohn Marino 
125a45ae5f8SJohn Marino   if (top_level)
126cf7f2e2dSJohn Marino     {
127cf7f2e2dSJohn Marino       observer_attach_new_thread (mi_new_thread);
128cf7f2e2dSJohn Marino       observer_attach_thread_exit (mi_thread_exit);
129cf7f2e2dSJohn Marino       observer_attach_inferior_added (mi_inferior_added);
130cf7f2e2dSJohn Marino       observer_attach_inferior_appeared (mi_inferior_appeared);
1315796c8dcSSimon Schubert       observer_attach_inferior_exit (mi_inferior_exit);
1325796c8dcSSimon Schubert       observer_attach_inferior_removed (mi_inferior_removed);
1335796c8dcSSimon Schubert       observer_attach_record_changed (mi_record_changed);
1345796c8dcSSimon Schubert       observer_attach_normal_stop (mi_on_normal_stop);
1355796c8dcSSimon Schubert       observer_attach_target_resumed (mi_on_resume);
1365796c8dcSSimon Schubert       observer_attach_solib_loaded (mi_solib_loaded);
1375796c8dcSSimon Schubert       observer_attach_solib_unloaded (mi_solib_unloaded);
1385796c8dcSSimon Schubert       observer_attach_about_to_proceed (mi_about_to_proceed);
1395796c8dcSSimon Schubert       observer_attach_traceframe_changed (mi_traceframe_changed);
1405796c8dcSSimon Schubert       observer_attach_tsv_created (mi_tsv_created);
141cf7f2e2dSJohn Marino       observer_attach_tsv_deleted (mi_tsv_deleted);
1425796c8dcSSimon Schubert       observer_attach_tsv_modified (mi_tsv_modified);
1435796c8dcSSimon Schubert       observer_attach_breakpoint_created (mi_breakpoint_created);
1445796c8dcSSimon Schubert       observer_attach_breakpoint_deleted (mi_breakpoint_deleted);
1455796c8dcSSimon Schubert       observer_attach_breakpoint_modified (mi_breakpoint_modified);
1465796c8dcSSimon Schubert       observer_attach_command_param_changed (mi_command_param_changed);
1475796c8dcSSimon Schubert       observer_attach_memory_changed (mi_memory_changed);
1485796c8dcSSimon Schubert 
1495796c8dcSSimon Schubert       /* The initial inferior is created before this function is
1505796c8dcSSimon Schubert 	 called, so we need to report it explicitly.  Use iteration in
1515796c8dcSSimon Schubert 	 case future version of GDB creates more than one inferior
1525796c8dcSSimon Schubert 	 up-front.  */
1535796c8dcSSimon Schubert       iterate_over_inferiors (report_initial_inferior, mi);
1545796c8dcSSimon Schubert     }
1555796c8dcSSimon Schubert 
1565796c8dcSSimon Schubert   return mi;
1575796c8dcSSimon Schubert }
1585796c8dcSSimon Schubert 
1595796c8dcSSimon Schubert static int
mi_interpreter_resume(void * data)1605796c8dcSSimon Schubert mi_interpreter_resume (void *data)
1615796c8dcSSimon Schubert {
1625796c8dcSSimon Schubert   struct mi_interp *mi = data;
1635796c8dcSSimon Schubert 
1645796c8dcSSimon Schubert   /* As per hack note in mi_interpreter_init, swap in the output
1655796c8dcSSimon Schubert      channels... */
1665796c8dcSSimon Schubert   gdb_setup_readline ();
1675796c8dcSSimon Schubert 
1685796c8dcSSimon Schubert   /* These overwrite some of the initialization done in
1695796c8dcSSimon Schubert      _intialize_event_loop.  */
1705796c8dcSSimon Schubert   call_readline = gdb_readline2;
1715796c8dcSSimon Schubert   input_handler = mi_execute_command_input_handler;
1725796c8dcSSimon Schubert   add_file_handler (input_fd, stdin_event_handler, 0);
1735796c8dcSSimon Schubert   async_command_editing_p = 0;
1745796c8dcSSimon Schubert   /* FIXME: This is a total hack for now.  PB's use of the MI
1755796c8dcSSimon Schubert      implicitly relies on a bug in the async support which allows
1765796c8dcSSimon Schubert      asynchronous commands to leak through the commmand loop.  The bug
1775796c8dcSSimon Schubert      involves (but is not limited to) the fact that sync_execution was
1785796c8dcSSimon Schubert      erroneously initialized to 0.  Duplicate by initializing it thus
1795796c8dcSSimon Schubert      here...  */
1805796c8dcSSimon Schubert   sync_execution = 0;
1815796c8dcSSimon Schubert 
1825796c8dcSSimon Schubert   gdb_stdout = mi->out;
1835796c8dcSSimon Schubert   /* Route error and log output through the MI.  */
1845796c8dcSSimon Schubert   gdb_stderr = mi->err;
1855796c8dcSSimon Schubert   gdb_stdlog = mi->log;
1865796c8dcSSimon Schubert   /* Route target output through the MI.  */
1875796c8dcSSimon Schubert   gdb_stdtarg = mi->targ;
1885796c8dcSSimon Schubert   /* Route target error through the MI as well.  */
1895796c8dcSSimon Schubert   gdb_stdtargerr = mi->targ;
1905796c8dcSSimon Schubert 
1915796c8dcSSimon Schubert   /* Replace all the hooks that we know about.  There really needs to
1925796c8dcSSimon Schubert      be a better way of doing this... */
1935796c8dcSSimon Schubert   clear_interpreter_hooks ();
1945796c8dcSSimon Schubert 
1955796c8dcSSimon Schubert   deprecated_show_load_progress = mi_load_progress;
1965796c8dcSSimon Schubert 
197cf7f2e2dSJohn Marino   /* If we're _the_ interpreter, take control.  */
1985796c8dcSSimon Schubert   if (current_interp_named_p (INTERP_MI1))
1995796c8dcSSimon Schubert     deprecated_command_loop_hook = mi1_command_loop;
2005796c8dcSSimon Schubert   else if (current_interp_named_p (INTERP_MI2))
2015796c8dcSSimon Schubert     deprecated_command_loop_hook = mi2_command_loop;
2025796c8dcSSimon Schubert   else if (current_interp_named_p (INTERP_MI3))
2035796c8dcSSimon Schubert     deprecated_command_loop_hook = mi3_command_loop;
2045796c8dcSSimon Schubert   else
2055796c8dcSSimon Schubert     deprecated_command_loop_hook = mi2_command_loop;
2065796c8dcSSimon Schubert 
2075796c8dcSSimon Schubert   return 1;
2085796c8dcSSimon Schubert }
2095796c8dcSSimon Schubert 
2105796c8dcSSimon Schubert static int
mi_interpreter_suspend(void * data)2115796c8dcSSimon Schubert mi_interpreter_suspend (void *data)
2125796c8dcSSimon Schubert {
2135796c8dcSSimon Schubert   gdb_disable_readline ();
2145796c8dcSSimon Schubert   return 1;
2155796c8dcSSimon Schubert }
2165796c8dcSSimon Schubert 
2175796c8dcSSimon Schubert static struct gdb_exception
mi_interpreter_exec(void * data,const char * command)2185796c8dcSSimon Schubert mi_interpreter_exec (void *data, const char *command)
219c50c785cSJohn Marino {
220c50c785cSJohn Marino   mi_execute_command_wrapper (command);
2215796c8dcSSimon Schubert   return exception_none;
2225796c8dcSSimon Schubert }
2235796c8dcSSimon Schubert 
224c50c785cSJohn Marino /* Never display the default GDB prompt in MI case.  */
225c50c785cSJohn Marino 
2265796c8dcSSimon Schubert static int
mi_interpreter_prompt_p(void * data)2275796c8dcSSimon Schubert mi_interpreter_prompt_p (void *data)
228c50c785cSJohn Marino {
229c50c785cSJohn Marino   return 0;
2305796c8dcSSimon Schubert }
2315796c8dcSSimon Schubert 
2325796c8dcSSimon Schubert void
mi_cmd_interpreter_exec(char * command,char ** argv,int argc)2335796c8dcSSimon Schubert mi_cmd_interpreter_exec (char *command, char **argv, int argc)
2345796c8dcSSimon Schubert {
2355796c8dcSSimon Schubert   struct interp *interp_to_use;
2365796c8dcSSimon Schubert   int i;
2375796c8dcSSimon Schubert   char *mi_error_message = NULL;
2385796c8dcSSimon Schubert   struct cleanup *old_chain;
2395796c8dcSSimon Schubert 
2405796c8dcSSimon Schubert   if (argc < 2)
2415796c8dcSSimon Schubert     error (_("-interpreter-exec: "
2425796c8dcSSimon Schubert 	     "Usage: -interpreter-exec interp command"));
2435796c8dcSSimon Schubert 
244cf7f2e2dSJohn Marino   interp_to_use = interp_lookup (argv[0]);
2455796c8dcSSimon Schubert   if (interp_to_use == NULL)
2465796c8dcSSimon Schubert     error (_("-interpreter-exec: could not find interpreter \"%s\""),
2475796c8dcSSimon Schubert 	   argv[0]);
2485796c8dcSSimon Schubert 
2495796c8dcSSimon Schubert   if (!interp_exec_p (interp_to_use))
2505796c8dcSSimon Schubert     error (_("-interpreter-exec: interpreter \"%s\" "
2515796c8dcSSimon Schubert 	     "does not support command execution"),
2525796c8dcSSimon Schubert 	      argv[0]);
2535796c8dcSSimon Schubert 
2545796c8dcSSimon Schubert   /* Insert the MI out hooks, making sure to also call the
2555796c8dcSSimon Schubert      interpreter's hooks if it has any.  */
2565796c8dcSSimon Schubert   /* KRS: We shouldn't need this... Events should be installed and
2575796c8dcSSimon Schubert      they should just ALWAYS fire something out down the MI
2585796c8dcSSimon Schubert      channel.  */
2595796c8dcSSimon Schubert   mi_insert_notify_hooks ();
2605796c8dcSSimon Schubert 
261c50c785cSJohn Marino   /* Now run the code.  */
262c50c785cSJohn Marino 
263c50c785cSJohn Marino   old_chain = make_cleanup (null_cleanup, 0);
264c50c785cSJohn Marino   for (i = 1; i < argc; i++)
265c50c785cSJohn Marino     {
266c50c785cSJohn Marino       struct gdb_exception e = interp_exec (interp_to_use, argv[i]);
2675796c8dcSSimon Schubert 
2685796c8dcSSimon Schubert       if (e.reason < 0)
2695796c8dcSSimon Schubert 	{
2705796c8dcSSimon Schubert 	  mi_error_message = xstrdup (e.message);
2715796c8dcSSimon Schubert 	  make_cleanup (xfree, mi_error_message);
2725796c8dcSSimon Schubert 	  break;
2735796c8dcSSimon Schubert 	}
2745796c8dcSSimon Schubert     }
2755796c8dcSSimon Schubert 
2765796c8dcSSimon Schubert   mi_remove_notify_hooks ();
2775796c8dcSSimon Schubert 
2785796c8dcSSimon Schubert   if (mi_error_message != NULL)
2795796c8dcSSimon Schubert     error ("%s", mi_error_message);
2805796c8dcSSimon Schubert   do_cleanups (old_chain);
2815796c8dcSSimon Schubert }
2825796c8dcSSimon Schubert 
2835796c8dcSSimon Schubert /* This inserts a number of hooks that are meant to produce
2845796c8dcSSimon Schubert    async-notify ("=") MI messages while running commands in another
2855796c8dcSSimon Schubert    interpreter using mi_interpreter_exec.  The canonical use for this
2865796c8dcSSimon Schubert    is to allow access to the gdb CLI interpreter from within the MI,
2875796c8dcSSimon Schubert    while still producing MI style output when actions in the CLI
2885796c8dcSSimon Schubert    command change GDB's state.  */
2895796c8dcSSimon Schubert 
2905796c8dcSSimon Schubert static void
mi_insert_notify_hooks(void)2915796c8dcSSimon Schubert mi_insert_notify_hooks (void)
2925796c8dcSSimon Schubert {
2935796c8dcSSimon Schubert   deprecated_query_hook = mi_interp_query_hook;
2945796c8dcSSimon Schubert }
2955796c8dcSSimon Schubert 
2965796c8dcSSimon Schubert static void
mi_remove_notify_hooks(void)2975796c8dcSSimon Schubert mi_remove_notify_hooks (void)
2985796c8dcSSimon Schubert {
2995796c8dcSSimon Schubert   deprecated_query_hook = NULL;
3005796c8dcSSimon Schubert }
3015796c8dcSSimon Schubert 
3025796c8dcSSimon Schubert static int
mi_interp_query_hook(const char * ctlstr,va_list ap)3035796c8dcSSimon Schubert mi_interp_query_hook (const char *ctlstr, va_list ap)
3045796c8dcSSimon Schubert {
3055796c8dcSSimon Schubert   return 1;
3065796c8dcSSimon Schubert }
3075796c8dcSSimon Schubert 
3085796c8dcSSimon Schubert static void
mi_execute_command_wrapper(const char * cmd)3095796c8dcSSimon Schubert mi_execute_command_wrapper (const char *cmd)
3105796c8dcSSimon Schubert {
3115796c8dcSSimon Schubert   mi_execute_command (cmd, stdin == instream);
3125796c8dcSSimon Schubert }
3135796c8dcSSimon Schubert 
3145796c8dcSSimon Schubert /* mi_execute_command_wrapper wrapper suitable for INPUT_HANDLER.  */
3155796c8dcSSimon Schubert 
3165796c8dcSSimon Schubert static void
mi_execute_command_input_handler(char * cmd)3175796c8dcSSimon Schubert mi_execute_command_input_handler (char *cmd)
3185796c8dcSSimon Schubert {
3195796c8dcSSimon Schubert   mi_execute_command_wrapper (cmd);
3205796c8dcSSimon Schubert 
3215796c8dcSSimon Schubert   fputs_unfiltered ("(gdb) \n", raw_stdout);
3225796c8dcSSimon Schubert   gdb_flush (raw_stdout);
3235796c8dcSSimon Schubert }
3245796c8dcSSimon Schubert 
3255796c8dcSSimon Schubert static void
mi1_command_loop(void)3265796c8dcSSimon Schubert mi1_command_loop (void)
327cf7f2e2dSJohn Marino {
328cf7f2e2dSJohn Marino   mi_command_loop (1);
329cf7f2e2dSJohn Marino }
3305796c8dcSSimon Schubert 
3315796c8dcSSimon Schubert static void
mi2_command_loop(void)332cf7f2e2dSJohn Marino mi2_command_loop (void)
333cf7f2e2dSJohn Marino {
3345796c8dcSSimon Schubert   mi_command_loop (2);
3355796c8dcSSimon Schubert }
3365796c8dcSSimon Schubert 
3375796c8dcSSimon Schubert static void
mi3_command_loop(void)3385796c8dcSSimon Schubert mi3_command_loop (void)
3395796c8dcSSimon Schubert {
3405796c8dcSSimon Schubert   mi_command_loop (3);
341cf7f2e2dSJohn Marino }
3425796c8dcSSimon Schubert 
3435796c8dcSSimon Schubert static void
mi_command_loop(int mi_version)3445796c8dcSSimon Schubert mi_command_loop (int mi_version)
3455796c8dcSSimon Schubert {
346cf7f2e2dSJohn Marino   /* Turn off 8 bit strings in quoted output.  Any character with the
347cf7f2e2dSJohn Marino      high bit set is printed using C's octal format.  */
3485796c8dcSSimon Schubert   sevenbit_strings = 1;
3495796c8dcSSimon Schubert 
3505796c8dcSSimon Schubert   /* Tell the world that we're alive.  */
351cf7f2e2dSJohn Marino   fputs_unfiltered ("(gdb) \n", raw_stdout);
352cf7f2e2dSJohn Marino   gdb_flush (raw_stdout);
3535796c8dcSSimon Schubert 
3545796c8dcSSimon Schubert   start_event_loop ();
3555796c8dcSSimon Schubert }
3565796c8dcSSimon Schubert 
357cf7f2e2dSJohn Marino static void
mi_new_thread(struct thread_info * t)3585796c8dcSSimon Schubert mi_new_thread (struct thread_info *t)
3595796c8dcSSimon Schubert {
360cf7f2e2dSJohn Marino   struct mi_interp *mi = top_level_interpreter_data ();
3615796c8dcSSimon Schubert   struct inferior *inf = find_inferior_pid (ptid_get_pid (t->ptid));
362cf7f2e2dSJohn Marino 
363cf7f2e2dSJohn Marino   gdb_assert (inf);
364cf7f2e2dSJohn Marino 
3655796c8dcSSimon Schubert   fprintf_unfiltered (mi->event_channel,
3665796c8dcSSimon Schubert 		      "thread-created,id=\"%d\",group-id=\"i%d\"",
3675796c8dcSSimon Schubert 		      t->num, inf->num);
3685796c8dcSSimon Schubert   gdb_flush (mi->event_channel);
369cf7f2e2dSJohn Marino }
3705796c8dcSSimon Schubert 
3715796c8dcSSimon Schubert static void
mi_thread_exit(struct thread_info * t,int silent)372cf7f2e2dSJohn Marino mi_thread_exit (struct thread_info *t, int silent)
3735796c8dcSSimon Schubert {
374cf7f2e2dSJohn Marino   struct mi_interp *mi;
375cf7f2e2dSJohn Marino   struct inferior *inf;
376cf7f2e2dSJohn Marino 
377cf7f2e2dSJohn Marino   if (silent)
378cf7f2e2dSJohn Marino     return;
379cf7f2e2dSJohn Marino 
380cf7f2e2dSJohn Marino   inf = find_inferior_pid (ptid_get_pid (t->ptid));
381cf7f2e2dSJohn Marino 
382cf7f2e2dSJohn Marino   mi = top_level_interpreter_data ();
383cf7f2e2dSJohn Marino   target_terminal_ours ();
384cf7f2e2dSJohn Marino   fprintf_unfiltered (mi->event_channel,
385cf7f2e2dSJohn Marino 		      "thread-exited,id=\"%d\",group-id=\"i%d\"",
386c50c785cSJohn Marino 		      t->num, inf->num);
387c50c785cSJohn Marino   gdb_flush (mi->event_channel);
388c50c785cSJohn Marino }
389c50c785cSJohn Marino 
390c50c785cSJohn Marino /* Emit notification on changing the state of record.  */
391c50c785cSJohn Marino 
392c50c785cSJohn Marino static void
mi_record_changed(struct inferior * inferior,int started)393c50c785cSJohn Marino mi_record_changed (struct inferior *inferior, int started)
394cf7f2e2dSJohn Marino {
395cf7f2e2dSJohn Marino   struct mi_interp *mi = top_level_interpreter_data ();
396cf7f2e2dSJohn Marino 
397cf7f2e2dSJohn Marino   fprintf_unfiltered (mi->event_channel,  "record-%s,thread-group=\"i%d\"",
398cf7f2e2dSJohn Marino 		      started ? "started" : "stopped", inferior->num);
399cf7f2e2dSJohn Marino 
400cf7f2e2dSJohn Marino   gdb_flush (mi->event_channel);
401cf7f2e2dSJohn Marino }
402cf7f2e2dSJohn Marino 
403cf7f2e2dSJohn Marino static void
mi_inferior_added(struct inferior * inf)404cf7f2e2dSJohn Marino mi_inferior_added (struct inferior *inf)
405cf7f2e2dSJohn Marino {
4065796c8dcSSimon Schubert   struct mi_interp *mi = top_level_interpreter_data ();
4075796c8dcSSimon Schubert 
4085796c8dcSSimon Schubert   target_terminal_ours ();
4095796c8dcSSimon Schubert   fprintf_unfiltered (mi->event_channel,
4105796c8dcSSimon Schubert 		      "thread-group-added,id=\"i%d\"",
4115796c8dcSSimon Schubert 		      inf->num);
4125796c8dcSSimon Schubert   gdb_flush (mi->event_channel);
4135796c8dcSSimon Schubert }
4145796c8dcSSimon Schubert 
4155796c8dcSSimon Schubert static void
mi_inferior_appeared(struct inferior * inf)4165796c8dcSSimon Schubert mi_inferior_appeared (struct inferior *inf)
4175796c8dcSSimon Schubert {
4185796c8dcSSimon Schubert   struct mi_interp *mi = top_level_interpreter_data ();
419cf7f2e2dSJohn Marino 
420cf7f2e2dSJohn Marino   target_terminal_ours ();
421a45ae5f8SJohn Marino   fprintf_unfiltered (mi->event_channel,
4225796c8dcSSimon Schubert 		      "thread-group-started,id=\"i%d\",pid=\"%d\"",
4235796c8dcSSimon Schubert 		      inf->num, inf->pid);
4245796c8dcSSimon Schubert   gdb_flush (mi->event_channel);
4255796c8dcSSimon Schubert }
4265796c8dcSSimon Schubert 
4275796c8dcSSimon Schubert static void
mi_inferior_exit(struct inferior * inf)428a45ae5f8SJohn Marino mi_inferior_exit (struct inferior *inf)
429a45ae5f8SJohn Marino {
430a45ae5f8SJohn Marino   struct mi_interp *mi = top_level_interpreter_data ();
431cf7f2e2dSJohn Marino 
432a45ae5f8SJohn Marino   target_terminal_ours ();
433a45ae5f8SJohn Marino   if (inf->has_exit_code)
434a45ae5f8SJohn Marino     fprintf_unfiltered (mi->event_channel,
435a45ae5f8SJohn Marino 			"thread-group-exited,id=\"i%d\",exit-code=\"%s\"",
436a45ae5f8SJohn Marino 			inf->num, int_string (inf->exit_code, 8, 0, 0, 1));
4375796c8dcSSimon Schubert   else
438a45ae5f8SJohn Marino     fprintf_unfiltered (mi->event_channel,
4395796c8dcSSimon Schubert 			"thread-group-exited,id=\"i%d\"", inf->num);
4405796c8dcSSimon Schubert 
4415796c8dcSSimon Schubert   gdb_flush (mi->event_channel);
4425796c8dcSSimon Schubert }
4435796c8dcSSimon Schubert 
4445796c8dcSSimon Schubert static void
mi_inferior_removed(struct inferior * inf)4455796c8dcSSimon Schubert mi_inferior_removed (struct inferior *inf)
4465796c8dcSSimon Schubert {
447cf7f2e2dSJohn Marino   struct mi_interp *mi = top_level_interpreter_data ();
4485796c8dcSSimon Schubert 
4495796c8dcSSimon Schubert   target_terminal_ours ();
4505796c8dcSSimon Schubert   fprintf_unfiltered (mi->event_channel,
4515796c8dcSSimon Schubert 		      "thread-group-removed,id=\"i%d\"",
4525796c8dcSSimon Schubert 		      inf->num);
4535796c8dcSSimon Schubert   gdb_flush (mi->event_channel);
454cf7f2e2dSJohn Marino }
455cf7f2e2dSJohn Marino 
456cf7f2e2dSJohn Marino static void
mi_on_normal_stop(struct bpstats * bs,int print_frame)457cf7f2e2dSJohn Marino mi_on_normal_stop (struct bpstats *bs, int print_frame)
4585796c8dcSSimon Schubert {
4595796c8dcSSimon Schubert   /* Since this can be called when CLI command is executing,
4605796c8dcSSimon Schubert      using cli interpreter, be sure to use MI uiout for output,
4615796c8dcSSimon Schubert      not the current one.  */
4625796c8dcSSimon Schubert   struct ui_out *mi_uiout = interp_ui_out (top_level_interpreter ());
4635796c8dcSSimon Schubert 
4645796c8dcSSimon Schubert   if (print_frame)
4655796c8dcSSimon Schubert     {
4665796c8dcSSimon Schubert       int core;
4675796c8dcSSimon Schubert 
4685796c8dcSSimon Schubert       if (current_uiout != mi_uiout)
4695796c8dcSSimon Schubert 	{
4705796c8dcSSimon Schubert 	  /* The normal_stop function has printed frame information
4715796c8dcSSimon Schubert 	     into CLI uiout, or some other non-MI uiout.  There's no
4725796c8dcSSimon Schubert 	     way we can extract proper fields from random uiout
4735796c8dcSSimon Schubert 	     object, so we print the frame again.  In practice, this
4745796c8dcSSimon Schubert 	     can only happen when running a CLI command in MI.  */
4755796c8dcSSimon Schubert 	  struct ui_out *saved_uiout = current_uiout;
476cf7f2e2dSJohn Marino 	  struct target_waitstatus last;
477c50c785cSJohn Marino 	  ptid_t last_ptid;
4785796c8dcSSimon Schubert 
4795796c8dcSSimon Schubert 	  current_uiout = mi_uiout;
4805796c8dcSSimon Schubert 
4815796c8dcSSimon Schubert 	  get_last_target_status (&last_ptid, &last);
4825796c8dcSSimon Schubert 	  bpstat_print (bs, last.kind);
4835796c8dcSSimon Schubert 
484a45ae5f8SJohn Marino 	  print_stack_frame (get_selected_frame (NULL), 0, SRC_AND_LOC);
485a45ae5f8SJohn Marino 	  current_uiout = saved_uiout;
486a45ae5f8SJohn Marino 	}
487a45ae5f8SJohn Marino 
488a45ae5f8SJohn Marino       ui_out_field_int (mi_uiout, "thread-id",
489a45ae5f8SJohn Marino 			pid_to_thread_id (inferior_ptid));
490a45ae5f8SJohn Marino       if (non_stop)
491a45ae5f8SJohn Marino 	{
492a45ae5f8SJohn Marino 	  struct cleanup *back_to = make_cleanup_ui_out_list_begin_end
493a45ae5f8SJohn Marino 	    (mi_uiout, "stopped-threads");
494a45ae5f8SJohn Marino 
495a45ae5f8SJohn Marino 	  ui_out_field_int (mi_uiout, NULL,
496a45ae5f8SJohn Marino 			    pid_to_thread_id (inferior_ptid));
497a45ae5f8SJohn Marino 	  do_cleanups (back_to);
498a45ae5f8SJohn Marino 	}
499a45ae5f8SJohn Marino       else
500a45ae5f8SJohn Marino 	ui_out_field_string (mi_uiout, "stopped-threads", "all");
501a45ae5f8SJohn Marino 
502a45ae5f8SJohn Marino       core = target_core_of_thread (inferior_ptid);
503a45ae5f8SJohn Marino       if (core != -1)
504a45ae5f8SJohn Marino 	ui_out_field_int (mi_uiout, "core", core);
505a45ae5f8SJohn Marino     }
506a45ae5f8SJohn Marino 
507a45ae5f8SJohn Marino   fputs_unfiltered ("*stopped", raw_stdout);
508a45ae5f8SJohn Marino   mi_out_put (mi_uiout, raw_stdout);
509a45ae5f8SJohn Marino   mi_out_rewind (mi_uiout);
510a45ae5f8SJohn Marino   mi_print_timing_maybe ();
511a45ae5f8SJohn Marino   fputs_unfiltered ("\n", raw_stdout);
512a45ae5f8SJohn Marino   gdb_flush (raw_stdout);
513a45ae5f8SJohn Marino }
514a45ae5f8SJohn Marino 
515a45ae5f8SJohn Marino static void
mi_about_to_proceed(void)516a45ae5f8SJohn Marino mi_about_to_proceed (void)
517a45ae5f8SJohn Marino {
518a45ae5f8SJohn Marino   /* Suppress output while calling an inferior function.  */
519a45ae5f8SJohn Marino 
520a45ae5f8SJohn Marino   if (!ptid_equal (inferior_ptid, null_ptid))
521a45ae5f8SJohn Marino     {
522a45ae5f8SJohn Marino       struct thread_info *tp = inferior_thread ();
523a45ae5f8SJohn Marino 
524a45ae5f8SJohn Marino       if (tp->control.in_infcall)
525a45ae5f8SJohn Marino 	return;
526a45ae5f8SJohn Marino     }
527a45ae5f8SJohn Marino 
528a45ae5f8SJohn Marino   mi_proceeded = 1;
529a45ae5f8SJohn Marino }
530a45ae5f8SJohn Marino 
531a45ae5f8SJohn Marino /* When the element is non-zero, no MI notifications will be emitted in
532a45ae5f8SJohn Marino    response to the corresponding observers.  */
533a45ae5f8SJohn Marino 
534a45ae5f8SJohn Marino struct mi_suppress_notification mi_suppress_notification =
535a45ae5f8SJohn Marino   {
536a45ae5f8SJohn Marino     0,
537a45ae5f8SJohn Marino     0,
538a45ae5f8SJohn Marino     0,
539a45ae5f8SJohn Marino   };
540a45ae5f8SJohn Marino 
541a45ae5f8SJohn Marino /* Emit notification on changing a traceframe.  */
542a45ae5f8SJohn Marino 
543a45ae5f8SJohn Marino static void
mi_traceframe_changed(int tfnum,int tpnum)544a45ae5f8SJohn Marino mi_traceframe_changed (int tfnum, int tpnum)
545a45ae5f8SJohn Marino {
546a45ae5f8SJohn Marino   struct mi_interp *mi = top_level_interpreter_data ();
547a45ae5f8SJohn Marino 
548a45ae5f8SJohn Marino   if (mi_suppress_notification.traceframe)
549a45ae5f8SJohn Marino     return;
550a45ae5f8SJohn Marino 
551a45ae5f8SJohn Marino   target_terminal_ours ();
552a45ae5f8SJohn Marino 
553a45ae5f8SJohn Marino   if (tfnum >= 0)
554a45ae5f8SJohn Marino     fprintf_unfiltered (mi->event_channel, "traceframe-changed,"
555a45ae5f8SJohn Marino 			"num=\"%d\",tracepoint=\"%d\"\n",
556a45ae5f8SJohn Marino 			tfnum, tpnum);
557a45ae5f8SJohn Marino   else
558a45ae5f8SJohn Marino     fprintf_unfiltered (mi->event_channel, "traceframe-changed,end");
559a45ae5f8SJohn Marino 
560a45ae5f8SJohn Marino   gdb_flush (mi->event_channel);
561a45ae5f8SJohn Marino }
562a45ae5f8SJohn Marino 
563a45ae5f8SJohn Marino /* Emit notification on creating a trace state variable.  */
564a45ae5f8SJohn Marino 
565a45ae5f8SJohn Marino static void
mi_tsv_created(const struct trace_state_variable * tsv)566a45ae5f8SJohn Marino mi_tsv_created (const struct trace_state_variable *tsv)
567a45ae5f8SJohn Marino {
568a45ae5f8SJohn Marino   struct mi_interp *mi = top_level_interpreter_data ();
569a45ae5f8SJohn Marino 
570a45ae5f8SJohn Marino   target_terminal_ours ();
571a45ae5f8SJohn Marino 
572a45ae5f8SJohn Marino   fprintf_unfiltered (mi->event_channel, "tsv-created,"
5735796c8dcSSimon Schubert 		      "name=\"%s\",initial=\"%s\"\n",
5745796c8dcSSimon Schubert 		      tsv->name, plongest (tsv->initial_value));
5755796c8dcSSimon Schubert 
5765796c8dcSSimon Schubert   gdb_flush (mi->event_channel);
5775796c8dcSSimon Schubert }
5785796c8dcSSimon Schubert 
5795796c8dcSSimon Schubert /* Emit notification on deleting a trace state variable.  */
5805796c8dcSSimon Schubert 
5815796c8dcSSimon Schubert static void
mi_tsv_deleted(const struct trace_state_variable * tsv)5825796c8dcSSimon Schubert mi_tsv_deleted (const struct trace_state_variable *tsv)
5835796c8dcSSimon Schubert {
5845796c8dcSSimon Schubert   struct mi_interp *mi = top_level_interpreter_data ();
5855796c8dcSSimon Schubert 
5865796c8dcSSimon Schubert   target_terminal_ours ();
5875796c8dcSSimon Schubert 
5885796c8dcSSimon Schubert   if (tsv != NULL)
589*74a8b0f5SJohn Marino     fprintf_unfiltered (mi->event_channel, "tsv-deleted,"
5905796c8dcSSimon Schubert 			"name=\"%s\"\n", tsv->name);
5915796c8dcSSimon Schubert   else
5925796c8dcSSimon Schubert     fprintf_unfiltered (mi->event_channel, "tsv-deleted\n");
5935796c8dcSSimon Schubert 
5945796c8dcSSimon Schubert   gdb_flush (mi->event_channel);
5955796c8dcSSimon Schubert }
5965796c8dcSSimon Schubert 
5975796c8dcSSimon Schubert /* Emit notification on modifying a trace state variable.  */
5985796c8dcSSimon Schubert 
5995796c8dcSSimon Schubert static void
mi_tsv_modified(const struct trace_state_variable * tsv)6005796c8dcSSimon Schubert mi_tsv_modified (const struct trace_state_variable *tsv)
6015796c8dcSSimon Schubert {
6025796c8dcSSimon Schubert   struct mi_interp *mi = top_level_interpreter_data ();
6035796c8dcSSimon Schubert   struct ui_out *mi_uiout = interp_ui_out (top_level_interpreter ());
6045796c8dcSSimon Schubert 
6055796c8dcSSimon Schubert   target_terminal_ours ();
6065796c8dcSSimon Schubert 
6075796c8dcSSimon Schubert   fprintf_unfiltered (mi->event_channel,
6085796c8dcSSimon Schubert 		      "tsv-modified");
609c50c785cSJohn Marino 
6105796c8dcSSimon Schubert   ui_out_redirect (mi_uiout, mi->event_channel);
6115796c8dcSSimon Schubert 
6125796c8dcSSimon Schubert   ui_out_field_string (mi_uiout, "name", tsv->name);
6135796c8dcSSimon Schubert   ui_out_field_string (mi_uiout, "initial",
6145796c8dcSSimon Schubert 		       plongest (tsv->initial_value));
6155796c8dcSSimon Schubert   if (tsv->value_known)
6165796c8dcSSimon Schubert     ui_out_field_string (mi_uiout, "current", plongest (tsv->value));
6175796c8dcSSimon Schubert 
6185796c8dcSSimon Schubert   ui_out_redirect (mi_uiout, NULL);
6195796c8dcSSimon Schubert 
6205796c8dcSSimon Schubert   gdb_flush (mi->event_channel);
6215796c8dcSSimon Schubert }
622cf7f2e2dSJohn Marino 
623cf7f2e2dSJohn Marino /* Emit notification about a created breakpoint.  */
6245796c8dcSSimon Schubert 
6255796c8dcSSimon Schubert static void
mi_breakpoint_created(struct breakpoint * b)6265796c8dcSSimon Schubert mi_breakpoint_created (struct breakpoint *b)
6275796c8dcSSimon Schubert {
6285796c8dcSSimon Schubert   struct mi_interp *mi = top_level_interpreter_data ();
6295796c8dcSSimon Schubert   struct ui_out *mi_uiout = interp_ui_out (top_level_interpreter ());
6305796c8dcSSimon Schubert   volatile struct gdb_exception e;
6315796c8dcSSimon Schubert 
6325796c8dcSSimon Schubert   if (mi_suppress_notification.breakpoint)
6335796c8dcSSimon Schubert     return;
6345796c8dcSSimon Schubert 
6355796c8dcSSimon Schubert   if (b->number <= 0)
6365796c8dcSSimon Schubert     return;
6375796c8dcSSimon Schubert 
6385796c8dcSSimon Schubert   target_terminal_ours ();
6395796c8dcSSimon Schubert   fprintf_unfiltered (mi->event_channel,
6405796c8dcSSimon Schubert 		      "breakpoint-created");
6415796c8dcSSimon Schubert   /* We want the output from gdb_breakpoint_query to go to
6425796c8dcSSimon Schubert      mi->event_channel.  One approach would be to just call
6435796c8dcSSimon Schubert      gdb_breakpoint_query, and then use mi_out_put to send the current
6445796c8dcSSimon Schubert      content of mi_outout into mi->event_channel.  However, that will
645cf7f2e2dSJohn Marino      break if anything is output to mi_uiout prior to calling the
6465796c8dcSSimon Schubert      breakpoint_created notifications.  So, we use
6475796c8dcSSimon Schubert      ui_out_redirect.  */
6485796c8dcSSimon Schubert   ui_out_redirect (mi_uiout, mi->event_channel);
6495796c8dcSSimon Schubert   TRY_CATCH (e, RETURN_MASK_ERROR)
6505796c8dcSSimon Schubert     gdb_breakpoint_query (mi_uiout, b->number, NULL);
6515796c8dcSSimon Schubert   ui_out_redirect (mi_uiout, NULL);
6525796c8dcSSimon Schubert 
6535796c8dcSSimon Schubert   gdb_flush (mi->event_channel);
6545796c8dcSSimon Schubert }
6555796c8dcSSimon Schubert 
6565796c8dcSSimon Schubert /* Emit notification about deleted breakpoint.  */
6575796c8dcSSimon Schubert 
6585796c8dcSSimon Schubert static void
mi_breakpoint_deleted(struct breakpoint * b)6595796c8dcSSimon Schubert mi_breakpoint_deleted (struct breakpoint *b)
6605796c8dcSSimon Schubert {
6615796c8dcSSimon Schubert   struct mi_interp *mi = top_level_interpreter_data ();
6625796c8dcSSimon Schubert 
6635796c8dcSSimon Schubert   if (mi_suppress_notification.breakpoint)
6645796c8dcSSimon Schubert     return;
6655796c8dcSSimon Schubert 
6665796c8dcSSimon Schubert   if (b->number <= 0)
6675796c8dcSSimon Schubert     return;
668cf7f2e2dSJohn Marino 
6695796c8dcSSimon Schubert   target_terminal_ours ();
670cf7f2e2dSJohn Marino 
6715796c8dcSSimon Schubert   fprintf_unfiltered (mi->event_channel, "breakpoint-deleted,id=\"%d\"",
672cf7f2e2dSJohn Marino 		      b->number);
673cf7f2e2dSJohn Marino 
6745796c8dcSSimon Schubert   gdb_flush (mi->event_channel);
6755796c8dcSSimon Schubert }
676cf7f2e2dSJohn Marino 
677cf7f2e2dSJohn Marino /* Emit notification about modified breakpoint.  */
678cf7f2e2dSJohn Marino 
679cf7f2e2dSJohn Marino static void
mi_breakpoint_modified(struct breakpoint * b)680cf7f2e2dSJohn Marino mi_breakpoint_modified (struct breakpoint *b)
681cf7f2e2dSJohn Marino {
682cf7f2e2dSJohn Marino   struct mi_interp *mi = top_level_interpreter_data ();
683cf7f2e2dSJohn Marino   struct ui_out *mi_uiout = interp_ui_out (top_level_interpreter ());
684cf7f2e2dSJohn Marino   volatile struct gdb_exception e;
6855796c8dcSSimon Schubert 
6865796c8dcSSimon Schubert   if (mi_suppress_notification.breakpoint)
6875796c8dcSSimon Schubert     return;
6885796c8dcSSimon Schubert 
6895796c8dcSSimon Schubert   if (b->number <= 0)
6905796c8dcSSimon Schubert     return;
6915796c8dcSSimon Schubert 
692cf7f2e2dSJohn Marino   target_terminal_ours ();
6935796c8dcSSimon Schubert   fprintf_unfiltered (mi->event_channel,
694cf7f2e2dSJohn Marino 		      "breakpoint-modified");
6955796c8dcSSimon Schubert   /* We want the output from gdb_breakpoint_query to go to
696cf7f2e2dSJohn Marino      mi->event_channel.  One approach would be to just call
697cf7f2e2dSJohn Marino      gdb_breakpoint_query, and then use mi_out_put to send the current
6985796c8dcSSimon Schubert      content of mi_outout into mi->event_channel.  However, that will
6995796c8dcSSimon Schubert      break if anything is output to mi_uiout prior to calling the
700cf7f2e2dSJohn Marino      breakpoint_created notifications.  So, we use
701cf7f2e2dSJohn Marino      ui_out_redirect.  */
702cf7f2e2dSJohn Marino   ui_out_redirect (mi_uiout, mi->event_channel);
703cf7f2e2dSJohn Marino   TRY_CATCH (e, RETURN_MASK_ERROR)
704cf7f2e2dSJohn Marino     gdb_breakpoint_query (mi_uiout, b->number, NULL);
705cf7f2e2dSJohn Marino   ui_out_redirect (mi_uiout, NULL);
706cf7f2e2dSJohn Marino 
7075796c8dcSSimon Schubert   gdb_flush (mi->event_channel);
7085796c8dcSSimon Schubert }
7095796c8dcSSimon Schubert 
710cf7f2e2dSJohn Marino static int
mi_output_running_pid(struct thread_info * info,void * arg)711cf7f2e2dSJohn Marino mi_output_running_pid (struct thread_info *info, void *arg)
712cf7f2e2dSJohn Marino {
713cf7f2e2dSJohn Marino   ptid_t *ptid = arg;
714cf7f2e2dSJohn Marino 
715cf7f2e2dSJohn Marino   if (ptid_get_pid (*ptid) == ptid_get_pid (info->ptid))
716cf7f2e2dSJohn Marino     fprintf_unfiltered (raw_stdout,
717cf7f2e2dSJohn Marino 			"*running,thread-id=\"%d\"\n",
718cf7f2e2dSJohn Marino 			info->num);
719cf7f2e2dSJohn Marino 
720cf7f2e2dSJohn Marino   return 0;
721cf7f2e2dSJohn Marino }
722cf7f2e2dSJohn Marino 
723cf7f2e2dSJohn Marino static int
mi_inferior_count(struct inferior * inf,void * arg)724cf7f2e2dSJohn Marino mi_inferior_count (struct inferior *inf, void *arg)
725cf7f2e2dSJohn Marino {
7265796c8dcSSimon Schubert   if (inf->pid != 0)
727a45ae5f8SJohn Marino     {
728a45ae5f8SJohn Marino       int *count_p = arg;
729a45ae5f8SJohn Marino       (*count_p)++;
730a45ae5f8SJohn Marino     }
731a45ae5f8SJohn Marino 
732a45ae5f8SJohn Marino   return 0;
733a45ae5f8SJohn Marino }
734a45ae5f8SJohn Marino 
7355796c8dcSSimon Schubert static void
mi_on_resume(ptid_t ptid)7365796c8dcSSimon Schubert mi_on_resume (ptid_t ptid)
7375796c8dcSSimon Schubert {
7385796c8dcSSimon Schubert   struct thread_info *tp = NULL;
7395796c8dcSSimon Schubert 
7405796c8dcSSimon Schubert   if (ptid_equal (ptid, minus_one_ptid) || ptid_is_pid (ptid))
7415796c8dcSSimon Schubert     tp = inferior_thread ();
7425796c8dcSSimon Schubert   else
7435796c8dcSSimon Schubert     tp = find_thread_ptid (ptid);
7445796c8dcSSimon Schubert 
7455796c8dcSSimon Schubert   /* Suppress output while calling an inferior function.  */
746a45ae5f8SJohn Marino   if (tp->control.in_infcall)
747a45ae5f8SJohn Marino     return;
7485796c8dcSSimon Schubert 
7495796c8dcSSimon Schubert   /* To cater for older frontends, emit ^running, but do it only once
7505796c8dcSSimon Schubert      per each command.  We do it here, since at this point we know
751a45ae5f8SJohn Marino      that the target was successfully resumed, and in non-async mode,
752a45ae5f8SJohn Marino      we won't return back to MI interpreter code until the target
753a45ae5f8SJohn Marino      is done running, so delaying the output of "^running" until then
754a45ae5f8SJohn Marino      will make it impossible for frontend to know what's going on.
7555796c8dcSSimon Schubert 
756      In future (MI3), we'll be outputting "^done" here.  */
757   if (!running_result_record_printed && mi_proceeded)
758     {
759       fprintf_unfiltered (raw_stdout, "%s^running\n",
760 			  current_token ? current_token : "");
761     }
762 
763   if (PIDGET (ptid) == -1)
764     fprintf_unfiltered (raw_stdout, "*running,thread-id=\"all\"\n");
765   else if (ptid_is_pid (ptid))
766     {
767       int count = 0;
768 
769       /* Backwards compatibility.  If there's only one inferior,
770 	 output "all", otherwise, output each resumed thread
771 	 individually.  */
772       iterate_over_inferiors (mi_inferior_count, &count);
773 
774       if (count == 1)
775 	fprintf_unfiltered (raw_stdout, "*running,thread-id=\"all\"\n");
776       else
777 	iterate_over_threads (mi_output_running_pid, &ptid);
778     }
779   else
780     {
781       struct thread_info *ti = find_thread_ptid (ptid);
782 
783       gdb_assert (ti);
784       fprintf_unfiltered (raw_stdout, "*running,thread-id=\"%d\"\n", ti->num);
785     }
786 
787   if (!running_result_record_printed && mi_proceeded)
788     {
789       running_result_record_printed = 1;
790       /* This is what gdb used to do historically -- printing prompt even if
791 	 it cannot actually accept any input.  This will be surely removed
792 	 for MI3, and may be removed even earler.  */
793       /* FIXME: review the use of target_is_async_p here -- is that
794 	 what we want? */
795       if (!target_is_async_p ())
796 	fputs_unfiltered ("(gdb) \n", raw_stdout);
797     }
798   gdb_flush (raw_stdout);
799 }
800 
801 static void
mi_solib_loaded(struct so_list * solib)802 mi_solib_loaded (struct so_list *solib)
803 {
804   struct mi_interp *mi = top_level_interpreter_data ();
805 
806   target_terminal_ours ();
807   if (gdbarch_has_global_solist (target_gdbarch ()))
808     fprintf_unfiltered (mi->event_channel,
809 			"library-loaded,id=\"%s\",target-name=\"%s\","
810 			"host-name=\"%s\",symbols-loaded=\"%d\"",
811 			solib->so_original_name, solib->so_original_name,
812 			solib->so_name, solib->symbols_loaded);
813   else
814     fprintf_unfiltered (mi->event_channel,
815 			"library-loaded,id=\"%s\",target-name=\"%s\","
816 			"host-name=\"%s\",symbols-loaded=\"%d\","
817 			"thread-group=\"i%d\"",
818 			solib->so_original_name, solib->so_original_name,
819 			solib->so_name, solib->symbols_loaded,
820 			current_inferior ()->num);
821 
822   gdb_flush (mi->event_channel);
823 }
824 
825 static void
mi_solib_unloaded(struct so_list * solib)826 mi_solib_unloaded (struct so_list *solib)
827 {
828   struct mi_interp *mi = top_level_interpreter_data ();
829 
830   target_terminal_ours ();
831   if (gdbarch_has_global_solist (target_gdbarch ()))
832     fprintf_unfiltered (mi->event_channel,
833 			"library-unloaded,id=\"%s\",target-name=\"%s\","
834 			"host-name=\"%s\"",
835 			solib->so_original_name, solib->so_original_name,
836 			solib->so_name);
837   else
838     fprintf_unfiltered (mi->event_channel,
839 			"library-unloaded,id=\"%s\",target-name=\"%s\","
840 			"host-name=\"%s\",thread-group=\"i%d\"",
841 			solib->so_original_name, solib->so_original_name,
842 			solib->so_name, current_inferior ()->num);
843 
844   gdb_flush (mi->event_channel);
845 }
846 
847 /* Emit notification about the command parameter change.  */
848 
849 static void
mi_command_param_changed(const char * param,const char * value)850 mi_command_param_changed (const char *param, const char *value)
851 {
852   struct mi_interp *mi = top_level_interpreter_data ();
853   struct ui_out *mi_uiout = interp_ui_out (top_level_interpreter ());
854 
855   if (mi_suppress_notification.cmd_param_changed)
856     return;
857 
858   target_terminal_ours ();
859 
860   fprintf_unfiltered (mi->event_channel,
861 		      "cmd-param-changed");
862 
863   ui_out_redirect (mi_uiout, mi->event_channel);
864 
865   ui_out_field_string (mi_uiout, "param", param);
866   ui_out_field_string (mi_uiout, "value", value);
867 
868   ui_out_redirect (mi_uiout, NULL);
869 
870   gdb_flush (mi->event_channel);
871 }
872 
873 /* Emit notification about the target memory change.  */
874 
875 static void
mi_memory_changed(struct inferior * inferior,CORE_ADDR memaddr,ssize_t len,const bfd_byte * myaddr)876 mi_memory_changed (struct inferior *inferior, CORE_ADDR memaddr,
877 		   ssize_t len, const bfd_byte *myaddr)
878 {
879   struct mi_interp *mi = top_level_interpreter_data ();
880   struct ui_out *mi_uiout = interp_ui_out (top_level_interpreter ());
881   struct obj_section *sec;
882 
883   if (mi_suppress_notification.memory)
884     return;
885 
886   target_terminal_ours ();
887 
888   fprintf_unfiltered (mi->event_channel,
889 		      "memory-changed");
890 
891   ui_out_redirect (mi_uiout, mi->event_channel);
892 
893   ui_out_field_fmt (mi_uiout, "thread-group", "i%d", inferior->num);
894   ui_out_field_core_addr (mi_uiout, "addr", target_gdbarch (), memaddr);
895   ui_out_field_fmt (mi_uiout, "len", "0x%zx", len);
896 
897   /* Append 'type=code' into notification if MEMADDR falls in the range of
898      sections contain code.  */
899   sec = find_pc_section (memaddr);
900   if (sec != NULL && sec->objfile != NULL)
901     {
902       flagword flags = bfd_get_section_flags (sec->objfile->obfd,
903 					      sec->the_bfd_section);
904 
905       if (flags & SEC_CODE)
906 	ui_out_field_string (mi_uiout, "type", "code");
907     }
908 
909   ui_out_redirect (mi_uiout, NULL);
910 
911   gdb_flush (mi->event_channel);
912 }
913 
914 static int
report_initial_inferior(struct inferior * inf,void * closure)915 report_initial_inferior (struct inferior *inf, void *closure)
916 {
917   /* This function is called from mi_intepreter_init, and since
918      mi_inferior_added assumes that inferior is fully initialized
919      and top_level_interpreter_data is set, we cannot call
920      it here.  */
921   struct mi_interp *mi = closure;
922 
923   target_terminal_ours ();
924   fprintf_unfiltered (mi->event_channel,
925 		      "thread-group-added,id=\"i%d\"",
926 		      inf->num);
927   gdb_flush (mi->event_channel);
928   return 0;
929 }
930 
931 static struct ui_out *
mi_ui_out(struct interp * interp)932 mi_ui_out (struct interp *interp)
933 {
934   struct mi_interp *mi = interp_data (interp);
935 
936   return mi->uiout;
937 }
938 
939 /* Save the original value of raw_stdout here when logging, so we can
940    restore correctly when done.  */
941 
942 static struct ui_file *saved_raw_stdout;
943 
944 /* Do MI-specific logging actions; save raw_stdout, and change all
945    the consoles to use the supplied ui-file(s).  */
946 
947 static int
mi_set_logging(struct interp * interp,int start_log,struct ui_file * out,struct ui_file * logfile)948 mi_set_logging (struct interp *interp, int start_log,
949 		struct ui_file *out, struct ui_file *logfile)
950 {
951   struct mi_interp *mi = interp_data (interp);
952 
953   if (!mi)
954     return 0;
955 
956   if (start_log)
957     {
958       /* The tee created already is based on gdb_stdout, which for MI
959 	 is a console and so we end up in an infinite loop of console
960 	 writing to ui_file writing to console etc.  So discard the
961 	 existing tee (it hasn't been used yet, and MI won't ever use
962 	 it), and create one based on raw_stdout instead.  */
963       if (logfile)
964 	{
965 	  ui_file_delete (out);
966 	  out = tee_file_new (raw_stdout, 0, logfile, 0);
967 	}
968 
969       saved_raw_stdout = raw_stdout;
970       raw_stdout = out;
971     }
972   else
973     {
974       raw_stdout = saved_raw_stdout;
975       saved_raw_stdout = NULL;
976     }
977 
978   mi_console_set_raw (mi->out, raw_stdout);
979   mi_console_set_raw (mi->err, raw_stdout);
980   mi_console_set_raw (mi->log, raw_stdout);
981   mi_console_set_raw (mi->targ, raw_stdout);
982   mi_console_set_raw (mi->event_channel, raw_stdout);
983 
984   return 1;
985 }
986 
987 extern initialize_file_ftype _initialize_mi_interp; /* -Wmissing-prototypes */
988 
989 void
_initialize_mi_interp(void)990 _initialize_mi_interp (void)
991 {
992   static const struct interp_procs procs =
993     {
994       mi_interpreter_init,	/* init_proc */
995       mi_interpreter_resume,	/* resume_proc */
996       mi_interpreter_suspend,	/* suspend_proc */
997       mi_interpreter_exec,	/* exec_proc */
998       mi_interpreter_prompt_p,	/* prompt_proc_p */
999       mi_ui_out, 		/* ui_out_proc */
1000       mi_set_logging		/* set_logging_proc */
1001     };
1002 
1003   /* The various interpreter levels.  */
1004   interp_add (interp_new (INTERP_MI1, &procs));
1005   interp_add (interp_new (INTERP_MI2, &procs));
1006   interp_add (interp_new (INTERP_MI3, &procs));
1007   interp_add (interp_new (INTERP_MI, &procs));
1008 }
1009