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]

[patch 1/2] Code cleanup: infcall fields moving


On Wed, 24 Nov 2010 13:42:53 +0100, Pedro Alves wrote:
> On Wednesday 24 November 2010 00:50:34, Jan Kratochvil wrote:
> > Some of them were already saved, just not into `struct inferior_thread_state'
> > but into `struct inferior_status'.  So extended now further the latter.
[...]
> > I find these two redundant, they could be merged?  I did not try to.
> > This could be a different patch.
> 
> Yeah, there's a bunch of duplication going around here, but these
> two do serve a slightly different purpose, as mentioned in the
> comment above each.

I have found them explained by the comment in inferior.h above the structs
opaque declarations; while writing the final ChangeLog entry.  The comments
above the structs definitions do not answer it too well IMO.  Unified them and
placed only at the structs definition.


> But I guess they could be merged if the
> logic of what-to-restore-and-when is preserved.  No opinion.

Did not merge them but I hope I have made their difference understandable.


> and then making struct thread_info embed a field of those,
> instead of all the the field duplication.

OK, done, I thought it will be too invasive but maybe it is OK.

Do you agree with this approach/naming?


Thanks,
Jan


gdb/
2010-11-26  Jan Kratochvil  <jan.kratochvil@redhat.com>

	Rename and move inferior_thread_state and inferior_status.
	* gdbthread.h (struct thread_control_state): New struct, move fields
	step_range_start, step_range_end, step_frame_id, step_stack_frame_id,
	trap_expected, proceed_to_finish, in_infcall, step_over_calls,
	stop_step and stop_bpstat here from struct thread_info.
	(struct thread_suspend_state): New struct, move field stop_signal here
	from struct thread_info.
	(struct thread_info): Move the fields above from this struct.
	* inferior.h: Move the inferior_thread_state and inferior_status
	declarations comment to their definitions at infrun.c.
	(struct inferior_control_state): New struct, move field stop_soon from
	struct inferior here.
	(struct inferior_suspend_state): New empty struct.
	(struct inferior): New fields control and suspend.  Move out field
	stop_soon.
	* infrun.c (struct inferior_thread_state): Rename to ...
	(infcall_suspend_state): ... here.  Replace field stop_signal by
	fields thread_suspend and inferior_suspend.
	(save_inferior_thread_state): Rename to ...
	(save_infcall_suspend_state): ... here.  New variable inf.  Update the
	code for new fields.
	(restore_inferior_thread_state): Rename to ...
	(restore_infcall_suspend_state): ... here.  New variable inf.  Update
	the code for new fields.
	(do_restore_inferior_thread_state_cleanup): Rename to ...
	(do_restore_infcall_suspend_state_cleanup): ... here.
	(make_cleanup_restore_inferior_thread_state): Rename to ...
	(make_cleanup_restore_infcall_suspend_state): ... here.
	(discard_inferior_thread_state): Rename to ...
	(discard_infcall_suspend_state): ... here.
	(get_inferior_thread_state_regcache): Rename to ...
	(get_infcall_suspend_state_regcache): ... here.
	(struct inferior_status): Rename to ...
	(struct infcall_control_state): ... here.  Replace fields
	step_range_start, step_range_end, step_frame_id, step_stack_frame_id,
	trap_expected, proceed_to_finish, in_infcall, step_over_calls,
	stop_step, stop_bpstat and stop_soon by fields thread_control and
	inferior_control.
	(save_inferior_status): Rename to ...
	(save_infcall_control_state): ... here.  Update the code for new
	fields.
	(restore_inferior_status): Rename to ...
	(restore_infcall_control_state): ... here.  Update the code for new
	fields.
	(do_restore_inferior_status_cleanup): Rename to ...
	(do_restore_infcall_control_state_cleanup): ... here.
	(make_cleanup_restore_inferior_status): Rename to ...
	(make_cleanup_restore_infcall_control_state): ... here.
	(discard_inferior_status): Rename to ...
	(discard_infcall_control_state): ... here.
	* alpha-tdep.c, breakpoint.c, dummy-frame.c, dummy-frame.h,
	exceptions.c, fbsd-nat.c, gdbthread.h, infcall.c, infcmd.c,
	inferior.c, inferior.h, infrun.c, linux-nat.c, mi/mi-interp.c,
	mips-tdep.c, procfs.c, solib-irix.c, solib-osf.c, solib-spu.c,
	solib-sunos.c, solib-svr4.c, thread.c, windows-nat.c: Update all the
	references to the moved fields and renamed functions.

--- a/gdb/alpha-tdep.c
+++ b/gdb/alpha-tdep.c
@@ -992,7 +992,7 @@ alpha_heuristic_proc_start (struct gdbarch *gdbarch, CORE_ADDR pc)
   /* It's not clear to me why we reach this point when stopping quietly,
      but with this test, at least we don't print out warnings for every
      child forked (eg, on decstation).  22apr93 rich@cygnus.com.  */
-  if (inf->stop_soon == NO_STOP_QUIETLY)
+  if (inf->control.stop_soon == NO_STOP_QUIETLY)
     {
       static int blurb_printed = 0;
 
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -3008,7 +3008,7 @@ breakpoint_about_to_proceed (void)
 	 interrupt the command list.  When the call finishes
 	 successfully, the inferior will be standing at the same
 	 breakpoint as if nothing happened.  */
-      if (tp->in_infcall)
+      if (tp->control.in_infcall)
 	return;
     }
 
@@ -3127,7 +3127,7 @@ bpstat_do_actions (void)
        and only return when it is stopped at the next breakpoint, we
        keep doing breakpoint actions until it returns false to
        indicate the inferior was not resumed.  */
-    if (!bpstat_do_actions_1 (&inferior_thread ()->stop_bpstat))
+    if (!bpstat_do_actions_1 (&inferior_thread ()->control.stop_bpstat))
       break;
 }
 
@@ -9680,7 +9680,7 @@ bpstat_remove_breakpoint_callback (struct thread_info *th, void *data)
 {
   struct breakpoint *bpt = data;
 
-  bpstat_remove_bp_location (th->stop_bpstat, bpt);
+  bpstat_remove_bp_location (th->control.stop_bpstat, bpt);
   return 0;
 }
 
--- a/gdb/dummy-frame.c
+++ b/gdb/dummy-frame.c
@@ -43,7 +43,7 @@ struct dummy_frame
      gdbarch_dummy_id.  */
   struct frame_id id;
   /* The caller's state prior to the call.  */
-  struct inferior_thread_state *caller_state;
+  struct infcall_suspend_state *caller_state;
 };
 
 static struct dummy_frame *dummy_frame_stack = NULL;
@@ -86,7 +86,7 @@ deprecated_pc_in_call_dummy (struct gdbarch *gdbarch, CORE_ADDR pc)
    dummy-frame stack.  */
 
 void
