This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[reverse] PATCH: Several interface changes


On Monday 06 October 2008 23:11:14, Michael Snyder wrote:
> Pedro Alves wrote:
> > A per-target property may seems to make sense on
> > single-threaded,single-inferior targets, but when you add support
> > for multi-inferiors per target (e.g., extended-remote has some of it now,
> > and I'm going to push more of it), or multi-threaded support, the
> > per-target setting may not make sense anymore --- explicit requests
> > at the target resume interface (just like your new packets) may make
> > more sense.  Imagine forward execution non-stop debugging in all threads
> > but one, which the user is examining in reverse.  What's the target
> > direction in this case?
> 
> Yakkk!!!

:-)  Here's an alternative interface I was considering and envisioning
when I mentioned the above.  Consider this just a suggestion.  If it
looks bad, let's quickly forget about it.

> > The question to me is --- when/why does the target (as in, the debug
> > API abstraction) ever need to know about the current direction that
> > it couldn't get from the core's request?

So, after last night's discussion, I came up with the attached to
see how it would look like.  The major change is that I consider the
reverse/forward-direction thing a property or the command the user
requested, and as such, belongs together with the other thread
stepping state we keep in struct thread_info, and the
target_ops implementation, adjusts itself to the direction GDB
requests with target_resume.  I've extended target_resume's interface
to accept this instead of a `step' boolean:

 enum target_resume_kind
   {
     /* Continue forward.  */
     rk_continue,

     /* Step forward.  */
     rk_step,

     /* Continue in the reverse direction.  */
     rk_continue_reverse,

     /* Step in the reverse direction.  */
     rk_step_reverse,
   };

(notice that the order of the things in the enum allows me to
miss some conversions --- I'm lazy).

  I can't say if I like this new target_resume interface or
not.  I just tried doing it to see how it would look.

(I can imagine that we're in the future going to extend the
target_resume interface to be more like gdbserver's, but, well,
that's another issue.)

So, the interface at the command level implementation is just
like it was before:

 1)  call clear_proceed_status ();

 2)  /* construct the step/continue request */

 3)  call proceed (...);

Where in #2, you can set the thread to go backwards by
doing:

     thread->reverse = 1;

The attached patch applies against the reverse-20080930-branch.

Other things I've done in the patch:

   * Added support for a "Tnn nohistory" stop reply that translates
    to TARGET_WAITKIND_NO_HISTORY.  When going multi-threaded, or
    multi-process this will allow things like "T05;thread:pPID.TID;nohistory"
    for free.  I absolutelly didn't test this.  I've no reverse aware target
    at hand.

   * At places, error out if async + reverse or non-stop + reverse
     was requested.

   * Added a target_can_reverse_p method, so infcmd.c can check if the
     target supports reverse execution before calling into the target.  Not
     strictly necessary, though, but I thought this was nicer this way.

I checked that I can use the record target on x86 (actually x86_64
with -m32) as good as without the patch, but it's quite possible I
broke things badly.

-- 
Pedro Alves
2008-10-07  Pedro Alves  <pedro@codesourcery.com>

	* gdbthread.h (struct thread_info) <reverse>: New field.
	* inf-ptrace.c (inf_ptrace_resume): Adjust.
	* infcmd.c (continue_1): Rename to ...
	(continue_1_1): ... this.  Add `reverse' parameter.  Adjust.
	(continue_command): Error out in reverse + async.  Call
	continue_1_1 instead of continue_1.
	(step_1): Error out in reverse + async or if the target doesn't
	support reverse execution.  Set the current thread's execution
	direction.  Adjust calls to step_once.
	(struct step_1_continuation_args) <reverse>: New field.
	(step_1_continuation): Adjust.
	(step_once): Add new `reverse' parameter.  Adjust.
	(finish_command): Adjust.
	* inferior.h (set_execution_direction, execution_direction):
	Declare.
	* infrun.c (displaced_step_fixup): Adjust.
	(clear_proceed_status): Clear tp->reverse.
	(proceed, handle_inferior_event): Adjust.
	* linux-nat.c (resume_callback, linux_nat_resume): Adjust.
	* record.c (record_beneath_to_resume): Adjust.
	(record_is_replay): New.
	(record_resume): Adjust.
	(record_wait, record_store_registers, record_xfer_partial)
	(record_insert_breakpoint, record_remove_breakpoint): Use
	record_is_replay instead of RECORD_IS_REPLAY.
	(record_get_exec_direction, record_set_exec_direction): Delete.
	(record_can_reverse_p): New.
	(init_record_ops): Register record_can_reverse_p.  Don't register
	record_get_exec_direction or record_set_exec_direction.
	(cmd_record_delete): Adjust.
	* record.h (RECORD_IS_REPLAY): Delete.
	(record_beneath_to_resume): Adjust.
	* remote.c (remote_vcont_resume, remote_resume): Adjust.
	(remote_wait): Accept a "nohistory" special register in T stop
	replies, and translate that to TARGET_WAITKIND_NO_HISTORY.
	(remote_can_reverse_p): New.
	(remote_get_exec_direction, remote_set_exec_direction): Delete.
	(init_remote_ops): Don't register remote_get_exec_direction or
	remote_set_exec_direction.  Register remote_can_reverse_p.
	* reverse.c: Include "inferior.h".
	(current_execution_direction): New global.
	(set_execution_direction, execution_direction): New.
	(set_exec_direction_func, show_exec_direction_func): Rewrite,
	don't throw errors.
	(exec_direction_default): Rename to ...
	(exec_direction_forward): ... this.
	(exec_reverse_once): Don't check for target support here.
	Adjust.
	* target.c (update_current_target): Don't inherit
	to_get_exec_direction or to_set_exec_direction.  Inherit and
	de_fault to_can_reverse_p.  Adjust.
	(target_resume, debug_to_resume): Adjust.
	* target.h (enum target_resume_kind): New.
	(struct target_ops) <to_resume>: Adjust to take it.
	<to_set_exec_direction, exec_direction_kind>: Delete fields.
	<to_can_reverse_p>: New field.
	(target_resume): Adjust.
	(target_can_reverse_p): New.
	(target_get_execution_direction, target_set_execution_direction): Delete.
	* fork-child.c (startup_inferior): Adjust.
	* i386-linux-nat.c (i386_linux_resume): Adjust.
	
---
 gdb/fork-child.c     |    4 +-
 gdb/gdbthread.h      |    3 +
 gdb/i386-linux-nat.c |    4 +-
 gdb/inf-ptrace.c     |    4 +-
 gdb/infcmd.c         |   68 ++++++++++++++++++++++++++++++++------
 gdb/inferior.h       |    6 +++
 gdb/infrun.c         |   36 ++++++++++++--------
 gdb/linux-nat.c      |    8 ++--
 gdb/record.c         |   82 ++++++++++++++++++++++-----------------------
 gdb/record.h         |    5 +-
 gdb/remote.c         |   72 +++++++++++++++++++++-------------------
 gdb/reverse.c        |   91 +++++++++++++++++++++++++++++++--------------------
 gdb/target.c         |   41 +++++++++++++++++-----
 gdb/target.h         |   57 +++++++++++++++++++------------
 14 files changed, 307 insertions(+), 174 deletions(-)

Index: src/gdb/gdbthread.h
===================================================================
--- src.orig/gdb/gdbthread.h	2008-10-07 16:13:25.000000000 +0100
+++ src/gdb/gdbthread.h	2008-10-07 16:20:31.000000000 +0100
@@ -168,6 +168,9 @@ struct thread_info
      at.  */
   bpstat stop_bpstat;
 
+  /* True if this thread is stepping/continuing in reverse.  */
+  int reverse;
+
   /* Private data used by the target vector implementation.  */
   struct private_thread_info *private;
 };
Index: src/gdb/inf-ptrace.c
===================================================================
--- src.orig/gdb/inf-ptrace.c	2008-10-07 16:13:25.000000000 +0100
+++ src/gdb/inf-ptrace.c	2008-10-07 16:20:31.000000000 +0100
@@ -352,10 +352,12 @@ inf_ptrace_stop (ptid_t ptid)
    that signal.  */
 
 static void
-inf_ptrace_resume (ptid_t ptid, int step, enum target_signal signal)
+inf_ptrace_resume (ptid_t ptid, enum target_resume_kind how,
+		   enum target_signal signal)
 {
   pid_t pid = ptid_get_pid (ptid);
   int request = PT_CONTINUE;
+  int step = (how == rk_step);
 
   if (pid == -1)
     /* Resume all threads.  Traditionally ptrace() only supports
Index: src/gdb/infcmd.c
===================================================================
--- src.orig/gdb/infcmd.c	2008-10-07 16:13:25.000000000 +0100
+++ src/gdb/infcmd.c	2008-10-07 16:20:31.000000000 +0100
@@ -105,7 +105,8 @@ static void signal_command (char *, int)
 static void jump_command (char *, int);
 
 static void step_1 (int, int, char *);
-static void step_once (int skip_subroutines, int single_inst, int count, int thread);
+static void step_once (int skip_subroutines, int single_inst, int count, int reverse,
+		       int thread);
 
 static void next_command (char *, int);
 
@@ -586,11 +587,19 @@ proceed_thread_callback (struct thread_i
   return 0;
 }
 
-void
-continue_1 (int all_threads)
+/* Helper for continue_1.  */
+
+/* If ALL_THREADS, continue all threads forward.  If REVERSE, do so in
+   reverse execution mode.  */
+
+static void
+continue_1_1 (int all_threads, int reverse)
 {
   ERROR_NO_INFERIOR;
 
+  if (non_stop && reverse)
+    error (_("Non-stop mode not supported with reverse execution."));
+
   if (non_stop && all_threads)
     {
       /* Don't error out if the current thread is running, because
@@ -609,16 +618,31 @@ continue_1 (int all_threads)
     {
       ensure_not_running ();
       clear_proceed_status ();
+
+      inferior_thread ()->reverse = reverse;
+
       proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 0);
     }
 }
 
+/* This should be renamed as it's a public function --- it is used by
+   MI.  */
+
+/* If ALL_THREADS, continue all threads forward.  */
+
+void
+continue_1 (int all_threads)
+{
+  continue_1_1 (all_threads, 0);
+}
+
 /* continue [-a] [proceed-count] [&]  */
 void
 continue_command (char *args, int from_tty)
 {
   int async_exec = 0;
   int all_threads = 0;
+  int reverse_exec = (execution_direction () == EXEC_REVERSE);
   ERROR_NO_INFERIOR;
 
   /* Find out whether we must run in the background. */
@@ -630,6 +654,13 @@ continue_command (char *args, int from_t
   if (async_exec && !target_can_async_p ())
     error (_("Asynchronous execution not supported on this target."));
 
+  if (reverse_exec && !target_can_reverse_p ())
+    error (_("Reverse execution not supported on this target."));
+
+  if (async_exec && reverse_exec)
+    error (_("\
+Asynchronous execution not supported with reverse execution."));
+
   /* If we are not asked to run in the bg, then prepare to run in the
      foreground, synchronously. */
   if (!async_exec && target_can_async_p ())
@@ -701,7 +732,7 @@ Can't resume all threads and specify pro
   if (from_tty)
     printf_filtered (_("Continuing.\n"));
 
-  continue_1 (all_threads);
+  continue_1_1 (all_threads, reverse_exec);
 }
 
 /* Step until outside of current statement.  */
@@ -748,6 +779,7 @@ step_1 (int skip_subroutines, int single
   struct cleanup *cleanups = make_cleanup (null_cleanup, NULL);
   int async_exec = 0;
   int thread = -1;
+  int reverse_exec = (execution_direction () == EXEC_REVERSE);
 
   ERROR_NO_INFERIOR;
   ensure_not_running ();
@@ -760,6 +792,13 @@ step_1 (int skip_subroutines, int single
   if (async_exec && !target_can_async_p ())
     error (_("Asynchronous execution not supported on this target."));
 
+  if (reverse_exec && !target_can_reverse_p ())
+    error (_("Reverse execution not supported on this target."));
+
+  if (async_exec && reverse_exec)
+    error (_("\
+Asynchronous execution not supported with reverse execution."));
+
   /* If we don't get a request of running in the bg, then we need
      to simulate synchronous (fg) execution. */
   if (!async_exec && target_can_async_p ())
@@ -788,6 +827,7 @@ step_1 (int skip_subroutines, int single
 	  struct thread_info *tp = inferior_thread ();
 	  clear_proceed_status ();
 	  tp->step_frame_id = get_frame_id (get_current_frame ());
+	  tp->reverse = reverse_exec;
 
 	  if (!single_inst)
 	    {
@@ -838,7 +878,7 @@ which has no line number information.\n"
      and handle them one at the time, through step_once(). */
   else
     {
-      step_once (skip_subroutines, single_inst, count, thread);
+      step_once (skip_subroutines, single_inst, count, reverse_exec, thread);
       /* We are running, and the continuation is installed.  It will
 	 disable the longjmp breakpoint as appropriate.  */
       discard_cleanups (cleanups);
@@ -850,6 +890,7 @@ struct step_1_continuation_args
   int count;
   int skip_subroutines;
   int single_inst;
+  int reverse;
   int thread;
 };
 
@@ -872,7 +913,8 @@ step_1_continuation (void *args)
 	{
 	  /* There are more steps to make, and we did stop due to
 	     ending a stepping range.  Do another step.  */
-	  step_once (a->skip_subroutines, a->single_inst, a->count - 1, a->thread);
+	  step_once (a->skip_subroutines, a->single_inst, a->count - 1,
+		     a->reverse, a->thread);
 	  return;
 	}
       tp->step_multi = 0;
@@ -892,7 +934,8 @@ step_1_continuation (void *args)
    called in case of step n with n>1, after the first step operation has
    been completed.*/
 static void 
-step_once (int skip_subroutines, int single_inst, int count, int thread)
+step_once (int skip_subroutines, int single_inst, int count, int reverse,
+	   int thread)
 {
   struct frame_info *frame;
   struct step_1_continuation_args *args;
@@ -906,6 +949,8 @@ step_once (int skip_subroutines, int sin
       struct thread_info *tp = inferior_thread ();
       clear_proceed_status ();
 
+      tp->reverse = reverse;
+
       frame = get_current_frame ();
       if (!frame)		/* Avoid coredump here.  Why tho? */
 	error (_("No current frame"));
@@ -956,6 +1001,7 @@ which has no line number information.\n"
       args->skip_subroutines = skip_subroutines;
       args->single_inst = single_inst;
       args->count = count;
+      args->reverse = reverse;
       args->thread = thread;
       add_intermediate_continuation (tp, step_1_continuation, args, xfree);
     }
@@ -1454,7 +1500,7 @@ finish_command (char *arg, int from_tty)
     error (_("Asynchronous execution not supported on this target."));
 
   /* Don't try to async in reverse.  */
-  if (async_exec && target_get_execution_direction () == EXEC_REVERSE)
+  if (async_exec && execution_direction () == EXEC_REVERSE)
     error (_("Asynchronous 'finish' not supported in reverse."));
 
   /* If we are not asked to run in the bg, then prepare to run in the
@@ -1478,6 +1524,8 @@ finish_command (char *arg, int from_tty)
 
   clear_proceed_status ();
 
+  tp->reverse = (execution_direction () == EXEC_REVERSE);
+
   /* Find the function we will return from.  */
 
   function = find_pc_function (get_frame_pc (get_selected_frame (NULL)));
@@ -1486,7 +1534,7 @@ finish_command (char *arg, int from_tty)
      source.  */
   if (from_tty)
     {
-      if (target_get_execution_direction () == EXEC_REVERSE)
+      if (tp->reverse)
 	printf_filtered (_("Run back to call of "));
       else
 	printf_filtered (_("Run till exit from "));
@@ -1494,7 +1542,7 @@ finish_command (char *arg, int from_tty)
       print_stack_frame (get_selected_frame (NULL), 1, LOCATION);
     }
 
-  if (target_get_execution_direction () == EXEC_REVERSE)
+  if (tp->reverse)
     {
       /* Split off at this point.  */
       finish_backward (function, tp);
Index: src/gdb/inferior.h
===================================================================
--- src.orig/gdb/inferior.h	2008-10-07 16:13:25.000000000 +0100
+++ src/gdb/inferior.h	2008-10-07 16:20:31.000000000 +0100
@@ -250,6 +250,12 @@ extern void error_is_running (void);
 /* Calls error_is_running if the current thread is running.  */
 extern void ensure_not_running (void);
 
+/* From reverse.c */
+
+extern void set_execution_direction (enum exec_direction_kind dir);
+
+extern enum exec_direction_kind execution_direction (void);
+
 /* From infcmd.c */
 
 extern void tty_command (char *, int);
Index: src/gdb/infrun.c
===================================================================
--- src.orig/gdb/infrun.c	2008-10-07 16:13:25.000000000 +0100
+++ src/gdb/infrun.c	2008-10-07 16:20:31.000000000 +0100
@@ -807,7 +807,7 @@ displaced_step_fixup (ptid_t event_ptid,
 
       displaced_step_ptid = null_ptid;
       displaced_step_prepare (ptid);
-      target_resume (ptid, 1, TARGET_SIGNAL_0);
+      target_resume (ptid, rk_step, TARGET_SIGNAL_0);
     }
 }
 
@@ -1071,7 +1071,12 @@ a command like `return' or `jump' to con
           displaced_step_dump_bytes (gdb_stdlog, buf, sizeof (buf));
         }
 
