]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
2006-05-02 Michael Snyder <msnyder@redhat.com>
authorMichael Snyder <msnyder@vmware.com>
Wed, 3 May 2006 00:27:27 +0000 (00:27 +0000)
committerMichael Snyder <msnyder@vmware.com>
Wed, 3 May 2006 00:27:27 +0000 (00:27 +0000)
* Target interface for reverse execution.
* target.h (enum target_waitkind):
Add new wait event, TARGET_WAITKIND_NO_HISTORY.
(enum exec_direction_kind): New enum.
(struct target_ops): New methods to_set_execdir, to_get_execdir.
* target.c (target_get_execdir): New generic method.
(target_set_execdir): Ditto.
* remote.c (remote_get_execdir, remote_set_execdir): New methods.
(remote_vcont_resume): Jump out if attempting reverse execution.
(remote_resume): Check for reverse exec direction, and send
appropriate command to target.
(remote_wait): Check target response for NO_HISTORY status.
Also check for empty reply (target doesn't understand "bs" or "bc).
(_initialize_remote): Add new methods to remote target vector.

gdb/ChangeLog
gdb/remote.c
gdb/target.c
gdb/target.h

index b2dd5f42cef131684645a418059daaaaa5079555..81fa9f7b8ab966fabec54d85f77c7b236dc61688 100644 (file)
@@ -1,3 +1,20 @@
+2006-05-02  Michael Snyder  <msnyder@redhat.com>
+
+       * Target interface for reverse execution.
+       * target.h (enum target_waitkind): 
+       Add new wait event, TARGET_WAITKIND_NO_HISTORY.
+       (enum exec_direction_kind): New enum.
+       (struct target_ops): New methods to_set_execdir, to_get_execdir.
+       * target.c (target_get_execdir): New generic method.
+       (target_set_execdir): Ditto.
+       * remote.c (remote_get_execdir, remote_set_execdir): New methods.
+       (remote_vcont_resume): Jump out if attempting reverse execution.
+       (remote_resume): Check for reverse exec direction, and send
+       appropriate command to target.
+       (remote_wait): Check target response for NO_HISTORY status.
+       Also check for empty reply (target doesn't understand "bs" or "bc).
+       (_initialize_remote): Add new methods to remote target vector.
+
 2006-04-30  Mark Kettenis  <kettenis@gnu.org>
 
        * breakpoint.c (insert_single_step_breakpoint): Make a failure to
index d1ffdb55d8dbc9b6d7c082b2e5b3237da5476833..5c78747e2d6fd53d7a385c6d22c08103b280ef98 100644 (file)
@@ -2327,6 +2327,10 @@ remote_vcont_resume (ptid_t ptid, int step, enum target_signal siggnal)
   char *buf = NULL, *outbuf;
   struct cleanup *old_cleanup;
 
+  /* vCont does not currently support reverse execution.  */
+  if (target_get_execdir () == EXEC_REVERSE)
+    return 0;
+
   if (remote_protocol_packets[PACKET_vCont].support == PACKET_SUPPORT_UNKNOWN)
     remote_vcont_probe (rs);
 
@@ -2419,7 +2423,15 @@ remote_resume (ptid_t ptid, int step, enum target_signal siggnal)
   else
     set_thread (pid, 0);       /* Run this thread.  */
 
-  if (siggnal != TARGET_SIGNAL_0)
+  if (target_get_execdir () == EXEC_REVERSE)
+    {
+      /* We don't pass signals to the target in reverse exec mode.  */
+      if (info_verbose && siggnal != TARGET_SIGNAL_0)
+       warning (_(" - Can't pass signal %d to target in reverse: ignored.\n"),
+                siggnal);
+      strcpy (buf, step ? "bs" : "bc");
+    }
+  else if (siggnal != TARGET_SIGNAL_0)
     {
       buf[0] = step ? 'S' : 'C';
       buf[1] = tohex (((int) siggnal >> 4) & 0xf);
@@ -2693,6 +2705,12 @@ remote_wait (ptid_t ptid, struct target_waitstatus *status)
       switch (buf[0])
        {
        case 'E':               /* Error of some sort.  */
+         if (buf[1] == '0' && buf[2] == '6' 
+             && target_get_execdir () == EXEC_REVERSE)
+           {
+             status->kind = TARGET_WAITKIND_NO_HISTORY;
+             goto got_status;
+           }
          warning (_("Remote failure reply: %s"), buf);
          continue;
        case 'F':               /* File-I/O request.  */
@@ -2823,10 +2841,10 @@ Packet: '%s'\n"),
          remote_console_output (buf + 1);
          continue;
        case '\0':
+         /* Zero length reply may mean that we tried 'S' or 'C' and
+            the remote system doesn't support it.  */
          if (last_sent_signal != TARGET_SIGNAL_0)
            {
-             /* Zero length reply means that we tried 'S' or 'C' and
-                the remote system doesn't support it.  */
              target_terminal_ours_for_output ();
              printf_filtered
                ("Can't send signals to this remote system.  %s not sent.\n",
@@ -2838,10 +2856,16 @@ Packet: '%s'\n"),
              putpkt ((char *) buf);
              continue;
            }
+         /* Or, it may mean that we tried "bs" or "bc" and
+            the remote system doesn't support that.  */
+         else if (target_get_execdir () == EXEC_REVERSE)
+           {
+             error (_("Target does not support reverse execution."));
+           }
          /* else fallthrough */
        default:
-         warning (_("Invalid remote reply: %s"), buf);
-         continue;
+         error (_("Invalid remote reply: %s"), buf);
+         break;        /* Lint.  */
        }
     }
 got_status:
@@ -5218,6 +5242,40 @@ remote_get_thread_local_address (ptid_t ptid, CORE_ADDR lm, CORE_ADDR offset)
   return 0;
 }
 
+/* Reverse execution.  
+   FIXME: set up as a capability.  */
+static enum exec_direction_kind remote_execdir = EXEC_FORWARD;
+
+static enum exec_direction_kind 
+remote_get_execdir (void)
+{
+  if (remote_debug && info_verbose)
+    printf_filtered ("remote execdir is %s\n", 
+                    remote_execdir == EXEC_FORWARD ? "forward" :
+                    remote_execdir == EXEC_REVERSE ? "reverse" :
+                    "unknown");
+  return remote_execdir;
+}
+
+static enum exec_direction_kind 
+remote_set_execdir (enum exec_direction_kind dir)
+{
+  if (remote_debug && info_verbose)
+    printf_filtered ("Set remote execdir: %s\n",
+                    dir == EXEC_FORWARD ? "forward" :
+                    dir == EXEC_REVERSE ? "reverse" :
+                    "bad direction");
+
+  /* FIXME: check target for capability.  */
+  if (dir == EXEC_FORWARD || dir == EXEC_REVERSE)
+    {
+      remote_execdir = dir;
+      return dir;
+    }
+  else
+    return EXEC_ERROR;
+}
+
 static void
 init_remote_ops (void)
 {
@@ -5265,6 +5323,8 @@ Specify the serial device it is connected to\n\
   remote_ops.to_has_registers = 1;
   remote_ops.to_has_execution = 1;
   remote_ops.to_has_thread_control = tc_schedlock;     /* can lock scheduler */
+  remote_ops.to_get_execdir = remote_get_execdir;
+  remote_ops.to_set_execdir = remote_set_execdir;
   remote_ops.to_magic = OPS_MAGIC;
 }
 
index 52e45270afbfd9d58ed6119991224344f6df3b09..c83760937cbd2fe4b86087542e64da071ddbc2a1 100644 (file)
@@ -457,6 +457,8 @@ update_current_target (void)
       INHERIT (to_find_memory_regions, t);
       INHERIT (to_make_corefile_notes, t);
       INHERIT (to_get_thread_local_address, t);
+      /* Do not inherit to_get_execdir.  */
+      /* Do not inherit to_set_execdir.  */
       INHERIT (to_magic, t);
     }
 #undef INHERIT
@@ -1501,6 +1503,61 @@ target_async_mask (int mask)
   return saved_async_masked_status;
 }
 