-dummy_frame_push (struct inferior_thread_state *caller_state,
+dummy_frame_push (struct infcall_suspend_state *caller_state,
 		  const struct frame_id *dummy_id)
 {
   struct dummy_frame *dummy_frame;
@@ -106,7 +106,7 @@ remove_dummy_frame (struct dummy_frame **dummy_ptr)
   struct dummy_frame *dummy = *dummy_ptr;
 
   *dummy_ptr = dummy->next;
-  discard_inferior_thread_state (dummy->caller_state);
+  discard_infcall_suspend_state (dummy->caller_state);
   xfree (dummy);
 }
 
@@ -118,9 +118,9 @@ pop_dummy_frame (struct dummy_frame **dummy_ptr)
 {
   struct dummy_frame *dummy;
 
-  restore_inferior_thread_state ((*dummy_ptr)->caller_state);
+  restore_infcall_suspend_state ((*dummy_ptr)->caller_state);
 
-  /* restore_inferior_status frees inf_state,
+  /* restore_infcall_control_state frees inf_state,
      all that remains is to pop *dummy_ptr */
   dummy = *dummy_ptr;
   *dummy_ptr = dummy->next;
@@ -220,7 +220,8 @@ dummy_frame_sniffer (const struct frame_unwind *self,
 	      struct dummy_frame_cache *cache;
 
 	      cache = FRAME_OBSTACK_ZALLOC (struct dummy_frame_cache);
-	      cache->prev_regcache = get_inferior_thread_state_regcache (dummyframe->caller_state);
+	      cache->prev_regcache = get_infcall_suspend_state_regcache
+						   (dummyframe->caller_state);
 	      cache->this_id = this_id;
 	      (*this_prologue_cache) = cache;
 	      return 1;
--- a/gdb/dummy-frame.h
+++ b/gdb/dummy-frame.h
@@ -23,7 +23,7 @@
 
 #include "frame.h"
 
-struct inferior_thread_state;
+struct infcall_suspend_state;
 struct frame_unwind;
 
 /* Push the information needed to identify, and unwind from, a dummy
@@ -39,7 +39,7 @@ struct frame_unwind;
    be expanded so that it knowns the lower/upper extent of the dummy
    frame's code.  */
 
-extern void dummy_frame_push (struct inferior_thread_state *caller_state,
+extern void dummy_frame_push (struct infcall_suspend_state *caller_state,
                               const struct frame_id *dummy_id);
 
 /* Pop the dummy frame DUMMY_ID, restoring program state to that before the
--- a/gdb/exceptions.c
+++ b/gdb/exceptions.c
@@ -226,7 +226,10 @@ throw_exception (struct gdb_exception exception)
   /* Perhaps it would be cleaner to do this via the cleanup chain (not sure
      I can think of a reason why that is vital, though).  */
   if (tp != NULL)
-    bpstat_clear_actions (tp->stop_bpstat);	/* Clear queued breakpoint commands */
+    {
+      /* Clear queued breakpoint commands */
+      bpstat_clear_actions (tp->control.stop_bpstat);
+    }
 
   disable_current_display ();
   do_cleanups (ALL_CLEANUPS);
--- a/gdb/fbsd-nat.c
+++ b/gdb/fbsd-nat.c
@@ -143,7 +143,7 @@ fbsd_find_memory_regions (find_memory_region_ftype func, void *obfd)
 static int
 find_signalled_thread (struct thread_info *info, void *data)
 {
-  if (info->stop_signal != TARGET_SIGNAL_0
+  if (info->suspend.stop_signal != TARGET_SIGNAL_0
       && ptid_get_pid (info->ptid) == ptid_get_pid (inferior_ptid))
     return 1;
 
@@ -157,7 +157,7 @@ find_stop_signal (void)
     iterate_over_threads (find_signalled_thread, NULL);
 
   if (info)
-    return info->stop_signal;
+    return info->suspend.stop_signal;
   else
     return TARGET_SIGNAL_0;
 }
--- a/gdb/gdbthread.h
+++ b/gdb/gdbthread.h
@@ -29,43 +29,14 @@ struct symtab;
 #include "ui-out.h"
 #include "inferior.h"
 
-struct thread_info
-{
-  struct thread_info *next;
-  ptid_t ptid;			/* "Actual process id";
-				    In fact, this may be overloaded with 
-				    kernel thread id, etc.  */
-  int num;			/* Convenient handle (GDB thread id) */
+/* Inferior thread specific part of `struct infcall_control_state'.
 
-  /* Non-zero means the thread is executing.  Note: this is different
-     from saying that there is an active target and we are stopped at
-     a breakpoint, for instance.  This is a real indicator whether the
-     thread is off and running.  */
-  /* This field is internal to thread.c.  Never access it directly,
-     use is_executing instead.  */
-  int executing_;
-
-  /* Frontend view of the thread state.  Note that the RUNNING/STOPPED
-     states are different from EXECUTING.  When the thread is stopped
-     internally while handling an internal event, like a software
-     single-step breakpoint, EXECUTING will be false, but running will
-     still be true.  As a possible future extension, this could turn
-     into enum { stopped, exited, stepping, finishing, until(ling),
-     running ... }  */
-  /* This field is internal to thread.c.  Never access it directly,
-     use is_running instead.  */
-  int state_;
-
-  /* If this is > 0, then it means there's code out there that relies
-     on this thread being listed.  Don't delete it from the lists even
-     if we detect it exiting.  */
-  int refcount;
+   Inferior process counterpart is `struct inferior_control_state'.  */
 
+struct thread_control_state
+{
   /* User/external stepping state.  */
 
-  /* Step-resume or longjmp-resume breakpoint.  */
-  struct breakpoint *step_resume_breakpoint;
-
   /* Range to single step within.
 
      If this is nonzero, respond to a single-step signal by continuing
@@ -88,17 +59,6 @@ struct thread_info
      any inlined frames).  */
   struct frame_id step_stack_frame_id;
 
-  int current_line;
-  struct symtab *current_symtab;
-
-  /* Internal stepping state.  */
-
-  /* Record the pc of the thread the last time it stopped.  This is
-     maintained by proceed and keep_going, and used in
-     adjust_pc_after_break to distinguish a hardware single-step
-     SIGTRAP from a breakpoint SIGTRAP.  */
-  CORE_ADDR prev_pc;
-
   /* Nonzero if we are presently stepping over a breakpoint.
 
      If we hit a breakpoint or watchpoint, and then continue, we need
@@ -123,6 +83,90 @@ struct thread_info
      by keep_going.  */
   int trap_expected;
 
+  /* Nonzero if the thread is being proceeded for a "finish" command
+     or a similar situation when stop_registers should be saved.  */
+  int proceed_to_finish;
+
+  /* Nonzero if the thread is being proceeded for an inferior function
+     call.  */
+  int in_infcall;
+
+  enum step_over_calls_kind step_over_calls;
+
+  /* Nonzero if stopped due to a step command.  */
+  int stop_step;
+
+  /* Chain containing status of breakpoint(s) the thread stopped
+     at.  */
+  bpstat stop_bpstat;
+};
+
+/* Inferior thread specific part of `struct infcall_suspend_state'.
+
+   Inferior process counterpart is `struct inferior_suspend_state'.  */
+
+struct thread_suspend_state
+{
+  /* Last signal that the inferior received (why it stopped).  */
+  enum target_signal stop_signal;
+};
+
+struct thread_info
+{
+  struct thread_info *next;
+  ptid_t ptid;			/* "Actual process id";
+				    In fact, this may be overloaded with 
+				    kernel thread id, etc.  */
+  int num;			/* Convenient handle (GDB thread id) */
+
+  /* Non-zero means the thread is executing.  Note: this is different
+     from saying that there is an active target and we are stopped at
+     a breakpoint, for instance.  This is a real indicator whether the
+     thread is off and running.  */
+  /* This field is internal to thread.c.  Never access it directly,
+     use is_executing instead.  */
+  int executing_;
+
+  /* Frontend view of the thread state.  Note that the RUNNING/STOPPED
+     states are different from EXECUTING.  When the thread is stopped
+     internally while handling an internal event, like a software
+     single-step breakpoint, EXECUTING will be false, but running will
+     still be true.  As a possible future extension, this could turn
+     into enum { stopped, exited, stepping, finishing, until(ling),
+     running ... }  */
+  /* This field is internal to thread.c.  Never access it directly,
+     use is_running instead.  */
+  int state_;
+
+  /* If this is > 0, then it means there's code out there that relies
+     on this thread being listed.  Don't delete it from the lists even
+     if we detect it exiting.  */
+  int refcount;
+
+  /* State of GDB control of inferior thread execution.
+     See `struct thread_control_state'.  */
+  struct thread_control_state control;
+
+  /* State of inferior thread to restore after GDB is done with an inferior
+     call.  See `struct thread_suspend_state'.  */
+  struct thread_suspend_state suspend;
+
+  /* User/external stepping state.  */
+
+  /* Step-resume or longjmp-resume breakpoint.  */
+  struct breakpoint *step_resume_breakpoint;
+
+  int current_line;
+  struct symtab *current_symtab;
+
+  /* Internal stepping state.  */
+
+  /* Record the pc of the thread the last time it stopped.  This is
+     maintained by proceed and keep_going, and used in
+     adjust_pc_after_break to distinguish a hardware single-step
+     SIGTRAP from a breakpoint SIGTRAP.  */
+  CORE_ADDR prev_pc;
+
   /* Should we step over breakpoint next time keep_going is called?  */
   int stepping_over_breakpoint;
 
@@ -153,19 +197,6 @@ struct thread_info
      command.  */
   struct continuation *intermediate_continuations;
 
-  /* Nonzero if the thread is being proceeded for a "finish" command
-     or a similar situation when stop_registers should be saved.  */
-  int proceed_to_finish;
-
-  /* Nonzero if the thread is being proceeded for an inferior function
-     call.  */
-  int in_infcall;
-
-  enum step_over_calls_kind step_over_calls;
-
-  /* Nonzero if stopped due to a step command.  */
-  int stop_step;
-
   /* If stepping, nonzero means step count is > 1 so don't print frame
      next time inferior stops if it stops due to stepping.  */
   int step_multi;
@@ -175,13 +206,6 @@ struct thread_info
      resume of the thread, and not immediately.  */
   struct target_waitstatus pending_follow;
 
-  /* Last signal that the inferior received (why it stopped).  */
-  enum target_signal stop_signal;
-
-  /* Chain containing status of breakpoint(s) the thread stopped
-     at.  */
-  bpstat stop_bpstat;
-
   /* True if this thread has been explicitly requested to stop.  */
   int stop_requested;
 
--- a/gdb/infcall.c
+++ b/gdb/infcall.c
@@ -360,16 +360,18 @@ run_inferior_call (struct thread_info *call_thread, CORE_ADDR real_pc)
 {
   volatile struct gdb_exception e;
   int saved_async = 0;
-  int saved_in_infcall = call_thread->in_infcall;
+  int saved_in_infcall = call_thread->control.in_infcall;
   ptid_t call_thread_ptid = call_thread->ptid;
   char *saved_target_shortname = xstrdup (target_shortname);
 
-  call_thread->in_infcall = 1;
+  call_thread->control.in_infcall = 1;
 
   clear_proceed_status ();
 
   disable_watchpoints_before_interactive_call_start ();
-  call_thread->proceed_to_finish = 1; /* We want stop_registers, please... */
+
+  /* We want stop_registers, please... */
+  call_thread->control.proceed_to_finish = 1;
 
   if (target_can_async_p ())
     saved_async = target_async_mask (0);
@@ -397,11 +399,11 @@ run_inferior_call (struct thread_info *call_thread, CORE_ADDR real_pc)
   if (e.reason < 0)
     {
       if (call_thread != NULL)
-	breakpoint_auto_delete (call_thread->stop_bpstat);
+	breakpoint_auto_delete (call_thread->control.stop_bpstat);
     }
 
   if (call_thread != NULL)
-    call_thread->in_infcall = saved_in_infcall;
+    call_thread->control.in_infcall = saved_in_infcall;
 
   xfree (saved_target_shortname);
 
@@ -440,9 +442,9 @@ call_function_by_hand (struct value *function, int nargs, struct value **args)
   struct type *values_type, *target_values_type;
   unsigned char struct_return = 0, lang_struct_return = 0;
   CORE_ADDR struct_addr = 0;
-  struct inferior_status *inf_status;
+  struct infcall_control_state *inf_status;
   struct cleanup *inf_status_cleanup;
-  struct inferior_thread_state *caller_state;
+  struct infcall_suspend_state *caller_state;
   CORE_ADDR funaddr;
   CORE_ADDR real_pc;
   struct type *ftype = check_typedef (value_type (function));
@@ -473,16 +475,17 @@ call_function_by_hand (struct value *function, int nargs, struct value **args)
 
   /* A cleanup for the inferior status.
      This is only needed while we're preparing the inferior function call.  */
-  inf_status = save_inferior_status ();
-  inf_status_cleanup = make_cleanup_restore_inferior_status (inf_status);
+  inf_status = save_infcall_control_state ();
+  inf_status_cleanup
+    = make_cleanup_restore_infcall_control_state (inf_status);
 
   /* Save the caller's registers and other state associated with the
      inferior itself so that they can be restored once the
      callee returns.  To allow nested calls the registers are (further
      down) pushed onto a dummy frame stack.  Include a cleanup (which
      is tossed once the regcache has been pushed).  */
-  caller_state = save_inferior_thread_state ();
-  make_cleanup_restore_inferior_thread_state (caller_state);
+  caller_state = save_infcall_suspend_state ();
+  make_cleanup_restore_infcall_suspend_state (caller_state);
 
   /* Ensure that the initial SP is correctly aligned.  */
   {
@@ -810,7 +813,7 @@ call_function_by_hand (struct value *function, int nargs, struct value **args)
       const char *name = get_function_name (funaddr,
                                             name_buf, sizeof (name_buf));
 
-      discard_inferior_status (inf_status);
+      discard_infcall_control_state (inf_status);
 
       /* We could discard the dummy frame here if the program exited,
          but it will get garbage collected the next time the program is
@@ -842,7 +845,7 @@ When the function is done executing, GDB will silently stop."),
 
       /* If we try to restore the inferior status,
 	 we'll crash as the inferior is no longer running.  */
-      discard_inferior_status (inf_status);
+      discard_infcall_control_state (inf_status);
 
       /* We could discard the dummy frame here given that the program exited,
          but it will get garbage collected the next time the program is
@@ -864,7 +867,7 @@ Evaluation of the expression containing the function\n\
 	 signal or breakpoint while our thread was running.
 	 There's no point in restoring the inferior status,
 	 we're in a different thread.  */
-      discard_inferior_status (inf_status);
+      discard_infcall_control_state (inf_status);
       /* Keep the dummy frame record, if the user switches back to the
 	 thread with the hand-call, we'll need it.  */
       if (stopped_by_random_signal)
@@ -905,7 +908,7 @@ When the function is done executing, GDB will silently stop."),
 
 	      /* We also need to restore inferior status to that before the
 		 dummy call.  */
-	      restore_inferior_status (inf_status);
+	      restore_infcall_control_state (inf_status);
 
 	      /* FIXME: Insert a bunch of wrap_here; name can be very
 		 long if it's a C++ name with arguments and stuff.  */
@@ -923,7 +926,7 @@ Evaluation of the expression containing the function\n\
 		 (default).
 		 Discard inferior status, we're not at the same point
 		 we started at.  */
-	      discard_inferior_status (inf_status);
+	      discard_infcall_control_state (inf_status);
 
 	      /* FIXME: Insert a bunch of wrap_here; name can be very
 		 long if it's a C++ name with arguments and stuff.  */
@@ -946,7 +949,7 @@ When the function is done executing, GDB will silently stop."),
 
 	  /* We also need to restore inferior status to that before
 	     the dummy call.  */
-	  restore_inferior_status (inf_status);
+	  restore_infcall_control_state (inf_status);
 
 	  error (_("\
 The program being debugged entered a std::terminate call, most likely\n\
@@ -965,7 +968,7 @@ will be abandoned."),
 	     Keep the dummy frame, the user may want to examine its state.
 	     Discard inferior status, we're not at the same point
 	     we started at.  */
-	  discard_inferior_status (inf_status);
+	  discard_infcall_control_state (inf_status);
 
 	  /* The following error message used to say "The expression
 	     which contained the function call has been discarded."
@@ -1002,7 +1005,7 @@ When the function is done executing, GDB will silently stop."),
 
     /* Inferior call is successful.  Restore the inferior status.
        At this stage, leave the RETBUF alone.  */
-    restore_inferior_status (inf_status);
+    restore_infcall_control_state (inf_status);
 
     /* Figure out the value returned by the function.  */
 
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -753,7 +753,7 @@ Can't resume all threads and specify proceed count simultaneously."));
 	  tp = find_thread_ptid (last_ptid);
 	}
       if (tp != NULL)
-	bs = tp->stop_bpstat;
+	bs = tp->control.stop_bpstat;
 
       while ((stat = bpstat_num (&bs, &num)) != 0)
 	if (stat > 0)
@@ -885,7 +885,7 @@ step_1 (int skip_subroutines, int single_inst, char *count_string)
 	  else
 	    tp = NULL;
 
-	  if (!tp || !tp->stop_step || !tp->step_multi)
+	  if (!tp || !tp->control.stop_step || !tp->step_multi)
 	    {
 	      /* If we stopped for some reason that is not stepping
 		 there are no further steps to make.  */
@@ -935,7 +935,7 @@ step_1_continuation (void *args)
       struct thread_info *tp;
 
       tp = inferior_thread ();
-      if (tp->step_multi && tp->stop_step)
+      if (tp->step_multi && tp->control.stop_step)
 	{
 	  /* There are more steps to make, and we did stop due to
 	     ending a stepping range.  Do another step.  */
@@ -993,18 +993,19 @@ step_once (int skip_subroutines, int single_inst, int count, int thread)
 
 	  pc = get_frame_pc (frame);
 	  find_pc_line_pc_range (pc,
-				 &tp->step_range_start, &tp->step_range_end);
+				 &tp->control.step_range_start,
+				 &tp->control.step_range_end);
 
 	  /* If we have no line info, switch to stepi mode.  */
-	  if (tp->step_range_end == 0 && step_stop_if_no_debug)
-	    tp->step_range_start = tp->step_range_end = 1;
-	  else if (tp->step_range_end == 0)
+	  if (tp->control.step_range_end == 0 && step_stop_if_no_debug)
+	    tp->control.step_range_start = tp->control.step_range_end = 1;
+	  else if (tp->control.step_range_end == 0)
 	    {
 	      char *name;
 
 	      if (find_pc_partial_function (pc, &name,
-					    &tp->step_range_start,
-					    &tp->step_range_end) == 0)
+					    &tp->control.step_range_start,
+					    &tp->control.step_range_end) == 0)
 		error (_("Cannot find bounds of current function"));
 
 	      target_terminal_ours ();
@@ -1016,16 +1017,16 @@ which has no line number information.\n"), name);
       else
 	{
 	  /* Say we are stepping, but stop after one insn whatever it does.  */
-	  tp->step_range_start = tp->step_range_end = 1;
+	  tp->control.step_range_start = tp->control.step_range_end = 1;
 	  if (!skip_subroutines)
 	    /* It is stepi.
 	       Don't step over function calls, not even to functions lacking
 	       line numbers.  */
-	    tp->step_over_calls = STEP_OVER_NONE;
+	    tp->control.step_over_calls = STEP_OVER_NONE;
 	}
 
       if (skip_subroutines)
-	tp->step_over_calls = STEP_OVER_ALL;
+	tp->control.step_over_calls = STEP_OVER_ALL;
 
       tp->step_multi = (count > 1);
       proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 1);
@@ -1255,18 +1256,18 @@ until_next_command (int from_tty)
       if (msymbol == NULL)
 	error (_("Execution is not within a known function."));
 
-      tp->step_range_start = SYMBOL_VALUE_ADDRESS (msymbol);
-      tp->step_range_end = pc;
+      tp->control.step_range_start = SYMBOL_VALUE_ADDRESS (msymbol);
+      tp->control.step_range_end = pc;
     }
   else
     {
       sal = find_pc_line (pc, 0);
 
-      tp->step_range_start = BLOCK_START (SYMBOL_BLOCK_VALUE (func));
-      tp->step_range_end = sal.end;
+      tp->control.step_range_start = BLOCK_START (SYMBOL_BLOCK_VALUE (func));
+      tp->control.step_range_end = sal.end;
     }
 
-  tp->step_over_calls = STEP_OVER_ALL;
+  tp->control.step_over_calls = STEP_OVER_ALL;
 
   tp->step_multi = 0;		/* Only one call to proceed */
 
@@ -1429,7 +1430,7 @@ finish_command_continuation (void *arg)
       && is_stopped (inferior_ptid))
     {
       tp = inferior_thread ();
-      bs = tp->stop_bpstat;
+      bs = tp->control.stop_bpstat;
     }
 
   if (bpstat_find_breakpoint (bs, a->breakpoint) != NULL
@@ -1460,7 +1461,7 @@ finish_command_continuation (void *arg)
 
   /* We suppress normal call of normal_stop observer and do it here so
      that the *stopped notification includes the return value.  */
-  if (bs != NULL && tp->proceed_to_finish)
+  if (bs != NULL && tp->control.proceed_to_finish)
     observer_notify_normal_stop (bs, 1 /* print frame */);
   delete_breakpoint (a->breakpoint);
 }
@@ -1493,7 +1494,7 @@ finish_backward (struct symbol *function)
   sal = find_pc_line (func_addr, 0);
 
   /* We don't need a return value.  */
-  tp->proceed_to_finish = 0;
+  tp->control.proceed_to_finish = 0;
   /* Special case: if we're sitting at the function entry point,
      then all we need to do is take a reverse singlestep.  We
      don't need to set a breakpoint, and indeed it would do us
@@ -1519,7 +1520,8 @@ finish_backward (struct symbol *function)
       old_chain = make_cleanup_delete_breakpoint (breakpoint);
       proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 0);
       /* We will be stopped when proceed returns.  */
-      back_up = bpstat_find_breakpoint (tp->stop_bpstat, breakpoint) != NULL;
+      back_up = (bpstat_find_breakpoint (tp->control.stop_bpstat, breakpoint)
+		 != NULL);
       do_cleanups (old_chain);
     }
   else
@@ -1529,7 +1531,7 @@ finish_backward (struct symbol *function)
       /* If in fact we hit the step-resume breakpoint (and not
 	 some other breakpoint), then we're almost there --
 	 we just need to back up by one more single-step.  */
-      tp->step_range_start = tp->step_range_end = 1;
+      tp->control.step_range_start = tp->control.step_range_end = 1;
       proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 1);
     }
   return;
@@ -1556,7 +1558,8 @@ finish_forward (struct symbol *function, struct frame_info *frame)
 
   old_chain = make_cleanup_delete_breakpoint (breakpoint);
 
-  tp->proceed_to_finish = 1;    /* We want stop_registers, please...  */
+  /* We want stop_registers, please...  */
+  tp->control.proceed_to_finish = 1;
   cargs = xmalloc (sizeof (*cargs));
 
   cargs->breakpoint = breakpoint;
@@ -1632,8 +1635,9 @@ finish_command (char *arg, int from_tty)
 
       init_sal (&empty_sal);
       set_step_info (frame, empty_sal);
-      tp->step_range_start = tp->step_range_end = get_frame_pc (frame);
-      tp->step_over_calls = STEP_OVER_ALL;
+      tp->control.step_range_start = get_frame_pc (frame);
+      tp->control.step_range_end = tp->control.step_range_start;
+      tp->control.step_over_calls = STEP_OVER_ALL;
 
       /* Print info on the selected frame, including level number but not
 	 source.  */
@@ -1699,13 +1703,13 @@ program_info (char *args, int from_tty)
     error (_("Selected thread is running."));
 
   tp = find_thread_ptid (ptid);
-  bs = tp->stop_bpstat;
+  bs = tp->control.stop_bpstat;
   stat = bpstat_num (&bs, &num);
 
   target_files_info ();
   printf_filtered (_("Program stopped at %s.\n"),
 		   paddress (target_gdbarch, stop_pc));
-  if (tp->stop_step)
+  if (tp->control.stop_step)
     printf_filtered (_("It stopped after being stepped.\n"));
   else if (stat != 0)
     {
@@ -1723,11 +1727,11 @@ It stopped at a breakpoint that has since been deleted.\n"));
 	  stat = bpstat_num (&bs, &num);
 	}
     }
-  else if (tp->stop_signal != TARGET_SIGNAL_0)
+  else if (tp->suspend.stop_signal != TARGET_SIGNAL_0)
     {
       printf_filtered (_("It stopped with signal %s, %s.\n"),
-		       target_signal_to_name (tp->stop_signal),
-		       target_signal_to_string (tp->stop_signal));
+		       target_signal_to_name (tp->suspend.stop_signal),
+		       target_signal_to_string (tp->suspend.stop_signal));
     }
 
   if (!from_tty)
