2003-09-28 Andrew Cagney <cagney@redhat.com>
[deliverable/binutils-gdb.git] / gdb / infcmd.c
index 56bd75d8484d434b77209441d205a6fe54e84581..4c74894da6eaafb0d7c61631159e11c816ee817f 100644 (file)
@@ -1,6 +1,6 @@
 /* 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
+   1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
    Free Software Foundation, Inc.
 
    This file is part of GDB.
@@ -42,6 +42,7 @@
 #include "parser-defs.h"
 #include "regcache.h"
 #include "reggroups.h"
+#include "block.h"
 #include <ctype.h>
 
 /* Functions exported for general use, in inferior.h: */
@@ -80,6 +81,8 @@ static void float_info (char *, int);
 
 static void detach_command (char *, int);
 
+static void disconnect_command (char *, int);
+
 static void unset_environment_command (char *, int);
 
 static void set_environment_command (char *, int);
@@ -114,8 +117,6 @@ void _initialize_infcmd (void);
 
 #define GO_USAGE   "Usage: go <location>\n"
 
-static void breakpoint_auto_delete_contents (PTR);
-
 #define ERROR_NO_INFERIOR \
    if (!target_has_execution) error ("The program is not being run.");
 
@@ -260,7 +261,6 @@ notice_args_read (char *args, int from_tty, struct cmd_list_element *c)
 \f
 /* Compute command-line string given argument vector.  This does the
    same shell processing as fork_inferior.  */
-/* ARGSUSED */
 char *
 construct_inferior_arguments (struct gdbarch *gdbarch, int argc, char **argv)
 {
@@ -369,7 +369,6 @@ strip_bg_char (char **args)
   return 0;
 }
 
