*** empty log message ***
[deliverable/binutils-gdb.git] / gdb / infcmd.c
index b7ef75d65694be3543aa0fdfa85e725da37d2286..f3a61f25be046eb9f894175b34201322d4591332 100644 (file)
@@ -1,7 +1,7 @@
 /* Memory-access and commands for "inferior" process, for GDB.
 
-   Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
-   1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+   Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
+   1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
    Free Software Foundation, Inc.
 
    This file is part of GDB.
@@ -18,8 +18,8 @@
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
 
 #include "defs.h"
 #include <signal.h>
@@ -47,6 +47,8 @@
 #include "solib.h"
 #include <ctype.h>
 #include "gdb_assert.h"
+#include "observer.h"
+#include "target-descriptions.h"
 
 /* Functions exported for general use, in inferior.h: */
 
@@ -136,7 +138,7 @@ static char **inferior_argv;
 
 /* File name for default use for standard in/out in the inferior.  */
 
-char *inferior_io_terminal;
+static char *inferior_io_terminal;
 
 /* Pid of our debugged inferior, or 0 if no inferior now.
    Since various parts of infrun.c test this to see whether there is a program
@@ -203,6 +205,24 @@ struct gdb_environ *inferior_environ;
 \f
 /* Accessor routines. */
 
+void 
+set_inferior_io_terminal (const char *terminal_name)
+{
+  if (inferior_io_terminal)
+    xfree (inferior_io_terminal);
+
+  if (!terminal_name)
+    inferior_io_terminal = NULL;
+  else
+    inferior_io_terminal = savestring (terminal_name, strlen (terminal_name));
+}
+
+const char *
+get_inferior_io_terminal (void)
+{
+  return inferior_io_terminal;
+}
+
 char *
 get_inferior_args (void)
 {
@@ -376,7 +396,47 @@ tty_command (char *file, int from_tty)
   if (file == 0)
     error_no_arg (_("terminal name for running target process"));
 
-  inferior_io_terminal = savestring (file, strlen (file));
+  set_inferior_io_terminal (file);
+}
+
+/* Common actions to take after creating any sort of inferior, by any
+   means (running, attaching, connecting, et cetera).  The target
+   should be stopped.  */
+
+void
+post_create_inferior (struct target_ops *target, int from_tty)
+{
+  /* If the target hasn't taken care of this already, do it now.
+     Targets which need to access registers during to_open,
+     to_create_inferior, or to_attach should do it earlier; but many
+     don't need to.  */
+  target_find_description ();
+
+  if (exec_bfd)
+    {
+      /* Sometimes the platform-specific hook loads initial shared
+        libraries, and sometimes it doesn't.  Try to do so first, so
+        that we can add them with the correct value for FROM_TTY.  */
+#ifdef SOLIB_ADD
+      SOLIB_ADD (NULL, from_tty, target, auto_solib_add);
+#else
+      solib_add (NULL, from_tty, target, auto_solib_add);
+#endif
+
+      /* Create the hooks to handle shared library load and unload
+        events.  */
+#ifdef SOLIB_CREATE_INFERIOR_HOOK
+      SOLIB_CREATE_INFERIOR_HOOK (PIDGET (inferior_ptid));
+#else
+      solib_create_inferior_hook ();
+#endif
+
+      /* Enable any breakpoints which were disabled when the
+        underlying shared library was deleted.  */
+      re_enable_breakpoints_in_shlibs ();
+    }
+
+  observer_notify_inferior_created (target, from_tty);
 }
 
 /* Kill the inferior if already running.  This function is designed
@@ -415,6 +475,10 @@ run_command_1 (char *args, int from_tty, int tbreak_at_main)
   kill_if_already_running (from_tty);
   clear_breakpoint_hit_counts ();
 
+  /* Clean up any leftovers from other runs.  Some other things from
+     this function should probably be moved into target_pre_inferior.  */
+  target_pre_inferior (from_tty);
+
   /* Purge old solib objfiles. */
   objfile_purge_solibs ();
 
@@ -492,6 +556,11 @@ run_command_1 (char *args, int from_tty, int tbreak_at_main)
      the value now.  */
   target_create_inferior (exec_file, get_inferior_args (),
                          environ_vector (inferior_environ), from_tty);
+
+  post_create_inferior (&current_target, from_tty);
+
+  /* Start the target running.  */
+  proceed ((CORE_ADDR) -1, TARGET_SIGNAL_0, 0);
 }
 
 
@@ -1093,6 +1162,7 @@ print_return_value (int struct_return, struct type *value_type)
   struct ui_stream *stb;
   struct value *value;
 