+/* Look through the list of possible targets for a target that can
+   support reverse execution.  */
+
+enum exec_direction_kind
+target_get_execdir (void)
+{
+  struct target_ops *t;
+
+  for (t = current_target.beneath; t != NULL; t = t->beneath)
+    {
+      if (t->to_get_execdir != NULL)
+       {
+         enum exec_direction_kind retval = t->to_get_execdir ();
+         if (targetdebug)
+           fprintf_unfiltered (gdb_stdlog, "%s->to_get_execdir () = %s\n",
+                               t->to_shortname, 
+                               retval == EXEC_FORWARD ? "Forward" :
+                               retval == EXEC_REVERSE ? "Reverse" :
+                               retval == EXEC_ERROR   ? "Error"   :
+                               "*unknown*");
+         return retval;
+       }
+    }
+
+  if (targetdebug)
+    fprintf_unfiltered (gdb_stdlog, "target_get_execdir: unsupported\n");
+  return EXEC_ERROR;
+}
+
+enum exec_direction_kind
+target_set_execdir (enum exec_direction_kind setdir)
+{
+  struct target_ops *t;
+
+  for (t = current_target.beneath; t != NULL; t = t->beneath)
+    {
+      if (t->to_set_execdir != NULL)
+       {
+         enum exec_direction_kind retval = t->to_set_execdir (setdir);
+         if (targetdebug)
+           fprintf_unfiltered (gdb_stdlog, "%s->to_set_execdir () = %s\n",
+                               t->to_shortname, 
+                               retval == EXEC_FORWARD ? "Forward" :
+                               retval == EXEC_REVERSE ? "Reverse" :
+                               retval == EXEC_ERROR   ? "Error"   :
+                               "*unknown*");
+         return retval;
+       }
+    }
+
+  if (targetdebug)
+    fprintf_unfiltered (gdb_stdlog, "target_set_execdir: unsupported\n");
+  return EXEC_ERROR;
+}
+
 /* Look through the list of possible targets for a target that can
    follow forks.  */
 
