Mention PR ld/12327 in ChangeLog entry.
[deliverable/binutils-gdb.git] / gdb / cli / cli-cmds.c
index d3694e43481be29b3c2807ac22383bd94dc45555..e5df8f520712b1a1e2882f7fc4143529993cf046 100644 (file)
@@ -1,6 +1,6 @@
 /* GDB CLI commands.
 
-   Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009
+   Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010
    Free Software Foundation, Inc.
 
    This file is part of GDB.
@@ -19,6 +19,8 @@
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
+#include "exceptions.h"
+#include "arch-utils.h"
 #include "readline/readline.h"
 #include "readline/tilde.h"
 #include "completer.h"
@@ -36,6 +38,7 @@
 #include "objfiles.h"
 #include "source.h"
 #include "disasm.h"
+#include "tracepoint.h"
 
 #include "ui-out.h"
 
@@ -45,6 +48,8 @@
 #include "cli/cli-setshow.h"
 #include "cli/cli-cmds.h"
 
+#include "python/python.h"
+
 #ifdef TUI
 #include "tui/tui.h"           /* For tui_active et.al.   */
 #endif
@@ -124,6 +129,10 @@ struct cmd_list_element *deletelist;
 
 struct cmd_list_element *detachlist;
 
+/* Chain containing all defined kill subcommands. */
+
+struct cmd_list_element *killlist;
+
 /* Chain containing all defined "enable breakpoint" subcommands. */
 
 struct cmd_list_element *enablebreaklist;
@@ -181,6 +190,21 @@ struct cmd_list_element *showchecklist;
 int source_verbose = 0;
 int trace_commands = 0;
 \f
+/* 'script-extension' option support.  */
+
+static const char script_ext_off[] = "off";
+static const char script_ext_soft[] = "soft";
+static const char script_ext_strict[] = "strict";
+
+static const char *script_ext_enums[] = {
+  script_ext_off,
+  script_ext_soft,
+  script_ext_strict,
+  NULL
+};
+
+static const char *script_ext_mode = script_ext_soft;
+\f
 /* Utility used everywhere when at least one argument is needed and
    none is supplied. */
 
@@ -223,6 +247,7 @@ compare_strings (const void *arg1, const void *arg2)
 {
   const char **s1 = (const char **) arg1;
   const char **s2 = (const char **) arg2;
+
   return strcmp (*s1, *s2);
 }
 