+  CHECK_TYPEDEF (value_type);
   gdb_assert (TYPE_CODE (value_type) != TYPE_CODE_VOID);
 
   /* FIXME: 2003-09-27: When returning from a nested inferior function
@@ -1106,8 +1176,8 @@ print_return_value (int struct_return, struct type *value_type)
     {
     case RETURN_VALUE_REGISTER_CONVENTION:
     case RETURN_VALUE_ABI_RETURNS_ADDRESS:
+    case RETURN_VALUE_ABI_PRESERVES_ADDRESS:
       value = allocate_value (value_type);
-      CHECK_TYPEDEF (value_type);
       gdbarch_return_value (current_gdbarch, value_type, stop_registers,
                            value_contents_raw (value), NULL);
       break;
@@ -1225,10 +1295,8 @@ finish_command (char *arg, int from_tty)
     error (_("The \"finish\" command does not take any arguments."));
   if (!target_has_execution)
     error (_("The program is not running."));
-  if (deprecated_selected_frame == NULL)
-    error (_("No selected frame."));
 
-  frame = get_prev_frame (deprecated_selected_frame);
+  frame = get_prev_frame (get_selected_frame (_("No selected frame.")));
   if (frame == 0)
     error (_("\"finish\" not meaningful in the outermost frame."));
 
@@ -1246,7 +1314,7 @@ finish_command (char *arg, int from_tty)
 
   /* Find the function we will return from.  */
 
-  function = find_pc_function (get_frame_pc (deprecated_selected_frame));
+  function = find_pc_function (get_frame_pc (get_selected_frame (NULL)));
 
   /* Print info on the selected frame, including level number but not
      source.  */
@@ -1524,7 +1592,7 @@ default_print_registers_info (struct gdbarch *gdbarch,
 {
   int i;
   const int numregs = NUM_REGS + NUM_PSEUDO_REGS;
-  char buffer[MAX_REGISTER_SIZE];
+  gdb_byte buffer[MAX_REGISTER_SIZE];
 
   for (i = 0; i < numregs; i++)
     {
@@ -1607,18 +1675,18 @@ default_print_registers_info (struct gdbarch *gdbarch,
 void
 registers_info (char *addr_exp, int fpregs)
 {
+  struct frame_info *frame;
   int regnum, numregs;
   char *end;
 
   if (!target_has_registers)
     error (_("The program has no registers now."));
-  if (deprecated_selected_frame == NULL)
-    error (_("No selected frame."));
+  frame = get_selected_frame (NULL);
 
   if (!addr_exp)
     {
       gdbarch_print_registers_info (current_gdbarch, gdb_stdout,
-                                   deprecated_selected_frame, -1, fpregs);
+                                   frame, -1, fpregs);
       return;
     }
 
@@ -1651,12 +1719,12 @@ registers_info (char *addr_exp, int fpregs)
 
       /* A register name?  */
       {
-       int regnum = frame_map_name_to_regnum (deprecated_selected_frame,
+       int regnum = frame_map_name_to_regnum (frame,
                                               start, end - start);
        if (regnum >= 0)
          {
            gdbarch_print_registers_info (current_gdbarch, gdb_stdout,
-                                         deprecated_selected_frame, regnum, fpregs);
+                                         frame, regnum, fpregs);
            continue;
          }
       }
@@ -1670,7 +1738,7 @@ registers_info (char *addr_exp, int fpregs)
            && regnum < NUM_REGS + NUM_PSEUDO_REGS)
          {
            gdbarch_print_registers_info (current_gdbarch, gdb_stdout,
-                                         deprecated_selected_frame, regnum, fpregs);
+                                         frame, regnum, fpregs);
            continue;
          }
       }
@@ -1696,7 +1764,7 @@ registers_info (char *addr_exp, int fpregs)
                if (gdbarch_register_reggroup_p (current_gdbarch, regnum,
                                                 group))
                  gdbarch_print_registers_info (current_gdbarch,
-                                               gdb_stdout, deprecated_selected_frame,
+                                               gdb_stdout, frame,
                                                regnum, fpregs);
              }
            continue;