@@ -2206,7 +2210,7 @@ proceed_after_attach_callback (struct thread_info *thread,
       && !is_exited (thread->ptid)
       && !is_executing (thread->ptid)
       && !thread->stop_requested
-      && thread->stop_signal == TARGET_SIGNAL_0)
+      && thread->suspend.stop_signal == TARGET_SIGNAL_0)
     {
       switch_to_thread (thread->ptid);
       clear_proceed_status ();
@@ -2256,7 +2260,7 @@ attach_command_post_wait (char *args, int from_tty, int async_exec)
   struct inferior *inferior;
 
   inferior = current_inferior ();
-  inferior->stop_soon = NO_STOP_QUIETLY;
+  inferior->control.stop_soon = NO_STOP_QUIETLY;
 
   /* If no exec file is yet known, try to determine it from the
      process itself.  */
@@ -2308,7 +2312,7 @@ attach_command_post_wait (char *args, int from_tty, int async_exec)
 	proceed_after_attach (inferior->pid);
       else
 	{
-	  if (inferior_thread ()->stop_signal == TARGET_SIGNAL_0)
+	  if (inferior_thread ()->suspend.stop_signal == TARGET_SIGNAL_0)
 	    {
 	      clear_proceed_status ();
 	      proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 0);
@@ -2447,7 +2451,7 @@ attach_command (char *args, int from_tty)
 	 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.  */
-      inferior->stop_soon = STOP_QUIETLY_NO_SIGSTOP;
+      inferior->control.stop_soon = STOP_QUIETLY_NO_SIGSTOP;
 
       if (target_can_async_p ())
 	{
@@ -2510,7 +2514,7 @@ notice_new_inferior (ptid_t ptid, int leave_running, int from_tty)
 	 that.  */
       target_stop (inferior_ptid);
 
-      inferior->stop_soon = STOP_QUIETLY_REMOTE;
+      inferior->control.stop_soon = STOP_QUIETLY_REMOTE;
 
       /* Wait for stop before proceeding.  */
       if (target_can_async_p ())
--- a/gdb/inferior.c
+++ b/gdb/inferior.c
@@ -124,7 +124,7 @@ add_inferior_silent (int pid)
   memset (inf, 0, sizeof (*inf));
   inf->pid = pid;
 
-  inf->stop_soon = NO_STOP_QUIETLY;
+  inf->control.stop_soon = NO_STOP_QUIETLY;
 
   inf->num = ++highest_inferior_num;
   inf->next = inferior_list;
--- a/gdb/inferior.h
+++ b/gdb/inferior.h
@@ -43,37 +43,25 @@ struct terminal_info;
 
 #include "progspace.h"
 
-/* Two structures are used to record inferior state.
+struct infcall_suspend_state;
+struct infcall_control_state;
 
-   inferior_thread_state contains state about the program itself like its
-   registers and any signal it received when it last stopped.
-   This state must be restored regardless of how the inferior function call
-   ends (either successfully, or after it hits a breakpoint or signal)
-   if the program is to properly continue where it left off.
+extern struct infcall_suspend_state *save_infcall_suspend_state (void);
+extern struct infcall_control_state *save_infcall_control_state (void);
 
-   inferior_status contains state regarding gdb's control of the inferior
-   itself like stepping control.  It also contains session state like the
-   user's currently selected frame.
+extern void restore_infcall_suspend_state (struct infcall_suspend_state *);
+extern void restore_infcall_control_state (struct infcall_control_state *);
 
-   Call these routines around hand called functions, including function calls
-   in conditional breakpoints for example.  */
+extern struct cleanup *make_cleanup_restore_infcall_suspend_state
+					    (struct infcall_suspend_state *);
+extern struct cleanup *make_cleanup_restore_infcall_control_state
+					    (struct infcall_control_state *);
 
-struct inferior_thread_state;
-struct inferior_status;
+extern void discard_infcall_suspend_state (struct infcall_suspend_state *);
+extern void discard_infcall_control_state (struct infcall_control_state *);
 
-extern struct inferior_thread_state *save_inferior_thread_state (void);
-extern struct inferior_status *save_inferior_status (void);
-
-extern void restore_inferior_thread_state (struct inferior_thread_state *);
-extern void restore_inferior_status (struct inferior_status *);
-
-extern struct cleanup *make_cleanup_restore_inferior_thread_state (struct inferior_thread_state *);
-extern struct cleanup *make_cleanup_restore_inferior_status (struct inferior_status *);
-
-extern void discard_inferior_thread_state (struct inferior_thread_state *);
-extern void discard_inferior_status (struct inferior_status *);
-
-extern struct regcache *get_inferior_thread_state_regcache (struct inferior_thread_state *);
+extern struct regcache *
+  get_infcall_suspend_state_regcache (struct infcall_suspend_state *);
 
 /* The -1 ptid, often used to indicate either an error condition
    or a "don't care" condition, i.e, "run all threads."  */
@@ -405,6 +393,24 @@ void displaced_step_dump_bytes (struct ui_file *file,
 
 struct private_inferior;
 
+/* Inferior process specific part of `struct infcall_control_state'.
+
+   Inferior thread counterpart is `struct thread_control_state'.  */
+
+struct inferior_control_state
+{
+  /* See the definition of stop_kind above.  */
+  enum stop_kind stop_soon;
+};
+
+/* Inferior process specific part of `struct infcall_suspend_state'.
+
+   Inferior thread counterpart is `struct thread_suspend_state'.  */
+
+struct inferior_suspend_state
+{
+};
+
 /* GDB represents the state of each program execution with an object
    called an inferior.  An inferior typically corresponds to a process
    but is more general and applies also to targets that do not have a
@@ -427,6 +433,14 @@ struct inferior
      the ptid_t.pid member of threads of this inferior.  */
   int pid;
 
+  /* State of GDB control of inferior process execution.
+     See `struct inferior_control_state'.  */
+  struct inferior_control_state control;
+
+  /* State of inferior process to restore after GDB is done with an inferior
+     call.  See `struct inferior_suspend_state'.  */
+  struct inferior_suspend_state suspend;
+
   /* True if this was an auto-created inferior, e.g. created from
      following a fork; false, if this inferior was manually added by
      the user, and we should not attempt to prune it
@@ -458,9 +472,6 @@ struct inferior
      in format described in environ.h.  */
   struct gdb_environ *environment;
 
-  /* See the definition of stop_kind above.  */
-  enum stop_kind stop_soon;
-
   /* Nonzero if this child process was attached rather than
      forked.  */
   int attach_flag;
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -426,9 +426,9 @@ follow_fork (void)
 	  {
 	    step_resume_breakpoint
 	      = clone_momentary_breakpoint (tp->step_resume_breakpoint);
-	    step_range_start = tp->step_range_start;
-	    step_range_end = tp->step_range_end;
-	    step_frame_id = tp->step_frame_id;
+	    step_range_start = tp->control.step_range_start;
+	    step_range_end = tp->control.step_range_end;
+	    step_frame_id = tp->control.step_frame_id;
 
 	    /* For now, delete the parent's sr breakpoint, otherwise,
 	       parent/child sr breakpoints are considered duplicates,
@@ -436,9 +436,9 @@ follow_fork (void)
 	       this when the breakpoints module becomes aware of
 	       inferiors and address spaces.  */
 	    delete_step_resume_breakpoint (tp);
-	    tp->step_range_start = 0;
-	    tp->step_range_end = 0;
-	    tp->step_frame_id = null_frame_id;
+	    tp->control.step_range_start = 0;
+	    tp->control.step_range_end = 0;
+	    tp->control.step_frame_id = null_frame_id;
 	  }
 
 	parent = inferior_ptid;
@@ -477,9 +477,9 @@ follow_fork (void)
 		  {
 		    tp = inferior_thread ();
 		    tp->step_resume_breakpoint = step_resume_breakpoint;
-		    tp->step_range_start = step_range_start;
-		    tp->step_range_end = step_range_end;
-		    tp->step_frame_id = step_frame_id;
+		    tp->control.step_range_start = step_range_start;
+		    tp->control.step_range_end = step_range_end;
+		    tp->control.step_frame_id = step_frame_id;
 		  }
 		else
 		  {
@@ -555,7 +555,7 @@ proceed_after_vfork_done (struct thread_info *thread,
       && is_running (thread->ptid)
       && !is_executing (thread->ptid)
       && !thread->stop_requested
-      && thread->stop_signal == TARGET_SIGNAL_0)
+      && thread->suspend.stop_signal == TARGET_SIGNAL_0)
     {
       if (debug_infrun)
 	fprintf_unfiltered (gdb_stdlog,
@@ -770,8 +770,8 @@ follow_exec (ptid_t pid, char *execd_pathname)
   /* If there was one, it's gone now.  We cannot truly step-to-next
      statement through an exec(). */
   th->step_resume_breakpoint = NULL;
-  th->step_range_start = 0;
-  th->step_range_end = 0;
+  th->control.step_range_start = 0;
+  th->control.step_range_end = 0;
 
   /* The target reports the exec event to the main thread, even if
      some other thread does the exec, and even if the main thread was
@@ -1431,7 +1431,7 @@ displaced_step_fixup (ptid_t event_ptid, enum target_signal signal)
 
 	  /* The breakpoint we were sitting under has since been
 	     removed.  */
-	  tp->trap_expected = 0;
+	  tp->control.trap_expected = 0;
 
 	  /* Go back to what we were trying to do.  */
 	  step = currently_stepping (tp);
@@ -1441,7 +1441,7 @@ displaced_step_fixup (ptid_t event_ptid, enum target_signal signal)
 				target_pid_to_str (tp->ptid), step);
 
 	  target_resume (ptid, step, TARGET_SIGNAL_0);
-	  tp->stop_signal = TARGET_SIGNAL_0;
+	  tp->suspend.stop_signal = TARGET_SIGNAL_0;
 
 	  /* This request was discarded.  See if there's any other
 	     thread waiting for its turn.  */
@@ -1592,7 +1592,7 @@ resume (int step, enum target_signal sig)
     fprintf_unfiltered (gdb_stdlog,
                         "infrun: resume (step=%d, signal=%d), "
 			"trap_expected=%d\n",
- 			step, sig, tp->trap_expected);
+ 			step, sig, tp->control.trap_expected);
 
   /* Normally, by the time we reach `resume', the breakpoints are either
      removed or inserted, as appropriate.  The exception is if we're sitting
@@ -1621,7 +1621,7 @@ a command like `return' or `jump' to continue execution."));
      event, displaced stepping breaks the vfork child similarly as single
      step software breakpoint.  */
   if (use_displaced_stepping (gdbarch)
-      && (tp->trap_expected
+      && (tp->control.trap_expected
 	  || (step && gdbarch_software_single_step_p (gdbarch)))
       && sig == TARGET_SIGNAL_0
       && !current_inferior ()->waiting_for_vfork_done)
@@ -1690,7 +1690,7 @@ a command like `return' or `jump' to continue execution."));
 	  resume_ptid = inferior_ptid;
 	}
       else if ((step || singlestep_breakpoints_inserted_p)
-	       && tp->trap_expected)
+	       && tp->control.trap_expected)
 	{
 	  /* We're allowing a thread to run past a breakpoint it has
 	     hit, by single-stepping the thread with the breakpoint
@@ -1729,7 +1729,7 @@ a command like `return' or `jump' to continue execution."));
 
       if (debug_displaced
           && use_displaced_stepping (gdbarch)
-          && tp->trap_expected)
+          && tp->control.trap_expected)
         {
 	  struct regcache *resume_regcache = get_thread_regcache (resume_ptid);
 	  struct gdbarch *resume_gdbarch = get_regcache_arch (resume_regcache);
@@ -1747,7 +1747,7 @@ a command like `return' or `jump' to continue execution."));
 
       /* Avoid confusing the next resume, if the next stop/resume
 	 happens to apply to another thread.  */
-      tp->stop_signal = TARGET_SIGNAL_0;
+      tp->suspend.stop_signal = TARGET_SIGNAL_0;
 
       target_resume (resume_ptid, step, sig);
     }
@@ -1768,20 +1768,20 @@ clear_proceed_status_thread (struct thread_info *tp)
 			"infrun: clear_proceed_status_thread (%s)\n",
 			target_pid_to_str (tp->ptid));
 
-  tp->trap_expected = 0;
-  tp->step_range_start = 0;
-  tp->step_range_end = 0;
-  tp->step_frame_id = null_frame_id;
-  tp->step_stack_frame_id = null_frame_id;
-  tp->step_over_calls = STEP_OVER_UNDEBUGGABLE;
+  tp->control.trap_expected = 0;
+  tp->control.step_range_start = 0;
+  tp->control.step_range_end = 0;
+  tp->control.step_frame_id = null_frame_id;
+  tp->control.step_stack_frame_id = null_frame_id;
+  tp->control.step_over_calls = STEP_OVER_UNDEBUGGABLE;
   tp->stop_requested = 0;
 
-  tp->stop_step = 0;
+  tp->control.stop_step = 0;
 
-  tp->proceed_to_finish = 0;
+  tp->control.proceed_to_finish = 0;
 
   /* Discard any remaining commands or status from previous stop.  */
-  bpstat_clear (&tp->stop_bpstat);
+  bpstat_clear (&tp->control.stop_bpstat);
 }
 
 static int
@@ -1818,7 +1818,7 @@ clear_proceed_status (void)
 	}
 
       inferior = current_inferior ();