@@ -231,7 +256,6 @@ compare_strings (const void *arg1, const void *arg2)
 static void
 complete_command (char *arg, int from_tty)
 {
-  int i;
   int argpoint;
   char **completions, *point, *arg_prefix;
 
@@ -273,6 +297,7 @@ complete_command (char *arg, int from_tty)
       while (item < size)
        {
          int next_item;
+
          printf_unfiltered ("%s%s\n", arg_prefix, completions[item]);
          next_item = item + 1;
          while (next_item < size
@@ -312,6 +337,9 @@ quit_command (char *args, int from_tty)
 {
   if (!quit_confirm ())
     error (_("Not confirmed."));
+
+  disconnect_tracing (from_tty);
+
   quit_force (args, from_tty);
 }
 
@@ -401,6 +429,7 @@ cd_command (char *dir, int from_tty)
              /* Search backwards for the directory just before the "/.."
                 and obliterate it and the "/..".  */
              char *q = p;
+
              while (q != current_directory && !IS_DIR_SEPARATOR (q[-1]))
                --q;
 
@@ -432,51 +461,143 @@ cd_command (char *dir, int from_tty)
     pwd_command ((char *) 0, 1);
 }
 \f
-void
-source_script (char *file, int from_tty)
+/* Show the current value of the 'script-extension' option.  */
+
+static void
+show_script_ext_mode (struct ui_file *file, int from_tty,
+                    struct cmd_list_element *c, const char *value)
 {
-  FILE *stream;
-  struct cleanup *old_cleanups;
-  char *full_pathname = NULL;
+  fprintf_filtered (file, _("\
+Script filename extension recognition is \"%s\".\n"),
+                   value);
+}
+
+/* Try to open SCRIPT_FILE.
+   If successful, the full path name is stored in *FULL_PATHP,
+   the stream is stored in *STREAMP, and return 1.
+   The caller is responsible for freeing *FULL_PATHP.
+   If not successful, return 0; errno is set for the last file
+   we tried to open.
+
+   If SEARCH_PATH is non-zero, and the file isn't found in cwd,
+   search for it in the source search path.
+
+   NOTE: This calls openp which uses xfullpath to compute the full path
+   instead of gdb_realpath.  Symbolic links are not resolved.  */
+
+int
+find_and_open_script (const char *script_file, int search_path,
+                     FILE **streamp, char **full_pathp)
+{
+  char *file;
   int fd;
+  struct cleanup *old_cleanups;
+  int search_flags = OPF_TRY_CWD_FIRST;
 
-  if (file == NULL || *file == 0)
+  file = tilde_expand (script_file);
+  old_cleanups = make_cleanup (xfree, file);
+
+  if (search_path)
+    search_flags |= OPF_SEARCH_IN_PATH;
+
+  /* Search for and open 'file' on the search path used for source
+     files.  Put the full location in *FULL_PATHP.  */
+  fd = openp (source_path, search_flags,
+             file, O_RDONLY, full_pathp);
+
+  if (fd == -1)
     {
-      error (_("source command requires file name of file to source."));
+      int save_errno = errno;
+      do_cleanups (old_cleanups);
+      errno = save_errno;
+      return 0;
     }
 
-  file = tilde_expand (file);
-  old_cleanups = make_cleanup (xfree, file);
+  do_cleanups (old_cleanups);
 
-  /* Search for and open 'file' on the search path used for source
-     files.  Put the full location in 'full_pathname'.  */
-  fd = openp (source_path, OPF_TRY_CWD_FIRST,
-             file, O_RDONLY, 0, &full_pathname);
-  make_cleanup (xfree, full_pathname);
+  *streamp = fdopen (fd, FOPEN_RT);
+  return 1;
+}
+
+/* Load script FILE, which has already been opened as STREAM.
+   STREAM is closed before we return.  */
 
-  /* Use the full path name, if it is found.  */
-  if (full_pathname != NULL && fd != -1)
+static void
+source_script_from_stream (FILE *stream, const char *file)
+{
+  if (script_ext_mode != script_ext_off
+      && strlen (file) > 3 && !strcmp (&file[strlen (file) - 3], ".py"))
     {
-      file = full_pathname;
+      volatile struct gdb_exception e;
+
+      TRY_CATCH (e, RETURN_MASK_ERROR)
+       {
+         source_python_script (stream, file);
+       }
+      if (e.reason < 0)
+       {
+         /* Should we fallback to ye olde GDB script mode?  */
+         if (script_ext_mode == script_ext_soft
+             && e.reason == RETURN_ERROR && e.error == UNSUPPORTED_ERROR)
+           {
+             fseek (stream, 0, SEEK_SET);
+             script_from_file (stream, (char*) file);
+           }
+         else
+           {
+             /* Nope, just punt.  */
+             fclose (stream);
+             throw_exception (e);
+           }
+       }
+      else
+       fclose (stream);
     }
+  else
+    script_from_file (stream, file);
+}
 
-  if (fd == -1)
+/* Worker to perform the "source" command.
+   Load script FILE.
+   If SEARCH_PATH is non-zero, and the file isn't found in cwd,
+   search for it in the source search path.  */
+
+static void
+source_script_with_search (const char *file, int from_tty, int search_path)
+{
+  FILE *stream;
+  char *full_path;
+  struct cleanup *old_cleanups;
+
+  if (file == NULL || *file == 0)
+    error (_("source command requires file name of file to source."));
+
+  if (!find_and_open_script (file, search_path, &stream, &full_path))
     {
+      /* The script wasn't found, or was otherwise inaccessible.
+        If the source command was invoked interactively, throw an error.
+        Otherwise (e.g. if it was invoked by a script), silently ignore
+        the error.  */
       if (from_tty)
        perror_with_name (file);
       else
-       {
-         do_cleanups (old_cleanups);
-         return;
-       }
+       return;
     }
 
-  stream = fdopen (fd, FOPEN_RT);
-  script_from_file (stream, file);
-
+  old_cleanups = make_cleanup (xfree, full_path);
+  source_script_from_stream (stream, file);
   do_cleanups (old_cleanups);
 }
 
+/* Wrapper around source_script_with_search to export it to main.c
+   for use in loading .gdbinit scripts.  */
+
+void
+source_script (char *file, int from_tty)
+{
+  source_script_with_search (file, from_tty, 0);
+}
+
 /* Return the source_verbose global variable to its previous state
    on exit from the source command, by whatever means.  */
 static void
@@ -492,33 +613,54 @@ source_command (char *args, int from_tty)
   struct cleanup *old_cleanups;
   char *file = args;
   int *old_source_verbose = xmalloc (sizeof(int));
+  int search_path = 0;
 
   *old_source_verbose = source_verbose;
   old_cleanups = make_cleanup (source_verbose_cleanup, old_source_verbose);
 
   /* -v causes the source command to run in verbose mode.
+     -s causes the file to be searched in the source search path,
+     even if the file name contains a '/'.
      We still have to be able to handle filenames with spaces in a
      backward compatible way, so buildargv is not appropriate.  */
 
   if (args)
     {
-      /* Make sure leading white space does not break the comparisons.  */
-      while (isspace(args[0]))
-       args++;
-
-      /* Is -v the first thing in the string?  */
-      if (args[0] == '-' && args[1] == 'v' && isspace (args[2]))
+      while (args[0] != '\0')
        {
-         source_verbose = 1;
+         /* Make sure leading white space does not break the comparisons.  */
+         while (isspace(args[0]))
+           args++;
+
+         if (args[0] != '-')
+           break;
 
-         /* Trim -v and whitespace from the filename.  */
-         file = &args[3];
-         while (isspace (file[0]))
-           file++;
+         if (args[1] == 'v' && isspace (args[2]))
+           {
+             source_verbose = 1;
+
+             /* Skip passed -v.  */
+             args = &args[3];
+           }
+         else if (args[1] == 's' && isspace (args[2]))
+           {
+             search_path = 1;
+
+             /* Skip passed -s.  */
+             args = &args[3];
+           }
+         else
+           break;
        }
+
+      while (isspace (args[0]))
+       args++;
+      file = args;
     }
 
-  source_script (file, from_tty);
+  source_script_with_search (file, from_tty, search_path);
+
+  do_cleanups (old_cleanups);
 }
 
 
@@ -538,7 +680,7 @@ echo_command (char *text, int from_tty)
            if (*p == 0)
              return;
 
-           c = parse_escape (&p);
+           c = parse_escape (get_current_arch (), &p);
            if (c >= 0)
              printf_filtered ("%c", c);
          }
