1130803Smarcel/* MI Command Set for GDB, the GNU debugger.
2130803Smarcel
3130803Smarcel   Copyright 2000, 2001, 2003 Free Software Foundation, Inc.
4130803Smarcel
598944Sobrien   Contributed by Cygnus Solutions (a Red Hat company).
698944Sobrien
798944Sobrien   This file is part of GDB.
898944Sobrien
998944Sobrien   This program is free software; you can redistribute it and/or modify
1098944Sobrien   it under the terms of the GNU General Public License as published by
1198944Sobrien   the Free Software Foundation; either version 2 of the License, or
1298944Sobrien   (at your option) any later version.
1398944Sobrien
1498944Sobrien   This program is distributed in the hope that it will be useful,
1598944Sobrien   but WITHOUT ANY WARRANTY; without even the implied warranty of
1698944Sobrien   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1798944Sobrien   GNU General Public License for more details.
1898944Sobrien
1998944Sobrien   You should have received a copy of the GNU General Public License
2098944Sobrien   along with this program; if not, write to the Free Software
2198944Sobrien   Foundation, Inc., 59 Temple Place - Suite 330,
2298944Sobrien   Boston, MA 02111-1307, USA.  */
2398944Sobrien
2498944Sobrien#include "defs.h"
2598944Sobrien#include "top.h"
2698944Sobrien#include "mi-cmds.h"
2798944Sobrien#include "gdb_string.h"
2898944Sobrien
2998944Sobrienextern void _initialize_mi_cmds (void);
3098944Sobrienstruct mi_cmd;
3198944Sobrienstatic struct mi_cmd **lookup_table (const char *command);
3298944Sobrienstatic void build_table (struct mi_cmd *commands);
3398944Sobrien
3498944Sobrien
3598944Sobrienstruct mi_cmd mi_cmds[] =
3698944Sobrien{
37130803Smarcel  { "break-after", { "ignore", 1 }, NULL, NULL },
38130803Smarcel  { "break-catch", { NULL, 0 }, NULL, NULL },
39130803Smarcel  { "break-commands", { NULL, 0 }, NULL, NULL },
40130803Smarcel  { "break-condition", { "cond", 1 }, NULL, NULL },
41130803Smarcel  { "break-delete", { "delete breakpoint", 1 }, NULL, NULL },
42130803Smarcel  { "break-disable", { "disable breakpoint", 1 }, NULL, NULL },
43130803Smarcel  { "break-enable", { "enable breakpoint", 1 }, NULL, NULL },
44130803Smarcel  { "break-info", { "info break", 1 }, NULL, NULL },
45130803Smarcel  { "break-insert", { NULL, 0 }, 0, mi_cmd_break_insert},
46130803Smarcel  { "break-list", { "info break", }, NULL, NULL },
47130803Smarcel  { "break-watch", { NULL, 0 }, 0, mi_cmd_break_watch},
48130803Smarcel  { "data-disassemble", { NULL, 0 }, 0, mi_cmd_disassemble},
49130803Smarcel  { "data-evaluate-expression", { NULL, 0 }, 0, mi_cmd_data_evaluate_expression},
50130803Smarcel  { "data-list-changed-registers", { NULL, 0 }, 0, mi_cmd_data_list_changed_registers},
51130803Smarcel  { "data-list-register-names", { NULL, 0 }, 0, mi_cmd_data_list_register_names},
52130803Smarcel  { "data-list-register-values", { NULL, 0 }, 0, mi_cmd_data_list_register_values},
53130803Smarcel  { "data-read-memory", { NULL, 0 }, 0, mi_cmd_data_read_memory},
54130803Smarcel  { "data-write-memory", { NULL, 0 }, 0, mi_cmd_data_write_memory},
55130803Smarcel  { "data-write-register-values", { NULL, 0 }, 0, mi_cmd_data_write_register_values},
56130803Smarcel  { "display-delete", { NULL, 0 }, NULL, NULL },
57130803Smarcel  { "display-disable", { NULL, 0 }, NULL, NULL },
58130803Smarcel  { "display-enable", { NULL, 0 }, NULL, NULL },
59130803Smarcel  { "display-insert", { NULL, 0 }, NULL, NULL },
60130803Smarcel  { "display-list", { NULL, 0 }, NULL, NULL },
61130803Smarcel  { "environment-cd", { NULL, 0 }, 0, mi_cmd_env_cd},
62130803Smarcel  { "environment-directory", { NULL, 0 }, 0, mi_cmd_env_dir},
63130803Smarcel  { "environment-path", { NULL, 0 }, 0, mi_cmd_env_path},
64130803Smarcel  { "environment-pwd", { NULL, 0 }, 0, mi_cmd_env_pwd},
65130803Smarcel  { "exec-abort", { NULL, 0 }, NULL, NULL },
66130803Smarcel  { "exec-arguments", { "set args", 1 }, NULL, NULL },
67130803Smarcel  { "exec-continue", { NULL, 0 }, mi_cmd_exec_continue},
68130803Smarcel  { "exec-finish", { NULL, 0 }, mi_cmd_exec_finish},
69130803Smarcel  { "exec-interrupt", { NULL, 0 }, mi_cmd_exec_interrupt},
70130803Smarcel  { "exec-next", { NULL, 0 }, mi_cmd_exec_next},
71130803Smarcel  { "exec-next-instruction", { NULL, 0 }, mi_cmd_exec_next_instruction},
72130803Smarcel  { "exec-return", { NULL, 0 }, mi_cmd_exec_return},
73130803Smarcel  { "exec-run", { NULL, 0 }, mi_cmd_exec_run},
74130803Smarcel  { "exec-show-arguments", { NULL, 0 }, NULL, NULL },
75130803Smarcel  { "exec-signal", { NULL, 0 }, NULL, NULL },
76130803Smarcel  { "exec-step", { NULL, 0 }, mi_cmd_exec_step},
77130803Smarcel  { "exec-step-instruction", { NULL, 0 }, mi_cmd_exec_step_instruction},
78130803Smarcel  { "exec-until", { NULL, 0 }, mi_cmd_exec_until},
79130803Smarcel  { "file-clear", { NULL, 0 }, NULL, NULL },
80130803Smarcel  { "file-exec-and-symbols", { "file", 1 }, NULL, NULL },
81130803Smarcel  { "file-exec-file", { "exec-file", 1 }, NULL, NULL },
82130803Smarcel  { "file-list-exec-sections", { NULL, 0 }, NULL, NULL },
83130803Smarcel  { "file-list-exec-source-file", { NULL, 0 }, 0, mi_cmd_file_list_exec_source_file},
84130803Smarcel  { "file-list-exec-source-files", { NULL, 0 }, NULL, NULL },
85130803Smarcel  { "file-list-shared-libraries", { NULL, 0 }, NULL, NULL },
86130803Smarcel  { "file-list-symbol-files", { NULL, 0 }, NULL, NULL },
87130803Smarcel  { "file-symbol-file", { "symbol-file", 1 }, NULL, NULL },
88130803Smarcel  { "gdb-complete", { NULL, 0 }, NULL, NULL },
89130803Smarcel  { "gdb-exit", { NULL, 0 }, 0, mi_cmd_gdb_exit},
90130803Smarcel  { "gdb-set", { "set", 1 }, NULL, NULL },
91130803Smarcel  { "gdb-show", { "show", 1 }, NULL, NULL },
92130803Smarcel  { "gdb-source", { NULL, 0 }, NULL, NULL },
93130803Smarcel  { "gdb-version", { "show version", 0 }, 0 },
94130803Smarcel  { "interpreter-exec", { NULL, 0 }, 0, mi_cmd_interpreter_exec},
95130803Smarcel  { "kod-info", { NULL, 0 }, NULL, NULL },
96130803Smarcel  { "kod-list", { NULL, 0 }, NULL, NULL },
97130803Smarcel  { "kod-list-object-types", { NULL, 0 }, NULL, NULL },
98130803Smarcel  { "kod-show", { NULL, 0 }, NULL, NULL },
99130803Smarcel  { "overlay-auto", { NULL, 0 }, NULL, NULL },
100130803Smarcel  { "overlay-list-mapping-state", { NULL, 0 }, NULL, NULL },
101130803Smarcel  { "overlay-list-overlays", { NULL, 0 }, NULL, NULL },
102130803Smarcel  { "overlay-map", { NULL, 0 }, NULL, NULL },
103130803Smarcel  { "overlay-off", { NULL, 0 }, NULL, NULL },
104130803Smarcel  { "overlay-on", { NULL, 0 }, NULL, NULL },
105130803Smarcel  { "overlay-unmap", { NULL, 0 }, NULL, NULL },
106130803Smarcel  { "signal-handle", { NULL, 0 }, NULL, NULL },
107130803Smarcel  { "signal-list-handle-actions", { NULL, 0 }, NULL, NULL },
108130803Smarcel  { "signal-list-signal-types", { NULL, 0 }, NULL, NULL },
109130803Smarcel  { "stack-info-depth", { NULL, 0 }, 0, mi_cmd_stack_info_depth},
110130803Smarcel  { "stack-info-frame", { NULL, 0 }, NULL, NULL },
111130803Smarcel  { "stack-list-arguments", { NULL, 0 }, 0, mi_cmd_stack_list_args},
112130803Smarcel  { "stack-list-exception-handlers", { NULL, 0 }, NULL, NULL },
113130803Smarcel  { "stack-list-frames", { NULL, 0 }, 0, mi_cmd_stack_list_frames},
114130803Smarcel  { "stack-list-locals", { NULL, 0 }, 0, mi_cmd_stack_list_locals},
115130803Smarcel  { "stack-select-frame", { NULL, 0 }, 0, mi_cmd_stack_select_frame},
116130803Smarcel  { "symbol-info-address", { NULL, 0 }, NULL, NULL },
117130803Smarcel  { "symbol-info-file", { NULL, 0 }, NULL, NULL },
118130803Smarcel  { "symbol-info-function", { NULL, 0 }, NULL, NULL },
119130803Smarcel  { "symbol-info-line", { NULL, 0 }, NULL, NULL },
120130803Smarcel  { "symbol-info-symbol", { NULL, 0 }, NULL, NULL },
121130803Smarcel  { "symbol-list-functions", { NULL, 0 }, NULL, NULL },
122130803Smarcel  { "symbol-list-lines", { NULL, 0 }, 0, mi_cmd_symbol_list_lines},
123130803Smarcel  { "symbol-list-types", { NULL, 0 }, NULL, NULL },
124130803Smarcel  { "symbol-list-variables", { NULL, 0 }, NULL, NULL },
125130803Smarcel  { "symbol-locate", { NULL, 0 }, NULL, NULL },
126130803Smarcel  { "symbol-type", { NULL, 0 }, NULL, NULL },
127130803Smarcel  { "target-attach", { NULL, 0 }, NULL, NULL },
128130803Smarcel  { "target-compare-sections", { NULL, 0 }, NULL, NULL },
129130803Smarcel  { "target-detach", { "detach", 0 }, 0 },
130130803Smarcel  { "target-disconnect", { "disconnect", 0 }, 0 },
131130803Smarcel  { "target-download", { NULL, 0 }, mi_cmd_target_download},
132130803Smarcel  { "target-exec-status", { NULL, 0 }, NULL, NULL },
133130803Smarcel  { "target-list-available-targets", { NULL, 0 }, NULL, NULL },
134130803Smarcel  { "target-list-current-targets", { NULL, 0 }, NULL, NULL },
135130803Smarcel  { "target-list-parameters", { NULL, 0 }, NULL, NULL },
136130803Smarcel  { "target-select", { NULL, 0 }, mi_cmd_target_select},
137130803Smarcel  { "thread-info", { NULL, 0 }, NULL, NULL },
138130803Smarcel  { "thread-list-all-threads", { NULL, 0 }, NULL, NULL },
139130803Smarcel  { "thread-list-ids", { NULL, 0 }, 0, mi_cmd_thread_list_ids},
140130803Smarcel  { "thread-select", { NULL, 0 }, 0, mi_cmd_thread_select},
141130803Smarcel  { "trace-actions", { NULL, 0 }, NULL, NULL },
142130803Smarcel  { "trace-delete", { NULL, 0 }, NULL, NULL },
143130803Smarcel  { "trace-disable", { NULL, 0 }, NULL, NULL },
144130803Smarcel  { "trace-dump", { NULL, 0 }, NULL, NULL },
145130803Smarcel  { "trace-enable", { NULL, 0 }, NULL, NULL },
146130803Smarcel  { "trace-exists", { NULL, 0 }, NULL, NULL },
147130803Smarcel  { "trace-find", { NULL, 0 }, NULL, NULL },
148130803Smarcel  { "trace-frame-number", { NULL, 0 }, NULL, NULL },
149130803Smarcel  { "trace-info", { NULL, 0 }, NULL, NULL },
150130803Smarcel  { "trace-insert", { NULL, 0 }, NULL, NULL },
151130803Smarcel  { "trace-list", { NULL, 0 }, NULL, NULL },
152130803Smarcel  { "trace-pass-count", { NULL, 0 }, NULL, NULL },
153130803Smarcel  { "trace-save", { NULL, 0 }, NULL, NULL },
154130803Smarcel  { "trace-start", { NULL, 0 }, NULL, NULL },
155130803Smarcel  { "trace-stop", { NULL, 0 }, NULL, NULL },
156130803Smarcel  { "var-assign", { NULL, 0 }, 0, mi_cmd_var_assign},
157130803Smarcel  { "var-create", { NULL, 0 }, 0, mi_cmd_var_create},
158130803Smarcel  { "var-delete", { NULL, 0 }, 0, mi_cmd_var_delete},
159130803Smarcel  { "var-evaluate-expression", { NULL, 0 }, 0, mi_cmd_var_evaluate_expression},
160130803Smarcel  { "var-info-expression", { NULL, 0 }, 0, mi_cmd_var_info_expression},
161130803Smarcel  { "var-info-num-children", { NULL, 0 }, 0, mi_cmd_var_info_num_children},
162130803Smarcel  { "var-info-type", { NULL, 0 }, 0, mi_cmd_var_info_type},
163130803Smarcel  { "var-list-children", { NULL, 0 }, 0, mi_cmd_var_list_children},
164130803Smarcel  { "var-set-format", { NULL, 0 }, 0, mi_cmd_var_set_format},
165130803Smarcel  { "var-show-attributes", { NULL, 0 }, 0, mi_cmd_var_show_attributes},
166130803Smarcel  { "var-show-format", { NULL, 0 }, 0, mi_cmd_var_show_format},
167130803Smarcel  { "var-update", { NULL, 0 }, 0, mi_cmd_var_update},
168130803Smarcel  { NULL, }
16998944Sobrien};
17098944Sobrien
17198944Sobrien/* Pointer to the mi command table (built at run time) */
17298944Sobrien
17398944Sobrienstatic struct mi_cmd **mi_table;
17498944Sobrien
17598944Sobrien/* A prime large enough to accomodate the entire command table */
17698944Sobrienenum
17798944Sobrien  {
17898944Sobrien    MI_TABLE_SIZE = 227
17998944Sobrien  };
18098944Sobrien
18198944Sobrien/* Exported function used to obtain info from the table */
18298944Sobrienstruct mi_cmd *
18398944Sobrienmi_lookup (const char *command)
18498944Sobrien{
18598944Sobrien  return *lookup_table (command);
18698944Sobrien}
18798944Sobrien
18898944Sobrien/* stat collecting */
18998944Sobrienstruct mi_cmd_stats
19098944Sobrien{
19198944Sobrien  int hit;
19298944Sobrien  int miss;
19398944Sobrien  int rehash;
19498944Sobrien};
19598944Sobrienstruct mi_cmd_stats stats;
19698944Sobrien
19798944Sobrien/* our lookup function */
19898944Sobrienstatic struct mi_cmd **
19998944Sobrienlookup_table (const char *command)
20098944Sobrien{
20198944Sobrien  const char *chp;
20298944Sobrien  unsigned int index = 0;
20398944Sobrien  /* compute our hash */
20498944Sobrien  for (chp = command; *chp; chp++)
20598944Sobrien    {
20698944Sobrien      /* some what arbitrary */
20798944Sobrien      index = ((index << 6) + (unsigned int) *chp) % MI_TABLE_SIZE;
20898944Sobrien    }
20998944Sobrien  /* look it up */
21098944Sobrien  while (1)
21198944Sobrien    {
21298944Sobrien      struct mi_cmd **entry = &mi_table[index];
21398944Sobrien      if ((*entry) == 0)
21498944Sobrien	{
21598944Sobrien	  /* not found, return pointer to next free. */
21698944Sobrien	  stats.miss++;
21798944Sobrien	  return entry;
21898944Sobrien	}
21998944Sobrien      if (strcmp (command, (*entry)->name) == 0)
22098944Sobrien	{
22198944Sobrien	  stats.hit++;
22298944Sobrien	  return entry;		/* found */
22398944Sobrien	}
22498944Sobrien      index = (index + 1) % MI_TABLE_SIZE;
22598944Sobrien      stats.rehash++;
22698944Sobrien    }
22798944Sobrien}
22898944Sobrien
22998944Sobrienstatic void
23098944Sobrienbuild_table (struct mi_cmd *commands)
23198944Sobrien{
23298944Sobrien  int nr_rehash = 0;
23398944Sobrien  int nr_entries = 0;
23498944Sobrien  struct mi_cmd *command;
23598944Sobrien  int sizeof_table = sizeof (struct mi_cmd **) * MI_TABLE_SIZE;
23698944Sobrien
23798944Sobrien  mi_table = xmalloc (sizeof_table);
23898944Sobrien  memset (mi_table, 0, sizeof_table);
23998944Sobrien  for (command = commands; command->name != 0; command++)
24098944Sobrien    {
24198944Sobrien      struct mi_cmd **entry = lookup_table (command->name);
24298944Sobrien      if (*entry)
24398944Sobrien	internal_error (__FILE__, __LINE__,
24498944Sobrien			"command `%s' appears to be duplicated",
24598944Sobrien			command->name);
24698944Sobrien      *entry = command;
24798944Sobrien      if (0)
24898944Sobrien	{
24998944Sobrien	  fprintf_unfiltered (gdb_stdlog, "%-30s %2d\n",
25098944Sobrien			      command->name, stats.rehash - nr_rehash);
25198944Sobrien	}
25298944Sobrien      nr_entries++;
25398944Sobrien      nr_rehash = stats.rehash;
25498944Sobrien    }
25598944Sobrien  if (0)
25698944Sobrien    {
25798944Sobrien      fprintf_filtered (gdb_stdlog, "Average %3.1f\n",
25898944Sobrien			(double) nr_rehash / (double) nr_entries);
25998944Sobrien    }
26098944Sobrien}
26198944Sobrien
26298944Sobrienvoid
26398944Sobrien_initialize_mi_cmds (void)
26498944Sobrien{
26598944Sobrien  build_table (mi_cmds);
26698944Sobrien  memset (&stats, 0, sizeof (stats));
26798944Sobrien}
268