-      inferior->stop_soon = NO_STOP_QUIETLY;
+      inferior->control.stop_soon = NO_STOP_QUIETLY;
     }
 
   stop_after_trap = 0;
@@ -2011,7 +2011,7 @@ proceed (CORE_ADDR addr, enum target_signal siggnal, int step)
 
   if (oneproc)
     {
-      tp->trap_expected = 1;
+      tp->control.trap_expected = 1;
       /* If displaced stepping is enabled, we can step over the
 	 breakpoint without hitting it, so leave all breakpoints
 	 inserted.  Otherwise we need to disable all breakpoints, step
@@ -2024,7 +2024,7 @@ proceed (CORE_ADDR addr, enum target_signal siggnal, int step)
   /* We can insert breakpoints if we're not trying to step over one,
      or if we are stepping over one but we're using displaced stepping
      to do so.  */
-  if (! tp->trap_expected || use_displaced_stepping (gdbarch))
+  if (! tp->control.trap_expected || use_displaced_stepping (gdbarch))
     insert_breakpoints ();
 
   if (!non_stop)
@@ -2046,18 +2046,18 @@ proceed (CORE_ADDR addr, enum target_signal siggnal, int step)
 	  last_thread = find_thread_ptid (last_ptid);
 	  if (last_thread)
 	    {
-	      tp->stop_signal = last_thread->stop_signal;
-	      last_thread->stop_signal = TARGET_SIGNAL_0;
+	      tp->suspend.stop_signal = last_thread->suspend.stop_signal;
+	      last_thread->suspend.stop_signal = TARGET_SIGNAL_0;
 	    }
 	}
     }
 
   if (siggnal != TARGET_SIGNAL_DEFAULT)
-    tp->stop_signal = siggnal;
+    tp->suspend.stop_signal = siggnal;
   /* If this signal should not be seen by program,
      give it zero.  Used for debugging signals.  */
-  else if (!signal_program[tp->stop_signal])
-    tp->stop_signal = TARGET_SIGNAL_0;
+  else if (!signal_program[tp->suspend.stop_signal])
+    tp->suspend.stop_signal = TARGET_SIGNAL_0;
 
   annotate_starting ();
 
@@ -2097,7 +2097,7 @@ proceed (CORE_ADDR addr, enum target_signal siggnal, int step)
   init_infwait_state ();
 
   /* Resume inferior.  */
-  resume (oneproc || step || bpstat_should_step (), tp->stop_signal);
+  resume (oneproc || step || bpstat_should_step (), tp->suspend.stop_signal);
 
   /* Wait for it to stop (if not standalone)
      and in any case decode why it stopped, and act accordingly.  */
@@ -2120,7 +2120,7 @@ start_remote (int from_tty)
 
   init_wait_for_inferior ();
   inferior = current_inferior ();
-  inferior->stop_soon = STOP_QUIETLY_REMOTE;
+  inferior->control.stop_soon = STOP_QUIETLY_REMOTE;
 
   /* Always go on waiting for the target, regardless of the mode. */
   /* FIXME: cagney/1999-09-23: At present it isn't possible to
@@ -2661,14 +2661,14 @@ fetch_inferior_event (void *client_data)
       delete_step_thread_step_resume_breakpoint ();
 
       /* We may not find an inferior if this was a process exit.  */
-      if (inf == NULL || inf->stop_soon == NO_STOP_QUIETLY)
+      if (inf == NULL || inf->control.stop_soon == NO_STOP_QUIETLY)
 	normal_stop ();
 
       if (target_has_execution
 	  && ecs->ws.kind != TARGET_WAITKIND_EXITED
 	  && ecs->ws.kind != TARGET_WAITKIND_SIGNALLED
 	  && ecs->event_thread->step_multi
-	  && ecs->event_thread->stop_step)
+	  && ecs->event_thread->control.stop_step)
 	inferior_event_handler (INF_EXEC_CONTINUE, NULL);
       else
 	inferior_event_handler (INF_EXEC_COMPLETE, NULL);
@@ -2692,8 +2692,8 @@ set_step_info (struct frame_info *frame, struct symtab_and_line sal)
 {
   struct thread_info *tp = inferior_thread ();
 
-  tp->step_frame_id = get_frame_id (frame);
-  tp->step_stack_frame_id = get_stack_frame_id (frame);
+  tp->control.step_frame_id = get_frame_id (frame);
+  tp->control.step_stack_frame_id = get_stack_frame_id (frame);
 
   tp->current_symtab = sal.symtab;
   tp->current_line = sal.line;
@@ -2933,21 +2933,22 @@ handle_syscall_event (struct execution_control_state *ecs)
         fprintf_unfiltered (gdb_stdlog, "infrun: syscall number = '%d'\n",
                             syscall_number);
 
-      ecs->event_thread->stop_bpstat
+      ecs->event_thread->control.stop_bpstat
 	= bpstat_stop_status (get_regcache_aspace (regcache),
 			      stop_pc, ecs->ptid);
-      ecs->random_signal = !bpstat_explains_signal (ecs->event_thread->stop_bpstat);
+      ecs->random_signal
+	= !bpstat_explains_signal (ecs->event_thread->control.stop_bpstat);
 
       if (!ecs->random_signal)
 	{
 	  /* Catchpoint hit.  */
-	  ecs->event_thread->stop_signal = TARGET_SIGNAL_TRAP;
+	  ecs->event_thread->suspend.stop_signal = TARGET_SIGNAL_TRAP;
 	  return 0;
 	}
     }
 
   /* If no catchpoint triggered for this, then keep going.  */
-  ecs->event_thread->stop_signal = TARGET_SIGNAL_0;
+  ecs->event_thread->suspend.stop_signal = TARGET_SIGNAL_0;
   keep_going (ecs);
   return 1;
 }
@@ -2990,7 +2991,7 @@ handle_inferior_event (struct execution_control_state *ecs)
       struct inferior *inf = find_inferior_pid (ptid_get_pid (ecs->ptid));
 
       gdb_assert (inf);
-      stop_soon = inf->stop_soon;
+      stop_soon = inf->control.stop_soon;
     }
   else
     stop_soon = NO_STOP_QUIETLY;
@@ -3267,7 +3268,7 @@ handle_inferior_event (struct execution_control_state *ecs)
 
       stop_pc = regcache_read_pc (get_thread_regcache (ecs->ptid));
 
-      ecs->event_thread->stop_bpstat
+      ecs->event_thread->control.stop_bpstat
 	= bpstat_stop_status (get_regcache_aspace (get_current_regcache ()),
 			      stop_pc, ecs->ptid);
 
@@ -3275,7 +3276,8 @@ handle_inferior_event (struct execution_control_state *ecs)
 	 causes a stop, not just if it may explain the signal.
 	 Software watchpoints, for example, always appear in the
 	 bpstat.  */
-      ecs->random_signal = !bpstat_causes_stop (ecs->event_thread->stop_bpstat);
+      ecs->random_signal
+	= !bpstat_causes_stop (ecs->event_thread->control.stop_bpstat);
 
       /* If no catchpoint triggered for this, then keep going.  */
       if (ecs->random_signal)
@@ -3285,7 +3287,7 @@ handle_inferior_event (struct execution_control_state *ecs)
 	  int should_resume;
 	  int follow_child = (follow_fork_mode_string == follow_fork_mode_child);
 
-	  ecs->event_thread->stop_signal = TARGET_SIGNAL_0;
+	  ecs->event_thread->suspend.stop_signal = TARGET_SIGNAL_0;
 
 	  should_resume = follow_fork ();
 
@@ -3319,7 +3321,7 @@ handle_inferior_event (struct execution_control_state *ecs)
 	    stop_stepping (ecs);
 	  return;
 	}
-      ecs->event_thread->stop_signal = TARGET_SIGNAL_TRAP;
+      ecs->event_thread->suspend.stop_signal = TARGET_SIGNAL_TRAP;
       goto process_event_stop_test;
 
     case TARGET_WAITKIND_VFORK_DONE:
@@ -3362,10 +3364,11 @@ handle_inferior_event (struct execution_control_state *ecs)
          stop.  */
       follow_exec (inferior_ptid, ecs->ws.value.execd_pathname);
 
-      ecs->event_thread->stop_bpstat
+      ecs->event_thread->control.stop_bpstat
 	= bpstat_stop_status (get_regcache_aspace (get_current_regcache ()),
 			      stop_pc, ecs->ptid);
-      ecs->random_signal = !bpstat_explains_signal (ecs->event_thread->stop_bpstat);
+      ecs->random_signal
+	= !bpstat_explains_signal (ecs->event_thread->control.stop_bpstat);
 
       /* Note that this may be referenced from inside
 	 bpstat_stop_status above, through inferior_has_execd.  */
@@ -3375,11 +3378,11 @@ handle_inferior_event (struct execution_control_state *ecs)
       /* If no catchpoint triggered for this, then keep going.  */
       if (ecs->random_signal)
 	{
-	  ecs->event_thread->stop_signal = TARGET_SIGNAL_0;
+	  ecs->event_thread->suspend.stop_signal = TARGET_SIGNAL_0;
 	  keep_going (ecs);
 	  return;
 	}
-      ecs->event_thread->stop_signal = TARGET_SIGNAL_TRAP;
+      ecs->event_thread->suspend.stop_signal = TARGET_SIGNAL_TRAP;
       goto process_event_stop_test;
 
       /* Be careful not to try to gather much state about a thread
@@ -3407,7 +3410,7 @@ handle_inferior_event (struct execution_control_state *ecs)
     case TARGET_WAITKIND_STOPPED:
       if (debug_infrun)
         fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_STOPPED\n");
-      ecs->event_thread->stop_signal = ecs->ws.value.sig;
+      ecs->event_thread->suspend.stop_signal = ecs->ws.value.sig;
       break;
 
     case TARGET_WAITKIND_NO_HISTORY:
@@ -3446,15 +3449,16 @@ targets should add new threads to the thread list themselves in non-stop mode.")
       /* Do we need to clean up the state of a thread that has
 	 completed a displaced single-step?  (Doing so usually affects
 	 the PC, so do it here, before we set stop_pc.)  */
-      displaced_step_fixup (ecs->ptid, ecs->event_thread->stop_signal);
+      displaced_step_fixup (ecs->ptid,
+			    ecs->event_thread->suspend.stop_signal);
 
       /* If we either finished a single-step or hit a breakpoint, but
 	 the user wanted this thread to be stopped, pretend we got a
 	 SIG0 (generic unsignaled stop).  */
 
       if (ecs->event_thread->stop_requested
-	  && ecs->event_thread->stop_signal == TARGET_SIGNAL_TRAP)
-	ecs->event_thread->stop_signal = TARGET_SIGNAL_0;
+	  && ecs->event_thread->suspend.stop_signal == TARGET_SIGNAL_TRAP)
+	ecs->event_thread->suspend.stop_signal = TARGET_SIGNAL_0;
     }
 
   stop_pc = regcache_read_pc (get_thread_regcache (ecs->ptid));
@@ -3498,7 +3502,7 @@ targets should add new threads to the thread list themselves in non-stop mode.")
       /* We've either finished single-stepping past the single-step
          breakpoint, or stopped for some other reason.  It would be nice if
          we could tell, but we can't reliably.  */
