15796c8dcSSimon Schubert /* MI Command Set for GDB, the GNU debugger.
2*ef5ccd6cSJohn Marino Copyright (C) 2000-2013 Free Software Foundation, Inc.
35796c8dcSSimon Schubert
45796c8dcSSimon Schubert Contributed by Cygnus Solutions (a Red Hat company).
55796c8dcSSimon Schubert
65796c8dcSSimon Schubert This file is part of GDB.
75796c8dcSSimon Schubert
85796c8dcSSimon Schubert This program is free software; you can redistribute it and/or modify
95796c8dcSSimon Schubert it under the terms of the GNU General Public License as published by
105796c8dcSSimon Schubert the Free Software Foundation; either version 3 of the License, or
115796c8dcSSimon Schubert (at your option) any later version.
125796c8dcSSimon Schubert
135796c8dcSSimon Schubert This program is distributed in the hope that it will be useful,
145796c8dcSSimon Schubert but WITHOUT ANY WARRANTY; without even the implied warranty of
155796c8dcSSimon Schubert MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
165796c8dcSSimon Schubert GNU General Public License for more details.
175796c8dcSSimon Schubert
185796c8dcSSimon Schubert You should have received a copy of the GNU General Public License
195796c8dcSSimon Schubert along with this program. If not, see <http://www.gnu.org/licenses/>. */
205796c8dcSSimon Schubert
215796c8dcSSimon Schubert #include "defs.h"
225796c8dcSSimon Schubert #include "top.h"
235796c8dcSSimon Schubert #include "mi-cmds.h"
245796c8dcSSimon Schubert #include "gdb_string.h"
25*ef5ccd6cSJohn Marino #include "mi-main.h"
265796c8dcSSimon Schubert
275796c8dcSSimon Schubert extern void _initialize_mi_cmds (void);
28*ef5ccd6cSJohn Marino
295796c8dcSSimon Schubert struct mi_cmd;
305796c8dcSSimon Schubert static struct mi_cmd **lookup_table (const char *command);
315796c8dcSSimon Schubert static void build_table (struct mi_cmd *commands);
325796c8dcSSimon Schubert
33*ef5ccd6cSJohn Marino static struct mi_cmd mi_cmds[] =
345796c8dcSSimon Schubert {
35*ef5ccd6cSJohn Marino /* Define a MI command of NAME, and its corresponding CLI command is
36*ef5ccd6cSJohn Marino CLI_NAME. */
37*ef5ccd6cSJohn Marino #define DEF_MI_CMD_CLI_1(NAME, CLI_NAME, ARGS_P, CALLED) \
38*ef5ccd6cSJohn Marino { NAME, { CLI_NAME, ARGS_P}, NULL, CALLED }
39*ef5ccd6cSJohn Marino #define DEF_MI_CMD_CLI(NAME, CLI_NAME, ARGS_P) \
40*ef5ccd6cSJohn Marino DEF_MI_CMD_CLI_1(NAME, CLI_NAME, ARGS_P, NULL)
41*ef5ccd6cSJohn Marino
42*ef5ccd6cSJohn Marino /* Define a MI command of NAME, and implemented by function MI_FUNC. */
43*ef5ccd6cSJohn Marino #define DEF_MI_CMD_MI_1(NAME, MI_FUNC, CALLED) \
44*ef5ccd6cSJohn Marino { NAME, {NULL, 0}, MI_FUNC, CALLED }
45*ef5ccd6cSJohn Marino #define DEF_MI_CMD_MI(NAME, MI_FUNC) DEF_MI_CMD_MI_1(NAME, MI_FUNC, NULL)
46*ef5ccd6cSJohn Marino
47*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("ada-task-info", mi_cmd_ada_task_info),
48*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("add-inferior", mi_cmd_add_inferior),
49*ef5ccd6cSJohn Marino DEF_MI_CMD_CLI_1 ("break-after", "ignore", 1,
50*ef5ccd6cSJohn Marino &mi_suppress_notification.breakpoint),
51*ef5ccd6cSJohn Marino DEF_MI_CMD_CLI_1 ("break-condition","cond", 1,
52*ef5ccd6cSJohn Marino &mi_suppress_notification.breakpoint),
53*ef5ccd6cSJohn Marino DEF_MI_CMD_MI_1 ("break-commands", mi_cmd_break_commands,
54*ef5ccd6cSJohn Marino &mi_suppress_notification.breakpoint),
55*ef5ccd6cSJohn Marino DEF_MI_CMD_CLI_1 ("break-delete", "delete breakpoint", 1,
56*ef5ccd6cSJohn Marino &mi_suppress_notification.breakpoint),
57*ef5ccd6cSJohn Marino DEF_MI_CMD_CLI_1 ("break-disable", "disable breakpoint", 1,
58*ef5ccd6cSJohn Marino &mi_suppress_notification.breakpoint),
59*ef5ccd6cSJohn Marino DEF_MI_CMD_CLI_1 ("break-enable", "enable breakpoint", 1,
60*ef5ccd6cSJohn Marino &mi_suppress_notification.breakpoint),
61*ef5ccd6cSJohn Marino DEF_MI_CMD_CLI ("break-info", "info break", 1),
62*ef5ccd6cSJohn Marino DEF_MI_CMD_MI_1 ("break-insert", mi_cmd_break_insert,
63*ef5ccd6cSJohn Marino &mi_suppress_notification.breakpoint),
64*ef5ccd6cSJohn Marino DEF_MI_CMD_CLI ("break-list", "info break", 0),
65*ef5ccd6cSJohn Marino DEF_MI_CMD_MI_1 ("break-passcount", mi_cmd_break_passcount,
66*ef5ccd6cSJohn Marino &mi_suppress_notification.breakpoint),
67*ef5ccd6cSJohn Marino DEF_MI_CMD_MI_1 ("break-watch", mi_cmd_break_watch,
68*ef5ccd6cSJohn Marino &mi_suppress_notification.breakpoint),
69*ef5ccd6cSJohn Marino DEF_MI_CMD_MI_1 ("catch-load", mi_cmd_catch_load,
70*ef5ccd6cSJohn Marino &mi_suppress_notification.breakpoint),
71*ef5ccd6cSJohn Marino DEF_MI_CMD_MI_1 ("catch-unload", mi_cmd_catch_unload,
72*ef5ccd6cSJohn Marino &mi_suppress_notification.breakpoint),
73*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("data-disassemble", mi_cmd_disassemble),
74*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("data-evaluate-expression", mi_cmd_data_evaluate_expression),
75*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("data-list-changed-registers",
76*ef5ccd6cSJohn Marino mi_cmd_data_list_changed_registers),
77*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("data-list-register-names", mi_cmd_data_list_register_names),
78*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("data-list-register-values", mi_cmd_data_list_register_values),
79*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("data-read-memory", mi_cmd_data_read_memory),
80*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("data-read-memory-bytes", mi_cmd_data_read_memory_bytes),
81*ef5ccd6cSJohn Marino DEF_MI_CMD_MI_1 ("data-write-memory", mi_cmd_data_write_memory,
82*ef5ccd6cSJohn Marino &mi_suppress_notification.memory),
83*ef5ccd6cSJohn Marino DEF_MI_CMD_MI_1 ("data-write-memory-bytes", mi_cmd_data_write_memory_bytes,
84*ef5ccd6cSJohn Marino &mi_suppress_notification.memory),
85*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("data-write-register-values",
86*ef5ccd6cSJohn Marino mi_cmd_data_write_register_values),
87*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("enable-timings", mi_cmd_enable_timings),
88*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("enable-pretty-printing", mi_cmd_enable_pretty_printing),
89*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("environment-cd", mi_cmd_env_cd),
90*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("environment-directory", mi_cmd_env_dir),
91*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("environment-path", mi_cmd_env_path),
92*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("environment-pwd", mi_cmd_env_pwd),
93*ef5ccd6cSJohn Marino DEF_MI_CMD_CLI ("exec-arguments", "set args", 1),
94*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("exec-continue", mi_cmd_exec_continue),
95*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("exec-finish", mi_cmd_exec_finish),
96*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("exec-jump", mi_cmd_exec_jump),
97*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("exec-interrupt", mi_cmd_exec_interrupt),
98*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("exec-next", mi_cmd_exec_next),
99*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("exec-next-instruction", mi_cmd_exec_next_instruction),
100*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("exec-return", mi_cmd_exec_return),
101*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("exec-run", mi_cmd_exec_run),
102*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("exec-step", mi_cmd_exec_step),
103*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("exec-step-instruction", mi_cmd_exec_step_instruction),
104*ef5ccd6cSJohn Marino DEF_MI_CMD_CLI ("exec-until", "until", 1),
105*ef5ccd6cSJohn Marino DEF_MI_CMD_CLI ("file-exec-and-symbols", "file", 1),
106*ef5ccd6cSJohn Marino DEF_MI_CMD_CLI ("file-exec-file", "exec-file", 1),
107*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("file-list-exec-source-file",
108*ef5ccd6cSJohn Marino mi_cmd_file_list_exec_source_file),
109*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("file-list-exec-source-files",
110*ef5ccd6cSJohn Marino mi_cmd_file_list_exec_source_files),
111*ef5ccd6cSJohn Marino DEF_MI_CMD_CLI ("file-symbol-file", "symbol-file", 1),
112*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("gdb-exit", mi_cmd_gdb_exit),
113*ef5ccd6cSJohn Marino DEF_MI_CMD_CLI_1 ("gdb-set", "set", 1,
114*ef5ccd6cSJohn Marino &mi_suppress_notification.cmd_param_changed),
115*ef5ccd6cSJohn Marino DEF_MI_CMD_CLI ("gdb-show", "show", 1),
116*ef5ccd6cSJohn Marino DEF_MI_CMD_CLI ("gdb-version", "show version", 0),
117*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("inferior-tty-set", mi_cmd_inferior_tty_set),
118*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("inferior-tty-show", mi_cmd_inferior_tty_show),
119*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("info-os", mi_cmd_info_os),
120*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("interpreter-exec", mi_cmd_interpreter_exec),
121*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("list-features", mi_cmd_list_features),
122*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("list-target-features", mi_cmd_list_target_features),
123*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("list-thread-groups", mi_cmd_list_thread_groups),
124*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("remove-inferior", mi_cmd_remove_inferior),
125*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("stack-info-depth", mi_cmd_stack_info_depth),
126*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("stack-info-frame", mi_cmd_stack_info_frame),
127*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("stack-list-arguments", mi_cmd_stack_list_args),
128*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("stack-list-frames", mi_cmd_stack_list_frames),
129*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("stack-list-locals", mi_cmd_stack_list_locals),
130*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("stack-list-variables", mi_cmd_stack_list_variables),
131*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("stack-select-frame", mi_cmd_stack_select_frame),
132*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("symbol-list-lines", mi_cmd_symbol_list_lines),
133*ef5ccd6cSJohn Marino DEF_MI_CMD_CLI ("target-attach", "attach", 1),
134*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("target-detach", mi_cmd_target_detach),
135*ef5ccd6cSJohn Marino DEF_MI_CMD_CLI ("target-disconnect", "disconnect", 0),
136*ef5ccd6cSJohn Marino DEF_MI_CMD_CLI ("target-download", "load", 1),
137*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("target-file-delete", mi_cmd_target_file_delete),
138*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("target-file-get", mi_cmd_target_file_get),
139*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("target-file-put", mi_cmd_target_file_put),
140*ef5ccd6cSJohn Marino DEF_MI_CMD_CLI ("target-select", "target", 1),
141*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("thread-info", mi_cmd_thread_info),
142*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("thread-list-ids", mi_cmd_thread_list_ids),
143*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("thread-select", mi_cmd_thread_select),
144*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("trace-define-variable", mi_cmd_trace_define_variable),
145*ef5ccd6cSJohn Marino DEF_MI_CMD_MI_1 ("trace-find", mi_cmd_trace_find,
146*ef5ccd6cSJohn Marino &mi_suppress_notification.traceframe),
147*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("trace-list-variables", mi_cmd_trace_list_variables),
148*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("trace-save", mi_cmd_trace_save),
149*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("trace-start", mi_cmd_trace_start),
150*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("trace-status", mi_cmd_trace_status),
151*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("trace-stop", mi_cmd_trace_stop),
152*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("var-assign", mi_cmd_var_assign),
153*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("var-create", mi_cmd_var_create),
154*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("var-delete", mi_cmd_var_delete),
155*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("var-evaluate-expression", mi_cmd_var_evaluate_expression),
156*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("var-info-path-expression", mi_cmd_var_info_path_expression),
157*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("var-info-expression", mi_cmd_var_info_expression),
158*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("var-info-num-children", mi_cmd_var_info_num_children),
159*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("var-info-type", mi_cmd_var_info_type),
160*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("var-list-children", mi_cmd_var_list_children),
161*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("var-set-format", mi_cmd_var_set_format),
162*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("var-set-frozen", mi_cmd_var_set_frozen),
163*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("var-set-update-range", mi_cmd_var_set_update_range),
164*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("var-set-visualizer", mi_cmd_var_set_visualizer),
165*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("var-show-attributes", mi_cmd_var_show_attributes),
166*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("var-show-format", mi_cmd_var_show_format),
167*ef5ccd6cSJohn Marino DEF_MI_CMD_MI ("var-update", mi_cmd_var_update),
1685796c8dcSSimon Schubert { NULL, }
1695796c8dcSSimon Schubert };
1705796c8dcSSimon Schubert
171*ef5ccd6cSJohn Marino /* Pointer to the mi command table (built at run time). */
1725796c8dcSSimon Schubert
1735796c8dcSSimon Schubert static struct mi_cmd **mi_table;
1745796c8dcSSimon Schubert
175*ef5ccd6cSJohn Marino /* A prime large enough to accomodate the entire command table. */
1765796c8dcSSimon Schubert enum
1775796c8dcSSimon Schubert {
1785796c8dcSSimon Schubert MI_TABLE_SIZE = 227
1795796c8dcSSimon Schubert };
1805796c8dcSSimon Schubert
181*ef5ccd6cSJohn Marino /* Exported function used to obtain info from the table. */
1825796c8dcSSimon Schubert struct mi_cmd *
mi_lookup(const char * command)1835796c8dcSSimon Schubert mi_lookup (const char *command)
1845796c8dcSSimon Schubert {
1855796c8dcSSimon Schubert return *lookup_table (command);
1865796c8dcSSimon Schubert }
1875796c8dcSSimon Schubert
188*ef5ccd6cSJohn Marino /* Used for collecting hash hit/miss statistics. */
189*ef5ccd6cSJohn Marino
1905796c8dcSSimon Schubert struct mi_cmd_stats
1915796c8dcSSimon Schubert {
1925796c8dcSSimon Schubert int hit;
1935796c8dcSSimon Schubert int miss;
1945796c8dcSSimon Schubert int rehash;
1955796c8dcSSimon Schubert };
1965796c8dcSSimon Schubert struct mi_cmd_stats stats;
1975796c8dcSSimon Schubert
198*ef5ccd6cSJohn Marino /* Look up a command. */
199*ef5ccd6cSJohn Marino
2005796c8dcSSimon Schubert static struct mi_cmd **
lookup_table(const char * command)2015796c8dcSSimon Schubert lookup_table (const char *command)
2025796c8dcSSimon Schubert {
2035796c8dcSSimon Schubert const char *chp;
2045796c8dcSSimon Schubert unsigned int index = 0;
205cf7f2e2dSJohn Marino
206*ef5ccd6cSJohn Marino /* Compute our hash. */
2075796c8dcSSimon Schubert for (chp = command; *chp; chp++)
2085796c8dcSSimon Schubert {
209*ef5ccd6cSJohn Marino /* We use a somewhat arbitrary formula. */
2105796c8dcSSimon Schubert index = ((index << 6) + (unsigned int) *chp) % MI_TABLE_SIZE;
2115796c8dcSSimon Schubert }
212*ef5ccd6cSJohn Marino
2135796c8dcSSimon Schubert while (1)
2145796c8dcSSimon Schubert {
2155796c8dcSSimon Schubert struct mi_cmd **entry = &mi_table[index];
2165796c8dcSSimon Schubert if ((*entry) == 0)
2175796c8dcSSimon Schubert {
2185796c8dcSSimon Schubert /* not found, return pointer to next free. */
2195796c8dcSSimon Schubert stats.miss++;
2205796c8dcSSimon Schubert return entry;
2215796c8dcSSimon Schubert }
2225796c8dcSSimon Schubert if (strcmp (command, (*entry)->name) == 0)
2235796c8dcSSimon Schubert {
2245796c8dcSSimon Schubert stats.hit++;
2255796c8dcSSimon Schubert return entry; /* found */
2265796c8dcSSimon Schubert }
2275796c8dcSSimon Schubert index = (index + 1) % MI_TABLE_SIZE;
2285796c8dcSSimon Schubert stats.rehash++;
2295796c8dcSSimon Schubert }
2305796c8dcSSimon Schubert }
2315796c8dcSSimon Schubert
2325796c8dcSSimon Schubert static void
build_table(struct mi_cmd * commands)2335796c8dcSSimon Schubert build_table (struct mi_cmd *commands)
2345796c8dcSSimon Schubert {
2355796c8dcSSimon Schubert int nr_rehash = 0;
2365796c8dcSSimon Schubert int nr_entries = 0;
2375796c8dcSSimon Schubert struct mi_cmd *command;
2385796c8dcSSimon Schubert int sizeof_table = sizeof (struct mi_cmd **) * MI_TABLE_SIZE;
2395796c8dcSSimon Schubert
2405796c8dcSSimon Schubert mi_table = xmalloc (sizeof_table);
2415796c8dcSSimon Schubert memset (mi_table, 0, sizeof_table);
2425796c8dcSSimon Schubert for (command = commands; command->name != 0; command++)
2435796c8dcSSimon Schubert {
2445796c8dcSSimon Schubert struct mi_cmd **entry = lookup_table (command->name);
245cf7f2e2dSJohn Marino
2465796c8dcSSimon Schubert if (*entry)
2475796c8dcSSimon Schubert internal_error (__FILE__, __LINE__,
2485796c8dcSSimon Schubert _("command `%s' appears to be duplicated"),
2495796c8dcSSimon Schubert command->name);
2505796c8dcSSimon Schubert *entry = command;
251*ef5ccd6cSJohn Marino /* FIXME lose these prints */
2525796c8dcSSimon Schubert if (0)
2535796c8dcSSimon Schubert {
2545796c8dcSSimon Schubert fprintf_unfiltered (gdb_stdlog, "%-30s %2d\n",
2555796c8dcSSimon Schubert command->name, stats.rehash - nr_rehash);
2565796c8dcSSimon Schubert }
2575796c8dcSSimon Schubert nr_entries++;
2585796c8dcSSimon Schubert nr_rehash = stats.rehash;
2595796c8dcSSimon Schubert }
2605796c8dcSSimon Schubert if (0)
2615796c8dcSSimon Schubert {
2625796c8dcSSimon Schubert fprintf_filtered (gdb_stdlog, "Average %3.1f\n",
2635796c8dcSSimon Schubert (double) nr_rehash / (double) nr_entries);
2645796c8dcSSimon Schubert }
2655796c8dcSSimon Schubert }
2665796c8dcSSimon Schubert
2675796c8dcSSimon Schubert void
_initialize_mi_cmds(void)2685796c8dcSSimon Schubert _initialize_mi_cmds (void)
2695796c8dcSSimon Schubert {
2705796c8dcSSimon Schubert build_table (mi_cmds);
2715796c8dcSSimon Schubert memset (&stats, 0, sizeof (stats));
2725796c8dcSSimon Schubert }
273