-/* ARGSUSED */
 void
 tty_command (char *file, int from_tty)
 {
@@ -542,7 +541,6 @@ continue_command (char *proc_count_exp, int from_tty)
 \f
 /* Step until outside of current statement.  */
 
-/* ARGSUSED */
 static void
 step_command (char *count_string, int from_tty)
 {
@@ -551,7 +549,6 @@ step_command (char *count_string, int from_tty)
 
 /* Likewise, but skip over subroutine calls as if single instructions.  */
 
-/* ARGSUSED */
 static void
 next_command (char *count_string, int from_tty)
 {
@@ -560,14 +557,12 @@ next_command (char *count_string, int from_tty)
 
 /* Likewise, but step only one instruction.  */
 
-/* ARGSUSED */
 void
 stepi_command (char *count_string, int from_tty)
 {
   step_1 (0, 1, count_string);
 }
 
-/* ARGSUSED */
 void
 nexti_command (char *count_string, int from_tty)
 {
@@ -583,7 +578,7 @@ disable_longjmp_breakpoint_cleanup (void *ignore)
 static void
 step_1 (int skip_subroutines, int single_inst, char *count_string)
 {
-  register int count = 1;
+  int count = 1;
   struct frame_info *frame;
   struct cleanup *cleanups = 0;
   int async_exec = 0;
@@ -805,7 +800,7 @@ which has no line number information.\n", name);
 static void
 jump_command (char *arg, int from_tty)
 {
-  register CORE_ADDR addr;
+  CORE_ADDR addr;
   struct symtabs_and_lines sals;
   struct symtab_and_line sal;
   struct symbol *fn;
@@ -854,7 +849,7 @@ jump_command (char *arg, int from_tty)
   if (fn != NULL && sfn != fn)
     {
       if (!query ("Line %d is not in `%s'.  Jump anyway? ", sal.line,
-                 SYMBOL_SOURCE_NAME (fn)))
+                 SYMBOL_PRINT_NAME (fn)))
        {
          error ("Not confirmed.");
          /* NOTREACHED */
@@ -949,116 +944,6 @@ signal_command (char *signum_exp, int from_tty)
   proceed (oursig == TARGET_SIGNAL_0 ? (CORE_ADDR) -1 : stop_pc, oursig, 0);
 }
 
-/* Call breakpoint_auto_delete on the current contents of the bpstat
-   pointed to by arg (which is really a bpstat *).  */
-
-static void
-breakpoint_auto_delete_contents (PTR arg)
-{
-  breakpoint_auto_delete (*(bpstat *) arg);
-}
-
-
-/* Execute a "stack dummy", a piece of code stored in the stack
-   by the debugger to be executed in the inferior.
-
-   To call: first, do PUSH_DUMMY_FRAME.
-   Then push the contents of the dummy.  It should end with a breakpoint insn.
-   Then call here, passing address at which to start the dummy.
-
-   The contents of all registers are saved before the dummy frame is popped
-   and copied into the buffer BUFFER.
-
-   The dummy's frame is automatically popped whenever that break is hit.
-   If that is the first time the program stops, run_stack_dummy
-   returns to its caller with that frame already gone and returns 0.
-   
-   Otherwise, run_stack-dummy returns a non-zero value.
-   If the called function receives a random signal, we do not allow the user
-   to continue executing it as this may not work.  The dummy frame is poped
-   and we return 1.
-   If we hit a breakpoint, we leave the frame in place and return 2 (the frame
-   will eventually be popped when we do hit the dummy end breakpoint).  */
-
-int
-run_stack_dummy (CORE_ADDR addr, struct regcache *buffer)
-{
-  struct cleanup *old_cleanups = make_cleanup (null_cleanup, 0);
-  int saved_async = 0;
-
-  /* Now proceed, having reached the desired place.  */
-  clear_proceed_status ();
-
-  if (CALL_DUMMY_BREAKPOINT_OFFSET_P)
-    {
-      struct breakpoint *bpt;
-      struct symtab_and_line sal;
-
-      init_sal (&sal);         /* initialize to zeroes */
-      if (CALL_DUMMY_LOCATION == AT_ENTRY_POINT)
-       {
-         sal.pc = CALL_DUMMY_ADDRESS ();
-       }
-      else
-       {
-         /* If defined, CALL_DUMMY_BREAKPOINT_OFFSET is where we need
-            to put a breakpoint instruction.  If not, the call dummy
-            already has the breakpoint instruction in it.
-
-            ADDR IS THE ADDRESS of the call dummy plus the
-            CALL_DUMMY_START_OFFSET, so we need to subtract the
-            CALL_DUMMY_START_OFFSET.  */
-         sal.pc = addr - CALL_DUMMY_START_OFFSET + CALL_DUMMY_BREAKPOINT_OFFSET;
-       }
-      sal.section = find_pc_overlay (sal.pc);
-
-      {
-       /* Set up a frame ID for the dummy frame so we can pass it to
-          set_momentary_breakpoint.  We need to give the breakpoint a
-          frame ID so that the breakpoint code can correctly
-          re-identify the dummy breakpoint.  */
-       struct frame_id frame = frame_id_build (read_fp (), sal.pc);
-       /* Create a momentary breakpoint at the return address of the
-           inferior.  That way it breaks when it returns.  */
-       bpt = set_momentary_breakpoint (sal, frame, bp_call_dummy);
-       bpt->disposition = disp_del;
-      }
-
-      /* If all error()s out of proceed ended up calling normal_stop (and
-         perhaps they should; it already does in the special case of error
-         out of resume()), then we wouldn't need this.  */
-      make_cleanup (breakpoint_auto_delete_contents, &stop_bpstat);
-    }
-
-  disable_watchpoints_before_interactive_call_start ();
-  proceed_to_finish = 1;       /* We want stop_registers, please... */
-
-  if (target_can_async_p ())
-    saved_async = target_async_mask (0);
-
-  proceed (addr, TARGET_SIGNAL_0, 0);
-
-  if (saved_async)
-    target_async_mask (saved_async);
-
-  enable_watchpoints_after_interactive_call_stop ();
-
-  discard_cleanups (old_cleanups);
-
-  /* We can stop during an inferior call because a signal is received. */
-  if (stopped_by_random_signal)
-    return 1;
-    
-  /* We may also stop prematurely because we hit a breakpoint in the
-     called routine. */
-  if (!stop_stack_dummy)
-    return 2;
-
-  /* On normal return, the stack dummy has been popped already.  */
-  regcache_cpy_no_passthrough (buffer, stop_registers);
-  return 0;
-}
-\f
 /* Proceed until we reach a different source line with pc greater than
    our current one or exit the function.  We skip calls in both cases.
 
@@ -1067,7 +952,6 @@ run_stack_dummy (CORE_ADDR addr, struct regcache *buffer)
    we set.  This may involve changes to wait_for_inferior and the
    proceed status code.  */
 
-/* ARGSUSED */
 static void
 until_next_command (int from_tty)
 {
@@ -1140,10 +1024,41 @@ until_command (char *arg, int from_tty)
     }
 
   if (arg)
-    until_break_command (arg, from_tty);
+    until_break_command (arg, from_tty, 0);
   else
     until_next_command (from_tty);
 }
+
+static void
+advance_command (char *arg, int from_tty)
+{
+  int async_exec = 0;
+
+  if (!target_has_execution)
+    error ("The program is not running.");
+
+  if (arg == NULL)
+    error_no_arg ("a location");
+
+  /* Find out whether we must run in the background.  */
+  if (arg != NULL)
+    async_exec = strip_bg_char (&arg);
+
+  /* If we must run in the background, but the target can't do it,
+     error out.  */
+  if (event_loop_p && async_exec && !target_can_async_p ())
+    error ("Asynchronous execution not supported on this target.");
+
+  /* If we are not asked to run in the bg, then prepare to run in the
+     foreground, synchronously.  */
+  if (event_loop_p && !async_exec && target_can_async_p ())
+    {
+      /* Simulate synchronous execution.  */
+      async_disable_stdin ();
+    }
+
+  until_break_command (arg, from_tty, 1);
+}
 \f
 
 /* Print the result of a function at the end of a 'finish' command. */
@@ -1169,7 +1084,7 @@ print_return_value (int structure_return, struct type *value_type)
       /* We cannot determine the contents of the structure because
         it is on the stack, and we don't know where, since we did not
         initiate the call, as opposed to the call_function_by_hand case */
-#ifdef VALUE_RETURNED_FROM_STACK
+#ifdef DEPRECATED_VALUE_RETURNED_FROM_STACK
       value = 0;
       ui_out_text (uiout, "Value returned has type: ");
       ui_out_field_string (uiout, "return-type", TYPE_NAME (value_type));
@@ -1199,7 +1114,7 @@ print_return_value (int structure_return, struct type *value_type)
 void
 finish_command_continuation (struct continuation_arg *arg)
 {
-  register struct symbol *function;
+  struct symbol *function;
   struct breakpoint *breakpoint;
   struct cleanup *cleanups;
 
@@ -1227,9 +1142,7 @@ finish_command_continuation (struct continuation_arg *arg)
 
       funcaddr = BLOCK_START (SYMBOL_BLOCK_VALUE (function));
 
-      struct_return = using_struct_return (value_of_variable (function, NULL),
-                                          funcaddr,
-                                          check_typedef (value_type),
+      struct_return = using_struct_return (check_typedef (value_type),
                                           BLOCK_GCC_COMPILED (SYMBOL_BLOCK_VALUE (function)));
 
       print_return_value (struct_return, value_type); 
@@ -1244,8 +1157,8 @@ static void
 finish_command (char *arg, int from_tty)
 {
   struct symtab_and_line sal;
-  register struct frame_info *frame;
-  register struct symbol *function;
+  struct frame_info *frame;
+  struct symbol *function;
   struct breakpoint *breakpoint;
   struct cleanup *old_chain;
   struct continuation_arg *arg1, *arg2, *arg3;
@@ -1355,9 +1268,7 @@ finish_command (char *arg, int from_tty)
          funcaddr = BLOCK_START (SYMBOL_BLOCK_VALUE (function));
 
          struct_return =
-           using_struct_return (value_of_variable (function, NULL),
-                                funcaddr,
-                                check_typedef (value_type),
+           using_struct_return (check_typedef (value_type),
                        BLOCK_GCC_COMPILED (SYMBOL_BLOCK_VALUE (function)));
 
          print_return_value (struct_return, value_type); 
@@ -1366,7 +1277,6 @@ finish_command (char *arg, int from_tty)
     }
 }
 \f
-/* ARGSUSED */
 static void
 program_info (char *args, int from_tty)
 {
@@ -1419,7 +1329,7 @@ environment_info (char *var, int from_tty)
 {
   if (var)
     {
-      register char *val = get_in_environ (inferior_environ, var);
+      char *val = get_in_environ (inferior_environ, var);
       if (val)
        {
          puts_filtered (var);
@@ -1436,7 +1346,7 @@ environment_info (char *var, int from_tty)
     }
   else
     {
-      register char **vector = environ_vector (inferior_environ);
+      char **vector = environ_vector (inferior_environ);
       while (*vector)
        {
          puts_filtered (*vector++);
@@ -1448,7 +1358,7 @@ environment_info (char *var, int from_tty)
 static void
 set_environment_command (char *arg, int from_tty)
 {
-  register char *p, *val, *var;
+  char *p, *val, *var;
   int nullset = 0;
 
   if (arg == 0)
@@ -1528,7 +1438,6 @@ unset_environment_command (char *var, int from_tty)
 
 static const char path_var_name[] = "PATH";
 
-/* ARGSUSED */
 static void
 path_info (char *args, int from_tty)
 {
@@ -1558,9 +1467,6 @@ path_command (char *dirname, int from_tty)
 }
 \f
 
-#ifdef REGISTER_NAMES
-char *gdb_register_names[] = REGISTER_NAMES;
-#endif
 /* Print out the machine register regnum. If regnum is -1, print all
    registers (print_all == 1) or all non-float and non-vector
    registers (print_all == 0).
@@ -1580,8 +1486,8 @@ default_print_registers_info (struct gdbarch *gdbarch,
 {
   int i;
   const int numregs = NUM_REGS + NUM_PSEUDO_REGS;
-  char *raw_buffer = alloca (MAX_REGISTER_RAW_SIZE);
-  char *virtual_buffer = alloca (MAX_REGISTER_VIRTUAL_SIZE);
+  char raw_buffer[MAX_REGISTER_SIZE];
+  char virtual_buffer[MAX_REGISTER_SIZE];
 
   if (DEPRECATED_DO_REGISTERS_INFO_P ())
     {
@@ -1631,9 +1537,9 @@ default_print_registers_info (struct gdbarch *gdbarch,
          The function frame_register_read() should have returned the
          pre-cooked register so no conversion is necessary.  */
       /* Convert raw data to virtual format if necessary.  */
-      if (REGISTER_CONVERTIBLE (i))
+      if (DEPRECATED_REGISTER_CONVERTIBLE (i))
        {
-         REGISTER_CONVERT_TO_VIRTUAL (i, REGISTER_VIRTUAL_TYPE (i),
+         DEPRECATED_REGISTER_CONVERT_TO_VIRTUAL (i, register_type (current_gdbarch, i),
                                       raw_buffer, virtual_buffer);
        }
       else
@@ -1644,11 +1550,11 @@ default_print_registers_info (struct gdbarch *gdbarch,
 
       /* If virtual format is floating, print it that way, and in raw
          hex.  */
-      if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (i)) == TYPE_CODE_FLT)
+      if (TYPE_CODE (register_type (current_gdbarch, i)) == TYPE_CODE_FLT)
        {
          int j;
 
-         val_print (REGISTER_VIRTUAL_TYPE (i), virtual_buffer, 0, 0,
+         val_print (register_type (current_gdbarch, i), virtual_buffer, 0, 0,
                     file, 0, 1, 0, Val_pretty_default);
 
          fprintf_filtered (file, "\t(raw 0x");
@@ -1666,14 +1572,14 @@ default_print_registers_info (struct gdbarch *gdbarch,
       else
        {
          /* Print the register in hex.  */
-         val_print (REGISTER_VIRTUAL_TYPE (i), virtual_buffer, 0, 0,
+         val_print (register_type (current_gdbarch, i), virtual_buffer, 0, 0,
                     file, 'x', 1, 0, Val_pretty_default);
           /* If not a vector register, print it also according to its
              natural format.  */
-         if (TYPE_VECTOR (REGISTER_VIRTUAL_TYPE (i)) == 0)
+         if (TYPE_VECTOR (register_type (current_gdbarch, i)) == 0)
            {
              fprintf_filtered (file, "\t");
-             val_print (REGISTER_VIRTUAL_TYPE (i), virtual_buffer, 0, 0,
+             val_print (register_type (current_gdbarch, i), virtual_buffer, 0, 0,
                         file, 0, 1, 0, Val_pretty_default);
            }
        }
@@ -1686,7 +1592,7 @@ void
 registers_info (char *addr_exp, int fpregs)
 {
   int regnum, numregs;
-  register char *end;
+  char *end;
 
   if (!target_has_registers)
     error ("The program has no registers now.");
@@ -1729,7 +1635,8 @@ registers_info (char *addr_exp, int fpregs)
 
       /* A register name?  */
       {
-       int regnum = frame_map_name_to_regnum (start, end - start);
+       int regnum = frame_map_name_to_regnum (deprecated_selected_frame,
+                                              start, end - start);
        if (regnum >= 0)
          {
            gdbarch_print_registers_info (current_gdbarch, gdb_stdout,
@@ -1754,24 +1661,24 @@ registers_info (char *addr_exp, int fpregs)
 
       /* A register group?  */
       {
-       struct reggroup *const *group;
-       for (group = reggroups (current_gdbarch);
-            (*group) != NULL;
-            group++)
+       struct reggroup *group;
+       for (group = reggroup_next (current_gdbarch, NULL);
+            group != NULL;
+            group = reggroup_next (current_gdbarch, group))
          {
            /* Don't bother with a length check.  Should the user
               enter a short register group name, go with the first
               group that matches.  */
-           if (strncmp (start, reggroup_name ((*group)), end - start) == 0)
+           if (strncmp (start, reggroup_name (group), end - start) == 0)
              break;
          }
-       if ((*group) != NULL)
+       if (group != NULL)
          {
            int regnum;
            for (regnum = 0; regnum < NUM_REGS + NUM_PSEUDO_REGS; regnum++)
              {
                if (gdbarch_register_reggroup_p (current_gdbarch, regnum,
-                                                (*group)))
+                                                group))
                  gdbarch_print_registers_info (current_gdbarch,
                                                gdb_stdout, deprecated_selected_frame,
                                                regnum, fpregs);
@@ -1882,8 +1789,13 @@ attach_command (char *args, int from_tty)
   /* No traps are generated when attaching to inferior under Mach 3
      or GNU hurd.  */
 #ifndef ATTACH_NO_WAIT
-  stop_soon_quietly = 1;
+  /* Careful here. See comments in inferior.h.  Basically some OSes
+     don't ignore SIGSTOPs on continue requests anymore.  We need a
+     way for handle_inferior_event to reset the stop_signal variable
+     after an attach, and this is what STOP_QUIETLY_NO_SIGSTOP is for.  */
+  stop_soon = STOP_QUIETLY_NO_SIGSTOP;
   wait_for_inferior ();
+  stop_soon = NO_STOP_QUIETLY;
 #endif
 
   /*
@@ -1951,6 +1863,26 @@ detach_command (char *args, int from_tty)
     detach_hook ();
 }
 
+/* Disconnect from the current target without resuming it (leaving it
+   waiting for a debugger).
+
+   We'd better not have left any breakpoints in the program or the
+   next debugger will get confused.  Currently only supported for some
+   remote targets, since the normal attach mechanisms don't work on
+   stopped processes on some native platforms (e.g. GNU/Linux).  */
+
+static void
+disconnect_command (char *args, int from_tty)
+{
+  dont_repeat ();              /* Not for the faint of heart */
+  target_disconnect (args, from_tty);
+#if defined(SOLIB_RESTART)
+  SOLIB_RESTART ();
+#endif
+  if (detach_hook)
+    detach_hook ();
+}
+
 /* Stop the execution of the target while running in async mode, in
    the backgound. */
 void
@@ -1963,7 +1895,6 @@ interrupt_target_command (char *args, int from_tty)
     }
 }
 
-/* ARGSUSED */
 static void
 print_float_info (struct gdbarch *gdbarch, struct ui_file *file,
                  struct frame_info *frame, const char *args)
@@ -1977,12 +1908,6 @@ print_float_info (struct gdbarch *gdbarch, struct ui_file *file,
     gdbarch_print_float_info (gdbarch, file, frame, args);
   else
     {
-#ifdef FLOAT_INFO
-#if GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL
-#error "FLOAT_INFO defined in multi-arch"
-#endif
-      FLOAT_INFO;
-#else
       int regnum;
       int printed_something = 0;
 
@@ -1997,7 +1922,6 @@ print_float_info (struct gdbarch *gdbarch, struct ui_file *file,
       if (!printed_something)
        fprintf_filtered (file, "\
 No floating-point info available for this processor.\n");
-#endif
     }
 }
 
@@ -2007,7 +1931,6 @@ float_info (char *args, int from_tty)
   print_float_info (current_gdbarch, gdb_stdout, deprecated_selected_frame, args);
 }
 \f
-/* ARGSUSED */
 static void
 unset_command (char *args, int from_tty)
 {
@@ -2096,6 +2019,11 @@ to specify the program, and to load its symbol table.");
 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.");
 
+  add_com ("disconnect", class_run, disconnect_command,
+          "Disconnect from a target.\n\
+The target will wait for another debugger to connect.  Not available for\n\
+all targets.");
+
   add_com ("signal", class_run, signal_command,
           "Continue program giving it signal specified by the argument.\n\
 An argument of \"0\" means continue program without giving it a signal.");
@@ -2130,11 +2058,15 @@ Argument N means do this N times (or till program stops for another reason).");
 
   c = add_com ("until", class_run, until_command,
               "Execute until the program reaches a source line greater than the current\n\
-or a specified line or address or function (same args as break command).\n\
-Execution will also stop upon exit from the current stack frame.");
+or a specified location (same args as break command) within the current frame.");
   set_cmd_completer (c, location_completer);
   add_com_alias ("u", "until", class_run, 1);
 
+  c = add_com ("advance", class_run, advance_command,
+              "Continue the program up to the given location (same form as args for break command).\n\
+Execution will also stop upon exit from the current stack frame.");
+  set_cmd_completer (c, location_completer);
+
   c = add_com ("jump", class_run, jump_command,
               "Continue program being debugged at specified line or address.\n\
 Give as argument either LINENUM or *ADDR, where ADDR is an expression\n\
This page took 0.062444 seconds and 4 git commands to generate.