-      target_resume (resume_ptid, step, sig);
+      if (step)
+	target_resume (resume_ptid,
+		       tp->reverse ? rk_step_reverse : rk_step, sig);
+      else
+	target_resume (resume_ptid,
+		       tp->reverse ? rk_continue_reverse : rk_continue, sig);
 
       /* Avoid confusing the next resume, if the next stop/resume
 	 happens to apply to another thread.  */
@@ -1101,6 +1106,7 @@ clear_proceed_status (void)
       tp->step_range_end = 0;
       tp->step_frame_id = null_frame_id;
       tp->step_over_calls = STEP_OVER_UNDEBUGGABLE;
+      tp->reverse = 0;
 
       tp->stop_step = 0;
 
@@ -1202,8 +1208,9 @@ proceed (CORE_ADDR addr, enum target_sig
 
   if (addr == (CORE_ADDR) -1)
     {
+      tp = inferior_thread ();
       if (pc == stop_pc && breakpoint_here_p (pc) 
-	  && target_get_execution_direction () != EXEC_REVERSE)
+	  && !tp->reverse)
 	/* There is a breakpoint at the address we will resume at,
 	   step one instruction before inserting breakpoints so that
 	   we do not stop right away (and report a second hit at this
@@ -2149,7 +2156,9 @@ handle_inferior_event (struct execution_
     case TARGET_WAITKIND_SYSCALL_RETURN:
       if (debug_infrun)
         fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_SYSCALL_RETURN\n");
-      target_resume (ecs->ptid, 1, TARGET_SIGNAL_0);
+      target_resume (ecs->ptid,
+		     ecs->event_thread->reverse ? rk_step_reverse : rk_step,
+		     TARGET_SIGNAL_0);
       prepare_to_wait (ecs);
       return;
 
@@ -2197,7 +2206,9 @@ targets should add new threads to the th
 	 in either the OS or the native code).  Therefore we need to
 	 continue all threads in order to make progress.  */
 
-      target_resume (RESUME_ALL, 0, TARGET_SIGNAL_0);
+      /* Can we step backwards into a threads deletion?  Ah, right, we
+	 don't support multi-threading in reverse yet.  */
+      target_resume (RESUME_ALL, rk_continue, TARGET_SIGNAL_0);
       prepare_to_wait (ecs);
       return;
     }
