This commit was manufactured by cvs2svn to create branch 'gdb_7_0-branch'.
[external/binutils.git] / gdb / cli / cli-cmds.c
index b0f5fa0..ce7c2a6 100644 (file)
@@ -1,6 +1,6 @@
 /* GDB CLI commands.
 
-   Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008
+   Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009
    Free Software Foundation, Inc.
 
    This file is part of GDB.
@@ -19,6 +19,7 @@
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
+#include "arch-utils.h"
 #include "readline/readline.h"
 #include "readline/tilde.h"
 #include "completer.h"
@@ -124,6 +125,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;
@@ -320,7 +325,9 @@ pwd_command (char *args, int from_tty)
 {
   if (args)
     error (_("The \"pwd\" command does not take an argument: %s"), args);
-  getcwd (gdb_dirbuf, sizeof (gdb_dirbuf));
+  if (! getcwd (gdb_dirbuf, sizeof (gdb_dirbuf)))
+    error (_("Error finding name of working directory: %s"),
+           safe_strerror (errno));
 
   if (strcmp (gdb_dirbuf, current_directory) != 0)
     printf_unfiltered (_("Working directory %s\n (canonically %s).\n"),
@@ -449,7 +456,8 @@ source_script (char *file, int from_tty)
   /* 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);
+             file, O_RDONLY, &full_pathname);
+  make_cleanup (xfree, full_pathname);
 
   /* Use the full path name, if it is found.  */
   if (full_pathname != NULL && fd != -1)
@@ -462,7 +470,10 @@ source_script (char *file, int from_tty)
       if (from_tty)
        perror_with_name (file);
       else
-       return;
+       {
+         do_cleanups (old_cleanups);
+         return;
+       }
     }
 
   stream = fdopen (fd, FOPEN_RT);
@@ -615,12 +626,10 @@ edit_command (char *arg, int from_tty)
   struct symtab_and_line sal;
   struct symbol *sym;
   char *arg1;
-  int cmdlen, log10;
-  unsigned m;
   char *editor;
   char *p, *fn;
 
-  /* Pull in the current default source line if necessary */
+  /* Pull in the current default source line if necessary */
   if (arg == 0)
     {
       set_default_source_symtab_and_line ();
@@ -638,17 +647,22 @@ edit_command (char *arg, int from_tty)
   else
     {
 
-      /* Now should only be one argument -- decode it in SAL */
+      /* Now should only be one argument -- decode it in SAL */
 
       arg1 = arg;
       sals = decode_line_1 (&arg1, 0, 0, 0, 0, 0);
 
-      if (! sals.nelts) return;  /*  C++  */
-      if (sals.nelts > 1) {
-        ambiguous_line_spec (&sals);
-        xfree (sals.sals);
-        return;
-      }
+      if (! sals.nelts)
+       {
+         /*  C++  */
+         return;
+       }
+      if (sals.nelts > 1)
+       {
+         ambiguous_line_spec (&sals);
+         xfree (sals.sals);
+         return;
+       }
 
       sal = sals.sals[0];
       xfree (sals.sals);
@@ -656,23 +670,28 @@ edit_command (char *arg, int from_tty)
       if (*arg1)
         error (_("Junk at end of line specification."));
 
-      /* if line was specified by address,
+      /* If line was specified by address,
          first print exactly which line, and which file.
          In this case, sal.symtab == 0 means address is outside
          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);
         }
 
@@ -686,10 +705,6 @@ edit_command (char *arg, int from_tty)
   if ((editor = (char *) getenv ("EDITOR")) == NULL)
       editor = "/bin/ex";
 
-  /* Approximate base-10 log of line to 1 unit for digit count */
-  for(log10=32, m=0x80000000; !(sal.line & m) && log10>0; log10--, m=m>>1);
-  log10 = 1 + (int)((log10 + (0 == ((m-1) & sal.line)))/3.32192809);
-
   /* If we don't already know the full absolute file name of the
      source file, find it now.  */
   if (!sal.symtab->fullname)
@@ -704,8 +719,8 @@ edit_command (char *arg, int from_tty)
   /* Quote the file name, in case it has whitespace or other special
      characters.  */
   p = xstrprintf ("%s +%d \"%s\"", editor, sal.line, fn);
-  shell_escape(p, from_tty);
-  xfree(p);
+  shell_escape (p, from_tty);
+  xfree (p);
 }
 
 static void
@@ -826,17 +841,22 @@ 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);
     }
 
@@ -887,7 +907,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))
@@ -897,10 +918,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);
@@ -908,7 +930,7 @@ 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
 }
@@ -918,12 +940,16 @@ print_disassembly (const char *name, CORE_ADDR low, CORE_ADDR high, int mixed)
    MIXED is non-zero to print source with the assembler.  */
 
 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)
@@ -931,36 +957,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
+     disassemble [/mr] low high
        - dump the assembly code in the range [LOW,HIGH)
 
-   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;
+  int flags;
 
   name = NULL;
-  mixed_source_and_assembly = 0;
+  flags = 0;
 
   if (arg && *arg == '/')
     {
@@ -974,7 +1002,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."));
@@ -987,7 +1018,7 @@ disassemble_command (char *arg, int from_tty)
 
   if (! arg || ! *arg)
     {
-      disassemble_current_function (mixed_source_and_assembly);
+      disassemble_current_function (flags);
       return;
     }
 
@@ -1005,9 +1036,9 @@ 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);
     }
   else
     {
@@ -1017,7 +1048,7 @@ disassemble_command (char *arg, int from_tty)
       high = parse_and_eval_address (space_index + 1);
     }
 
-  print_disassembly (name, low, high, mixed_source_and_assembly);
+  print_disassembly (gdbarch, name, low, high, flags);
 }
 
 static void
@@ -1045,17 +1076,18 @@ 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);
        }
     }
 }
@@ -1106,7 +1138,7 @@ ambiguous_line_spec (struct symtabs_and_lines *sals)
 static void
 set_debug (char *arg, int from_tty)
 {
-  printf_unfiltered (_("\"set debug\" must be followed by the name of a print subcommand.\n"));
+  printf_unfiltered (_("\"set debug\" must be followed by the name of a debug subcommand.\n"));
   help_list (setdebuglist, "set debug ", -1, gdb_stdout);
 }
 
@@ -1242,9 +1274,9 @@ 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_async_ok (c);
+
   c = add_cmd ("cd", class_files, cd_command, _("\
 Set working directory to DIR for debugger and program being debugged.\n\
 The change does not take effect for the program being debugged\n\
@@ -1284,7 +1316,6 @@ when GDB is started."), gdbinit);
   c = add_com ("help", class_support, help_command,
               _("Print list of commands."));
   set_cmd_completer (c, command_completer);
-  set_cmd_async_ok (c);
   add_com_alias ("q", "quit", class_support, 1);
   add_com_alias ("h", "help", class_support, 1);
 
@@ -1310,19 +1341,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_async_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_async_ok (c);
+                 &showlist, "show ", 0, &cmdlist);
   /* Another way to get at the same thing.  */
   add_info ("set", show_command, _("Show all GDB settings."));
 
@@ -1428,6 +1458,7 @@ 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."));
   set_cmd_completer (c, location_completer);