]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - gdb/infcmd.c
2003-04-08 Elena Zannoni <ezannoni@redhat.com>
[thirdparty/binutils-gdb.git] / gdb / infcmd.c
index 6b4d7ae367a6a49cf4a6f067e547316e0ce47e7b..01ab3d7b0deefe7ab1a10e2f1516e0e59e6dc522 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: */
@@ -114,7 +115,7 @@ void _initialize_infcmd (void);
 
 #define GO_USAGE   "Usage: go <location>\n"
 
-static void breakpoint_auto_delete_contents (PTR);
+static void breakpoint_auto_delete_contents (void *);
 
 #define ERROR_NO_INFERIOR \
    if (!target_has_execution) error ("The program is not being run.");
@@ -182,7 +183,7 @@ CORE_ADDR step_range_end;   /* Exclusive */
    This is how we know when we step into a subroutine call,
    and how to set the frame for the breakpoint used to step out.  */
 
-CORE_ADDR step_frame_address;
+struct frame_id step_frame_id;
 
 /* Our notion of the current stack pointer.  */
 
@@ -278,7 +279,7 @@ construct_inferior_arguments (struct gdbarch *gdbarch, int argc, char **argv)
 
       /* We over-compute the size.  It shouldn't matter.  */
       for (i = 0; i < argc; ++i)
-       length += 2 * strlen (argv[i]) + 1;
+       length += 2 * strlen (argv[i]) + 1 + 2 * (argv[i][0] == '\0');
 
       result = (char *) xmalloc (length);
       out = result;
@@ -288,11 +289,20 @@ construct_inferior_arguments (struct gdbarch *gdbarch, int argc, char **argv)
          if (i > 0)
            *out++ = ' ';
 
-         for (cp = argv[i]; *cp; ++cp)
+         /* Need to handle empty arguments specially.  */
+         if (argv[i][0] == '\0')
            {
-             if (strchr (special, *cp) != NULL)
-               *out++ = '\\';
-             *out++ = *cp;
+             *out++ = '\'';
+             *out++ = '\'';
+           }
+         else
+           {
+             for (cp = argv[i]; *cp; ++cp)
+               {
+                 if (strchr (special, *cp) != NULL)
+                   *out++ = '\\';
+                 *out++ = *cp;
+               }
            }
        }
       *out = '\0';
@@ -618,7 +628,7 @@ step_1 (int skip_subroutines, int single_inst, char *count_string)
          frame = get_current_frame ();
          if (!frame)           /* Avoid coredump here.  Why tho? */
            error ("No current frame");
-         step_frame_address = get_frame_base (frame);
+         step_frame_id = get_frame_id (frame);
          step_sp = read_sp ();
 
          if (!single_inst)
@@ -733,7 +743,7 @@ step_once (int skip_subroutines, int single_inst, int count)
       frame = get_current_frame ();
       if (!frame)              /* Avoid coredump here.  Why tho? */
        error ("No current frame");
-      step_frame_address = get_frame_base (frame);
+      step_frame_id = get_frame_id (frame);
       step_sp = read_sp ();
 
       if (!single_inst)
@@ -845,7 +855,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 */
@@ -944,7 +954,7 @@ signal_command (char *signum_exp, int from_tty)
    pointed to by arg (which is really a bpstat *).  */
 
 static void
-breakpoint_auto_delete_contents (PTR arg)
+breakpoint_auto_delete_contents (void *arg)
 {
   breakpoint_auto_delete (*(bpstat *) arg);
 }
@@ -976,49 +986,46 @@ run_stack_dummy (CORE_ADDR addr, struct regcache *buffer)
 {
   struct cleanup *old_cleanups = make_cleanup (null_cleanup, 0);
   int saved_async = 0;
+  struct breakpoint *bpt;
+  struct symtab_and_line sal;
 
   /* Now proceed, having reached the desired place.  */
   clear_proceed_status ();
 
-  if (CALL_DUMMY_BREAKPOINT_OFFSET_P)
+  init_sal (&sal);             /* initialize to zeroes */
+  if (CALL_DUMMY_LOCATION == AT_ENTRY_POINT)
     {
-      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
-       {
-         sal.pc = addr - CALL_DUMMY_START_OFFSET + CALL_DUMMY_BREAKPOINT_OFFSET;
-       }
-      sal.section = find_pc_overlay (sal.pc);
-
-      /* Set up a FRAME for the dummy frame so we can pass it to
-         set_momentary_breakpoint.  We need to give the breakpoint a
-         frame in case there is only one copy of the dummy (e.g.
-         CALL_DUMMY_LOCATION == AFTER_TEXT_END).  */
-      flush_cached_frames ();
-      set_current_frame (create_new_frame (read_fp (), sal.pc));
-
-      /* 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.  */
-      bpt = set_momentary_breakpoint (sal,
-                                     get_current_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);
+      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... */
@@ -1096,7 +1103,7 @@ until_next_command (int from_tty)
     }
 
   step_over_calls = STEP_OVER_ALL;
-  step_frame_address = get_frame_base (frame);
+  step_frame_id = get_frame_id (frame);
   step_sp = read_sp ();
 
   step_multi = 0;              /* Only one call to proceed */
@@ -1130,10 +1137,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. */
@@ -1272,10 +1310,10 @@ finish_command (char *arg, int from_tty)
 
   clear_proceed_status ();
 
-  sal = find_pc_line (frame->pc, 0);
-  sal.pc = frame->pc;
+  sal = find_pc_line (get_frame_pc (frame), 0);
+  sal.pc = get_frame_pc (frame);
 
-  breakpoint = set_momentary_breakpoint (sal, frame, bp_finish);
+  breakpoint = set_momentary_breakpoint (sal, get_frame_id (frame), bp_finish);
 
   if (!event_loop_p || !target_can_async_p ())
     old_chain = make_cleanup_delete_breakpoint (breakpoint);
@@ -1284,7 +1322,7 @@ finish_command (char *arg, int from_tty)
 
   /* Find the function we will return from.  */
 
-  function = find_pc_function (deprecated_selected_frame->pc);
+  function = find_pc_function (get_frame_pc (deprecated_selected_frame));
 
   /* Print info on the selected frame, including level number
      but not source.  */
@@ -1623,7 +1661,7 @@ default_print_registers_info (struct gdbarch *gdbarch,
       /* Convert raw data to virtual format if necessary.  */
       if (REGISTER_CONVERTIBLE (i))
        {
-         REGISTER_CONVERT_TO_VIRTUAL (i, REGISTER_VIRTUAL_TYPE (i),
+         REGISTER_CONVERT_TO_VIRTUAL (i, register_type (current_gdbarch, i),
                                       raw_buffer, virtual_buffer);
        }
       else
@@ -1634,11 +1672,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");
@@ -1656,14 +1694,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);
            }
        }
@@ -1872,8 +1910,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
 
   /*
@@ -1967,12 +2010,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;
 
@@ -1987,7 +2024,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
     }
 }
 
@@ -2120,11 +2156,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\