@@ -1724,11 +1792,6 @@ static void
 print_vector_info (struct gdbarch *gdbarch, struct ui_file *file,
                   struct frame_info *frame, const char *args)
 {
-  if (!target_has_registers)
-    error (_("The program has no registers now."));
-  if (deprecated_selected_frame == NULL)
-    error (_("No selected frame."));
-
   if (gdbarch_print_vector_info_p (gdbarch))
     gdbarch_print_vector_info (gdbarch, file, frame, args);
   else
@@ -1752,7 +1815,11 @@ print_vector_info (struct gdbarch *gdbarch, struct ui_file *file,
 static void
 vector_info (char *args, int from_tty)
 {
-  print_vector_info (current_gdbarch, gdb_stdout, deprecated_selected_frame, args);
+  if (!target_has_registers)
+    error (_("The program has no registers now."));
+
+  print_vector_info (current_gdbarch, gdb_stdout,
+                    get_selected_frame (NULL), args);
 }
 \f
 
@@ -1788,10 +1855,14 @@ attach_command (char *args, int from_tty)
        error (_("Not killed."));
     }
 
+  /* Clean up any leftovers from other runs.  Some other things from
+     this function should probably be moved into target_pre_inferior.  */
+  target_pre_inferior (from_tty);
+
   /* Clear out solib state. Otherwise the solib state of the previous
      inferior might have survived and is entirely wrong for the new
-     target.  This has been observed on Linux using glibc 2.3. How to
-     reproduce:
+     target.  This has been observed on GNU/Linux using glibc 2.3. How
+     to reproduce:
 
      bash$ ./foo&
      [1] 4711
@@ -1864,18 +1935,12 @@ attach_command (char *args, int from_tty)
       reread_symbols ();
     }
 
-#ifdef SOLIB_ADD
-  /* Add shared library symbols from the newly attached process, if any.  */
-  SOLIB_ADD ((char *) 0, from_tty, &current_target, auto_solib_add);
-#else
-  solib_add (NULL, from_tty, &current_target, auto_solib_add);
-#endif
-  re_enable_breakpoints_in_shlibs ();
-
   /* Take any necessary post-attaching actions for this platform.
    */
   target_post_attach (PIDGET (inferior_ptid));
 
+  post_create_inferior (&current_target, from_tty);
+
   /* Install inferior's terminal modes.  */
   target_terminal_inferior ();
 
@@ -1944,11 +2009,6 @@ static void
 print_float_info (struct gdbarch *gdbarch, struct ui_file *file,
                  struct frame_info *frame, const char *args)
 {
-  if (!target_has_registers)
-    error (_("The program has no registers now."));
-  if (deprecated_selected_frame == NULL)
-    error (_("No selected frame."));
-
   if (gdbarch_print_float_info_p (gdbarch))
     gdbarch_print_float_info (gdbarch, file, frame, args);
   else
@@ -1973,8 +2033,11 @@ No floating-point info available for this processor.\n");
 static void
 float_info (char *args, int from_tty)
 {
+  if (!target_has_registers)
+    error (_("The program has no registers now."));
+
   print_float_info (current_gdbarch, gdb_stdout, 
-                   deprecated_selected_frame, args);
+                   get_selected_frame (NULL), args);
 }
 \f
 static void
@@ -1988,11 +2051,15 @@ unset_command (char *args, int from_tty)
 void
 _initialize_infcmd (void)
 {
-  struct cmd_list_element *c;
+  struct cmd_list_element *c = NULL;
 
-  c = add_com ("tty", class_run, tty_command,
-              _("Set terminal for future runs of program being debugged."));
-  set_cmd_completer (c, filename_completer);
+  /* add the filename of the terminal connected to inferior I/O */
+  add_setshow_filename_cmd ("inferior-tty", class_run,
+                           &inferior_io_terminal, _("\
+Set terminal for future runs of program being debugged."), _("\
+Show terminal for future runs of program being debugged."), _("\
+Usage: set inferior-tty /dev/pts/1"), NULL, NULL, &setlist, &showlist);
+  add_com_alias ("tty", "set inferior-tty", class_alias, 0);
 
   add_setshow_optional_filename_cmd ("args", class_run,
                                     &inferior_args, _("\
@@ -2058,10 +2125,11 @@ directory, or (if not found there) using the source file search path\n\
 (see the \"directory\" command).  You can also use the \"file\" command\n\
 to specify the program, and to load its symbol table."));
 
-  add_com ("detach", class_run, detach_command, _("\
+  add_prefix_cmd ("detach", class_run, detach_command, _("\
 Detach a process or file previously attached.\n\
 If a process, it is no longer traced, and it continues its execution.  If\n\
-you were debugging a file, the file is closed and gdb no longer accesses it."));
+you were debugging a file, the file is closed and gdb no longer accesses it."),
+                 &detachlist, "detach ", 0, &cmdlist);
 
   add_com ("disconnect", class_run, disconnect_command, _("\
 Disconnect from a target.\n\
This page took 0.028544 seconds and 4 git commands to generate.