@@ -2501,7 +2512,7 @@ targets should add new threads to the th
       if (!HAVE_STEPPABLE_WATCHPOINT)
 	remove_breakpoints ();
       registers_changed ();
-      target_resume (ecs->ptid, 1, TARGET_SIGNAL_0);	/* Single step */
+      target_resume (ecs->ptid, rk_step, TARGET_SIGNAL_0);	/* Single step */
       waiton_ptid = ecs->ptid;
       if (HAVE_STEPPABLE_WATCHPOINT)
 	infwait_state = infwait_step_watch_state;
@@ -2886,7 +2897,7 @@ infrun: BPSTAT_WHAT_SET_LONGJMP_RESUME (
 	    return;
 	  }
 	if (stop_pc == ecs->stop_func_start
-	    && target_get_execution_direction () == EXEC_REVERSE)
+	    && ecs->event_thread->reverse)
 	  {
 	    /* We are stepping over a function call in reverse, and
 	       just hit the step-resume breakpoint at the start
@@ -3070,7 +3081,7 @@ infrun: BPSTAT_WHAT_SET_LONGJMP_RESUME (
 	 keep going back to the call point).  */
       if (stop_pc == ecs->event_thread->step_range_start
 	  && stop_pc != ecs->stop_func_start
-	  && target_get_execution_direction () == EXEC_REVERSE)
+	  && ecs->event_thread->reverse)
 	{
 	  ecs->event_thread->stop_step = 1;
 	  print_stop_reason (END_STEPPING_RANGE, 0);
@@ -3140,7 +3151,7 @@ infrun: BPSTAT_WHAT_SET_LONGJMP_RESUME (
 		    ecs->event_thread->step_frame_id)
       && (frame_id_eq (frame_unwind_id (get_current_frame ()),
 		       ecs->event_thread->step_frame_id)
-	  || target_get_execution_direction () == EXEC_REVERSE))
+	  || ecs->event_thread->reverse))
     {
       CORE_ADDR real_stop_pc;
 
@@ -3178,7 +3189,7 @@ infrun: BPSTAT_WHAT_SET_LONGJMP_RESUME (
 	     get there, we'll need to single-step back to the
 	     caller.  */
 
-	  if (target_get_execution_direction () == EXEC_REVERSE)
+	  if (ecs->event_thread->reverse)
 	    {
 	      struct symtab_and_line sr_sal;
 	      init_sal (&sr_sal);
@@ -3230,7 +3241,7 @@ infrun: BPSTAT_WHAT_SET_LONGJMP_RESUME (
 	    /* Find start of appropriate source line (either first or
 	       last line in callee, depending on execution
 	       direction).  */	      
-	    if (target_get_execution_direction () == EXEC_REVERSE)
+	    if (ecs->event_thread->reverse)
 	      stepped_into_function_backward (ecs);
 	    else
 	      stepped_into_function (ecs);
@@ -3250,7 +3261,7 @@ infrun: BPSTAT_WHAT_SET_LONGJMP_RESUME (
 	  return;
 	}
 
-      if (target_get_execution_direction () == EXEC_REVERSE)
+      if (ecs->event_thread->reverse)
 	{
 	  /* Set a breakpoint at callee's start address.
 	     From there we can step once and be back in the caller.  */
@@ -4800,7 +4811,6 @@ show_non_stop (struct ui_file *file, int
 		    value);
 }
 
-
 void
 _initialize_infrun (void)
 {
Index: src/gdb/linux-nat.c
===================================================================
--- src.orig/gdb/linux-nat.c	2008-10-07 16:13:25.000000000 +0100
+++ src/gdb/linux-nat.c	2008-10-07 16:20:31.000000000 +0100
@@ -1714,7 +1714,7 @@ resume_callback (struct lwp_info *lp, vo
   if (lp->stopped && lp->status == 0)
     {
       linux_ops->to_resume (pid_to_ptid (GET_LWP (lp->ptid)),
-			    0, TARGET_SIGNAL_0);
+			    rk_continue, TARGET_SIGNAL_0);
       if (debug_linux_nat)
 	fprintf_unfiltered (gdb_stdlog,
 			    "RC:  PTRACE_CONT %s, 0, 0 (resume sibling)\n",
@@ -1748,10 +1748,12 @@ resume_set_callback (struct lwp_info *lp
 }
 
 static void
-linux_nat_resume (ptid_t ptid, int step, enum target_signal signo)
+linux_nat_resume (ptid_t ptid, enum target_resume_kind how,
+		  enum target_signal signo)
 {
   struct lwp_info *lp;
   int resume_all;
+  int step = (how == rk_step);
 
   if (debug_linux_nat)
     fprintf_unfiltered (gdb_stdlog,
@@ -1859,7 +1861,7 @@ linux_nat_resume (ptid_t ptid, int step,
   if (resume_all)
     iterate_over_lwps (resume_callback, NULL);
 
-  linux_ops->to_resume (ptid, step, signo);
+  linux_ops->to_resume (ptid, how, signo);
   memset (&lp->siginfo, 0, sizeof (lp->siginfo));
 
   if (debug_linux_nat)
Index: src/gdb/record.c
===================================================================
--- src.orig/gdb/record.c	2008-10-07 16:13:25.000000000 +0100
+++ src/gdb/record.c	2008-10-07 16:20:31.000000000 +0100
@@ -53,7 +53,8 @@ int record_will_store_registers = 0;
 extern struct bp_location *bp_location_chain;
 
 /* The real beneath function pointers.  */
-void (*record_beneath_to_resume) (ptid_t, int, enum target_signal);
+void (*record_beneath_to_resume) (ptid_t, enum target_resume_kind,
+				  enum target_signal);
 ptid_t (*record_beneath_to_wait) (ptid_t, struct target_waitstatus *);
 void (*record_beneath_to_store_registers) (struct regcache *, int regno);
 LONGEST (*record_beneath_to_xfer_partial) (struct target_ops * ops,
@@ -432,15 +433,35 @@ record_close (int quitting)
   record_list_release (record_list);
 }
 
+static int record_is_replay;
+
 static void
-record_resume (ptid_t ptid, int step, enum target_signal siggnal)
+record_resume (ptid_t ptid, enum target_resume_kind how,
+	       enum target_signal siggnal)
 {
-  record_resume_step = step;
+  record_resume_step = (how == rk_step || how == rk_step_reverse);
+
+  switch (how)
+    {
+    case rk_step_reverse:
+    case rk_continue_reverse:
+      record_exec_direction = EXEC_REVERSE;
+      break;
+    case rk_step:
+    case rk_continue:
+      record_exec_direction = EXEC_FORWARD;
+      break;
+    }
 
-  if (!RECORD_IS_REPLAY)
+  record_is_replay = (record_list->next != NULL
+		      || how == rk_step_reverse
+		      || how == rk_continue_reverse);
+
+  if (!record_is_replay)
     {
       record_message (current_gdbarch);
-      record_beneath_to_resume (ptid, 1, siggnal);
+
+      record_beneath_to_resume (ptid, rk_step, siggnal);
     }
 }
 
@@ -487,10 +508,8 @@ record_wait (ptid_t ptid, struct target_
 			  record_resume_step);
     }
 
-  if (!RECORD_IS_REPLAY)
-    {
-      return record_beneath_to_wait (ptid, status);
-    }
+  if (!record_is_replay)
+    return record_beneath_to_wait (ptid, status);
   else
     {
       struct sigaction act, old_act;
@@ -597,8 +616,8 @@ record_wait (ptid_t ptid, struct target_
 	      if (record_debug > 1)
 		{
 		  fprintf_unfiltered (gdb_stdlog,
-				      "Process record: record_end 0x%s to inferior need_dasm = %d.\n",
-				      paddr_nz ((CORE_ADDR)record_list),
+				      "Process record: record_end %p to inferior need_dasm = %d.\n",
+				      record_list,
 				      record_list->u.need_dasm);
 		}
 
@@ -809,7 +828,7 @@ record_store_registers (struct regcache 
 {
   if (!record_not_record)
     {
-      if (RECORD_IS_REPLAY)
+      if (record_is_replay)
 	{
 	  int n;
 	  struct cleanup *old_cleanups;
@@ -874,7 +893,7 @@ record_xfer_partial (struct target_ops *
       && (object == TARGET_OBJECT_MEMORY
 	  || object == TARGET_OBJECT_RAW_MEMORY) && writebuf)
     {
-      if (RECORD_IS_REPLAY)
+      if (record_is_replay)
 	{
 	  /* Let user choice if he want to write memory or not.  */
 	  if (!nquery (_("Because GDB is in replay mode, writing to memory will destroy the record from this point forward.  Write memory at address 0x%s?"),
@@ -931,7 +950,7 @@ record_xfer_partial (struct target_ops *
 static int
 record_insert_breakpoint (struct bp_target_info *bp_tgt)
 {
-  if (!RECORD_IS_REPLAY)
+  if (!record_is_replay)
     {
       return record_beneath_to_insert_breakpoint (bp_tgt);
     }
@@ -942,7 +961,7 @@ record_insert_breakpoint (struct bp_targ
 static int
 record_remove_breakpoint (struct bp_target_info *bp_tgt)
 {
-  if (!RECORD_IS_REPLAY)
+  if (!record_is_replay)
     {
       return record_beneath_to_remove_breakpoint (bp_tgt);
     }
@@ -950,31 +969,13 @@ record_remove_breakpoint (struct bp_targ
   return 0;
 }
 
-static enum exec_direction_kind
-record_get_exec_direction (void)
-{
-  if (record_debug > 1)
-    printf_filtered ("Process record: exec direction is %s\n",
-		     record_exec_direction == EXEC_FORWARD ? "forward" :
-		     record_exec_direction == EXEC_REVERSE ? "reverse" : 
-		     "unknown");
-  return record_exec_direction;
-}
-
 static int
-record_set_exec_direction (enum exec_direction_kind dir)
+record_can_reverse_p (void)
 {
-  if (record_debug)
-    printf_filtered ("Process record: set exec direction: %s\n",
-		     dir == EXEC_FORWARD ? "forward" :
-		     dir == EXEC_REVERSE ? "reverse" : 
-		     "bad direction");
-
-  /* FIXME: check target for capability.  */
-  if (dir == EXEC_FORWARD || dir == EXEC_REVERSE)
-    return (record_exec_direction = dir);
-  else
-    return EXEC_ERROR;
+  /* Sure we can!  */
+
+  /* Actually, we should check for architecture support here.  */
+  return 1;
 }
 
 static void
@@ -997,8 +998,7 @@ init_record_ops (void)
   record_ops.to_xfer_partial = record_xfer_partial;
   record_ops.to_insert_breakpoint = record_insert_breakpoint;
   record_ops.to_remove_breakpoint = record_remove_breakpoint;
-  record_ops.to_get_exec_direction = record_get_exec_direction;
-  record_ops.to_set_exec_direction = record_set_exec_direction;
+  record_ops.to_can_reverse_p = record_can_reverse_p;
   record_ops.to_stratum = record_stratum;
   record_ops.to_magic = OPS_MAGIC;
 }
@@ -1026,7 +1026,7 @@ cmd_record_delete (char *args, int from_
 {
   if (RECORD_IS_USED)
     {
-      if (RECORD_IS_REPLAY)
+      if (record_is_replay)
 	{
 	  if (!from_tty || query (_("Process record: delete the log from this point forward and begin to record the running message at current PC?")))
 	    {
Index: src/gdb/record.h
===================================================================
--- src.orig/gdb/record.h	2008-10-07 16:13:25.000000000 +0100
+++ src/gdb/record.h	2008-10-07 16:20:31.000000000 +0100
@@ -22,8 +22,6 @@
 
 #define RECORD_IS_USED   \
      (current_target.beneath == &record_ops)
-#define RECORD_IS_REPLAY \
-     (record_list->next || record_exec_direction == EXEC_REVERSE)
 #define RECORD_TARGET_SUPPORT_RECORD_WAIT	(record_ops.beneath->to_support_record_wait)
 
 typedef struct record_reg_s
@@ -85,7 +83,8 @@ extern int record_arch_list_add_end (int
 extern void record_message (struct gdbarch *gdbarch);
 extern void record_not_record_set (void);
 
-extern void (*record_beneath_to_resume) (ptid_t, int, enum target_signal);
+extern void (*record_beneath_to_resume) (ptid_t, enum target_resume_kind,
+					 enum target_signal);
 extern ptid_t (*record_beneath_to_wait) (ptid_t, struct target_waitstatus *);
 extern void (*record_beneath_to_store_registers) (struct regcache *, int regno);
 extern LONGEST (*record_beneath_to_xfer_partial) (struct target_ops * ops,
Index: src/gdb/remote.c
===================================================================
--- src.orig/gdb/remote.c	2008-10-07 16:13:25.000000000 +0100
+++ src/gdb/remote.c	2008-10-07 16:20:31.000000000 +0100
@@ -91,8 +91,8 @@ static void remote_prepare_to_store (str
 
 static void remote_fetch_registers (struct regcache *regcache, int regno);
 
-static void remote_resume (ptid_t ptid, int step,
-                           enum target_signal siggnal);
+static void remote_resume (ptid_t ptid, enum target_resume_kind how,
+			   enum target_signal siggnal);
 static void remote_open (char *name, int from_tty);
 
 static void extended_remote_open (char *name, int from_tty);
@@ -3256,11 +3256,18 @@ remote_vcont_probe (struct remote_state 
    moment.  */
 
 static int
-remote_vcont_resume (ptid_t ptid, int step, enum target_signal siggnal)
+remote_vcont_resume (ptid_t ptid, enum target_resume_kind how,
+		     enum target_signal siggnal)
 {
   struct remote_state *rs = get_remote_state ();
   char *p;
   char *endp;
+  int step = rk_step;
+
+  /* There are no vCont packets supporting reverse execution
+     (yet).  */
+  if (how == rk_step_reverse || rk_continue_reverse)
+    return 0;
 
   if (remote_protocol_packets[PACKET_vCont].support == PACKET_SUPPORT_UNKNOWN)
     remote_vcont_probe (rs);
@@ -3362,10 +3369,12 @@ static enum target_signal last_sent_sign
 static int last_sent_step;
 
 static void
-remote_resume (ptid_t ptid, int step, enum target_signal siggnal)
+remote_resume (ptid_t ptid, enum target_resume_kind how,
+	       enum target_signal siggnal)
 {
   struct remote_state *rs = get_remote_state ();
   char *buf;
+  int step = (how == rk_step);
 
   last_sent_signal = siggnal;
   last_sent_step = step;
@@ -3374,7 +3383,7 @@ remote_resume (ptid_t ptid, int step, en
   remote_pass_signals ();
 
   /* The vCont packet doesn't need to specify threads via Hc.  */
-  if (remote_vcont_resume (ptid, step, siggnal))
+  if (remote_vcont_resume (ptid, how, siggnal))
     goto done;
 
   /* All other supported resume packets do use Hc, so set the continue
@@ -3385,7 +3394,7 @@ remote_resume (ptid_t ptid, int step, en
     set_continue_thread (ptid);
 
   buf = rs->buf;
-  if (target_get_execution_direction () == EXEC_REVERSE)
+  if (how == rk_step_reverse || how == rk_continue_reverse)
     {
       /* We don't pass signals to the target in reverse exec mode.  */
       if (info_verbose && siggnal != TARGET_SIGNAL_0)
@@ -3616,6 +3625,7 @@ remote_wait (ptid_t ptid, struct target_
   ptid_t event_ptid = null_ptid;
   ULONGEST addr;
   int solibs_changed = 0;
+  int nohistory = 0;
 
   status->kind = TARGET_WAITKIND_EXITED;
   status->value.integer = 0;
@@ -3734,6 +3744,16 @@ Packet: '%s'\n"),
 			solibs_changed = 1;
 			p = p_temp;
 		      }
+		    else if (strncmp (p, "nohistory", p1 - p) == 0)
+		      {
+			p1++;
+			p_temp = p1;
+			while (*p_temp && *p_temp != ';')
+			  p_temp++;
+
+			nohistory = 1;
+			p = p_temp;
+		      }
 		    else
  		      {
  			/* Silently skip unknown optional info.  */
@@ -3779,6 +3799,8 @@ Packet: '%s'\n"),
 	case 'S':		/* Old style status, just signal only.  */
 	  if (solibs_changed)
 	    status->kind = TARGET_WAITKIND_LOADED;
+	  else if (nohistory)
+	    status->kind = TARGET_WAITKIND_NO_HISTORY;
 	  else
 	    {
 	      status->kind = TARGET_WAITKIND_STOPPED;
@@ -7560,35 +7582,20 @@ remote_command (char *args, int from_tty
   help_list (remote_cmdlist, "remote ", -1, gdb_stdout);
 }
 
+static int
+remote_can_reverse_p (void)
+{
+  /* We can either detect that the remote side doesn't support the
+     reverse resume packets, or add a qSupported feature later.  */
+
+  /* Unconditionaly assume we can for now.  */
+  return 1;
+}
+
 /* Reverse execution.
    TODO: set up as a capability.  */
 static enum exec_direction_kind remote_exec_direction = EXEC_FORWARD;
 
-static enum exec_direction_kind remote_get_exec_direction (void)
-{
-  if (remote_debug && info_verbose)
-    printf_filtered ("remote exec direction is %s\n",
-		     remote_exec_direction == EXEC_FORWARD ? _("forward") :
-		     remote_exec_direction == EXEC_REVERSE ? _("reverse") :
-		     "unknown");
-  return remote_exec_direction;
-}
-
-static int remote_set_exec_direction (enum exec_direction_kind dir)
-{
-  if (remote_debug && info_verbose)
-    printf_filtered ("Set remote exec direction: %s\n",
-		     dir == EXEC_FORWARD ? _("forward") :
-		     dir == EXEC_REVERSE ? _("reverse") :
-		     "bad direction");
-
-  /* TODO: check target for capability.  */
-  if (dir == EXEC_FORWARD || dir == EXEC_REVERSE)
-    return (remote_exec_direction = dir);
-  else
-    return EXEC_ERROR;
-}
-
 static void
 init_remote_ops (void)
 {
@@ -7637,8 +7644,6 @@ Specify the serial device it is connecte
   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_exec_direction = remote_get_exec_direction;
-  remote_ops.to_set_exec_direction = remote_set_exec_direction;
   remote_ops.to_magic = OPS_MAGIC;
   remote_ops.to_memory_map = remote_memory_map;
   remote_ops.to_flash_erase = remote_flash_erase;
@@ -7651,6 +7656,7 @@ Specify the serial device it is connecte
   remote_ops.to_async_mask = remote_async_mask;
   remote_ops.to_terminal_inferior = remote_terminal_inferior;
   remote_ops.to_terminal_ours = remote_terminal_ours;
+  remote_ops.to_can_reverse_p = remote_can_reverse_p;
 }
 
 /* Set up the extended remote vector by making a copy of the standard
Index: src/gdb/reverse.c
===================================================================
--- src.orig/gdb/reverse.c	2008-10-07 16:13:25.000000000 +0100
+++ src/gdb/reverse.c	2008-10-07 16:36:35.000000000 +0100
@@ -25,6 +25,30 @@
 #include "top.h"
 #include "cli/cli-cmds.h"
 #include "cli/cli-decode.h"
+#include "inferior.h"
+
+/* The default current (user command level) execution direction.  All
+   targets that support execution should be able to go forward.  */
+
+enum exec_direction_kind current_exec_direction = EXEC_FORWARD;
+
+/* Set the default desired direction.  We don't check for availability
+   here, because the user may set this before the target is
+   connected/open.  If the target doesn't support reverse, either the
+   execution command issued, or target_resume will take care of
+   erroring out.  */
+
+void
+set_execution_direction (enum exec_direction_kind dir)
+{
+  current_exec_direction = dir;
+}
+
+enum exec_direction_kind
+execution_direction (void)
+{
+  return current_exec_direction;
+}
 
 /* User interface for reverse debugging:
    Set exec-direction / show exec-direction commands (returns error 
@@ -43,50 +67,51 @@ static void
 set_exec_direction_func (char *args, int from_tty,
 			 struct cmd_list_element *cmd)
 {
-  if (target_get_execution_direction () != EXEC_ERROR)
-    {
-      enum exec_direction_kind dir = EXEC_ERROR;
+  enum exec_direction_kind dir;
 
-      if (!strcmp (exec_direction, exec_forward))
-	dir = EXEC_FORWARD;
-      else if (!strcmp (exec_direction, exec_reverse))
-	dir = EXEC_REVERSE;
-
-      if (target_set_execution_direction (dir) != EXEC_ERROR)
-	return;
+  if (!strcmp (exec_direction, exec_forward))
+    dir = EXEC_FORWARD;
+  else if (!strcmp (exec_direction, exec_reverse))
+    dir = EXEC_REVERSE;
+  else
+    {
+      internal_error (__FILE__, __LINE__,
+		      "unhandled execution direction");
+      return;
     }
+
+  set_execution_direction (dir);
 }
 
 static void
 show_exec_direction_func (struct ui_file *out, int from_tty,
 			  struct cmd_list_element *cmd, const char *value)
 {
-  enum exec_direction_kind dir = target_get_execution_direction ();
+  enum exec_direction_kind dir = execution_direction ();
 
-  switch (dir) {
-  case EXEC_FORWARD:
-    fprintf_filtered (out, _("Forward\n"));
-    break;
-  case EXEC_REVERSE:
-    fprintf_filtered (out, _("Reverse\n"));
-    break;
-  case EXEC_ERROR:
-  default:
-    fprintf_filtered,  (out, 
-			_("Forward (target `%s' does not support exec-direction)\n"),
-			target_shortname);
-    break;
+  switch (dir)
+    {
+    case EXEC_FORWARD:
+      fprintf_filtered (out, _("Forward\n"));
+      break;
+    case EXEC_REVERSE:
+      fprintf_filtered (out, _("Reverse\n"));
+      break;
+    default:
+      internal_error (__FILE__, __LINE__,
+		      "unhandled execution direction");
+      break;
   }
 }
 
 /* User interface:
-   reverse-step, reverse-next etc. (returns error unles 
-   target implements to_set_exec_direction method).  */
+   reverse-step, reverse-next etc.  */
 
-static void exec_direction_default (void *notused)
+static void
+exec_direction_forward (void *notused)
 {
   /* Return execution direction to default state.  */
-  target_set_execution_direction (EXEC_FORWARD);
+  set_execution_direction (EXEC_FORWARD);
 }
 
 static void
@@ -94,20 +119,16 @@ exec_reverse_once (char *cmd, char *args
 {
   /* String buffer for command consing.  */
   char reverse_command[512];
-  enum exec_direction_kind dir = target_get_execution_direction ();
+  enum exec_direction_kind dir = execution_direction ();
   struct cleanup *old_chain;
 
-  if (dir == EXEC_ERROR)
-    error (_("Target %s does not support this command."), target_shortname);
-
   if (dir == EXEC_REVERSE)
     error (_("Already in reverse mode.  Use '%s' or 'set exec-dir forward'."),
 	   cmd);
 
-  if (target_set_execution_direction (EXEC_REVERSE) == EXEC_ERROR)
-    error (_("Target %s does not support this command."), target_shortname);
+  set_execution_direction (EXEC_REVERSE);
 
-  old_chain = make_cleanup (exec_direction_default, NULL);
+  old_chain = make_cleanup (exec_direction_forward, NULL);
   sprintf (reverse_command, "%s %s", cmd, args ? args : "");
   execute_command (reverse_command, from_tty);
   do_cleanups (old_chain);
Index: src/gdb/target.c
===================================================================
--- src.orig/gdb/target.c	2008-10-07 16:13:25.000000000 +0100
+++ src/gdb/target.c	2008-10-07 16:39:33.000000000 +0100
@@ -104,7 +104,8 @@ static void debug_to_attach (char *, int
 
 static void debug_to_detach (char *, int);
 
-static void debug_to_resume (ptid_t, int, enum target_signal);
+static void debug_to_resume (ptid_t, enum target_resume_kind,
+			     enum target_signal);
 
 static ptid_t debug_to_wait (ptid_t, struct target_waitstatus *);
 
@@ -465,14 +466,13 @@ update_current_target (void)
       INHERIT (to_find_memory_regions, t);
       INHERIT (to_make_corefile_notes, t);
       INHERIT (to_get_thread_local_address, t);
-      INHERIT (to_get_exec_direction, t);
-      INHERIT (to_set_exec_direction, t);
       /* Do not inherit to_read_description.  */
       /* Do not inherit to_search_memory.  */
       INHERIT (to_magic, t);
       /* Do not inherit to_memory_map.  */
       /* Do not inherit to_flash_erase.  */
       /* Do not inherit to_flash_done.  */
+      INHERIT (to_can_reverse_p, t);
 
       /* Set the real beneath function pointers. */
       if (t != &record_ops)
@@ -526,7 +526,8 @@ update_current_target (void)
 	    (void (*) (char *, int))
 	    target_ignore);
   de_fault (to_resume,
-	    (void (*) (ptid_t, int, enum target_signal))
+	    (void (*) (ptid_t, enum target_resume_kind,
+		       enum target_signal))
 	    noprocess);
   de_fault (to_wait,
 	    (ptid_t (*) (ptid_t, struct target_waitstatus *))
@@ -661,6 +662,7 @@ update_current_target (void)
   de_fault (to_async_mask,
 	    (int (*) (int))
 	    return_one);
+  de_fault (to_can_reverse_p, return_zero);
   current_target.to_read_description = NULL;
 #undef de_fault
 
@@ -1836,10 +1838,11 @@ target_disconnect (char *args, int from_
 }
 
 void
-target_resume (ptid_t ptid, int step, enum target_signal signal)
+target_resume (ptid_t ptid, enum target_resume_kind how,
+	       enum target_signal signal)
 {
   dcache_invalidate (target_dcache);
-  (*current_target.to_resume) (ptid, step, signal);
+  (*current_target.to_resume) (ptid, how, signal);
   set_executing (ptid, 1);
   set_running (ptid, 1);
 }
@@ -2527,12 +2530,30 @@ debug_to_detach (char *args, int from_tt
 }
 
 static void
-debug_to_resume (ptid_t ptid, int step, enum target_signal siggnal)
+debug_to_resume (ptid_t ptid, enum target_resume_kind how, enum target_signal siggnal)
 {
-  debug_target.to_resume (ptid, step, siggnal);
+  const char *howstr;
 
-  fprintf_unfiltered (gdb_stdlog, "target_resume (%d, %s, %s)\n", PIDGET (ptid),
-		      step ? "step" : "continue",
+  debug_target.to_resume (ptid, how, siggnal);
+
+  switch (how)
+    {
+    case rk_step:
+      howstr = "step";
+      break;
+    case rk_continue:
+      howstr = "continue";
+      break;
+    case rk_step_reverse:
+      howstr = "step reverse";
+      break;
+    case rk_continue_reverse:
+      howstr = "continue reverse";
+      break;
+    }
+
+  fprintf_unfiltered (gdb_stdlog, "target_resume (%s, %s, %s)\n",
+		      target_pid_to_str (ptid), howstr,
 		      target_signal_to_name (siggnal));
 }
 
Index: src/gdb/target.h
===================================================================
--- src.orig/gdb/target.h	2008-10-07 16:13:25.000000000 +0100
+++ src/gdb/target.h	2008-10-07 16:20:31.000000000 +0100
@@ -152,6 +152,29 @@ struct target_waitstatus
     value;
   };
 
+/* I'm explicitly leaving the order as
+
+    rk_continue == 0
+    rk_step == 1
+
+    to be compatible with the old interface, so I can avoid fixing up
+    all the target_resume callers for now.  */
+
+enum target_resume_kind
+  {
+    /* Continue forward.  */
+    rk_continue,
+
+    /* Step forward.  */
+    rk_step,
+
+    /* Continue in the reverse direction.  */
+    rk_continue_reverse,
+
+    /* Step in the reverse direction.  */
+    rk_step_reverse,
+  };
+
 /* Reverse execution.  */
 enum exec_direction_kind
   {
@@ -340,7 +363,7 @@ struct target_ops
     void (*to_post_attach) (int);
     void (*to_detach) (char *, int);
     void (*to_disconnect) (struct target_ops *, char *, int);
-    void (*to_resume) (ptid_t, int, enum target_signal);
+    void (*to_resume) (ptid_t, enum target_resume_kind, enum target_signal);
     ptid_t (*to_wait) (ptid_t, struct target_waitstatus *);
     void (*to_fetch_registers) (struct regcache *, int);
     void (*to_store_registers) (struct regcache *, int);
@@ -536,10 +559,8 @@ struct target_ops
 			     const gdb_byte *pattern, ULONGEST pattern_len,
 			     CORE_ADDR *found_addrp);
 
-    /* Set execution direction (forward/reverse).  */
-    int (*to_set_exec_direction) (enum exec_direction_kind);
-    /* Get execution direction (forward/reverse).  */
-    enum exec_direction_kind (*to_get_exec_direction) (void);
+    /* Returns true if the target supports reverse execution.  */
+    int (*to_can_reverse_p) (void);
 
     /* Default value is 0. Mean that this target doesn't support record wait.
        Need the help of infrun.c(handle_inferior_event). Set to 1 if this
@@ -618,12 +639,13 @@ extern void target_detach (char *, int);
 
 extern void target_disconnect (char *, int);
 
-/* Resume execution of the target process PTID.  STEP says whether to
-   single-step or to run free; SIGGNAL is the signal to be given to
-   the target, or TARGET_SIGNAL_0 for no signal.  The caller may not
-   pass TARGET_SIGNAL_DEFAULT.  */
+/* Resume execution of the target process PTID.  HOW says how to
+   proceed; SIGGNAL is the signal to be given to the target, or
+   TARGET_SIGNAL_0 for no signal.  The caller may not pass
+   TARGET_SIGNAL_DEFAULT.  */
 
-extern void target_resume (ptid_t ptid, int step, enum target_signal signal);
+extern void target_resume (ptid_t ptid, enum target_resume_kind how,
+			   enum target_signal signal);
 
 /* Wait for process pid to do something.  PTID = -1 to wait for any
    pid to do something.  Return pid of child, or -1 in case of error;
@@ -992,6 +1014,9 @@ extern int target_async_permitted;
 
 int target_supports_non_stop (void);
 
+#define target_can_reverse_p() \
+  (current_target.to_can_reverse_p ())
+
 /* Put the target in async mode with the specified callback function. */
 #define target_async(CALLBACK,CONTEXT) \
      (current_target.to_async ((CALLBACK), (CONTEXT)))
@@ -1150,18 +1175,6 @@ extern int target_stopped_data_address_p
 #define target_watchpoint_addr_within_range(target, addr, start, length) \
   (*target.to_watchpoint_addr_within_range) (target, addr, start, length)
 
-/* Forward/reverse execution direction.
-   These will only be implemented by a target that supports reverse execution.
-*/
-#define target_get_execution_direction() \
-    (current_target.to_get_exec_direction ? \
-     (*current_target.to_get_exec_direction) () : EXEC_ERROR)
-
-#define target_set_execution_direction(DIR) \
-    (current_target.to_set_exec_direction ? \
-     (*current_target.to_set_exec_direction) (DIR) : EXEC_ERROR)
-
-
 extern const struct target_desc *target_read_description (struct target_ops *);
 
 /* Utility implementation of searching memory.  */
Index: src/gdb/fork-child.c
===================================================================
--- src.orig/gdb/fork-child.c	2008-10-07 16:13:25.000000000 +0100
+++ src/gdb/fork-child.c	2008-10-07 16:20:31.000000000 +0100
@@ -490,7 +490,7 @@ startup_inferior (int ntraps)
       if (resume_signal != TARGET_SIGNAL_TRAP)
 	{
 	  /* Let shell child handle its own signals in its own way.  */
-	  target_resume (resume_ptid, 0, resume_signal);
+	  target_resume (resume_ptid, rk_continue, resume_signal);
 	}
       else
 	{
@@ -516,7 +516,7 @@ startup_inferior (int ntraps)
 	    break;
 
 	  /* Just make it go on.  */
-	  target_resume (resume_ptid, 0, TARGET_SIGNAL_0);
+	  target_resume (resume_ptid, rk_continue, TARGET_SIGNAL_0);
 	}
     }
 }
Index: src/gdb/i386-linux-nat.c
===================================================================
--- src.orig/gdb/i386-linux-nat.c	2008-10-07 16:13:25.000000000 +0100
+++ src/gdb/i386-linux-nat.c	2008-10-07 16:20:31.000000000 +0100
@@ -744,9 +744,11 @@ static const unsigned char linux_syscall
    If SIGNAL is nonzero, give it that signal.  */
 
 static void
-i386_linux_resume (ptid_t ptid, int step, enum target_signal signal)
+i386_linux_resume (ptid_t ptid, enum target_resume_kind how,
+		   enum target_signal signal)
 {
   int pid = PIDGET (ptid);
+  int step = (how == rk_step);
 
   int request = PTRACE_CONT;
 

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]