aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Snyder <msnyder@vmware.com>2006-05-03 00:27:27 +0000
committerMichael Snyder <msnyder@vmware.com>2006-05-03 00:27:27 +0000
commit4540c267a37186fb669d7044cee438a62fbb651c (patch)
treef921616b8f2e700de2b31039bf70fa7e0884a603
parent4b5eb65210b3b44b4f0ea8c7a95a16f199fbd057 (diff)
downloadfsf-binutils-gdb-4540c267a37186fb669d7044cee438a62fbb651c.zip
fsf-binutils-gdb-4540c267a37186fb669d7044cee438a62fbb651c.tar.gz
fsf-binutils-gdb-4540c267a37186fb669d7044cee438a62fbb651c.tar.bz2
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.
-rw-r--r--gdb/ChangeLog17
-rw-r--r--gdb/remote.c70
-rw-r--r--gdb/target.c57
-rw-r--r--gdb/target.h25
4 files changed, 163 insertions, 6 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index b2dd5f4..81fa9f7 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -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
diff --git a/gdb/remote.c b/gdb/remote.c
index d1ffdb5..5c78747 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -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;
}
diff --git a/gdb/target.c b/gdb/target.c
index 52e4527..c837609 100644
--- a/gdb/target.c
+++ b/gdb/target.c
@@ -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
@@ -1502,6 +1504,61 @@ target_async_mask (int mask)
}
/* 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. */
int
diff --git a/gdb/target.h b/gdb/target.h
index 7decfd7..8a9f7fe 100644
--- a/gdb/target.h
+++ b/gdb/target.h
@@ -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.