index 7decfd7f954f0b895aedc459dbf7767119658733..8a9f7febcbbf6481db4df9156f02bea8333d6cde 100644 (file)
@@ -130,7 +130,11 @@ enum target_waitkind
        inferior, rather than being stuck in the remote_async_wait()
        function. This way the event loop is responsive to other events,
        like for instance the user typing.  */
-    TARGET_WAITKIND_IGNORE
+    TARGET_WAITKIND_IGNORE,
+
+    /* The target has run out of history information,
+       and cannot run backward any further.  */
+    TARGET_WAITKIND_NO_HISTORY
   };
 
 struct target_waitstatus
@@ -149,6 +153,14 @@ struct target_waitstatus
     value;
   };
 
+/* Reverse execution.  */
+enum exec_direction_kind 
+  {
+    EXEC_FORWARD,
+    EXEC_REVERSE,
+    EXEC_ERROR
+  };
+
 /* Possible types of events that the inferior handler will have to
    deal with.  */
 enum inferior_event_type
@@ -424,6 +436,11 @@ struct target_ops
                                gdb_byte *readbuf, const gdb_byte *writebuf,
                                ULONGEST offset, LONGEST len);
 
+    /* Set execution direction (forward/reverse).  */
+    enum exec_direction_kind (*to_set_execdir) (enum exec_direction_kind);
+    /* Get execution direction (forward/reverse).  */
+    enum exec_direction_kind (*to_get_execdir) (void);
+
     int to_magic;
     /* Need sub-structure for target machine related rather than comm related?
      */
@@ -1070,6 +1087,12 @@ extern int target_stopped_data_address_p (struct target_ops *);
 #define target_stopped_data_address_p(CURRENT_TARGET) (1)
 #endif
 
+/* Forward/reverse execution direction.  These will only be
+   implemented by a target that supports reverse execution.  */
+
+extern enum exec_direction_kind target_get_execdir (void);
+extern enum exec_direction_kind target_set_execdir (enum exec_direction_kind);
+
 /* This will only be defined by a target that supports catching vfork events,
    such as HP-UX.