@@ -641,7 +783,6 @@ edit_command (char *arg, int from_tty)
     }
   else
     {
-
       /* Now should only be one argument -- decode it in SAL.  */
 
       arg1 = arg;
@@ -671,17 +812,23 @@ edit_command (char *arg, int from_tty)
          of all known source files, not that user failed to give a filename.  */
       if (*arg == '*')
         {
+         struct gdbarch *gdbarch;
+
           if (sal.symtab == 0)
            /* FIXME-32x64--assumes sal.pc fits in long.  */
            error (_("No source file for address %s."),
                   hex_string ((unsigned long) sal.pc));
+
+         gdbarch = get_objfile_arch (sal.symtab->objfile);
           sym = find_pc_function (sal.pc);
           if (sym)
-           printf_filtered ("%s is in %s (%s:%d).\n", paddress (sal.pc),
-                            SYMBOL_PRINT_NAME (sym), sal.symtab->filename,
-                            sal.line);
+           printf_filtered ("%s is in %s (%s:%d).\n",
+                            paddress (gdbarch, sal.pc),
+                            SYMBOL_PRINT_NAME (sym),
+                            sal.symtab->filename, sal.line);
           else
-           printf_filtered ("%s is at %s:%d.\n", paddress (sal.pc),
+           printf_filtered ("%s is at %s:%d.\n",
+                            paddress (gdbarch, sal.pc),
                             sal.symtab->filename, sal.line);
         }
 
@@ -831,17 +978,23 @@ list_command (char *arg, int from_tty)
      of all known source files, not that user failed to give a filename.  */
   if (*arg == '*')
     {
+      struct gdbarch *gdbarch;
+
       if (sal.symtab == 0)
        /* FIXME-32x64--assumes sal.pc fits in long.  */
        error (_("No source file for address %s."),
               hex_string ((unsigned long) sal.pc));
+
+      gdbarch = get_objfile_arch (sal.symtab->objfile);
       sym = find_pc_function (sal.pc);
       if (sym)
        printf_filtered ("%s is in %s (%s:%d).\n",
-                        paddress (sal.pc), SYMBOL_PRINT_NAME (sym),
+                        paddress (gdbarch, sal.pc),
+                        SYMBOL_PRINT_NAME (sym),
                         sal.symtab->filename, sal.line);
       else
-       printf_filtered ("%s is at %s:%d.\n", paddress (sal.pc),
+       printf_filtered ("%s is at %s:%d.\n",
+                        paddress (gdbarch, sal.pc),
                         sal.symtab->filename, sal.line);
     }
 
@@ -892,7 +1045,8 @@ list_command (char *arg, int from_tty)
    MIXED is non-zero to print source with the assembler.  */
 
 static void
-print_disassembly (const char *name, CORE_ADDR low, CORE_ADDR high, int mixed)
+print_disassembly (struct gdbarch *gdbarch, const char *name,
+                  CORE_ADDR low, CORE_ADDR high, int flags)
 {
 #if defined(TUI)
   if (!tui_is_window_visible (DISASSEM_WIN))
@@ -902,10 +1056,11 @@ print_disassembly (const char *name, CORE_ADDR low, CORE_ADDR high, int mixed)
       if (name != NULL)
         printf_filtered ("for function %s:\n", name);
       else
-        printf_filtered ("from %s to %s:\n", paddress (low), paddress (high));
+        printf_filtered ("from %s to %s:\n",
+                        paddress (gdbarch, low), paddress (gdbarch, high));
 
       /* Dump the specified range.  */
-      gdb_disassembly (uiout, 0, 0, mixed, -1, low, high);
+      gdb_disassembly (gdbarch, uiout, 0, flags, -1, low, high);
 
       printf_filtered ("End of assembler dump.\n");
       gdb_flush (gdb_stdout);
@@ -913,22 +1068,25 @@ print_disassembly (const char *name, CORE_ADDR low, CORE_ADDR high, int mixed)
 #if defined(TUI)
   else
     {
-      tui_show_assembly (low);
+      tui_show_assembly (gdbarch, low);
     }
 #endif
 }
 
 /* Subroutine of disassemble_command to simplify it.
-   Print a disassembly of the current function.
-   MIXED is non-zero to print source with the assembler.  */
+   Print a disassembly of the current function according to FLAGS.  */
 
 static void
-disassemble_current_function (int mixed)
+disassemble_current_function (int flags)
 {
+  struct frame_info *frame;
+  struct gdbarch *gdbarch;
   CORE_ADDR low, high, pc;
   char *name;
 
-  pc = get_frame_pc (get_selected_frame (_("No frame selected.")));
+  frame = get_selected_frame (_("No frame selected."));
+  gdbarch = get_frame_arch (frame);
+  pc = get_frame_pc (frame);
   if (find_pc_partial_function (pc, &name, &low, &high) == 0)
     error (_("No function contains program counter for selected frame."));
 #if defined(TUI)
@@ -936,36 +1094,38 @@ disassemble_current_function (int mixed)
      `tui_version'.  */
   if (tui_active)
     /* FIXME: cagney/2004-02-07: This should be an observer.  */
-    low = tui_get_low_disassembly_address (low, pc);
+    low = tui_get_low_disassembly_address (gdbarch, low, pc);
 #endif
-  low += gdbarch_deprecated_function_start_offset (current_gdbarch);
+  low += gdbarch_deprecated_function_start_offset (gdbarch);
 
-  print_disassembly (name, low, high, mixed);
+  print_disassembly (gdbarch, name, low, high, flags);
 }
 
 /* Dump a specified section of assembly code.
 
    Usage:
-     disassemble [/m]
+     disassemble [/mr]
        - dump the assembly code for the function of the current pc
-     disassemble [/m] addr
+     disassemble [/mr] addr
        - dump the assembly code for the function at ADDR
-     disassemble [/m] low high
-       - dump the assembly code in the range [LOW,HIGH)
+     disassemble [/mr] low,high
+     disassemble [/mr] low,+length
+       - dump the assembly code in the range [LOW,HIGH), or [LOW,LOW+length)
 
-   A /m modifier will include source code with the assembly.  */
+   A /m modifier will include source code with the assembly.
+   A /r modifier will include raw instructions in hex with the assembly.  */
 
 static void
 disassemble_command (char *arg, int from_tty)
 {
+  struct gdbarch *gdbarch = get_current_arch ();
   CORE_ADDR low, high;
   char *name;
-  CORE_ADDR pc, pc_masked;
-  char *space_index;
-  int mixed_source_and_assembly;
+  CORE_ADDR pc;
+  int flags;
 
   name = NULL;
-  mixed_source_and_assembly = 0;
+  flags = 0;
 
   if (arg && *arg == '/')
     {
@@ -979,7 +1139,10 @@ disassemble_command (char *arg, int from_tty)
          switch (*arg++)
            {
            case 'm':
-             mixed_source_and_assembly = 1;
+             flags |= DISASSEMBLY_SOURCE;
+             break;
+           case 'r':
+             flags |= DISASSEMBLY_RAW_INSN;
              break;
            default:
              error (_("Invalid disassembly modifier."));
@@ -992,17 +1155,17 @@ disassemble_command (char *arg, int from_tty)
 
   if (! arg || ! *arg)
     {
-      disassemble_current_function (mixed_source_and_assembly);
+      flags |= DISASSEMBLY_OMIT_FNAME;
+      disassemble_current_function (flags);
       return;
     }
 
-  /* FIXME: 'twould be nice to allow spaces in the expression for the first
-     arg.  Allow comma separater too?  */
-
-  if (!(space_index = (char *) strchr (arg, ' ')))
+  pc = value_as_address (parse_to_comma_and_eval (&arg));
+  if (arg[0] == ',')
+    ++arg;
+  if (arg[0] == '\0')
     {
       /* One argument.  */
-      pc = parse_and_eval_address (arg);
       if (find_pc_partial_function (pc, &name, &low, &high) == 0)
        error (_("No function contains specified address."));
 #if defined(TUI)
@@ -1010,19 +1173,29 @@ disassemble_command (char *arg, int from_tty)
         `tui_version'.  */
       if (tui_active)
        /* FIXME: cagney/2004-02-07: This should be an observer.  */
-       low = tui_get_low_disassembly_address (low, pc);
+       low = tui_get_low_disassembly_address (gdbarch, low, pc);
 #endif
-      low += gdbarch_deprecated_function_start_offset (current_gdbarch);
+      low += gdbarch_deprecated_function_start_offset (gdbarch);
+      flags |= DISASSEMBLY_OMIT_FNAME;
     }
   else
     {
       /* Two arguments.  */
-      *space_index = '\0';
-      low = parse_and_eval_address (arg);
-      high = parse_and_eval_address (space_index + 1);
+      int incl_flag = 0;
+      low = pc;
+      while (isspace (*arg))
+       arg++;
+      if (arg[0] == '+')
+       {
+         ++arg;
+         incl_flag = 1;
+       }
+      high = parse_and_eval_address (arg);
+      if (incl_flag)
+       high += low;
     }
 
-  print_disassembly (name, low, high, mixed_source_and_assembly);
+  print_disassembly (gdbarch, name, low, high, flags);
 }
 
 static void
@@ -1050,17 +1223,19 @@ show_user (char *args, int from_tty)
 
   if (args)
     {
-      c = lookup_cmd (&args, cmdlist, "", 0, 1);
+      char *comname = args;
+
+      c = lookup_cmd (&comname, cmdlist, "", 0, 1);
       if (c->class != class_user)
        error (_("Not a user command."));
-      show_user_1 (c, gdb_stdout);
+      show_user_1 (c, "", args, gdb_stdout);
     }
   else
     {
       for (c = cmdlist; c; c = c->next)
        {
-         if (c->class == class_user)
-           show_user_1 (c, gdb_stdout);
+         if (c->class == class_user || c->prefixlist != NULL)
+           show_user_1 (c, "", c->name, gdb_stdout);
        }
     }
 }
@@ -1075,6 +1250,7 @@ apropos_command (char *searchstr, int from_tty)
   regex_t pattern;
   char *pattern_fastmap;
   char errorbuffer[512];
+
   pattern_fastmap = xcalloc (256, sizeof (char));
   if (searchstr == NULL)
       error (_("REGEXP string is empty"));
@@ -1247,9 +1423,8 @@ The commands below can be used to select other frames by number or address."),
 
   /* Define general commands. */
 
-  c = add_com ("pwd", class_files, pwd_command, _("\
+  add_com ("pwd", class_files, pwd_command, _("\
 Print working directory.  This is used for your program as well."));
-  set_cmd_no_selected_thread_ok (c);
 
   c = add_cmd ("cd", class_files, cd_command, _("\
 Set working directory to DIR for debugger and program being debugged.\n\
@@ -1278,19 +1453,35 @@ Commands defined in this way may have up to ten arguments."));
 
   source_help_text = xstrprintf (_("\
 Read commands from a file named FILE.\n\
-Optional -v switch (before the filename) causes each command in\n\
-FILE to be echoed as it is executed.\n\
+\n\
+Usage: source [-s] [-v] FILE\n\
+-s: search for the script in the source search path,\n\
+    even if FILE contains directories.\n\
+-v: each command in FILE is echoed as it is executed.\n\
+\n\
 Note that the file \"%s\" is read automatically in this way\n\
 when GDB is started."), gdbinit);
   c = add_cmd ("source", class_support, source_command,
               source_help_text, &cmdlist);
   set_cmd_completer (c, filename_completer);
 
+  add_setshow_enum_cmd ("script-extension", class_support,
+                       script_ext_enums, &script_ext_mode, _("\
+Set mode for script filename extension recognition."), _("\
+Show mode for script filename extension recognition."), _("\
+off  == no filename extension recognition (all sourced files are GDB scripts)\n\
+soft == evaluate script according to filename extension, fallback to GDB script"
+  "\n\
+strict == evaluate script according to filename extension, error if not supported"
+  ),
+                       NULL,
+                       show_script_ext_mode,
+                       &setlist, &showlist);
+
   add_com ("quit", class_support, quit_command, _("Exit gdb."));
   c = add_com ("help", class_support, help_command,
               _("Print list of commands."));
   set_cmd_completer (c, command_completer);
-  set_cmd_no_selected_thread_ok (c);
   add_com_alias ("q", "quit", class_support, 1);
   add_com_alias ("h", "help", class_support, 1);
 
@@ -1316,19 +1507,18 @@ Without an argument, history expansion is enabled."),
                           show_history_expansion_p,
                           &sethistlist, &showhistlist);
 
-  c = add_prefix_cmd ("info", class_info, info_command, _("\
+  add_prefix_cmd ("info", class_info, info_command, _("\
 Generic command for showing things about the program being debugged."),
-                     &infolist, "info ", 0, &cmdlist);
-  set_cmd_no_selected_thread_ok (c);
+                 &infolist, "info ", 0, &cmdlist);
   add_com_alias ("i", "info", class_info, 1);
+  add_com_alias ("inf", "info", class_info, 1);
 
   add_com ("complete", class_obscure, complete_command,
           _("List the completions for the rest of the line as a command."));
 
-  c = add_prefix_cmd ("show", class_info, show_command, _("\
+  add_prefix_cmd ("show", class_info, show_command, _("\
 Generic command for showing things about the debugger."),
-                     &showlist, "show ", 0, &cmdlist);
-  set_cmd_no_selected_thread_ok (c);
+                 &showlist, "show ", 0, &cmdlist);
   /* Another way to get at the same thing.  */
   add_info ("set", show_command, _("Show all GDB settings."));
 
@@ -1434,8 +1624,10 @@ With two args if one is empty it stands for ten lines away from the other arg.")
 Disassemble a specified section of memory.\n\
 Default is the function surrounding the pc of the selected frame.\n\
 With a /m modifier, source lines are included (if available).\n\
+With a /r modifier, raw instructions in hex are included.\n\
 With a single argument, the function surrounding that address is dumped.\n\
-Two arguments are taken as a range of memory to dump."));
+Two arguments (separated by a comma) are taken as a range of memory to dump,\n\
+  in the form of \"start,end\", or \"start,+length\"."));
   set_cmd_completer (c, location_completer);
   if (xdb_commands)
     add_com_alias ("va", "disassemble", class_xdb, 0);
This page took 0.031852 seconds and 4 git commands to generate.