-      if (ecs->event_thread->stop_signal == TARGET_SIGNAL_TRAP)
+      if (ecs->event_thread->suspend.stop_signal == TARGET_SIGNAL_TRAP)
 	{
 	  if (debug_infrun)
 	    fprintf_unfiltered (gdb_stdlog, "infrun: stepping_past_singlestep_breakpoint\n");
@@ -3507,7 +3511,7 @@ targets should add new threads to the thread list themselves in non-stop mode.")
 	  singlestep_breakpoints_inserted_p = 0;
 
 	  ecs->random_signal = 0;
-	  ecs->event_thread->trap_expected = 0;
+	  ecs->event_thread->control.trap_expected = 0;
 
 	  context_switch (saved_singlestep_ptid);
 	  if (deprecated_context_hook)
@@ -3526,7 +3530,7 @@ targets should add new threads to the thread list themselves in non-stop mode.")
 
       /* If we stopped for some other reason than single-stepping, ignore
 	 the fact that we were supposed to switch back.  */
-      if (ecs->event_thread->stop_signal == TARGET_SIGNAL_TRAP)
+      if (ecs->event_thread->suspend.stop_signal == TARGET_SIGNAL_TRAP)
 	{
 	  if (debug_infrun)
 	    fprintf_unfiltered (gdb_stdlog,
@@ -3558,7 +3562,7 @@ targets should add new threads to the thread list themselves in non-stop mode.")
      another thread.  If so, then step that thread past the breakpoint,
      and continue it.  */
 
-  if (ecs->event_thread->stop_signal == TARGET_SIGNAL_TRAP)
+  if (ecs->event_thread->suspend.stop_signal == TARGET_SIGNAL_TRAP)
     {
       int thread_hop_needed = 0;
       struct address_space *aspace = 
@@ -3624,11 +3628,11 @@ targets should add new threads to the thread list themselves in non-stop mode.")
 		    singlestep_ptid.  Don't swap here, since that's
 		    the context we want to use.  Just fudge our
 		    state and continue.  */
-                 stop_signal = ecs->event_thread->stop_signal;
-                 ecs->event_thread->stop_signal = TARGET_SIGNAL_0;
+                 stop_signal = ecs->event_thread->suspend.stop_signal;
+                 ecs->event_thread->suspend.stop_signal = TARGET_SIGNAL_0;
                  ecs->ptid = singlestep_ptid;
                  ecs->event_thread = find_thread_ptid (ecs->ptid);
-                 ecs->event_thread->stop_signal = stop_signal;
+                 ecs->event_thread->suspend.stop_signal = stop_signal;
                  stop_pc = new_singlestep_pc;
                }
              else
@@ -3787,8 +3791,8 @@ targets should add new threads to the thread list themselves in non-stop mode.")
   ecs->stop_func_start
     += gdbarch_deprecated_function_start_offset (gdbarch);
   ecs->event_thread->stepping_over_breakpoint = 0;
-  bpstat_clear (&ecs->event_thread->stop_bpstat);
-  ecs->event_thread->stop_step = 0;
+  bpstat_clear (&ecs->event_thread->control.stop_bpstat);
+  ecs->event_thread->control.stop_step = 0;
   stop_print_frame = 1;
   ecs->random_signal = 0;
   stopped_by_random_signal = 0;
@@ -3796,11 +3800,11 @@ targets should add new threads to the thread list themselves in non-stop mode.")
   /* Hide inlined functions starting here, unless we just performed stepi or
      nexti.  After stepi and nexti, always show the innermost frame (not any
      inline function call sites).  */
-  if (ecs->event_thread->step_range_end != 1)
+  if (ecs->event_thread->control.step_range_end != 1)
     skip_inline_frames (ecs->ptid);
 
-  if (ecs->event_thread->stop_signal == TARGET_SIGNAL_TRAP
-      && ecs->event_thread->trap_expected
+  if (ecs->event_thread->suspend.stop_signal == TARGET_SIGNAL_TRAP
+      && ecs->event_thread->control.trap_expected
       && gdbarch_single_step_through_delay_p (gdbarch)
       && currently_stepping (ecs->event_thread))
     {
@@ -3814,7 +3818,8 @@ targets should add new threads to the thread list themselves in non-stop mode.")
 
       if (debug_infrun && step_through_delay)
 	fprintf_unfiltered (gdb_stdlog, "infrun: step through delay\n");
-      if (ecs->event_thread->step_range_end == 0 && step_through_delay)
+      if (ecs->event_thread->control.step_range_end == 0
+	  && step_through_delay)
 	{
 	  /* The user issued a continue when stopped at a breakpoint.
 	     Set up for another trap and get out of here.  */
@@ -3842,11 +3847,12 @@ targets should add new threads to the thread list themselves in non-stop mode.")
      3) set ecs->random_signal to 1, and the decision between 1 and 2
      will be made according to the signal handling tables.  */
 
-  if (ecs->event_thread->stop_signal == TARGET_SIGNAL_TRAP
+  if (ecs->event_thread->suspend.stop_signal == TARGET_SIGNAL_TRAP
       || stop_soon == STOP_QUIETLY || stop_soon == STOP_QUIETLY_NO_SIGSTOP
       || stop_soon == STOP_QUIETLY_REMOTE)
     {
-      if (ecs->event_thread->stop_signal == TARGET_SIGNAL_TRAP && stop_after_trap)
+      if (ecs->event_thread->suspend.stop_signal == TARGET_SIGNAL_TRAP
+	  && stop_after_trap)
 	{
           if (debug_infrun)
 	    fprintf_unfiltered (gdb_stdlog, "infrun: stopped\n");
@@ -3886,17 +3892,17 @@ targets should add new threads to the thread list themselves in non-stop mode.")
 	 TARGET_SIGNAL_0, meaning: stopped for no particular reason
 	 other than GDB's request.  */
       if (stop_soon == STOP_QUIETLY_NO_SIGSTOP
-	  && (ecs->event_thread->stop_signal == TARGET_SIGNAL_STOP
-	      || ecs->event_thread->stop_signal == TARGET_SIGNAL_TRAP
-	      || ecs->event_thread->stop_signal == TARGET_SIGNAL_0))
+	  && (ecs->event_thread->suspend.stop_signal == TARGET_SIGNAL_STOP
+	      || ecs->event_thread->suspend.stop_signal == TARGET_SIGNAL_TRAP
+	      || ecs->event_thread->suspend.stop_signal == TARGET_SIGNAL_0))
 	{
 	  stop_stepping (ecs);
-	  ecs->event_thread->stop_signal = TARGET_SIGNAL_0;
+	  ecs->event_thread->suspend.stop_signal = TARGET_SIGNAL_0;
 	  return;
 	}
 
       /* See if there is a breakpoint at the current PC.  */
-      ecs->event_thread->stop_bpstat
+      ecs->event_thread->control.stop_bpstat
 	= bpstat_stop_status (get_regcache_aspace (get_current_regcache ()),
 			      stop_pc, ecs->ptid);
 
@@ -3913,8 +3919,8 @@ targets should add new threads to the thread list themselves in non-stop mode.")
 	 set.  */
 
       if (debug_infrun
-	  && ecs->event_thread->stop_signal == TARGET_SIGNAL_TRAP
-	  && !bpstat_explains_signal (ecs->event_thread->stop_bpstat)
+	  && ecs->event_thread->suspend.stop_signal == TARGET_SIGNAL_TRAP
+	  && !bpstat_explains_signal (ecs->event_thread->control.stop_bpstat)
 	  && stopped_by_watchpoint)
 	fprintf_unfiltered (gdb_stdlog, "\
 infrun: no user watchpoint explains watchpoint SIGTRAP, ignoring\n");
@@ -3939,18 +3945,19 @@ infrun: no user watchpoint explains watchpoint SIGTRAP, ignoring\n");
          be necessary for call dummies on a non-executable stack on
          SPARC.  */
 
-      if (ecs->event_thread->stop_signal == TARGET_SIGNAL_TRAP)
+      if (ecs->event_thread->suspend.stop_signal == TARGET_SIGNAL_TRAP)
 	ecs->random_signal
-	  = !(bpstat_explains_signal (ecs->event_thread->stop_bpstat)
+	  = !(bpstat_explains_signal (ecs->event_thread->control.stop_bpstat)
 	      || stopped_by_watchpoint
-	      || ecs->event_thread->trap_expected
-	      || (ecs->event_thread->step_range_end
+	      || ecs->event_thread->control.trap_expected
+	      || (ecs->event_thread->control.step_range_end
 		  && ecs->event_thread->step_resume_breakpoint == NULL));
       else
 	{
-	  ecs->random_signal = !bpstat_explains_signal (ecs->event_thread->stop_bpstat);
+	  ecs->random_signal = !bpstat_explains_signal
+				     (ecs->event_thread->control.stop_bpstat);
 	  if (!ecs->random_signal)
-	    ecs->event_thread->stop_signal = TARGET_SIGNAL_TRAP;
+	    ecs->event_thread->suspend.stop_signal = TARGET_SIGNAL_TRAP;
 	}
     }
 
@@ -3979,15 +3986,16 @@ process_event_stop_test:
 
       if (debug_infrun)
 	 fprintf_unfiltered (gdb_stdlog, "infrun: random signal %d\n",
-			     ecs->event_thread->stop_signal);
+			     ecs->event_thread->suspend.stop_signal);
 
       stopped_by_random_signal = 1;
 
-      if (signal_print[ecs->event_thread->stop_signal])
+      if (signal_print[ecs->event_thread->suspend.stop_signal])
 	{
 	  printed = 1;
 	  target_terminal_ours_for_output ();
-	  print_signal_received_reason (ecs->event_thread->stop_signal);
+	  print_signal_received_reason
+				     (ecs->event_thread->suspend.stop_signal);
 	}
       /* Always stop on signals if we're either just gaining control
 	 of the program, or the user explicitly requested this thread
@@ -3995,7 +4003,7 @@ process_event_stop_test:
       if (stop_soon != NO_STOP_QUIETLY
 	  || ecs->event_thread->stop_requested
 	  || (!inf->detaching
-	      && signal_stop_state (ecs->event_thread->stop_signal)))
+	      && signal_stop_state (ecs->event_thread->suspend.stop_signal)))
 	{
 	  stop_stepping (ecs);
 	  return;
@@ -4006,11 +4014,11 @@ process_event_stop_test:
 	target_terminal_inferior ();
 
       /* Clear the signal if it should not be passed.  */
-      if (signal_program[ecs->event_thread->stop_signal] == 0)
-	ecs->event_thread->stop_signal = TARGET_SIGNAL_0;
+      if (signal_program[ecs->event_thread->suspend.stop_signal] == 0)
+	ecs->event_thread->suspend.stop_signal = TARGET_SIGNAL_0;
 
       if (ecs->event_thread->prev_pc == stop_pc
-	  && ecs->event_thread->trap_expected
+	  && ecs->event_thread->control.trap_expected
 	  && ecs->event_thread->step_resume_breakpoint == NULL)
 	{
 	  /* We were just starting a new sequence, attempting to
@@ -4034,12 +4042,12 @@ process_event_stop_test:
 	  return;
 	}
 
-      if (ecs->event_thread->step_range_end != 0
-	  && ecs->event_thread->stop_signal != TARGET_SIGNAL_0
-	  && (ecs->event_thread->step_range_start <= stop_pc
-	      && stop_pc < ecs->event_thread->step_range_end)
+      if (ecs->event_thread->control.step_range_end != 0
+	  && ecs->event_thread->suspend.stop_signal != TARGET_SIGNAL_0
+	  && (ecs->event_thread->control.step_range_start <= stop_pc
+	      && stop_pc < ecs->event_thread->control.step_range_end)
 	  && frame_id_eq (get_stack_frame_id (frame),
-			  ecs->event_thread->step_stack_frame_id)
+			  ecs->event_thread->control.step_stack_frame_id)
 	  && ecs->event_thread->step_resume_breakpoint == NULL)
 	{
 	  /* The inferior is about to take a signal that will take it
@@ -4076,7 +4084,7 @@ process_event_stop_test:
     CORE_ADDR jmp_buf_pc;
     struct bpstat_what what;
 
-    what = bpstat_what (ecs->event_thread->stop_bpstat);
+    what = bpstat_what (ecs->event_thread->control.stop_bpstat);
 
     if (what.call_dummy)
       {
@@ -4130,7 +4138,7 @@ infrun: BPSTAT_WHAT_SET_LONGJMP_RESUME (!gdbarch_get_longjmp_target)\n");
 	gdb_assert (ecs->event_thread->step_resume_breakpoint != NULL);
 	delete_step_resume_breakpoint (ecs->event_thread);
 
-	ecs->event_thread->stop_step = 1;
+	ecs->event_thread->control.stop_step = 1;
 	print_end_stepping_range_reason ();
 	stop_stepping (ecs);
 	return;
@@ -4217,8 +4225,8 @@ infrun: BPSTAT_WHAT_SET_LONGJMP_RESUME (!gdbarch_get_longjmp_target)\n");
 	  /* However, if the current thread is blocked on some internal
 	     breakpoint, and we simply need to step over that breakpoint
 	     to get it going again, do that first.  */
-	  if ((ecs->event_thread->trap_expected
-	       && ecs->event_thread->stop_signal != TARGET_SIGNAL_TRAP)
+	  if ((ecs->event_thread->control.trap_expected
+	       && ecs->event_thread->suspend.stop_signal != TARGET_SIGNAL_TRAP)
 	      || ecs->event_thread->stepping_over_breakpoint)
 	    {
 	      keep_going (ecs);
@@ -4259,7 +4267,7 @@ infrun: not switching back to stepped thread, it has vanished\n");
 	  /* Otherwise, we no longer expect a trap in the current thread.
 	     Clear the trap_expected flag before switching back -- this is
 	     what keep_going would do as well, if we called it.  */
-	  ecs->event_thread->trap_expected = 0;
+	  ecs->event_thread->control.trap_expected = 0;
 
 	  if (debug_infrun)
 	    fprintf_unfiltered (gdb_stdlog,
@@ -4294,8 +4302,8 @@ infrun: not switching back to stepped thread, it has vanished\n");
       /* Else, stop and report the catchpoint(s) whose triggering
          caused us to begin stepping. */
       ecs->event_thread->stepping_through_solib_after_catch = 0;
-      bpstat_clear (&ecs->event_thread->stop_bpstat);
-      ecs->event_thread->stop_bpstat
+      bpstat_clear (&ecs->event_thread->control.stop_bpstat);
+      ecs->event_thread->control.stop_bpstat
 	= bpstat_copy (ecs->event_thread->stepping_through_solib_catchpoints);
       bpstat_clear (&ecs->event_thread->stepping_through_solib_catchpoints);
       stop_print_frame = 1;
@@ -4316,7 +4324,7 @@ infrun: not switching back to stepped thread, it has vanished\n");
       return;
     }
 
-  if (ecs->event_thread->step_range_end == 0)
+  if (ecs->event_thread->control.step_range_end == 0)
     {
       if (debug_infrun)
 	 fprintf_unfiltered (gdb_stdlog, "infrun: no stepping, continue\n");
@@ -4341,26 +4349,26 @@ infrun: not switching back to stepped thread, it has vanished\n");
      through a function epilogue and therefore must detect when
      the current-frame changes in the middle of a line.  */
 
-  if (stop_pc >= ecs->event_thread->step_range_start
-      && stop_pc < ecs->event_thread->step_range_end
+  if (stop_pc >= ecs->event_thread->control.step_range_start
+      && stop_pc < ecs->event_thread->control.step_range_end
       && (execution_direction != EXEC_REVERSE
 	  || frame_id_eq (get_frame_id (frame),
-			  ecs->event_thread->step_frame_id)))
+			  ecs->event_thread->control.step_frame_id)))
     {
       if (debug_infrun)
 	fprintf_unfiltered
 	  (gdb_stdlog, "infrun: stepping inside range [%s-%s]\n",
-	   paddress (gdbarch, ecs->event_thread->step_range_start),
-	   paddress (gdbarch, ecs->event_thread->step_range_end));
+	   paddress (gdbarch, ecs->event_thread->control.step_range_start),
+	   paddress (gdbarch, ecs->event_thread->control.step_range_end));
 
       /* When stepping backward, stop at beginning of line range
 	 (unless it's the function entry point, in which case
 	 keep going back to the call point).  */
-      if (stop_pc == ecs->event_thread->step_range_start
+      if (stop_pc == ecs->event_thread->control.step_range_start
 	  && stop_pc != ecs->stop_func_start
 	  && execution_direction == EXEC_REVERSE)
 	{
-	  ecs->event_thread->stop_step = 1;
+	  ecs->event_thread->control.stop_step = 1;
 	  print_end_stepping_range_reason ();
 	  stop_stepping (ecs);
 	}
@@ -4385,7 +4393,7 @@ infrun: not switching back to stepped thread, it has vanished\n");
      down, so there is nothing for us to do here.  */
 
   if (execution_direction != EXEC_REVERSE
-      && ecs->event_thread->step_over_calls == STEP_OVER_UNDEBUGGABLE
+      && ecs->event_thread->control.step_over_calls == STEP_OVER_UNDEBUGGABLE
       && in_solib_dynsym_resolve_code (stop_pc))
     {
       CORE_ADDR pc_after_resolver =
@@ -4412,9 +4420,9 @@ infrun: not switching back to stepped thread, it has vanished\n");
       return;
     }
 
-  if (ecs->event_thread->step_range_end != 1
-      && (ecs->event_thread->step_over_calls == STEP_OVER_UNDEBUGGABLE
-	  || ecs->event_thread->step_over_calls == STEP_OVER_ALL)
+  if (ecs->event_thread->control.step_range_end != 1
+      && (ecs->event_thread->control.step_over_calls == STEP_OVER_UNDEBUGGABLE
+	  || ecs->event_thread->control.step_over_calls == STEP_OVER_ALL)
       && get_frame_type (frame) == SIGTRAMP_FRAME)
     {
       if (debug_infrun)
@@ -4446,10 +4454,10 @@ infrun: not switching back to stepped thread, it has vanished\n");
      have code_addr == &_start.  See the comment in frame_id_eq
      for more.  */
   if (!frame_id_eq (get_stack_frame_id (frame),
-		    ecs->event_thread->step_stack_frame_id)
+		    ecs->event_thread->control.step_stack_frame_id)
       && (frame_id_eq (frame_unwind_caller_id (get_current_frame ()),
-		       ecs->event_thread->step_stack_frame_id)
-	  && (!frame_id_eq (ecs->event_thread->step_stack_frame_id,
+		       ecs->event_thread->control.step_stack_frame_id)
+	  && (!frame_id_eq (ecs->event_thread->control.step_stack_frame_id,
 			    outer_frame_id)
 	      || step_start_function != find_pc_function (stop_pc))))
     {
@@ -4458,8 +4466,8 @@ infrun: not switching back to stepped thread, it has vanished\n");
       if (debug_infrun)
 	 fprintf_unfiltered (gdb_stdlog, "infrun: stepped into subroutine\n");
 
-      if ((ecs->event_thread->step_over_calls == STEP_OVER_NONE)
-	  || ((ecs->event_thread->step_range_end == 1)
+      if ((ecs->event_thread->control.step_over_calls == STEP_OVER_NONE)
+	  || ((ecs->event_thread->control.step_range_end == 1)
 	      && in_prologue (gdbarch, ecs->event_thread->prev_pc,
 			      ecs->stop_func_start)))
 	{
@@ -4470,7 +4478,7 @@ infrun: not switching back to stepped thread, it has vanished\n");
 	     thought it was a subroutine call but it was not.  Stop as
 	     well.  FENN */
 	  /* And this works the same backward as frontward.  MVS */
-	  ecs->event_thread->stop_step = 1;
+	  ecs->event_thread->control.stop_step = 1;
 	  print_end_stepping_range_reason ();
 	  stop_stepping (ecs);
 	  return;
@@ -4479,7 +4487,7 @@ infrun: not switching back to stepped thread, it has vanished\n");
       /* Reverse stepping through solib trampolines.  */
 
       if (execution_direction == EXEC_REVERSE
-	  && ecs->event_thread->step_over_calls != STEP_OVER_NONE
+	  && ecs->event_thread->control.step_over_calls != STEP_OVER_NONE
 	  && (gdbarch_skip_trampoline_code (gdbarch, frame, stop_pc)
 	      || (ecs->stop_func_start == 0
 		  && in_solib_dynsym_resolve_code (stop_pc))))
@@ -4493,7 +4501,7 @@ infrun: not switching back to stepped thread, it has vanished\n");
 	  return;
 	}
 
-      if (ecs->event_thread->step_over_calls == STEP_OVER_ALL)
+      if (ecs->event_thread->control.step_over_calls == STEP_OVER_ALL)
 	{
 	  /* We're doing a "next".
 
@@ -4573,10 +4581,10 @@ infrun: not switching back to stepped thread, it has vanished\n");
       /* If we have no line number and the step-stop-if-no-debug is
          set, we stop the step so that the user has a chance to switch
          in assembly mode.  */
-      if (ecs->event_thread->step_over_calls == STEP_OVER_UNDEBUGGABLE
+      if (ecs->event_thread->control.step_over_calls == STEP_OVER_UNDEBUGGABLE
 	  && step_stop_if_no_debug)
 	{
-	  ecs->event_thread->stop_step = 1;
+	  ecs->event_thread->control.stop_step = 1;
 	  print_end_stepping_range_reason ();
 	  stop_stepping (ecs);
 	  return;
@@ -4606,7 +4614,7 @@ infrun: not switching back to stepped thread, it has vanished\n");
   /* Reverse stepping through solib trampolines.  */
 
   if (execution_direction == EXEC_REVERSE
-      && ecs->event_thread->step_over_calls != STEP_OVER_NONE)
+      && ecs->event_thread->control.step_over_calls != STEP_OVER_NONE)
     {
       if (gdbarch_skip_trampoline_code (gdbarch, frame, stop_pc)
 	  || (ecs->stop_func_start == 0
@@ -4679,7 +4687,7 @@ infrun: not switching back to stepped thread, it has vanished\n");
   /* NOTE: tausq/2004-05-24: This if block used to be done before all
      the trampoline processing logic, however, there are some trampolines 
      that have no names, so we should do trampoline handling first.  */
-  if (ecs->event_thread->step_over_calls == STEP_OVER_UNDEBUGGABLE
+  if (ecs->event_thread->control.step_over_calls == STEP_OVER_UNDEBUGGABLE
       && ecs->stop_func_name == NULL
       && stop_pc_sal.line == 0)
     {
@@ -4700,7 +4708,7 @@ infrun: not switching back to stepped thread, it has vanished\n");
 	  /* If we have no line number and the step-stop-if-no-debug
 	     is set, we stop the step so that the user has a chance to
 	     switch in assembly mode.  */
-	  ecs->event_thread->stop_step = 1;
+	  ecs->event_thread->control.stop_step = 1;
 	  print_end_stepping_range_reason ();
 	  stop_stepping (ecs);
 	  return;
@@ -4715,13 +4723,13 @@ infrun: not switching back to stepped thread, it has vanished\n");
 	}
     }
 
-  if (ecs->event_thread->step_range_end == 1)
+  if (ecs->event_thread->control.step_range_end == 1)
     {
       /* It is stepi or nexti.  We always want to stop stepping after
          one instruction.  */
       if (debug_infrun)
 	 fprintf_unfiltered (gdb_stdlog, "infrun: stepi/nexti\n");
-      ecs->event_thread->stop_step = 1;
+      ecs->event_thread->control.stop_step = 1;
       print_end_stepping_range_reason ();
       stop_stepping (ecs);
       return;
@@ -4735,7 +4743,7 @@ infrun: not switching back to stepped thread, it has vanished\n");
          or can this happen as a result of a return or longjmp?).  */
       if (debug_infrun)
 	 fprintf_unfiltered (gdb_stdlog, "infrun: no line number info\n");
-      ecs->event_thread->stop_step = 1;
+      ecs->event_thread->control.stop_step = 1;
       print_end_stepping_range_reason ();
       stop_stepping (ecs);
       return;
@@ -4746,7 +4754,7 @@ infrun: not switching back to stepped thread, it has vanished\n");
      a new inline function.  */
 
   if (frame_id_eq (get_frame_id (get_current_frame ()),
-		   ecs->event_thread->step_frame_id)
+		   ecs->event_thread->control.step_frame_id)
       && inline_skipped_frames (ecs->ptid))
     {
       struct symtab_and_line call_sal;
@@ -4757,7 +4765,7 @@ infrun: not switching back to stepped thread, it has vanished\n");
 
       find_frame_sal (get_current_frame (), &call_sal);
 
-      if (ecs->event_thread->step_over_calls != STEP_OVER_ALL)
+      if (ecs->event_thread->control.step_over_calls != STEP_OVER_ALL)
 	{
 	  /* For "step", we're going to stop.  But if the call site
 	     for this inlined function is on the same source line as
@@ -4768,7 +4776,7 @@ infrun: not switching back to stepped thread, it has vanished\n");
 	      && call_sal.symtab == ecs->event_thread->current_symtab)
 	    step_into_inline_frame (ecs->ptid);
 
-	  ecs->event_thread->stop_step = 1;
+	  ecs->event_thread->control.stop_step = 1;
 	  print_end_stepping_range_reason ();
 	  stop_stepping (ecs);
 	  return;
@@ -4783,7 +4791,7 @@ infrun: not switching back to stepped thread, it has vanished\n");
 	    keep_going (ecs);
 	  else
 	    {
-	      ecs->event_thread->stop_step = 1;
+	      ecs->event_thread->control.stop_step = 1;
 	      print_end_stepping_range_reason ();
 	      stop_stepping (ecs);
 	    }
@@ -4798,19 +4806,19 @@ infrun: not switching back to stepped thread, it has vanished\n");
 
   if (get_frame_type (get_current_frame ()) == INLINE_FRAME
       && !frame_id_eq (get_frame_id (get_current_frame ()),
-		       ecs->event_thread->step_frame_id)
+		       ecs->event_thread->control.step_frame_id)
       && stepped_in_from (get_current_frame (),
-			  ecs->event_thread->step_frame_id))
+			  ecs->event_thread->control.step_frame_id))
     {
       if (debug_infrun)
 	fprintf_unfiltered (gdb_stdlog,
 			    "infrun: stepping through inlined function\n");
 
-      if (ecs->event_thread->step_over_calls == STEP_OVER_ALL)
+      if (ecs->event_thread->control.step_over_calls == STEP_OVER_ALL)
 	keep_going (ecs);
       else
 	{
-	  ecs->event_thread->stop_step = 1;
+	  ecs->event_thread->control.stop_step = 1;
 	  print_end_stepping_range_reason ();
 	  stop_stepping (ecs);
 	}
@@ -4827,7 +4835,7 @@ infrun: not switching back to stepped thread, it has vanished\n");
          better.  */
       if (debug_infrun)
 	 fprintf_unfiltered (gdb_stdlog, "infrun: stepped to a different line\n");
-      ecs->event_thread->stop_step = 1;
+      ecs->event_thread->control.stop_step = 1;
       print_end_stepping_range_reason ();
       stop_stepping (ecs);
       return;
@@ -4840,8 +4848,8 @@ infrun: not switching back to stepped thread, it has vanished\n");
      new line in mid-statement, we continue stepping.  This makes
      things like for(;;) statements work better.)  */
 
-  ecs->event_thread->step_range_start = stop_pc_sal.pc;
-  ecs->event_thread->step_range_end = stop_pc_sal.end;
+  ecs->event_thread->control.step_range_start = stop_pc_sal.pc;
+  ecs->event_thread->control.step_range_end = stop_pc_sal.end;
   set_step_info (frame, stop_pc_sal);
 
   if (debug_infrun)
@@ -4854,8 +4862,8 @@ infrun: not switching back to stepped thread, it has vanished\n");
 static int
 currently_stepping (struct thread_info *tp)
 {
-  return ((tp->step_range_end && tp->step_resume_breakpoint == NULL)
- 	  || tp->trap_expected
+  return ((tp->control.step_range_end && tp->step_resume_breakpoint == NULL)
+ 	  || tp->control.trap_expected
  	  || tp->stepping_through_solib_after_catch
  	  || bpstat_should_step ());
 }
@@ -4869,8 +4877,8 @@ currently_stepping_or_nexting_callback (struct thread_info *tp, void *data)
   if (tp == data)
     return 0;
 
-  return (tp->step_range_end
- 	  || tp->trap_expected
+  return (tp->control.step_range_end
+ 	  || tp->control.trap_expected
  	  || tp->stepping_through_solib_after_catch);
 }
 
@@ -4928,7 +4936,7 @@ handle_step_into_function (struct gdbarch *gdbarch,
   if (ecs->stop_func_start == stop_pc)
     {
       /* We are already there: stop now.  */
-      ecs->event_thread->stop_step = 1;
+      ecs->event_thread->control.stop_step = 1;
       print_end_stepping_range_reason ();
       stop_stepping (ecs);
       return;
@@ -4947,7 +4955,8 @@ handle_step_into_function (struct gdbarch *gdbarch,
       insert_step_resume_breakpoint_at_sal (gdbarch, sr_sal, null_frame_id);
 
       /* And make sure stepping stops right away then.  */
-      ecs->event_thread->step_range_end = ecs->event_thread->step_range_start;
+      ecs->event_thread->control.step_range_end
+        = ecs->event_thread->control.step_range_start;
     }
   keep_going (ecs);
 }
@@ -4974,7 +4983,7 @@ handle_step_into_function_backward (struct gdbarch *gdbarch,
   if (stop_func_sal.pc == stop_pc)
     {
       /* We're there already.  Just stop stepping now.  */
-      ecs->event_thread->stop_step = 1;
+      ecs->event_thread->control.stop_step = 1;
       print_end_stepping_range_reason ();
       stop_stepping (ecs);
     }
@@ -4983,8 +4992,8 @@ handle_step_into_function_backward (struct gdbarch *gdbarch,
       /* Else just reset the step range and keep going.
 	 No step-resume breakpoint, they don't work for
 	 epilogues, which can have multiple entry paths.  */
-      ecs->event_thread->step_range_start = stop_func_sal.pc;
-      ecs->event_thread->step_range_end = stop_func_sal.end;
+      ecs->event_thread->control.step_range_start = stop_func_sal.pc;
+      ecs->event_thread->control.step_range_end = stop_func_sal.end;
       keep_going (ecs);
     }
   return;
@@ -5124,8 +5133,8 @@ keep_going (struct execution_control_state *ecs)
   /* If we did not do break;, it means we should keep running the
      inferior and not return to debugger.  */
 
-  if (ecs->event_thread->trap_expected
-      && ecs->event_thread->stop_signal != TARGET_SIGNAL_TRAP)
+  if (ecs->event_thread->control.trap_expected
+      && ecs->event_thread->suspend.stop_signal != TARGET_SIGNAL_TRAP)
     {
       /* We took a signal (which we are supposed to pass through to
 	 the inferior, else we'd not get here) and we haven't yet
@@ -5133,7 +5142,7 @@ keep_going (struct execution_control_state *ecs)
 
       discard_cleanups (old_cleanups);
       resume (currently_stepping (ecs->event_thread),
-	      ecs->event_thread->stop_signal);
+	      ecs->event_thread->suspend.stop_signal);
     }
   else
     {
@@ -5178,7 +5187,8 @@ keep_going (struct execution_control_state *ecs)
 	    }
 	}
 
-      ecs->event_thread->trap_expected = ecs->event_thread->stepping_over_breakpoint;
+      ecs->event_thread->control.trap_expected
+	= ecs->event_thread->stepping_over_breakpoint;
 
       /* Do not deliver SIGNAL_TRAP (except when the user explicitly
          specifies that such a signal should be delivered to the
@@ -5192,13 +5202,13 @@ keep_going (struct execution_control_state *ecs)
          simulator; the simulator then delivers the hardware
          equivalent of a SIGNAL_TRAP to the program being debugged. */
 
-      if (ecs->event_thread->stop_signal == TARGET_SIGNAL_TRAP
-	  && !signal_program[ecs->event_thread->stop_signal])
-	ecs->event_thread->stop_signal = TARGET_SIGNAL_0;
+      if (ecs->event_thread->suspend.stop_signal == TARGET_SIGNAL_TRAP
+	  && !signal_program[ecs->event_thread->suspend.stop_signal])
+	ecs->event_thread->suspend.stop_signal = TARGET_SIGNAL_0;
 
       discard_cleanups (old_cleanups);
       resume (currently_stepping (ecs->event_thread),
-	      ecs->event_thread->stop_signal);
+	      ecs->event_thread->suspend.stop_signal);
     }
 
   prepare_to_wait (ecs);
@@ -5235,7 +5245,8 @@ prepare_to_wait (struct execution_control_state *ecs)
 static void
 print_end_stepping_range_reason (void)
 {
-  if ((!inferior_thread ()->step_multi || !inferior_thread ()->stop_step)
+  if ((!inferior_thread ()->step_multi
+       || !inferior_thread ()->control.stop_step)
       && ui_out_is_mi_like_p (uiout))
     ui_out_field_string (uiout, "reason",
                          async_reason_lookup (EXEC_ASYNC_END_STEPPING_RANGE));
@@ -5411,7 +5422,7 @@ Further execution is probably impossible.\n"));
       && last.kind != TARGET_WAITKIND_SIGNALLED
       && last.kind != TARGET_WAITKIND_EXITED
       && inferior_thread ()->step_multi
-      && inferior_thread ()->stop_step)
+      && inferior_thread ()->control.stop_step)
     goto done;
 
   target_terminal_ours ();
@@ -5463,7 +5474,7 @@ Further execution is probably impossible.\n"));
 	  int do_frame_printing = 1;
 	  struct thread_info *tp = inferior_thread ();
 
-	  bpstat_ret = bpstat_print (tp->stop_bpstat);
+	  bpstat_ret = bpstat_print (tp->control.stop_bpstat);
 	  switch (bpstat_ret)
 	    {
 	    case PRINT_UNKNOWN:
@@ -5482,8 +5493,8 @@ Further execution is probably impossible.\n"));
 	      /* FIXME: cagney/2002-12-01: Given that a frame ID does
 	         (or should) carry around the function and does (or
 	         should) use that when doing a frame comparison.  */
-	      if (tp->stop_step
-		  && frame_id_eq (tp->step_frame_id,
+	      if (tp->control.stop_step
+		  && frame_id_eq (tp->control.step_frame_id,
 				  get_frame_id (get_current_frame ()))
 		  && step_start_function == find_pc_function (stop_pc))
 		source_flag = SRC_LINE;	/* finished step, just print source line */
@@ -5519,7 +5530,7 @@ Further execution is probably impossible.\n"));
 
   /* Save the function value return registers, if we care.
      We might be about to restore their previous contents.  */
-  if (inferior_thread ()->proceed_to_finish)
+  if (inferior_thread ()->control.proceed_to_finish)
     {
       /* This should not be necessary.  */
       if (stop_registers)
@@ -5534,7 +5545,7 @@ Further execution is probably impossible.\n"));
     {
       /* Pop the empty frame that contains the stack dummy.
 	 This also restores inferior state prior to the call
-	 (struct inferior_thread_state).  */
+	 (struct infcall_suspend_state).  */
       struct frame_info *frame = get_current_frame ();
 
       gdb_assert (get_frame_type (frame) == DUMMY_FRAME);
@@ -5542,7 +5553,7 @@ Further execution is probably impossible.\n"));
       /* frame_pop() calls reinit_frame_cache as the last thing it does
 	 which means there's currently no selected frame.  We don't need
 	 to re-establish a selected frame if the dummy call returns normally,
-	 that will be done by restore_inferior_status.  However, we do have
+	 that will be done by restore_infcall_control_state.  However, we do have
 	 to handle the case where the dummy call is returning after being
 	 stopped (e.g. the dummy call previously hit a breakpoint).  We
 	 can't know which case we have so just always re-establish a
@@ -5569,12 +5580,12 @@ done:
       || last.kind == TARGET_WAITKIND_SIGNALLED
       || last.kind == TARGET_WAITKIND_EXITED
       || (!inferior_thread ()->step_multi
-	  && !(inferior_thread ()->stop_bpstat
-	       && inferior_thread ()->proceed_to_finish)
-	  && !inferior_thread ()->in_infcall))
+	  && !(inferior_thread ()->control.stop_bpstat
+	       && inferior_thread ()->control.proceed_to_finish)
+	  && !inferior_thread ()->control.in_infcall))
     {
       if (!ptid_equal (inferior_ptid, null_ptid))
-	observer_notify_normal_stop (inferior_thread ()->stop_bpstat,
+	observer_notify_normal_stop (inferior_thread ()->control.stop_bpstat,
 				     stop_print_frame);
       else
 	observer_notify_normal_stop (NULL, stop_print_frame);
@@ -5586,7 +5597,7 @@ done:
 	  && last.kind != TARGET_WAITKIND_EXITED)
 	/* Delete the breakpoint we stopped at, if it wants to be deleted.
 	   Delete any breakpoint that is to be deleted at the next stop.  */
-	breakpoint_auto_delete (inferior_thread ()->stop_bpstat);
+	breakpoint_auto_delete (inferior_thread ()->control.stop_bpstat);
     }
 
   /* Try to get rid of automatically added inferiors that are no
@@ -6033,17 +6044,18 @@ siginfo_make_value (struct gdbarch *gdbarch, struct internalvar *var)
 }
 
 
-/* Inferior thread state.
-   These are details related to the inferior itself, and don't include
-   things like what frame the user had selected or what gdb was doing
-   with the target at the time.
-   For inferior function calls these are things we want to restore
-   regardless of whether the function call successfully completes
-   or the dummy frame has to be manually popped.  */
+/* infcall_suspend_state contains state about the program itself like its
+   registers and any signal it received when it last stopped.
+   This state must be restored regardless of how the inferior function call
+   ends (either successfully, or after it hits a breakpoint or signal)
+   if the program is to properly continue where it left off.  */
 
-struct inferior_thread_state
+struct infcall_suspend_state
 {
-  enum target_signal stop_signal;
+  struct thread_suspend_state thread_suspend;
+  struct inferior_suspend_state inferior_suspend;
+
+  /* Other fields:  */
   CORE_ADDR stop_pc;
   struct regcache *registers;
 
@@ -6056,11 +6068,12 @@ struct inferior_thread_state
   gdb_byte *siginfo_data;
 };
 
-struct inferior_thread_state *
-save_inferior_thread_state (void)
+struct infcall_suspend_state *
+save_infcall_suspend_state (void)
 {
-  struct inferior_thread_state *inf_state;
+  struct infcall_suspend_state *inf_state;
   struct thread_info *tp = inferior_thread ();
+  struct inferior *inf = current_inferior ();
   struct regcache *regcache = get_current_regcache ();
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
   gdb_byte *siginfo_data = NULL;
@@ -6085,7 +6098,7 @@ save_inferior_thread_state (void)
 	}
     }
 
-  inf_state = XZALLOC (struct inferior_thread_state);
+  inf_state = XZALLOC (struct infcall_suspend_state);
 
   if (siginfo_data)
     {
@@ -6093,10 +6106,12 @@ save_inferior_thread_state (void)
       inf_state->siginfo_data = siginfo_data;
     }
 
-  inf_state->stop_signal = tp->stop_signal;
+  inf_state->thread_suspend = tp->suspend;
+  inf_state->inferior_suspend = inf->suspend;
+
   /* run_inferior_call will not use the signal due to its `proceed' call with
      TARGET_SIGNAL_0 anyway.  */
-  tp->stop_signal = TARGET_SIGNAL_0;
+  tp->suspend.stop_signal = TARGET_SIGNAL_0;
 
   inf_state->stop_pc = stop_pc;
 
@@ -6108,13 +6123,16 @@ save_inferior_thread_state (void)
 /* Restore inferior session state to INF_STATE.  */
 
 void
-restore_inferior_thread_state (struct inferior_thread_state *inf_state)
+restore_infcall_suspend_state (struct infcall_suspend_state *inf_state)
 {
   struct thread_info *tp = inferior_thread ();
+  struct inferior *inf = current_inferior ();
   struct regcache *regcache = get_current_regcache ();
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
 
-  tp->stop_signal = inf_state->stop_signal;
+  tp->suspend = inf_state->thread_suspend;
+  inf->suspend = inf_state->inferior_suspend;
+
   stop_pc = inf_state->stop_pc;
 
   if (inf_state->siginfo_gdbarch == gdbarch)
@@ -6133,23 +6151,24 @@ restore_inferior_thread_state (struct inferior_thread_state *inf_state)
     /* NB: The register write goes through to the target.  */
     regcache_cpy (regcache, inf_state->registers);
 
-  discard_inferior_thread_state (inf_state);
+  discard_infcall_suspend_state (inf_state);
 }
 
 static void
-do_restore_inferior_thread_state_cleanup (void *state)
+do_restore_infcall_suspend_state_cleanup (void *state)
 {
-  restore_inferior_thread_state (state);
+  restore_infcall_suspend_state (state);
 }
 
 struct cleanup *
-make_cleanup_restore_inferior_thread_state (struct inferior_thread_state *inf_state)
+make_cleanup_restore_infcall_suspend_state
+  (struct infcall_suspend_state *inf_state)
 {
-  return make_cleanup (do_restore_inferior_thread_state_cleanup, inf_state);
+  return make_cleanup (do_restore_infcall_suspend_state_cleanup, inf_state);
 }
 
 void
-discard_inferior_thread_state (struct inferior_thread_state *inf_state)
+discard_infcall_suspend_state (struct infcall_suspend_state *inf_state)
 {
   regcache_xfree (inf_state->registers);
   xfree (inf_state->siginfo_data);
@@ -6157,33 +6176,19 @@ discard_inferior_thread_state (struct inferior_thread_state *inf_state)
 }
 
 struct regcache *
-get_inferior_thread_state_regcache (struct inferior_thread_state *inf_state)
+get_infcall_suspend_state_regcache (struct infcall_suspend_state *inf_state)
 {
   return inf_state->registers;
 }
 
-/* Session related state for inferior function calls.
-   These are the additional bits of state that need to be restored
-   when an inferior function call successfully completes.
+/* infcall_control_state contains state regarding gdb's control of the
+   inferior itself like stepping control.  It also contains session state like
+   the user's currently selected frame.  */
 
-   Keep the fields in order as present in their original structures.  */
-
-struct inferior_status
+struct infcall_control_state
 {
-  /* Direct copies of the struct thread_info fields:  */
-  CORE_ADDR step_range_start;
-  CORE_ADDR step_range_end;
-  struct frame_id step_frame_id;
-  struct frame_id step_stack_frame_id;
-  int trap_expected;
-  int proceed_to_finish;
-  int in_infcall;
-  enum step_over_calls_kind step_over_calls;
-  int stop_step;
-  bpstat stop_bpstat;
-
-  /* Direct copies of the struct inferior fields:  */
-  int stop_soon;
+  struct thread_control_state thread_control;
+  struct inferior_control_state inferior_control;
 
   /* Other fields:  */
   enum stop_stack_kind stop_stack_dummy;
@@ -6197,33 +6202,21 @@ struct inferior_status
 /* Save all of the information associated with the inferior<==>gdb
    connection.  */
 
-struct inferior_status *
-save_inferior_status (void)
+struct infcall_control_state *
+save_infcall_control_state (void)
 {
-  struct inferior_status *inf_status = XMALLOC (struct inferior_status);
+  struct infcall_control_state *inf_status = xmalloc (sizeof (*inf_status));
   struct thread_info *tp = inferior_thread ();
   struct inferior *inf = current_inferior ();
 
-  /* Direct copies of the struct thread_info fields:  */
-  inf_status->step_range_start = tp->step_range_start;
-  inf_status->step_range_end = tp->step_range_end;
-  inf_status->step_frame_id = tp->step_frame_id;
-  inf_status->step_stack_frame_id = tp->step_stack_frame_id;
-  inf_status->trap_expected = tp->trap_expected;
-  inf_status->proceed_to_finish = tp->proceed_to_finish;
-  inf_status->in_infcall = tp->in_infcall;
-  inf_status->step_over_calls = tp->step_over_calls;
-  inf_status->stop_step = tp->stop_step;
-
-  /* Save original bpstat chain here; replace it with copy of chain.
-     If caller's caller is walking the chain, they'll be happier if we
-     hand them back the original chain when restore_inferior_status is
-     called.  */
-  inf_status->stop_bpstat = tp->stop_bpstat;
-  tp->stop_bpstat = bpstat_copy (tp->stop_bpstat);
+  inf_status->thread_control = tp->control;
+  inf_status->inferior_control = inf->control;
 
-  /* Direct copies of the struct inferior fields:  */
-  inf_status->stop_soon = inf->stop_soon;
+  /* Save original bpstat chain to INF_STATUS; replace it in TP with copy of
+     chain.  If caller's caller is walking the chain, they'll be happier if we
+     hand them back the original chain when restore_infcall_control_state is
+     called.  */
+  tp->control.stop_bpstat = bpstat_copy (tp->control.stop_bpstat);
 
   /* Other fields:  */
   inf_status->stop_stack_dummy = stop_stack_dummy;
@@ -6259,29 +6252,16 @@ restore_selected_frame (void *args)
 /* Restore inferior session state to INF_STATUS.  */
 
 void
-restore_inferior_status (struct inferior_status *inf_status)
+restore_infcall_control_state (struct infcall_control_state *inf_status)
 {
   struct thread_info *tp = inferior_thread ();
   struct inferior *inf = current_inferior ();
 
-  /* Direct copies of the struct thread_info fields:  */
-  tp->step_range_start = inf_status->step_range_start;
-  tp->step_range_end = inf_status->step_range_end;
-  tp->step_frame_id = inf_status->step_frame_id;
-  tp->step_stack_frame_id = inf_status->step_stack_frame_id;
-  tp->trap_expected = inf_status->trap_expected;
-  tp->proceed_to_finish = inf_status->proceed_to_finish;
-  tp->in_infcall = inf_status->in_infcall;
-  tp->step_over_calls = inf_status->step_over_calls;
-  tp->stop_step = inf_status->stop_step;
-
   /* Handle the bpstat_copy of the chain.  */
-  bpstat_clear (&tp->stop_bpstat);
-  tp->stop_bpstat = inf_status->stop_bpstat;
-  inf_status->stop_bpstat = NULL;
+  bpstat_clear (&tp->control.stop_bpstat);
 
-  /* Direct copies of the struct inferior fields:  */
-  inf->stop_soon = inf_status->stop_soon;
+  tp->control = inf_status->thread_control;
+  inf->control = inf_status->inferior_control;
 
   /* Other fields:  */
   stop_stack_dummy = inf_status->stop_stack_dummy;
@@ -6306,22 +6286,23 @@ restore_inferior_status (struct inferior_status *inf_status)
 }
 
 static void
-do_restore_inferior_status_cleanup (void *sts)
+do_restore_infcall_control_state_cleanup (void *sts)
 {
-  restore_inferior_status (sts);
+  restore_infcall_control_state (sts);
 }
 
 struct cleanup *
-make_cleanup_restore_inferior_status (struct inferior_status *inf_status)
+make_cleanup_restore_infcall_control_state
+  (struct infcall_control_state *inf_status)
 {
-  return make_cleanup (do_restore_inferior_status_cleanup, inf_status);
+  return make_cleanup (do_restore_infcall_control_state_cleanup, inf_status);
 }
 
 void
-discard_inferior_status (struct inferior_status *inf_status)
+discard_infcall_control_state (struct infcall_control_state *inf_status)
 {
-  /* See save_inferior_status for info on stop_bpstat. */
-  bpstat_clear (&inf_status->stop_bpstat);
+  /* See save_infcall_control_state for info on stop_bpstat. */
+  bpstat_clear (&inf_status->thread_control.stop_bpstat);
   xfree (inf_status);
 }
 
--- a/gdb/linux-nat.c
+++ b/gdb/linux-nat.c
@@ -1648,7 +1648,7 @@ get_pending_status (struct lwp_info *lp, int *status)
     {
       struct thread_info *tp = find_thread_ptid (lp->ptid);
 
-      signo = tp->stop_signal;
+      signo = tp->suspend.stop_signal;
     }
   else if (!non_stop)
     {
@@ -1661,7 +1661,7 @@ get_pending_status (struct lwp_info *lp, int *status)
 	{
 	  struct thread_info *tp = find_thread_ptid (lp->ptid);
 
-	  signo = tp->stop_signal;
+	  signo = tp->suspend.stop_signal;
 	}
     }
 
@@ -1917,7 +1917,7 @@ linux_nat_resume (struct target_ops *ops,
 
       /* Defer to common code if we're gaining control of the
 	 inferior.  */
-      if (inf->stop_soon == NO_STOP_QUIETLY
+      if (inf->control.stop_soon == NO_STOP_QUIETLY
 	  && signal_stop_state (saved_signo) == 0
 	  && signal_print_state (saved_signo) == 0
 	  && signal_pass_state (saved_signo) == 1)
@@ -3580,7 +3580,7 @@ retry:
 	 skip the signal handler, or, if we're gaining control of the
 	 inferior.  */
       if (!lp->step
-	  && inf->stop_soon == NO_STOP_QUIETLY
+	  && inf->control.stop_soon == NO_STOP_QUIETLY
 	  && signal_stop_state (signo) == 0
 	  && signal_print_state (signo) == 0
 	  && signal_pass_state (signo) == 1)
@@ -4162,7 +4162,7 @@ linux_nat_find_memory_regions (find_memory_region_ftype func, void *obfd)
 static int
 find_signalled_thread (struct thread_info *info, void *data)
 {
-  if (info->stop_signal != TARGET_SIGNAL_0
+  if (info->suspend.stop_signal != TARGET_SIGNAL_0
       && ptid_get_pid (info->ptid) == ptid_get_pid (inferior_ptid))
     return 1;
 
@@ -4176,7 +4176,7 @@ find_stop_signal (void)
     iterate_over_threads (find_signalled_thread, NULL);
 
   if (info)
-    return info->stop_signal;
+    return info->suspend.stop_signal;
   else
     return TARGET_SIGNAL_0;
 }
--- a/gdb/mi/mi-interp.c
+++ b/gdb/mi/mi-interp.c
@@ -434,7 +434,7 @@ mi_about_to_proceed (void)
     {
       struct thread_info *tp = inferior_thread ();
 
-      if (tp->in_infcall)
+      if (tp->control.in_infcall)
 	return;
     }
 
@@ -477,7 +477,7 @@ mi_on_resume (ptid_t ptid)
     tp = find_thread_ptid (ptid);
 
   /* Suppress output while calling an inferior function.  */
-  if (tp->in_infcall)
+  if (tp->control.in_infcall)
     return;
 
   /* To cater for older frontends, emit ^running, but do it only once
--- a/gdb/mips-tdep.c
+++ b/gdb/mips-tdep.c
@@ -2558,7 +2558,7 @@ heuristic_proc_start (struct gdbarch *gdbarch, CORE_ADDR pc)
 	   stop_soon, but with this test, at least we
 	   don't print out warnings for every child forked (eg, on
 	   decstation).  22apr93 rich@cygnus.com.  */
-	if (inf->stop_soon == NO_STOP_QUIETLY)
+	if (inf->control.stop_soon == NO_STOP_QUIETLY)
 	  {
 	    static int blurb_printed = 0;
 
--- a/gdb/procfs.c
+++ b/gdb/procfs.c
@@ -5690,7 +5690,7 @@ procfs_corefile_thread_callback (procinfo *pi, procinfo *thread, void *data)
 static int
 find_signalled_thread (struct thread_info *info, void *data)
 {
-  if (info->stop_signal != TARGET_SIGNAL_0
+  if (info->suspend.stop_signal != TARGET_SIGNAL_0
       && ptid_get_pid (info->ptid) == ptid_get_pid (inferior_ptid))
     return 1;
 
@@ -5704,7 +5704,7 @@ find_stop_signal (void)
     iterate_over_threads (find_signalled_thread, NULL);
 
   if (info)
-    return info->stop_signal;
+    return info->suspend.stop_signal;
   else
     return TARGET_SIGNAL_0;
 }
--- a/gdb/solib-irix.c
+++ b/gdb/solib-irix.c
@@ -469,15 +469,15 @@ irix_solib_create_inferior_hook (int from_tty)
 
   clear_proceed_status ();
 
-  inf->stop_soon = STOP_QUIETLY;
-  tp->stop_signal = TARGET_SIGNAL_0;
+  inf->control.stop_soon = STOP_QUIETLY;
+  tp->suspend.stop_signal = TARGET_SIGNAL_0;
 
   do
     {
-      target_resume (pid_to_ptid (-1), 0, tp->stop_signal);
+      target_resume (pid_to_ptid (-1), 0, tp->suspend.stop_signal);
       wait_for_inferior (0);
     }
-  while (tp->stop_signal != TARGET_SIGNAL_TRAP);
+  while (tp->suspend.stop_signal != TARGET_SIGNAL_TRAP);
 
   /* We are now either at the "mapping complete" breakpoint (or somewhere
      else, a condition we aren't prepared to deal with anyway), so adjust
@@ -496,7 +496,7 @@ irix_solib_create_inferior_hook (int from_tty)
      Delaying the resetting of stop_soon until after symbol loading
      suppresses the warning.  */
   solib_add ((char *) 0, 0, (struct target_ops *) 0, auto_solib_add);
-  inf->stop_soon = NO_STOP_QUIETLY;
+  inf->control.stop_soon = NO_STOP_QUIETLY;
 }
 
 /* LOCAL FUNCTION
--- a/gdb/solib-osf.c
+++ b/gdb/solib-osf.c
@@ -340,14 +340,14 @@ osf_solib_create_inferior_hook (int from_tty)
 
   tp = inferior_thread ();
   clear_proceed_status ();
-  inf->stop_soon = STOP_QUIETLY;
-  tp->stop_signal = TARGET_SIGNAL_0;
+  inf->control.stop_soon = STOP_QUIETLY;
+  tp->suspend.stop_signal = TARGET_SIGNAL_0;
   do
     {
-      target_resume (minus_one_ptid, 0, tp->stop_signal);
+      target_resume (minus_one_ptid, 0, tp->suspend.stop_signal);
       wait_for_inferior (0);
     }
-  while (tp->stop_signal != TARGET_SIGNAL_TRAP);
+  while (tp->suspend.stop_signal != TARGET_SIGNAL_TRAP);
 
   /*  solib_add will call reinit_frame_cache.
      But we are stopped in the runtime loader and we do not have symbols
@@ -356,7 +356,7 @@ osf_solib_create_inferior_hook (int from_tty)
      Delaying the resetting of stop_soon until after symbol loading
      suppresses the warning.  */
   solib_add ((char *) 0, 0, (struct target_ops *) 0, auto_solib_add);
-  inf->stop_soon = NO_STOP_QUIETLY;
+  inf->control.stop_soon = NO_STOP_QUIETLY;
 }
 
 /* target_so_ops callback.  Do additional symbol handling, lookup, etc. after
--- a/gdb/solib-spu.c
+++ b/gdb/solib-spu.c
@@ -85,13 +85,13 @@ spu_skip_standalone_loader (void)
 	 this will step past the first instruction of the stand-alone SPE
 	 executable loader, but we don't care about that.  */
 
-      inferior_thread ()->in_infcall = 1;   /* Suppress MI messages.  */
+      inferior_thread ()->control.in_infcall = 1; /* Suppress MI messages.  */
 
       target_resume (inferior_ptid, 1, TARGET_SIGNAL_0);
       target_wait (minus_one_ptid, &ws, 0);
       set_executing (minus_one_ptid, 0);
 
-      inferior_thread ()->in_infcall = 0;
+      inferior_thread ()->control.in_infcall = 0;
     }
 }
 
--- a/gdb/solib-sunos.c
+++ b/gdb/solib-sunos.c
@@ -772,15 +772,15 @@ sunos_solib_create_inferior_hook (int from_tty)
 
   clear_proceed_status ();
 
-  inf->stop_soon = STOP_QUIETLY;
-  tp->stop_signal = TARGET_SIGNAL_0;
+  inf->control.stop_soon = STOP_QUIETLY;
+  tp->suspend.stop_signal = TARGET_SIGNAL_0;
   do
     {
-      target_resume (pid_to_ptid (-1), 0, tp->stop_signal);
+      target_resume (pid_to_ptid (-1), 0, tp->suspend.stop_signal);
       wait_for_inferior (0);
     }
-  while (tp->stop_signal != TARGET_SIGNAL_TRAP);
-  inf->stop_soon = NO_STOP_QUIETLY;
+  while (tp->suspend.stop_signal != TARGET_SIGNAL_TRAP);
+  inf->control.stop_soon = NO_STOP_QUIETLY;
 
   /* We are now either at the "mapping complete" breakpoint (or somewhere
      else, a condition we aren't prepared to deal with anyway), so adjust
--- a/gdb/solib-svr4.c
+++ b/gdb/solib-svr4.c
@@ -2188,15 +2188,15 @@ svr4_solib_create_inferior_hook (int from_tty)
   tp = inferior_thread ();
 
   clear_proceed_status ();
-  inf->stop_soon = STOP_QUIETLY;
-  tp->stop_signal = TARGET_SIGNAL_0;
+  inf->control.stop_soon = STOP_QUIETLY;
+  tp->suspend.stop_signal = TARGET_SIGNAL_0;
   do
     {
-      target_resume (pid_to_ptid (-1), 0, tp->stop_signal);
+      target_resume (pid_to_ptid (-1), 0, tp->suspend.stop_signal);
       wait_for_inferior (0);
     }
-  while (tp->stop_signal != TARGET_SIGNAL_TRAP);
-  inf->stop_soon = NO_STOP_QUIETLY;
+  while (tp->suspend.stop_signal != TARGET_SIGNAL_TRAP);
+  inf->control.stop_soon = NO_STOP_QUIETLY;
 #endif /* defined(_SCO_DS) */
 }
 
--- a/gdb/thread.c
+++ b/gdb/thread.c
@@ -103,7 +103,7 @@ clear_thread_inferior_resources (struct thread_info *tp)
       tp->step_resume_breakpoint = NULL;
     }
 
-  bpstat_clear (&tp->stop_bpstat);
+  bpstat_clear (&tp->control.stop_bpstat);
 
   discard_all_intermediate_continuations_thread (tp);
   discard_all_continuations_thread (tp);
--- a/gdb/windows-nat.c
+++ b/gdb/windows-nat.c
@@ -1704,20 +1704,20 @@ do_initial_windows_stuff (struct target_ops *ops, DWORD pid, int attaching)
   target_terminal_inferior ();
 
   windows_initialization_done = 0;
-  inf->stop_soon = STOP_QUIETLY;
+  inf->control.stop_soon = STOP_QUIETLY;
   while (1)
     {
       stop_after_trap = 1;
       wait_for_inferior (0);
       tp = inferior_thread ();
-      if (tp->stop_signal != TARGET_SIGNAL_TRAP)
-	resume (0, tp->stop_signal);
+      if (tp->suspend.stop_signal != TARGET_SIGNAL_TRAP)
+	resume (0, tp->suspend.stop_signal);
       else
 	break;
     }
 
   windows_initialization_done = 1;
-  inf->stop_soon = NO_STOP_QUIETLY;
+  inf->control.stop_soon = NO_STOP_QUIETLY;
   stop_after_trap = 0;
   return;
 }


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