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]

Modernize solaris threads support.


Started out as getting rid of a couple of deprecated_xfer_memory instances...

This patch modernizes solaris/posix threads support (sol-threads.c), and
solaris core file debugging support (also implemented in sol-threads.c).

* converts sol-threads.c:sol_threads_ops from a process_statum to a
  thread_stratum target.

* gets rid of the procfs_suppress_run hack.

* Adds a `this' target_ops pointer to a few more target_ops callbacks,
  so we get rid of a bunch of things like this, by instead calling
  the target beneath:

   -  if (target_has_execution)
   -    procfs_ops.to_fetch_registers (regcache, -1);
   -  else
   -    orig_core_ops.to_fetch_registers (regcache, -1);

* Since sol_threads_ops is now a thread_statum target, it can sit
  on top of the core target.  When I ended up trimming all the now
  unnecessary reimplementations that the sol_core_ops target was
  doing, there was nothing left, so the "solaris-core" target can
  go away --- solaris can use the standard corelow.c target.  Also, after
  this cleaning up, this comment is no longer valid:

  -  /* On Solaris/x86, when debugging a threaded core file from process
  -     <n>, the following causes "info threads" to produce "procfs:
  -     couldn't find pid <n> in procinfo list" where <n> is the pid of
  -     the process that produced the core file.  Disable it for now. */
  -#if 0

  With my my previous patch to handle the solaris ".reg/XXX" section name
  "encoding", debugging threaded core files works flawlessly.

* This hack in sol-threads.c:

 -  /* FIXME: This code takes errant advantage of the order in which
 -     initialization routines are run.  _initialize_corelow must run before
 -     this one otherwise orig_core_ops will still contain zeros and the work
 -     of init_sol_core_ops will be undone.  */
 -  memcpy (&orig_core_ops, &core_ops, sizeof (struct target_ops));
 -  memcpy (&core_ops, &sol_core_ops, sizeof (struct target_ops));
 -  add_target (&core_ops);
 -

 ... that worked together with this one in corelow.c:

 -/* non-zero if we should not do the add_target call in
 -   _initialize_corelow; not initialized (i.e., bss) so that
 -   the target can initialize it (i.e., data) if appropriate.
 -   This needs to be set at compile time because we don't know
 -   for sure whether the target's initialize routine is called
 -   before us or after us. */
 -int coreops_suppress_target;
 -
  void
 _initialize_corelow (void)
  {
    init_core_ops ();
 
 -  if (!coreops_suppress_target)
 -    add_target (&core_ops);

 ... are history.

* I've cleaned up procfs.c a little bit, by making that
  target inherit inf-child.c, which allows us to drop
  some duplication.  procfs.c:procfs_ops disappears.

* I've added a new gdbarch method similar to target_pid_to_str, that
  is used by corelow.c, so it knows how to print a ptid comming
  from a solaris core file.  The target_pid_to_str method is a bit
  wonky if you consider cross debugging, either remote or core file. 
  With this method, we get consistent LWP "info threads" output, no matter
  which host is being used to debug the core.

The above drops a bunch of code from GDB, while fixing up a few bugs (see more
about that below).  The rest of the patch is adjustment to all targets to the
target_ops tweaks.  It actually got rid of the inf-ttrace.c:ttrace_ops_hack hack
in the process, and removed most references to bsd-uthread.c:bsd_uthread_ops_hack.

Since this includes adjustments to almost, if not all native targets, it's
impossible (for me) to test them all.  However, other than solaris changes,
these should be pretty mechanical changes, so if I messed something
up, it should be pretty trivial to fix.

Of course, after having gone through most of this, I noticed
that the sol-threads.c target wasn't working at all for a few years
now (PR 9242):

  [Native Solaris thread debugging broken since 2006-01-24]
  <http://sourceware.org/ml/gdb/2006-05/msg00379.html>
  <http://sourceware.org/bugzilla/show_bug.cgi?id=9242>

So this patch fixes the PR, and restores GDB's behavior on solaris to what
it was circa GDB 6.3.  Notice that the gdb shipped with opensolaris 10 is
still 6.3, may be due to this.

Comments?

I've tested this on x86_64-linux, sparc solaris 8 and sparc solaris 5.10.1.  The
testsuite is a bit flacky on solaris, but results don't look bad.

I've also manually tested on i386 opensolaris 10 (actually wrote the
patch there), but regtesting on this platform is broken due
to stty issues.

-- 
Pedro Alves

2009-02-16  Pedro Alves  <pedro@codesourcery.com>

	* corelow.c (get_core_registers): Adjust.
	(core_file_thread_alive): Rename to...
	(core_thread_alive): ... this.
	(core_pid_to_str): Try gdbarch_core_pid_to_str first.
	(init_core_ops): Adjust.
	(coreops_suppress_target): Delete.
	(_initialize_corelow): Unconditionally add core_ops.
	* procfs.c: Include "inf-child.h".
	(procfs_ops): Delete.
	(init_procfs_ops): Delete.  Reimplement as...
	(procfs_target): ... this, inheriting from inf-child.
	(procfs_attach, procfs_detach, procfs_fetch_registers): Adjust.
	(procfs_prepare_to_store): Delete.
	(procfs_store_registers, procfs_resume): Adjust.
	(procfs_open): Delete.
	(procfs_suppress_run): Delete.
	(procfs_can_run): Delete.
	(procfs_mourn_inferior): Adjust.
	(procfs_init_inferior): Add target_ops parameter.  Adjust.
	(procfs_create_inferior): Don't pass procfs_init_inferior to
	fork_inferior.  Instead call it after fork_inferior returns.
	(procfs_find_new_threads): Adjust.
	(_initialize_procfs): Adjust to use procfs_target instead of
	init_procfs_ops.
	* sol-thread.c (orig_core_ops, sol_core_ops): Delete.
	(lwp_to_thread): Use target_thread_alive.
	(sol_thread_open): Delete.
	(sol_thread_attach): Delete.
	(sol_thread_detach, sol_thread_resume, sol_thread_wait)
	(sol_thread_fetch_registers, sol_thread_store_registers): Adjust
	to use find_target_beneath.
	(sol_thread_prepare_to_store, sol_thread_xfer_memory): Delete.
	(sol_thread_xfer_partial): Adjust to use find_target_beneath.
	(sol_thread_files_info, sol_thread_kill_inferior): Delete.
	(check_for_thread_db): New.
	(sol_thread_notice_signals, sol_thread_create_inferior): Delete.
	(sol_thread_new_objfile): Call check_for_thread_db.
	(sol_thread_mourn_inferior): Adjust to use find_target_beneath.
	(sol_thread_can_run): Delete.
	(sol_thread_alive): Adjust to use find_target_beneath.
	(sol_thread_stop): Delete.
	(rw_common): Use target_write_memory or target_read_memory.
	(ps_lgetregs, ps_lgetfpregs): Use target_fetch_registers.
	(ps_lsetregs, ps_lsetfpregs): Use target_store_registers.
	(solaris_pid_to_str): Remove check for libthread_db initialization
	failing.
	(sol_find_new_threads): Remove check for libthread_db
	initialization failing, or for an invalid inferior_ptid.  Adjust
	to use find_target_beneath.
	(sol_core_open, sol_core_close, sol_core_detach,
	sol_core_files_info, sol_find_memory_regions,
	sol_make_note_section, ignore): Delete.
	(init_sol_thread_ops): Make it a thread_stratum target.  Remove
	unneeded callback settings.
	(init_sol_core_ops): Delete.
	(_initialize_sol_thread): No longer call init_sol_core_ops, set
	procfs_suppress_run, or hack with core_ops.

	* target.h (struct target_ops): Add a target_ops * parameter to
	to_resume, to_fetch_registers, to_store_registers, to_thread_alive
	and to_find_new_threads.
	(target_fetch_registers, target_store_registers)
	(target_thread_alive, target_find_new_threads): Redeclare as
	function.
	
	* target.c (update_current_target): Do not inherit or de_fault
	to_resume, to_fetch_registers, to_store_registers,
	to_thread_alive, to_find_new_threads.
	(target_resume): Adjust.
	(target_thread_alive, target_find_new_threads): New.
	(debug_to_resume, debug_to_fetch_registers): Delete.
	(target_fetch_registers): New.
	(debug_to_store_registers): Delete.
	(target_store_registers): New.
	(debug_to_thread_alive, debug_to_find_new_threads): Delete.
	(setup_target_debug): Adjust.
	
	* gdbcore.h (core_ops): Delete declaration.
	
	* inf-ptrace.c, linux-nat.c, remote.c, amd64-linux-nat.c,
	inf-child.c, linux-thread-db.c, bsd-uthread.c, inf-ttrace.c,
	i386-sol2-tdep.c, darwin-nat.c, gnu-nat.c, go32-nat.c,
	hpux-thread.c, i386-linux-nat.c, i386fbsd-nat.c, monitor.c,
	nto-procfs.c, remote-m32r-sdi.c, remote-mips.c, windows-nat.c,
	alphabsd-nat.c, amd64bsd-nat.c, arm-linux-nat.c, armnbsd-nat.c,
	bsd-kvm.c, hppa-hpux-nat.c, hppa-linux-nat.c, hppabsd-nat.c,
	hppanbsd-nat.c, i386-darwin-nat.c, i386bsd-nat.c,
	ia64-linux-nat.c, m32r-linux-nat.c, m68kbsd-nat.c,
	m68klinux-nat.c, m88kbsd-nat.c, mips-linux-nat.c,
	mips64obsd-nat.c, mipsnbsd-nat.c, ppc-linux-nat.c, ppcnbsd-nat.c,
	ppcobsd-nat.c, remote-sim.c, rs6000-nat.c, s390-nat.c,
	shnbsd-nat.c, sparc-nat.c, sparc-nat.h, spu-linux-nat.c,
	vaxbsd-nat.c, xtensa-linux-nat.c: Adjust to target_ops changes.

	* gdbarch.sh (core_pid_to_str): New gdbarch callback.
	* gdbarch.h, gdbarch.c: Regenerate.

	* sol2-tdep.c: Include "inferior.h".
	(sol2_core_pid_to_str): New.
	* sol2-tdep.h (sol2_core_pid_to_str): Declare.

	* amd64-sol2-tdep.c (amd64_sol2_init_abi): Set it.
	* sparc-sol2-tdep.c (sparc32_sol2_init_abi): Set it.
	* sparc64-sol2-tdep.c (sparc64_sol2_init_abi): Set it.
	* i386-sol2-tdep.c (i386_sol2_init_abi): Set it.

---
 gdb/alphabsd-nat.c      |    6 
 gdb/amd64-linux-nat.c   |    6 
 gdb/amd64-sol2-tdep.c   |    3 
 gdb/amd64bsd-nat.c      |    6 
 gdb/arm-linux-nat.c     |    6 
 gdb/armnbsd-nat.c       |    6 
 gdb/bsd-kvm.c           |    6 
 gdb/bsd-uthread.c       |   41 ++-
 gdb/corelow.c           |   30 +-
 gdb/darwin-nat.c        |   18 -
 gdb/gdbarch.c           |   33 +++
 gdb/gdbarch.h           |    9 
 gdb/gdbarch.sh          |    4 
 gdb/gdbcore.h           |    4 
 gdb/gnu-nat.c           |   11 -
 gdb/go32-nat.c          |   15 -
 gdb/hppa-hpux-nat.c     |    6 
 gdb/hppa-linux-nat.c    |    6 
 gdb/hppabsd-nat.c       |    6 
 gdb/hppanbsd-nat.c      |    6 
 gdb/hpux-thread.c       |   31 +-
 gdb/i386-darwin-nat.c   |    6 
 gdb/i386-linux-nat.c    |    9 
 gdb/i386-sol2-tdep.c    |    3 
 gdb/i386bsd-nat.c       |    6 
 gdb/i386fbsd-nat.c      |    3 
 gdb/ia64-linux-nat.c    |    6 
 gdb/inf-child.c         |    6 
 gdb/inf-ptrace.c        |   11 -
 gdb/inf-ttrace.c        |   26 +-
 gdb/linux-nat.c         |   28 +-
 gdb/linux-thread-db.c   |   24 +-
 gdb/m32r-linux-nat.c    |    6 
 gdb/m68kbsd-nat.c       |    6 
 gdb/m68klinux-nat.c     |    6 
 gdb/m88kbsd-nat.c       |    6 
 gdb/mips-linux-nat.c    |   10 
 gdb/mips64obsd-nat.c    |    6 
 gdb/mipsnbsd-nat.c      |    6 
 gdb/monitor.c           |   11 -
 gdb/nto-procfs.c        |   23 +-
 gdb/ppc-linux-nat.c     |    6 
 gdb/ppcnbsd-nat.c       |    6 
 gdb/ppcobsd-nat.c       |    6 
 gdb/procfs.c            |  190 ++++++-----------
 gdb/remote-m32r-sdi.c   |   59 +----
 gdb/remote-mips.c       |   20 -
 gdb/remote-sim.c        |   16 -
 gdb/remote.c            |   25 --
 gdb/rs6000-nat.c        |    6 
 gdb/s390-nat.c          |    6 
 gdb/shnbsd-nat.c        |    6 
 gdb/sol-thread.c        |  511 ++++++++----------------------------------------
 gdb/sol2-tdep.c         |   13 +
 gdb/sol2-tdep.h         |    2 
 gdb/sparc-nat.c         |    6 
 gdb/sparc-nat.h         |    6 
 gdb/sparc-sol2-tdep.c   |    3 
 gdb/sparc64-sol2-tdep.c |    3 
 gdb/spu-linux-nat.c     |    6 
 gdb/target.c            |  170 ++++++++-------
 gdb/target.h            |   22 --
 gdb/vaxbsd-nat.c        |    6 
 gdb/windows-nat.c       |   23 +-
 gdb/xtensa-linux-nat.c  |    6 
 65 files changed, 685 insertions(+), 905 deletions(-)

Index: src/gdb/corelow.c
===================================================================
--- src.orig/gdb/corelow.c	2009-02-16 03:22:34.000000000 +0000
+++ src/gdb/corelow.c	2009-02-16 03:26:06.000000000 +0000
@@ -81,12 +81,8 @@ static void core_close (int);
 
 static void core_close_cleanup (void *ignore);
 
-static void get_core_registers (struct regcache *, int);
-
 static void add_to_thread_list (bfd *, asection *, void *);
 
-static int core_file_thread_alive (ptid_t tid);
-
 static void init_core_ops (void);
 
 void _initialize_corelow (void);
@@ -525,7 +521,8 @@ get_core_register_section (struct regcac
 /* We just get all the registers, so we don't use regno.  */
 
 static void
-get_core_registers (struct regcache *regcache, int regno)
+get_core_registers (struct target_ops *ops,
+		    struct regcache *regcache, int regno)
 {
   int i;
 
@@ -678,7 +675,7 @@ ignore (struct bp_target_info *bp_tgt)
    behaviour.
  */
 static int
-core_file_thread_alive (ptid_t tid)
+core_thread_alive (struct target_ops *ops, ptid_t ptid)
 {
   return 1;
 }
@@ -702,6 +699,14 @@ core_pid_to_str (struct target_ops *ops,
 {
   static char buf[64];
 
+  if (core_gdbarch
+      && gdbarch_core_pid_to_str_p (core_gdbarch))
+    {
+      char *ret = gdbarch_core_pid_to_str (core_gdbarch, ptid);
+      if (ret != NULL)
+	return ret;
+    }
+
   if (ptid_get_lwp (ptid) == 0)
     xsnprintf (buf, sizeof buf, "<main task>");
   else
@@ -730,7 +735,7 @@ init_core_ops (void)
   core_ops.to_insert_breakpoint = ignore;
   core_ops.to_remove_breakpoint = ignore;
   core_ops.to_create_inferior = find_default_create_inferior;
-  core_ops.to_thread_alive = core_file_thread_alive;
+  core_ops.to_thread_alive = core_thread_alive;
   core_ops.to_read_description = core_read_description;
   core_ops.to_pid_to_str = core_pid_to_str;
   core_ops.to_stratum = core_stratum;
@@ -740,19 +745,10 @@ init_core_ops (void)
   core_ops.to_magic = OPS_MAGIC;
 }
 
-/* non-zero if we should not do the add_target call in
-   _initialize_corelow; not initialized (i.e., bss) so that
-   the target can initialize it (i.e., data) if appropriate.
-   This needs to be set at compile time because we don't know
-   for sure whether the target's initialize routine is called
-   before us or after us. */
-int coreops_suppress_target;
-
 void
 _initialize_corelow (void)
 {
   init_core_ops ();
 
-  if (!coreops_suppress_target)
-    add_target (&core_ops);
+  add_target (&core_ops);
 }
Index: src/gdb/procfs.c
===================================================================
--- src.orig/gdb/procfs.c	2009-02-16 00:20:30.000000000 +0000
+++ src/gdb/procfs.c	2009-02-16 03:26:06.000000000 +0000
@@ -29,6 +29,7 @@
 #include "gdbcmd.h"
 #include "gdbthread.h"
 #include "regcache.h"
+#include "inf-child.h"
 
 #if defined (NEW_PROC_API)
 #define _STRUCTURED_PROC 1	/* Should be done by configure script. */
@@ -111,17 +112,17 @@
  * This module defines the GDB target vector and its methods.
  */
 
-static void procfs_open (char *, int);
 static void procfs_attach (struct target_ops *, char *, int);
 static void procfs_detach (struct target_ops *, char *, int);
-static void procfs_resume (ptid_t, int, enum target_signal);
-static int procfs_can_run (void);
+static void procfs_resume (struct target_ops *,
+			   ptid_t, int, enum target_signal);
 static void procfs_stop (ptid_t);
 static void procfs_files_info (struct target_ops *);
-static void procfs_fetch_registers (struct regcache *, int);
-static void procfs_store_registers (struct regcache *, int);
+static void procfs_fetch_registers (struct target_ops *,
+				    struct regcache *, int);
+static void procfs_store_registers (struct target_ops *,
+				    struct regcache *, int);
 static void procfs_notice_signals (ptid_t);
-static void procfs_prepare_to_store (struct regcache *);
 static void procfs_kill_inferior (void);
 static void procfs_mourn_inferior (struct target_ops *ops);
 static void procfs_create_inferior (struct target_ops *, char *, 
@@ -137,9 +138,9 @@ static LONGEST procfs_xfer_partial (stru
 				    gdb_byte *readbuf, const gdb_byte *writebuf,
 				    ULONGEST offset, LONGEST len);
 
-static int procfs_thread_alive (ptid_t);
+static int procfs_thread_alive (struct target_ops *ops, ptid_t);
 
-void procfs_find_new_threads (void);
+void procfs_find_new_threads (struct target_ops *ops);
 char *procfs_pid_to_str (struct target_ops *, ptid_t);
 
 static int proc_find_memory_regions (int (*) (CORE_ADDR,
@@ -152,8 +153,6 @@ static char * procfs_make_note_section (
 
 static int procfs_can_use_hw_breakpoint (int, int, int);
 
-struct target_ops procfs_ops;		/* the target vector */
-
 #if defined (PR_MODEL_NATIVE) && (PR_MODEL_NATIVE == PR_MODEL_LP64)
 /* When GDB is built as 64-bit application on Solaris, the auxv data is
    presented in 64-bit format.  We need to provide a custom parser to handle 
@@ -182,60 +181,46 @@ procfs_auxv_parse (struct target_ops *op
 }
 #endif
 
-static void
-init_procfs_ops (void)
+static struct target_ops *
+procfs_target (void)
 {
-  procfs_ops.to_shortname           = "procfs";
-  procfs_ops.to_longname            = "Unix /proc child process";
-  procfs_ops.to_doc                 =
+  struct target_ops *t = inf_child_target ();
+
+  t->to_shortname           = "procfs";
+  t->to_longname            = "Unix /proc child process";
+  t->to_doc                 =
     "Unix /proc child process (started by the \"run\" command).";
-  procfs_ops.to_open                = procfs_open;
-  procfs_ops.to_can_run             = procfs_can_run;
-  procfs_ops.to_create_inferior     = procfs_create_inferior;
-  procfs_ops.to_kill                = procfs_kill_inferior;
-  procfs_ops.to_mourn_inferior      = procfs_mourn_inferior;
-  procfs_ops.to_attach              = procfs_attach;
-  procfs_ops.to_detach              = procfs_detach;
-  procfs_ops.to_wait                = procfs_wait;
-  procfs_ops.to_resume              = procfs_resume;
-  procfs_ops.to_prepare_to_store    = procfs_prepare_to_store;
-  procfs_ops.to_fetch_registers     = procfs_fetch_registers;
-  procfs_ops.to_store_registers     = procfs_store_registers;
-  procfs_ops.to_xfer_partial        = procfs_xfer_partial;
-  procfs_ops.deprecated_xfer_memory = procfs_xfer_memory;
-  procfs_ops.to_insert_breakpoint   =  memory_insert_breakpoint;
-  procfs_ops.to_remove_breakpoint   =  memory_remove_breakpoint;
-  procfs_ops.to_notice_signals      = procfs_notice_signals;
-  procfs_ops.to_files_info          = procfs_files_info;
-  procfs_ops.to_stop                = procfs_stop;
-
-  procfs_ops.to_terminal_init       = terminal_init_inferior;
-  procfs_ops.to_terminal_inferior   = terminal_inferior;
-  procfs_ops.to_terminal_ours_for_output = terminal_ours_for_output;
-  procfs_ops.to_terminal_ours       = terminal_ours;
-  procfs_ops.to_terminal_save_ours  = terminal_save_ours;
-  procfs_ops.to_terminal_info       = child_terminal_info;
-
-  procfs_ops.to_find_new_threads    = procfs_find_new_threads;
-  procfs_ops.to_thread_alive        = procfs_thread_alive;
-  procfs_ops.to_pid_to_str          = procfs_pid_to_str;
-
-  procfs_ops.to_has_all_memory      = 1;
-  procfs_ops.to_has_memory          = 1;
-  procfs_ops.to_has_execution       = 1;
-  procfs_ops.to_has_stack           = 1;
-  procfs_ops.to_has_registers       = 1;
-  procfs_ops.to_stratum             = process_stratum;
-  procfs_ops.to_has_thread_control  = tc_schedlock;
-  procfs_ops.to_find_memory_regions = proc_find_memory_regions;
-  procfs_ops.to_make_corefile_notes = procfs_make_note_section;
-  procfs_ops.to_can_use_hw_breakpoint = procfs_can_use_hw_breakpoint;
+  t->to_create_inferior     = procfs_create_inferior;
+  t->to_kill                = procfs_kill_inferior;
+  t->to_mourn_inferior      = procfs_mourn_inferior;
+  t->to_attach              = procfs_attach;
+  t->to_detach              = procfs_detach;
+  t->to_wait                = procfs_wait;
+  t->to_resume              = procfs_resume;
+  t->to_fetch_registers     = procfs_fetch_registers;
+  t->to_store_registers     = procfs_store_registers;
+  t->to_xfer_partial        = procfs_xfer_partial;
+  t->deprecated_xfer_memory = procfs_xfer_memory;
+  t->to_notice_signals      = procfs_notice_signals;
+  t->to_files_info          = procfs_files_info;
+  t->to_stop                = procfs_stop;
+
+  t->to_find_new_threads    = procfs_find_new_threads;
+  t->to_thread_alive        = procfs_thread_alive;
+  t->to_pid_to_str          = procfs_pid_to_str;
+
+  t->to_has_thread_control  = tc_schedlock;
+  t->to_find_memory_regions = proc_find_memory_regions;
+  t->to_make_corefile_notes = procfs_make_note_section;
+  t->to_can_use_hw_breakpoint = procfs_can_use_hw_breakpoint;
 
 #if defined(PR_MODEL_NATIVE) && (PR_MODEL_NATIVE == PR_MODEL_LP64)
-  procfs_ops.to_auxv_parse = procfs_auxv_parse;
+  t->to_auxv_parse = procfs_auxv_parse;
 #endif
 
-  procfs_ops.to_magic               = OPS_MAGIC;
+  t->to_magic               = OPS_MAGIC;
+
+  return t;
 }
 
 /* =================== END, TARGET_OPS "MODULE" =================== */
@@ -3630,7 +3615,7 @@ procfs_attach (struct target_ops *ops, c
       fflush (stdout);
     }
   inferior_ptid = do_attach (pid_to_ptid (pid));
-  push_target (&procfs_ops);
+  push_target (ops);
 }
 
 static void
@@ -3659,7 +3644,7 @@ procfs_detach (struct target_ops *ops, c
 
   inferior_ptid = null_ptid;
   detach_inferior (pid);
-  unpush_target (&procfs_ops);
+  unpush_target (ops);
 }
 
 static ptid_t
@@ -3790,7 +3775,8 @@ do_detach (int signo)
    when the process is resumed.  */
 
 static void
-procfs_fetch_registers (struct regcache *regcache, int regnum)
+procfs_fetch_registers (struct target_ops *ops,
+			struct regcache *regcache, int regnum)
 {
   gdb_gregset_t *gregs;
   procinfo *pi;
@@ -3827,17 +3813,6 @@ procfs_fetch_registers (struct regcache 
     }
 }
 
-/* Get ready to modify the registers array.  On machines which store
-   individual registers, this doesn't need to do anything.  On
-   machines which store all the registers in one fell swoop, such as
-   /proc, this makes sure that registers contains all the registers
-   from the program being debugged.  */
-
-static void
-procfs_prepare_to_store (struct regcache *regcache)
-{
-}
-
 /* Store register REGNUM back into the inferior.  If REGNUM is -1, do
    this for all registers.
 
@@ -3849,7 +3824,8 @@ procfs_prepare_to_store (struct regcache
    writing one register might affect the value of others, etc.  */
 
 static void
-procfs_store_registers (struct regcache *regcache, int regnum)
+procfs_store_registers (struct target_ops *ops,
+			struct regcache *regcache, int regnum)
 {
   gdb_gregset_t *gregs;
   procinfo *pi;
@@ -4564,7 +4540,8 @@ make_signal_thread_runnable (procinfo *p
  */
 
 static void
-procfs_resume (ptid_t ptid, int step, enum target_signal signo)
+procfs_resume (struct target_ops *ops,
+	       ptid_t ptid, int step, enum target_signal signo)
 {
   procinfo *pi, *thread;
   int native_signo;
@@ -4701,44 +4678,6 @@ procfs_files_info (struct target_ops *ig
 }
 
 /*
- * Function: target_open
- *
- * A dummy: you don't open procfs.
- */
-
-static void
-procfs_open (char *args, int from_tty)
-{
-  error (_("Use the \"run\" command to start a Unix child process."));
-}
-
-/*
- * Function: target_can_run
- *
- * This tells GDB that this target vector can be invoked
- * for "run" or "attach".
- */
-
-int procfs_suppress_run = 0;	/* Non-zero if procfs should pretend not to
-				   be a runnable target.  Used by targets
-				   that can sit atop procfs, such as solaris
-				   thread support.  */
-
-
-static int
-procfs_can_run (void)
-{
-  /* This variable is controlled by modules that sit atop procfs that
-     may layer their own process structure atop that provided here.
-     sol-thread.c does this because of the Solaris two-level thread
-     model.  */
-
-  /* NOTE: possibly obsolete -- use the thread_stratum approach instead. */
-
-  return !procfs_suppress_run;
-}
-
-/*
  * Function: target_stop
  *
  * Stop the child process asynchronously, as when the
@@ -4856,7 +4795,7 @@ procfs_mourn_inferior (struct target_ops
       if (pi)
 	destroy_procinfo (pi);
     }
-  unpush_target (&procfs_ops);
+  unpush_target (ops);
 
   if (dbx_link_bpt != NULL)
     {
@@ -4878,7 +4817,7 @@ procfs_mourn_inferior (struct target_ops
  */
 
 static void
-procfs_init_inferior (int pid)
+procfs_init_inferior (struct target_ops *ops, int pid)
 {
   procinfo *pi;
   gdb_sigset_t signals;
@@ -4887,8 +4826,7 @@ procfs_init_inferior (int pid)
 
   /* This routine called on the parent side (GDB side)
      after GDB forks the inferior.  */
-
-  push_target (&procfs_ops);
+  push_target (ops);
 
   if ((pi = create_procinfo (pid, 0)) == NULL)
     perror ("procfs: out of memory in 'init_inferior'");
@@ -5119,6 +5057,8 @@ procfs_create_inferior (struct target_op
 {
   char *shell_file = getenv ("SHELL");
   char *tryname;
+  int pid;
+
   if (shell_file != NULL && strchr (shell_file, '/') == NULL)
     {
 
@@ -5187,8 +5127,10 @@ procfs_create_inferior (struct target_op
       shell_file = tryname;
     }
 
-  fork_inferior (exec_file, allargs, env, procfs_set_exec_trap,
-		 procfs_init_inferior, NULL, shell_file);
+  pid = fork_inferior (exec_file, allargs, env, procfs_set_exec_trap,
+		       NULL, NULL, shell_file);
+
+  procfs_init_inferior (ops, pid);
 
 #ifdef SYS_syssgi
   /* Make sure to cancel the syssgi() syscall-exit notifications.  
@@ -5227,7 +5169,7 @@ procfs_notice_thread (procinfo *pi, proc
  */
 
 void
-procfs_find_new_threads (void)
+procfs_find_new_threads (struct target_ops *ops)
 {
   procinfo *pi;
 
@@ -5247,7 +5189,7 @@ procfs_find_new_threads (void)
  */
 
 static int
-procfs_thread_alive (ptid_t ptid)
+procfs_thread_alive (struct target_ops *ops, ptid_t ptid)
 {
   int proc, thread;
   procinfo *pi;
@@ -6024,8 +5966,12 @@ proc_untrace_sysexit_cmd (char *args, in
 void
 _initialize_procfs (void)
 {
-  init_procfs_ops ();
-  add_target (&procfs_ops);
+  struct target_ops * t;
+
+  t = procfs_target ();
+
+  add_target (t);
+
   add_info ("proc", info_proc_cmd, _("\
 Show /proc process information about any running process.\n\
 Specify process id, or use the program being debugged by default.\n\
Index: src/gdb/sol-thread.c
===================================================================
--- src.orig/gdb/sol-thread.c	2009-02-16 00:20:29.000000000 +0000
+++ src/gdb/sol-thread.c	2009-02-16 05:20:41.000000000 +0000
@@ -68,18 +68,8 @@
 
 #include "gdb_string.h"
 
-extern struct target_ops sol_thread_ops;	/* Forward declaration */
-extern struct target_ops sol_core_ops;	/* Forward declaration */
-
-/* place to store core_ops before we overwrite it */
-static struct target_ops orig_core_ops;
-
 struct target_ops sol_thread_ops;
-struct target_ops sol_core_ops;
 
-extern int procfs_suppress_run;
-extern struct target_ops procfs_ops;	/* target vector for procfs.c */
-extern struct target_ops core_ops;	/* target vector for corelow.c */
 extern char *procfs_pid_to_str (struct target_ops *ops, ptid_t ptid);
 
 /* Prototypes for supply_gregset etc. */
@@ -104,12 +94,7 @@ static struct ps_prochandle main_ph;
 static td_thragent_t *main_ta;
 static int sol_thread_active = 0;
 
-static void sol_thread_resume (ptid_t ptid, int step, enum target_signal signo);
-static int sol_thread_alive (ptid_t ptid);
-static void sol_core_close (int quitting);
-
 static void init_sol_thread_ops (void);
-static void init_sol_core_ops (void);
 
 /* Default definitions: These must be defined in tm.h if they are to
    be shared with a process module such as procfs.  */
@@ -309,7 +294,7 @@ lwp_to_thread (ptid_t lwp)
 
   /* It's an LWP.  Convert it to a thread ID.  */
 
-  if (!sol_thread_alive (lwp))
+  if (!target_thread_alive (lwp))
     return pid_to_ptid (-1);	/* Must be a defunct LPW.  */
 
   val = p_td_ta_map_lwp2thr (main_ta, GET_LWP (lwp), &th);
@@ -335,41 +320,8 @@ lwp_to_thread (ptid_t lwp)
 
 
 /* Most target vector functions from here on actually just pass
-   through to procfs.c, as they don't need to do anything specific for
-   threads.  */
-
-static void
-sol_thread_open (char *arg, int from_tty)
-{
-  procfs_ops.to_open (arg, from_tty);
-}
-
-/* Attach to process PID, then initialize for debugging it and wait
-   for the trace-trap that results from attaching.  */
-
-static void
-sol_thread_attach (struct target_ops *ops, char *args, int from_tty)
-{
-  sol_thread_active = 0;
-  procfs_ops.to_attach (&procfs_ops, args, from_tty);
-
-  /* Must get symbols from shared libraries before libthread_db can run!  */
-  solib_add (NULL, from_tty, (struct target_ops *) 0, auto_solib_add);
-
-  if (sol_thread_active)
-    {
-      ptid_t ptid;
-      printf_filtered ("sol-thread active.\n");
-      main_ph.ptid = inferior_ptid; /* Save for xfer_memory.  */
-      push_target (&sol_thread_ops);
-      ptid = lwp_to_thread (inferior_ptid);
-      if (PIDGET (ptid) != -1)
-	thread_change_ptid (inferior_ptid, ptid);
-    }
-
-  /* FIXME: Might want to iterate over all the threads and register
-     them.  */
-}
+   through to the layer beneath, as they don't need to do anything
+   specific for threads.  */
 
 /* Take a program previously attached to and detaches it.  The program
    resumes execution and will no longer stop on signals, etc.  We'd
@@ -381,10 +333,12 @@ sol_thread_attach (struct target_ops *op
 static void
 sol_thread_detach (struct target_ops *ops, char *args, int from_tty)
 {
+  struct target_ops *beneath = find_target_beneath (ops);
+
   sol_thread_active = 0;
   inferior_ptid = pid_to_ptid (PIDGET (main_ph.ptid));
-  unpush_target (&sol_thread_ops);
-  procfs_ops.to_detach (&procfs_ops, args, from_tty);
+  unpush_target (ops);
+  beneath->to_detach (beneath, args, from_tty);
 }
 
 /* Resume execution of process PTID.  If STEP is nozero, then just
@@ -393,9 +347,11 @@ sol_thread_detach (struct target_ops *op
    ID for procfs.  */
 
 static void
-sol_thread_resume (ptid_t ptid, int step, enum target_signal signo)
+sol_thread_resume (struct target_ops *ops,
+		   ptid_t ptid, int step, enum target_signal signo)
 {
   struct cleanup *old_chain;
+  struct target_ops *beneath = find_target_beneath (ops);
 
   old_chain = save_inferior_ptid ();
 
@@ -415,7 +371,7 @@ sol_thread_resume (ptid_t ptid, int step
 		 GET_THREAD (save_ptid));
     }
 
-  procfs_ops.to_resume (ptid, step, signo);
+  beneath->to_resume (beneath, ptid, step, signo);
 
   do_cleanups (old_chain);
 }
@@ -429,6 +385,7 @@ sol_thread_wait (struct target_ops *ops,
 {
   ptid_t rtnval;
   ptid_t save_ptid;
+  struct target_ops *beneath = find_target_beneath (ops);
   struct cleanup *old_chain;
 
   save_ptid = inferior_ptid;
@@ -450,7 +407,7 @@ sol_thread_wait (struct target_ops *ops,
 		 GET_THREAD (save_ptid));
     }
 
-  rtnval = procfs_ops.to_wait (&procfs_ops, ptid, ourstatus);
+  rtnval = beneath->to_wait (beneath, ptid, ourstatus);
 
   if (ourstatus->kind != TARGET_WAITKIND_EXITED)
     {
@@ -477,7 +434,8 @@ sol_thread_wait (struct target_ops *ops,
 }
 
 static void
-sol_thread_fetch_registers (struct regcache *regcache, int regnum)
+sol_thread_fetch_registers (struct target_ops *ops,
+			    struct regcache *regcache, int regnum)
 {
   thread_t thread;
   td_thrhandle_t thandle;
@@ -486,6 +444,7 @@ sol_thread_fetch_registers (struct regca
   prfpregset_t fpregset;
   gdb_gregset_t *gregset_p = &gregset;
   gdb_fpregset_t *fpregset_p = &fpregset;
+  struct target_ops *beneath = find_target_beneath (ops);
 
 #if 0
   int xregsize;
@@ -494,11 +453,8 @@ sol_thread_fetch_registers (struct regca
 
   if (!is_thread (inferior_ptid))
     {
-      /* It's an LWP; pass the request on to procfs.  */
-      if (target_has_execution)
-	procfs_ops.to_fetch_registers (regcache, regnum);
-      else
-	orig_core_ops.to_fetch_registers (regcache, regnum);
+      /* It's an LWP; pass the request on to the layer beneath.  */
+      beneath->to_fetch_registers (beneath, regcache, regnum);
       return;
     }
 
@@ -555,7 +511,8 @@ sol_thread_fetch_registers (struct regca
 }
 
 static void
-sol_thread_store_registers (struct regcache *regcache, int regnum)
+sol_thread_store_registers (struct target_ops *ops,
+			    struct regcache *regcache, int regnum)
 {
   thread_t thread;
   td_thrhandle_t thandle;
@@ -569,8 +526,10 @@ sol_thread_store_registers (struct regca
 
   if (!is_thread (inferior_ptid))
     {
-      /* It's an LWP; pass the request on to procfs.c.  */
-      procfs_ops.to_store_registers (regcache, regnum);
+      struct target_ops *beneath = find_target_beneath (ops);
+
+      /* It's an LWP; pass the request on to the layer beneath.  */
+      beneath->to_store_registers (beneath, regcache, regnum);
       return;
     }
 
@@ -644,56 +603,6 @@ sol_thread_store_registers (struct regca
 #endif
 }
 
-/* Get ready to modify the registers array.  On machines which store
-   individual registers, this doesn't need to do anything.  On
-   machines which store all the registers in one fell swoop, this
-   makes sure that registers contains all the registers from the
-   program being debugged.  */
-
-static void
-sol_thread_prepare_to_store (struct regcache *regcache)
-{
-  procfs_ops.to_prepare_to_store (regcache);
-}
-
-/* Transfer LEN bytes between GDB address MYADDR and target address
-   MEMADDR.  If DOWRITE is non-zero, transfer them to the target,
-   otherwise transfer them from the target.  TARGET is unused.
-
-   Returns the number of bytes transferred.  */
-
-static int
-sol_thread_xfer_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len,
-			int dowrite, struct mem_attrib *attrib,
-			struct target_ops *target)
-{
-  int retval;
-  struct cleanup *old_chain;
-
-  old_chain = save_inferior_ptid ();
-
-  if (is_thread (inferior_ptid) || !target_thread_alive (inferior_ptid))
-    {
-      /* It's either a thread or an LWP that isn't alive.  Any live
-         LWP will do so use the first available.
-
-	 NOTE: We don't need to call switch_to_thread; we're just
-	 reading memory.  */
-      inferior_ptid = procfs_first_available ();
-    }
-
-  if (target_has_execution)
-    retval = procfs_ops.deprecated_xfer_memory (memaddr, myaddr, len,
-						dowrite, attrib, target);
-  else
-    retval = orig_core_ops.deprecated_xfer_memory (memaddr, myaddr, len,
-						   dowrite, attrib, target);
-
-  do_cleanups (old_chain);
-
-  return retval;
-}
-
 /* Perform partial transfers on OBJECT.  See target_read_partial and
    target_write_partial for details of each variant.  One, and only
    one, of readbuf or writebuf must be non-NULL.  */
@@ -706,6 +615,7 @@ sol_thread_xfer_partial (struct target_o
 {
   int retval;
   struct cleanup *old_chain;
+  struct target_ops *beneath = find_target_beneath (ops);
 
   old_chain = save_inferior_ptid ();
 
@@ -719,59 +629,67 @@ sol_thread_xfer_partial (struct target_o
       inferior_ptid = procfs_first_available ();
     }
 
-  if (target_has_execution)
-    retval = procfs_ops.to_xfer_partial (ops, object, annex,
-					 readbuf, writebuf, offset, len);
-  else
-    retval = orig_core_ops.to_xfer_partial (ops, object, annex,
-					    readbuf, writebuf, offset, len);
+  retval = beneath->to_xfer_partial (beneath, object, annex,
+				     readbuf, writebuf, offset, len);
 
   do_cleanups (old_chain);
 
   return retval;
 }
 
-/* Print status information about what we're accessing.  */
-
-static void
-sol_thread_files_info (struct target_ops *ignore)
-{
-  procfs_ops.to_files_info (ignore);
-}
-
 static void
-sol_thread_kill_inferior (void)
+check_for_thread_db (void)
 {
-  procfs_ops.to_kill ();
-}
+  td_err_e err;
+  ptid_t ptid;
 
-static void
-sol_thread_notice_signals (ptid_t ptid)
-{
-  procfs_ops.to_notice_signals (pid_to_ptid (PIDGET (ptid)));
-}
+  /* Do nothing if we couldn't load libthread_db.so.1.  */
+  if (p_td_ta_new == NULL)
+    return;
 
-/* Fork an inferior process, and start debugging it with /proc.  */
+  if (sol_thread_active)
+    /* Nothing to do.  The thread library was already detected and the
+       target vector was already activated.  */
+    return;
 
-static void
-sol_thread_create_inferior (struct target_ops *ops, char *exec_file,
-			    char *allargs, char **env, int from_tty)
-{
-  sol_thread_active = 0;
-  procfs_ops.to_create_inferior (&procfs_ops, exec_file, allargs, env, from_tty);
+  /* Now, initialize libthread_db.  This needs to be done after the
+     shared libraries are located because it needs information from
+     the user's thread library.  */
 
-  if (sol_thread_active && !ptid_equal (inferior_ptid, null_ptid))
+  err = p_td_init ();
+  if (err != TD_OK)
     {
-      ptid_t ptid;
+      warning (_("sol_thread_new_objfile: td_init: %s"), td_err_string (err));
+      return;
+    }
+
+  /* Now attempt to open a connection to the thread library.  */
+  err = p_td_ta_new (&main_ph, &main_ta);
+  switch (err)
+    {
+    case TD_NOLIBTHREAD:
+      /* No thread library was detected.  */
+      break;
 
-      /* Save for xfer_memory.  */
-      main_ph.ptid = inferior_ptid;
+    case TD_OK:
+      printf_unfiltered (_("[Thread debugging using libthread_db enabled]\n"));
 
+      /* The thread library was detected.  Activate the sol_thread target.  */
       push_target (&sol_thread_ops);
+      sol_thread_active = 1;
 
+      main_ph.ptid = inferior_ptid; /* Save for xfer_memory.  */
       ptid = lwp_to_thread (inferior_ptid);
       if (PIDGET (ptid) != -1)
-	thread_change_ptid (inferior_ptid, ptid);
+	inferior_ptid = ptid;
+
+      target_find_new_threads ();
+      break;
+
+    default:
+      warning (_("Cannot initialize thread debugging library: %s"),
+	       td_err_string (err));
+      break;
     }
 }
 
@@ -784,40 +702,8 @@ sol_thread_create_inferior (struct targe
 static void
 sol_thread_new_objfile (struct objfile *objfile)
 {
-  td_err_e val;
-
-  if (!objfile)
-    {
-      sol_thread_active = 0;
-      return;
-    }
-
-  /* Don't do anything if init failed to resolve the libthread_db
-     library.  */
-  if (!procfs_suppress_run)
-    return;
-
-  /* Now, initialize libthread_db.  This needs to be done after the
-     shared libraries are located because it needs information from
-     the user's thread library.  */
-
-  val = p_td_init ();
-  if (val != TD_OK)
-    {
-      warning (_("sol_thread_new_objfile: td_init: %s"), td_err_string (val));
-      return;
-    }
-
-  val = p_td_ta_new (&main_ph, &main_ta);
-  if (val == TD_NOLIBTHREAD)
-    return;
-  else if (val != TD_OK)
-    {
-      warning (_("sol_thread_new_objfile: td_ta_new: %s"), td_err_string (val));
-      return;
-    }
-
-  sol_thread_active = 1;
+  if (objfile != NULL)
+    check_for_thread_db ();
 }
 
 /* Clean up after the inferior dies.  */
@@ -825,40 +711,19 @@ sol_thread_new_objfile (struct objfile *
 static void
 sol_thread_mourn_inferior (struct target_ops *ops)
 {
+  struct target_ops *beneath = find_target_beneath (ops);
+
   sol_thread_active = 0;
-  unpush_target (&sol_thread_ops);
-  procfs_ops.to_mourn_inferior (&procfs_ops);
-}
 
-/* Mark our target-struct as eligible for stray "run" and "attach"
-   commands.  */
+  unpush_target (ops);
 
-static int
-sol_thread_can_run (void)
-{
-  return procfs_suppress_run;
+  beneath->to_mourn_inferior (beneath);
 }
 
-/*
-
-   LOCAL FUNCTION
-
-   sol_thread_alive     - test thread for "aliveness"
-
-   SYNOPSIS
-
-   static bool sol_thread_alive (ptid_t ptid);
-
-   DESCRIPTION
-
-   returns true if thread still active in inferior.
-
- */
-
 /* Return true if PTID is still active in the inferior.  */
 
 static int
-sol_thread_alive (ptid_t ptid)
+sol_thread_alive (struct target_ops *ops, ptid_t ptid)
 {
   if (is_thread (ptid))
     {
@@ -876,19 +741,13 @@ sol_thread_alive (ptid_t ptid)
     }
   else
     {
-      /* It's an LPW; pass the request on to procfs.  */
-      if (target_has_execution)
-	return procfs_ops.to_thread_alive (ptid);
-      else
-	return orig_core_ops.to_thread_alive (ptid);
+      struct target_ops *beneath = find_target_beneath (ops);
+
+      /* It's an LPW; pass the request on to the layer below.  */
+      return beneath->to_thread_alive (beneath, ptid);
     }
 }
 
-static void
-sol_thread_stop (ptid_t ptid)
-{
-  procfs_ops.to_stop (ptid);
-}
 
 /* These routines implement the lower half of the thread_db interface,
    i.e. the ps_* routines.  */
@@ -980,6 +839,7 @@ static ps_err_e
 rw_common (int dowrite, const struct ps_prochandle *ph, gdb_ps_addr_t addr,
 	   char *buf, int size)
 {
+  int ret;
   struct cleanup *old_chain;
 
   old_chain = save_inferior_ptid ();
@@ -1001,50 +861,14 @@ rw_common (int dowrite, const struct ps_
     addr &= 0xffffffff;
 #endif
 
-  while (size > 0)
-    {
-      int cc;
-
-      /* FIXME: passing 0 as attrib argument.  */
-      if (target_has_execution)
-	cc = procfs_ops.deprecated_xfer_memory (addr, buf, size,
-						dowrite, 0, &procfs_ops);
-      else
-	cc = orig_core_ops.deprecated_xfer_memory (addr, buf, size,
-						   dowrite, 0, &core_ops);
-
-      if (cc < 0)
-	{
-	  if (dowrite == 0)
-	    print_sys_errmsg ("rw_common (): read", errno);
-	  else
-	    print_sys_errmsg ("rw_common (): write", errno);
-
-	  do_cleanups (old_chain);
-
-	  return PS_ERR;
-	}
-      else if (cc == 0)
-	{
-	  if (dowrite == 0)
-	    warning (_("rw_common (): unable to read at addr 0x%lx"),
-		     (long) addr);
-	  else
-	    warning (_("rw_common (): unable to write at addr 0x%lx"),
-		     (long) addr);
-
-	  do_cleanups (old_chain);
-
-	  return PS_ERR;
-	}
-
-      size -= cc;
-      buf += cc;
-    }
+  if (dowrite)
+    ret = target_write_memory (addr, buf, size);
+  else
+    ret = target_read_memory (addr, buf, size);
 
   do_cleanups (old_chain);
 
-  return PS_OK;
+  return (ret == 0 ? PS_OK : PS_ERR);
 }
 
 /* Copies SIZE bytes from target process .data segment to debugger memory.  */
@@ -1096,10 +920,7 @@ ps_lgetregs (gdb_ps_prochandle_t ph, lwp
   inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
   regcache = get_thread_regcache (inferior_ptid);
 
-  if (target_has_execution)
-    procfs_ops.to_fetch_registers (regcache, -1);
-  else
-    orig_core_ops.to_fetch_registers (regcache, -1);
+  target_fetch_registers (regcache, -1);
   fill_gregset (regcache, (gdb_gregset_t *) gregset, -1);
 
   do_cleanups (old_chain);
@@ -1122,10 +943,7 @@ ps_lsetregs (gdb_ps_prochandle_t ph, lwp
   regcache = get_thread_regcache (inferior_ptid);
 
   supply_gregset (regcache, (const gdb_gregset_t *) gregset);
-  if (target_has_execution)
-    procfs_ops.to_store_registers (regcache, -1);
-  else
-    orig_core_ops.to_store_registers (regcache, -1);
+  target_store_registers (regcache, -1);
 
   do_cleanups (old_chain);
 
@@ -1232,10 +1050,7 @@ ps_lgetfpregs (gdb_ps_prochandle_t ph, l
   inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
   regcache = get_thread_regcache (inferior_ptid);
 
-  if (target_has_execution)
-    procfs_ops.to_fetch_registers (regcache, -1);
-  else
-    orig_core_ops.to_fetch_registers (regcache, -1);
+  target_fetch_registers (regcache, -1);
   fill_fpregset (regcache, (gdb_fpregset_t *) fpregset, -1);
 
   do_cleanups (old_chain);
@@ -1258,10 +1073,7 @@ ps_lsetfpregs (gdb_ps_prochandle_t ph, l
   regcache = get_thread_regcache (inferior_ptid);
 
   supply_fpregset (regcache, (const gdb_fpregset_t *) fpregset);
-  if (target_has_execution)
-    procfs_ops.to_store_registers (regcache, -1);
-  else
-    orig_core_ops.to_store_registers (regcache, -1);
+  target_store_registers (regcache, -1);
 
   do_cleanups (old_chain);
 
@@ -1328,10 +1140,6 @@ solaris_pid_to_str (struct target_ops *o
 {
   static char buf[100];
 
-  /* In case init failed to resolve the libthread_db library.  */
-  if (!procfs_suppress_run)
-    return procfs_pid_to_str (&procfs_ops, ptid);
-
   if (is_thread (ptid))
     {
       ptid_t lwp;
@@ -1377,21 +1185,13 @@ sol_find_new_threads_callback (const td_
 }
 
 static void
-sol_find_new_threads (void)
+sol_find_new_threads (struct target_ops *ops)
 {
-  /* Don't do anything if init failed to resolve the libthread_db
-     library.  */
-  if (!procfs_suppress_run)
-    return;
-
-  if (PIDGET (inferior_ptid) == -1)
-    {
-      printf_filtered ("No process.\n");
-      return;
-    }
+  struct target_ops *beneath = find_target_beneath (ops);
 
   /* First Find any new LWP's.  */
-  procfs_ops.to_find_new_threads ();
+  if (beneath->to_find_new_threads != NULL)
+    beneath->to_find_new_threads (beneath);
 
   /* Then find any new user-level threads.  */
   p_td_ta_thr_iter (main_ta, sol_find_new_threads_callback, (void *) 0,
@@ -1399,31 +1199,6 @@ sol_find_new_threads (void)
 		    TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
 }
 
-static void
-sol_core_open (char *filename, int from_tty)
-{
-  orig_core_ops.to_open (filename, from_tty);
-}
-
-static void
-sol_core_close (int quitting)
-{
-  orig_core_ops.to_close (quitting);
-}
-
-static void
-sol_core_detach (struct target_ops *ops, char *args, int from_tty)
-{
-  unpush_target (&core_ops);
-  orig_core_ops.to_detach (&orig_core_ops, args, from_tty);
-}
-
-static void
-sol_core_files_info (struct target_ops *t)
-{
-  orig_core_ops.to_files_info (t);
-}
-
 /* Worker bee for the "info sol-thread" command.  This is a callback
    function that gets called once for each Solaris user-level thread
    (i.e. not for LWPs) in the inferior.  Print anything interesting
@@ -1511,119 +1286,32 @@ info_solthreads (char *args, int from_tt
 		    TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
 }
 
-static int
-sol_find_memory_regions (int (*func) (CORE_ADDR, unsigned long,
-				      int, int, int, void *),
-			 void *data)
-{
-  return procfs_ops.to_find_memory_regions (func, data);
-}
-
-static char *
-sol_make_note_section (bfd *obfd, int *note_size)
-{
-  return procfs_ops.to_make_corefile_notes (obfd, note_size);
-}
-
-static int
-ignore (struct bp_target_info *bp_tgt)
-{
-  return 0;
-}
-
 static void
 init_sol_thread_ops (void)
 {
   sol_thread_ops.to_shortname = "solaris-threads";
   sol_thread_ops.to_longname = "Solaris threads and pthread.";
   sol_thread_ops.to_doc = "Solaris threads and pthread support.";
-  sol_thread_ops.to_open = sol_thread_open;
-  sol_thread_ops.to_attach = sol_thread_attach;
   sol_thread_ops.to_detach = sol_thread_detach;
   sol_thread_ops.to_resume = sol_thread_resume;
   sol_thread_ops.to_wait = sol_thread_wait;
   sol_thread_ops.to_fetch_registers = sol_thread_fetch_registers;
   sol_thread_ops.to_store_registers = sol_thread_store_registers;
-  sol_thread_ops.to_prepare_to_store = sol_thread_prepare_to_store;
-  sol_thread_ops.deprecated_xfer_memory = sol_thread_xfer_memory;
   sol_thread_ops.to_xfer_partial = sol_thread_xfer_partial;
-  sol_thread_ops.to_files_info = sol_thread_files_info;
-  sol_thread_ops.to_insert_breakpoint = memory_insert_breakpoint;
-  sol_thread_ops.to_remove_breakpoint = memory_remove_breakpoint;
-  sol_thread_ops.to_terminal_init = terminal_init_inferior;
-  sol_thread_ops.to_terminal_inferior = terminal_inferior;
-  sol_thread_ops.to_terminal_ours_for_output = terminal_ours_for_output;
-  sol_thread_ops.to_terminal_ours = terminal_ours;
-  sol_thread_ops.to_terminal_save_ours = terminal_save_ours;
-  sol_thread_ops.to_terminal_info = child_terminal_info;
-  sol_thread_ops.to_kill = sol_thread_kill_inferior;
-  sol_thread_ops.to_create_inferior = sol_thread_create_inferior;
   sol_thread_ops.to_mourn_inferior = sol_thread_mourn_inferior;
-  sol_thread_ops.to_can_run = sol_thread_can_run;
-  sol_thread_ops.to_notice_signals = sol_thread_notice_signals;
   sol_thread_ops.to_thread_alive = sol_thread_alive;
   sol_thread_ops.to_pid_to_str = solaris_pid_to_str;
   sol_thread_ops.to_find_new_threads = sol_find_new_threads;
-  sol_thread_ops.to_stop = sol_thread_stop;
-  sol_thread_ops.to_stratum = process_stratum;
-  sol_thread_ops.to_has_all_memory = 1;
-  sol_thread_ops.to_has_memory = 1;
-  sol_thread_ops.to_has_stack = 1;
-  sol_thread_ops.to_has_registers = 1;
-  sol_thread_ops.to_has_execution = 1;
-  sol_thread_ops.to_has_thread_control = tc_none;
-  sol_thread_ops.to_find_memory_regions = sol_find_memory_regions;
-  sol_thread_ops.to_make_corefile_notes = sol_make_note_section;
+  sol_thread_ops.to_stratum = thread_stratum;
   sol_thread_ops.to_magic = OPS_MAGIC;
 }
 
-static void
-init_sol_core_ops (void)
-{
-  sol_core_ops.to_shortname = "solaris-core";
-  sol_core_ops.to_longname = "Solaris core threads and pthread.";
-  sol_core_ops.to_doc = "Solaris threads and pthread support for core files.";
-  sol_core_ops.to_open = sol_core_open;
-  sol_core_ops.to_close = sol_core_close;
-  sol_core_ops.to_attach = sol_thread_attach;
-  sol_core_ops.to_detach = sol_core_detach;
-  sol_core_ops.to_fetch_registers = sol_thread_fetch_registers;
-  sol_core_ops.deprecated_xfer_memory = sol_thread_xfer_memory;
-  sol_core_ops.to_xfer_partial = sol_thread_xfer_partial;
-  sol_core_ops.to_files_info = sol_core_files_info;
-  sol_core_ops.to_insert_breakpoint = ignore;
-  sol_core_ops.to_remove_breakpoint = ignore;
-  sol_core_ops.to_create_inferior = sol_thread_create_inferior;
-  sol_core_ops.to_stratum = core_stratum;
-  sol_core_ops.to_has_memory = 1;
-  sol_core_ops.to_has_stack = 1;
-  sol_core_ops.to_has_registers = 1;
-  sol_core_ops.to_has_thread_control = tc_none;
-  sol_core_ops.to_thread_alive = sol_thread_alive;
-  sol_core_ops.to_pid_to_str = solaris_pid_to_str;
-  /* On Solaris/x86, when debugging a threaded core file from process
-     <n>, the following causes "info threads" to produce "procfs:
-     couldn't find pid <n> in procinfo list" where <n> is the pid of
-     the process that produced the core file.  Disable it for now. */
-#if 0
-  sol_core_ops.to_find_new_threads = sol_find_new_threads;
-#endif
-  sol_core_ops.to_magic = OPS_MAGIC;
-}
-
-/* We suppress the call to add_target of core_ops in corelow because
-   if there are two targets in the stratum core_stratum,
-   find_core_target won't know which one to return.  See corelow.c for
-   an additonal comment on coreops_suppress_target.  */
-int coreops_suppress_target = 1;
-
 void
 _initialize_sol_thread (void)
 {
   void *dlhandle;
 
   init_sol_thread_ops ();
-  init_sol_core_ops ();
 
   dlhandle = dlopen ("libthread_db.so.1", RTLD_NOW);
   if (!dlhandle)
@@ -1659,19 +1347,9 @@ _initialize_sol_thread (void)
 
   add_target (&sol_thread_ops);
 
-  procfs_suppress_run = 1;
-
   add_cmd ("sol-threads", class_maintenance, info_solthreads,
 	   _("Show info on Solaris user threads."), &maintenanceinfolist);
 
-  /* FIXME: This code takes errant advantage of the order in which
-     initialization routines are run.  _initialize_corelow must run before
-     this one otherwise orig_core_ops will still contain zeros and the work
-     of init_sol_core_ops will be undone.  */
-  memcpy (&orig_core_ops, &core_ops, sizeof (struct target_ops));
-  memcpy (&core_ops, &sol_core_ops, sizeof (struct target_ops));
-  add_target (&core_ops);
-
   /* Hook into new_objfile notification.  */
   observer_attach_new_objfile (sol_thread_new_objfile);
   return;
@@ -1683,8 +1361,5 @@ _initialize_sol_thread (void)
   if (dlhandle)
     dlclose (dlhandle);
 
-  /* Allow the user to debug non-threaded core files.  */
-  add_target (&core_ops);
-
   return;
 }
Index: src/gdb/target.h
===================================================================
--- src.orig/gdb/target.h	2009-02-16 00:20:29.000000000 +0000
+++ src/gdb/target.h	2009-02-16 03:26:06.000000000 +0000
@@ -332,11 +332,11 @@ struct target_ops
     void (*to_post_attach) (int);
     void (*to_detach) (struct target_ops *ops, char *, int);
     void (*to_disconnect) (struct target_ops *, char *, int);
-    void (*to_resume) (ptid_t, int, enum target_signal);
+    void (*to_resume) (struct target_ops *, ptid_t, int, enum target_signal);
     ptid_t (*to_wait) (struct target_ops *,
 		      ptid_t, struct target_waitstatus *);
-    void (*to_fetch_registers) (struct regcache *, int);
-    void (*to_store_registers) (struct regcache *, int);
+    void (*to_fetch_registers) (struct target_ops *, struct regcache *, int);
+    void (*to_store_registers) (struct target_ops *, struct regcache *, int);
     void (*to_prepare_to_store) (struct regcache *);
 
     /* Transfer LEN bytes of memory between GDB address MYADDR and
@@ -404,8 +404,8 @@ struct target_ops
     void (*to_mourn_inferior) (struct target_ops *);
     int (*to_can_run) (void);
     void (*to_notice_signals) (ptid_t ptid);
-    int (*to_thread_alive) (ptid_t ptid);
-    void (*to_find_new_threads) (void);
+    int (*to_thread_alive) (struct target_ops *, ptid_t ptid);
+    void (*to_find_new_threads) (struct target_ops *);
     char *(*to_pid_to_str) (struct target_ops *, ptid_t);
     char *(*to_extra_thread_info) (struct thread_info *);
     void (*to_stop) (ptid_t);
@@ -634,15 +634,13 @@ extern ptid_t target_wait (ptid_t ptid, 
 
 /* Fetch at least register REGNO, or all regs if regno == -1.  No result.  */
 
-#define	target_fetch_registers(regcache, regno)	\
-     (*current_target.to_fetch_registers) (regcache, regno)
+extern void target_fetch_registers (struct regcache *regcache, int regno);
 
 /* Store at least register REGNO, or all regs if REGNO == -1.
    It can store as many registers as it wants to, so target_prepare_to_store
    must have been previously called.  Calls error() if there are problems.  */
 
-#define	target_store_registers(regcache, regs)	\
-     (*current_target.to_store_registers) (regcache, regs)
+extern void target_store_registers (struct regcache *regcache, int regs);
 
 /* Get ready to modify the registers array.  On machines which store
    individual registers, this doesn't need to do anything.  On machines
@@ -918,13 +916,11 @@ void target_mourn_inferior (void);
 
 /* Check to see if a thread is still alive.  */
 
-#define target_thread_alive(ptid) \
-     (*current_target.to_thread_alive) (ptid)
+extern int target_thread_alive (ptid_t ptid);
 
 /* Query for new threads and add them to the thread list.  */
 
-#define target_find_new_threads() \
-     (*current_target.to_find_new_threads) ()
+extern void target_find_new_threads (void);
 
 /* Make target stop in a continuable fashion.  (For instance, under
    Unix, this should act like SIGSTOP).  This function is normally
Index: src/gdb/gdbcore.h
===================================================================
--- src.orig/gdb/gdbcore.h	2009-02-16 00:20:29.000000000 +0000
+++ src/gdb/gdbcore.h	2009-02-16 03:26:06.000000000 +0000
@@ -114,10 +114,6 @@ extern void exec_file_clear (int from_tt
 
 extern void validate_files (void);
 
-/* The target vector for core files. */
-
-extern struct target_ops core_ops;
-
 /* The current default bfd target.  */
 
 extern char *gnutarget;
Index: src/gdb/inf-ptrace.c
===================================================================
--- src.orig/gdb/inf-ptrace.c	2009-02-16 00:20:29.000000000 +0000
+++ src/gdb/inf-ptrace.c	2009-02-16 03:26:06.000000000 +0000
@@ -351,7 +351,8 @@ inf_ptrace_stop (ptid_t ptid)
    that signal.  */
 
 static void
-inf_ptrace_resume (ptid_t ptid, int step, enum target_signal signal)
+inf_ptrace_resume (struct target_ops *ops,
+		   ptid_t ptid, int step, enum target_signal signal)
 {
   pid_t pid = ptid_get_pid (ptid);
   int request = PT_CONTINUE;
@@ -598,7 +599,7 @@ inf_ptrace_xfer_partial (struct target_o
 /* Return non-zero if the thread specified by PTID is alive.  */
 
 static int
-inf_ptrace_thread_alive (ptid_t ptid)
+inf_ptrace_thread_alive (struct target_ops *ops, ptid_t ptid)
 {
   /* ??? Is kill the right way to do this?  */
   return (kill (ptid_get_pid (ptid), 0) != -1);
@@ -705,7 +706,8 @@ inf_ptrace_fetch_register (struct regcac
    for all registers.  */
 
 static void
-inf_ptrace_fetch_registers (struct regcache *regcache, int regnum)
+inf_ptrace_fetch_registers (struct target_ops *ops,
+			    struct regcache *regcache, int regnum)
 {
   if (regnum == -1)
     for (regnum = 0;
@@ -762,7 +764,8 @@ inf_ptrace_store_register (const struct 
    this for all registers.  */
 
 void
-inf_ptrace_store_registers (struct regcache *regcache, int regnum)
+inf_ptrace_store_registers (struct target_ops *ops,
+			    struct regcache *regcache, int regnum)
 {
   if (regnum == -1)
     for (regnum = 0;
Index: src/gdb/linux-nat.c
===================================================================
--- src.orig/gdb/linux-nat.c	2009-02-16 00:20:29.000000000 +0000
+++ src/gdb/linux-nat.c	2009-02-16 03:26:06.000000000 +0000
@@ -990,7 +990,7 @@ static struct sigaction sigchld_default_
 
 /* Prototypes for local functions.  */
 static int stop_wait_callback (struct lwp_info *lp, void *data);
-static int linux_nat_thread_alive (ptid_t ptid);
+static int linux_thread_alive (ptid_t ptid);
 static char *linux_child_pid_to_exec_file (int pid);
 static int cancel_breakpoint (struct lwp_info *lp);
 
@@ -1664,7 +1664,8 @@ resume_callback (struct lwp_info *lp, vo
 {
   if (lp->stopped && lp->status == 0)
     {
-      linux_ops->to_resume (pid_to_ptid (GET_LWP (lp->ptid)),
+      linux_ops->to_resume (linux_ops,
+			    pid_to_ptid (GET_LWP (lp->ptid)),
 			    0, TARGET_SIGNAL_0);
       if (debug_linux_nat)
 	fprintf_unfiltered (gdb_stdlog,
@@ -1699,7 +1700,8 @@ resume_set_callback (struct lwp_info *lp
 }
 
 static void
-linux_nat_resume (ptid_t ptid, int step, enum target_signal signo)
+linux_nat_resume (struct target_ops *ops,
+		  ptid_t ptid, int step, enum target_signal signo)
 {
   struct lwp_info *lp;
   int resume_all;
@@ -1810,7 +1812,7 @@ linux_nat_resume (ptid_t ptid, int step,
   if (resume_all)
     iterate_over_lwps (resume_callback, NULL);
 
-  linux_ops->to_resume (ptid, step, signo);
+  linux_ops->to_resume (linux_ops, ptid, step, signo);
   memset (&lp->siginfo, 0, sizeof (lp->siginfo));
 
   if (debug_linux_nat)
@@ -2655,7 +2657,7 @@ linux_nat_filter_event (int lwpid, int s
      thread model, LWPs other than the main thread do not issue
      signals when they exit so we must check whenever the thread has
      stopped.  A similar check is made in stop_wait_callback().  */
-  if (num_lwps > 1 && !linux_nat_thread_alive (lp->ptid))
+  if (num_lwps > 1 && !linux_thread_alive (lp->ptid))
     {
       if (debug_linux_nat)
 	fprintf_unfiltered (gdb_stdlog,
@@ -2686,7 +2688,7 @@ linux_nat_filter_event (int lwpid, int s
 
       registers_changed ();
 
-      linux_ops->to_resume (pid_to_ptid (GET_LWP (lp->ptid)),
+      linux_ops->to_resume (linux_ops, pid_to_ptid (GET_LWP (lp->ptid)),
 			    lp->step, TARGET_SIGNAL_0);
       if (debug_linux_nat)
 	fprintf_unfiltered (gdb_stdlog,
@@ -2716,7 +2718,7 @@ linux_nat_filter_event (int lwpid, int s
       lp->ignore_sigint = 0;
 
       registers_changed ();
-      linux_ops->to_resume (pid_to_ptid (GET_LWP (lp->ptid)),
+      linux_ops->to_resume (linux_ops, pid_to_ptid (GET_LWP (lp->ptid)),
 			    lp->step, TARGET_SIGNAL_0);
       if (debug_linux_nat)
 	fprintf_unfiltered (gdb_stdlog,
@@ -2885,7 +2887,7 @@ retry:
       /* Resume the thread.  It should halt immediately returning the
          pending SIGSTOP.  */
       registers_changed ();
-      linux_ops->to_resume (pid_to_ptid (GET_LWP (lp->ptid)),
+      linux_ops->to_resume (linux_ops, pid_to_ptid (GET_LWP (lp->ptid)),
 			    lp->step, TARGET_SIGNAL_0);
       if (debug_linux_nat)
 	fprintf_unfiltered (gdb_stdlog,
@@ -3006,7 +3008,7 @@ retry:
 	     newly attached threads may cause an unwanted delay in
 	     getting them running.  */
 	  registers_changed ();
-	  linux_ops->to_resume (pid_to_ptid (GET_LWP (lp->ptid)),
+	  linux_ops->to_resume (linux_ops, pid_to_ptid (GET_LWP (lp->ptid)),
 				lp->step, signo);
 	  if (debug_linux_nat)
 	    fprintf_unfiltered (gdb_stdlog,
@@ -3334,7 +3336,7 @@ linux_nat_xfer_partial (struct target_op
 }
 
 static int
-linux_nat_thread_alive (ptid_t ptid)
+linux_thread_alive (ptid_t ptid)
 {
   int err;
 
@@ -3357,6 +3359,12 @@ linux_nat_thread_alive (ptid_t ptid)
   return 1;
 }
 
+static int
+linux_nat_thread_alive (struct target_ops *ops, ptid_t ptid)
+{
+  return linux_thread_alive (ptid);
+}
+
 static char *
 linux_nat_pid_to_str (struct target_ops *ops, ptid_t ptid)
 {
Index: src/gdb/remote.c
===================================================================
--- src.orig/gdb/remote.c	2009-02-16 00:20:29.000000000 +0000
+++ src/gdb/remote.c	2009-02-16 03:26:06.000000000 +0000
@@ -91,10 +91,6 @@ static void remote_files_info (struct ta
 
 static void remote_prepare_to_store (struct regcache *regcache);
 
-static void remote_fetch_registers (struct regcache *regcache, int regno);
-
-static void remote_resume (ptid_t ptid, int step,
-                           enum target_signal siggnal);
 static void remote_open (char *name, int from_tty);
 
 static void extended_remote_open (char *name, int from_tty);
@@ -103,8 +99,6 @@ static void remote_open_1 (char *, int, 
 
 static void remote_close (int quitting);
 
-static void remote_store_registers (struct regcache *regcache, int regno);
-
 static void remote_mourn (struct target_ops *ops);
 
 static void extended_remote_restart (void);
@@ -141,8 +135,6 @@ static void interrupt_query (void);
 static void set_general_thread (struct ptid ptid);
 static void set_continue_thread (struct ptid ptid);
 
-static int remote_thread_alive (ptid_t);
-
 static void get_offsets (void);
 
 static void skip_frame (void);
@@ -1327,7 +1319,7 @@ set_general_process (void)
     system.  */
 
 static int
-remote_thread_alive (ptid_t ptid)
+remote_thread_alive (struct target_ops *ops, ptid_t ptid)
 {
   struct remote_state *rs = get_remote_state ();
   int tid = ptid_get_tid (ptid);
@@ -2133,7 +2125,7 @@ remote_find_new_threads (void)
  */
 
 static void
-remote_threads_info (void)
+remote_threads_info (struct target_ops *ops)
 {
   struct remote_state *rs = get_remote_state ();
   char *bufp;
@@ -2580,7 +2572,7 @@ remote_start_remote (struct ui_out *uiou
 	 controlling.  We default to adding them in the running state.
 	 The '?' query below will then tell us about which threads are
 	 stopped.  */
-      remote_threads_info ();
+      remote_threads_info (args->target);
     }
   else if (rs->non_stop_aware)
     {
@@ -3413,7 +3405,7 @@ extended_remote_attach_1 (struct target_
 
   if (non_stop)
     /* Get list of threads.  */
-    remote_threads_info ();
+    remote_threads_info (target);
   else
     /* Add the main thread to the thread list.  */
     add_thread_silent (inferior_ptid);
@@ -3696,7 +3688,8 @@ static enum target_signal last_sent_sign
 static int last_sent_step;
 
 static void
-remote_resume (ptid_t ptid, int step, enum target_signal siggnal)
+remote_resume (struct target_ops *ops,
+	       ptid_t ptid, int step, enum target_signal siggnal)
 {
   struct remote_state *rs = get_remote_state ();
   char *buf;
@@ -4960,7 +4953,8 @@ fetch_registers_using_g (struct regcache
 }
 
 static void
-remote_fetch_registers (struct regcache *regcache, int regnum)
+remote_fetch_registers (struct target_ops *ops,
+			struct regcache *regcache, int regnum)
 {
   struct remote_state *rs = get_remote_state ();
   struct remote_arch_state *rsa = get_remote_arch_state ();
@@ -5109,7 +5103,8 @@ store_registers_using_G (const struct re
    of the register cache buffer.  FIXME: ignores errors.  */
 
 static void
-remote_store_registers (struct regcache *regcache, int regnum)
+remote_store_registers (struct target_ops *ops,
+			struct regcache *regcache, int regnum)
 {
   struct remote_state *rs = get_remote_state ();
   struct remote_arch_state *rsa = get_remote_arch_state ();
Index: src/gdb/target.c
===================================================================
--- src.orig/gdb/target.c	2009-02-16 00:20:29.000000000 +0000
+++ src/gdb/target.c	2009-02-16 03:26:06.000000000 +0000
@@ -97,12 +97,6 @@ static struct target_ops debug_target;
 
 static void debug_to_open (char *, int);
 
-static void debug_to_resume (ptid_t, int, enum target_signal);
-
-static void debug_to_fetch_registers (struct regcache *, int);
-
-static void debug_to_store_registers (struct regcache *, int);
-
 static void debug_to_prepare_to_store (struct regcache *);
 
 static void debug_to_files_info (struct target_ops *);
@@ -152,8 +146,6 @@ static int debug_to_can_run (void);
 
 static void debug_to_notice_signals (ptid_t);
 
-static int debug_to_thread_alive (ptid_t);
-
 static void debug_to_stop (ptid_t);
 
 /* NOTE: cagney/2004-09-29: Many targets reference this variable in
@@ -412,10 +404,10 @@ update_current_target (void)
       INHERIT (to_attach_no_wait, t);
       /* Do not inherit to_detach.  */
       /* Do not inherit to_disconnect.  */
-      INHERIT (to_resume, t);
+      /* Do not inherit to_resume.  */
       /* Do not inherit to_wait.  */
-      INHERIT (to_fetch_registers, t);
-      INHERIT (to_store_registers, t);
+      /* Do not inherit to_fetch_registers.  */
+      /* Do not inherit to_store_registers.  */
       INHERIT (to_prepare_to_store, t);
       INHERIT (deprecated_xfer_memory, t);
       INHERIT (to_files_info, t);
@@ -455,8 +447,8 @@ update_current_target (void)
       /* Do not inherit to_mourn_inferiour.  */
       INHERIT (to_can_run, t);
       INHERIT (to_notice_signals, t);
-      INHERIT (to_thread_alive, t);
-      INHERIT (to_find_new_threads, t);
+      /* Do not inherit to_thread_alive.  */
+      /* Do not inherit to_find_new_threads.  */
       /* Do not inherit to_pid_to_str.  */
       INHERIT (to_extra_thread_info, t);
       INHERIT (to_stop, t);
@@ -509,15 +501,6 @@ update_current_target (void)
   de_fault (to_post_attach,
 	    (void (*) (int))
 	    target_ignore);
-  de_fault (to_resume,
-	    (void (*) (ptid_t, int, enum target_signal))
-	    noprocess);
-  de_fault (to_fetch_registers,
-	    (void (*) (struct regcache *, int))
-	    target_ignore);
-  de_fault (to_store_registers,
-	    (void (*) (struct regcache *, int))
-	    noprocess);
   de_fault (to_prepare_to_store,
 	    (void (*) (struct regcache *))
 	    noprocess);
@@ -614,12 +597,6 @@ update_current_target (void)
   de_fault (to_notice_signals,
 	    (void (*) (ptid_t))
 	    target_ignore);
-  de_fault (to_thread_alive,
-	    (int (*) (ptid_t))
-	    return_zero);
-  de_fault (to_find_new_threads,
-	    (void (*) (void))
-	    target_ignore);
   de_fault (to_extra_thread_info,
 	    (char *(*) (struct thread_info *))
 	    return_zero);
@@ -1892,10 +1869,28 @@ target_pid_to_str (ptid_t ptid)
 void
 target_resume (ptid_t ptid, int step, enum target_signal signal)
 {
+  struct target_ops *t;
+
   dcache_invalidate (target_dcache);
-  (*current_target.to_resume) (ptid, step, signal);
-  set_executing (ptid, 1);
-  set_running (ptid, 1);
+
+  for (t = current_target.beneath; t != NULL; t = t->beneath)
+    {
+      if (t->to_resume != NULL)
+	{
+	  t->to_resume (t, ptid, step, signal);
+	  if (targetdebug)
+	    fprintf_unfiltered (gdb_stdlog, "target_resume (%d, %s, %s)\n",
+				PIDGET (ptid),
+				step ? "step" : "continue",
+				target_signal_to_name (signal));
+
+	  set_executing (ptid, 1);
+	  set_running (ptid, 1);
+	  return;
+	}
+    }
+
+  noprocess ();
 }
 /* Look through the list of possible targets for a target that can
    follow forks.  */
@@ -2607,22 +2602,51 @@ target_attach (char *args, int from_tty)
 		  "could not find a target to attach");
 }
 
-static void
-debug_to_post_attach (int pid)
+int
+target_thread_alive (ptid_t ptid)
 {
-  debug_target.to_post_attach (pid);
+  struct target_ops *t;
+  for (t = current_target.beneath; t != NULL; t = t->beneath)
+    {
+      if (t->to_thread_alive != NULL)
+	{
+	  int retval;
 
-  fprintf_unfiltered (gdb_stdlog, "target_post_attach (%d)\n", pid);
+	  retval = t->to_thread_alive (t, ptid);
+	  if (targetdebug)
+	    fprintf_unfiltered (gdb_stdlog, "target_thread_alive (%d) = %d\n",
+				PIDGET (ptid), retval);
+
+	  return retval;
+	}
+    }
+
+  return 0;
+}
+
+void
+target_find_new_threads (void)
+{
+  struct target_ops *t;
+  for (t = current_target.beneath; t != NULL; t = t->beneath)
+    {
+      if (t->to_find_new_threads != NULL)
+	{
+	  t->to_find_new_threads (t);
+	  if (targetdebug)
+	    fprintf_unfiltered (gdb_stdlog, "target_find_new_threads ()\n");
+
+	  return;
+	}
+    }
 }
 
 static void
-debug_to_resume (ptid_t ptid, int step, enum target_signal siggnal)
+debug_to_post_attach (int pid)
 {
-  debug_target.to_resume (ptid, step, siggnal);
+  debug_target.to_post_attach (pid);
 
-  fprintf_unfiltered (gdb_stdlog, "target_resume (%d, %s, %s)\n", PIDGET (ptid),
-		      step ? "step" : "continue",
-		      target_signal_to_name (siggnal));
+  fprintf_unfiltered (gdb_stdlog, "target_post_attach (%d)\n", pid);
 }
 
 /* Return a pretty printed form of target_waitstatus.
@@ -2700,19 +2724,41 @@ debug_print_register (const char * func,
   fprintf_unfiltered (gdb_stdlog, "\n");
 }
 
-static void
-debug_to_fetch_registers (struct regcache *regcache, int regno)
+void
+target_fetch_registers (struct regcache *regcache, int regno)
 {
-  debug_target.to_fetch_registers (regcache, regno);
-  debug_print_register ("target_fetch_registers", regcache, regno);
+  struct target_ops *t;
+  for (t = current_target.beneath; t != NULL; t = t->beneath)
+    {
+      if (t->to_fetch_registers != NULL)
+	{
+	  t->to_fetch_registers (t, regcache, regno);
+	  if (targetdebug)
+	    debug_print_register ("target_fetch_registers", regcache, regno);
+	  return;
+	}
+    }
 }
 
-static void
-debug_to_store_registers (struct regcache *regcache, int regno)
+void
+target_store_registers (struct regcache *regcache, int regno)
 {
-  debug_target.to_store_registers (regcache, regno);
-  debug_print_register ("target_store_registers", regcache, regno);
-  fprintf_unfiltered (gdb_stdlog, "\n");
+
+  struct target_ops *t;
+  for (t = current_target.beneath; t != NULL; t = t->beneath)
+    {
+      if (t->to_store_registers != NULL)
+	{
+	  t->to_store_registers (t, regcache, regno);
+	  if (targetdebug)
+	    {
+	      debug_print_register ("target_store_registers", regcache, regno);
+	    }
+	  return;
+	}
+    }
+
+  noprocess ();
 }
 
 static void
@@ -3124,27 +3170,6 @@ debug_to_notice_signals (ptid_t ptid)
                       PIDGET (ptid));
 }
 
-static int
-debug_to_thread_alive (ptid_t ptid)
-{
-  int retval;
-
-  retval = debug_target.to_thread_alive (ptid);
-
-  fprintf_unfiltered (gdb_stdlog, "target_thread_alive (%d) = %d\n",
-		      PIDGET (ptid), retval);
-
-  return retval;
-}
-
-static void
-debug_to_find_new_threads (void)
-{
-  debug_target.to_find_new_threads ();
-
-  fputs_unfiltered ("target_find_new_threads ()\n", gdb_stdlog);
-}
-
 static void
 debug_to_stop (ptid_t ptid)
 {
@@ -3182,9 +3207,6 @@ setup_target_debug (void)
 
   current_target.to_open = debug_to_open;
   current_target.to_post_attach = debug_to_post_attach;
-  current_target.to_resume = debug_to_resume;
-  current_target.to_fetch_registers = debug_to_fetch_registers;
-  current_target.to_store_registers = debug_to_store_registers;
   current_target.to_prepare_to_store = debug_to_prepare_to_store;
   current_target.deprecated_xfer_memory = deprecated_debug_xfer_memory;
   current_target.to_files_info = debug_to_files_info;
@@ -3219,8 +3241,6 @@ setup_target_debug (void)
   current_target.to_has_exited = debug_to_has_exited;
   current_target.to_can_run = debug_to_can_run;
   current_target.to_notice_signals = debug_to_notice_signals;
-  current_target.to_thread_alive = debug_to_thread_alive;
-  current_target.to_find_new_threads = debug_to_find_new_threads;
   current_target.to_stop = debug_to_stop;
   current_target.to_rcmd = debug_to_rcmd;
   current_target.to_pid_to_exec_file = debug_to_pid_to_exec_file;
Index: src/gdb/amd64-linux-nat.c
===================================================================
--- src.orig/gdb/amd64-linux-nat.c	2009-02-16 00:20:29.000000000 +0000
+++ src/gdb/amd64-linux-nat.c	2009-02-16 03:26:06.000000000 +0000
@@ -155,7 +155,8 @@ fill_fpregset (const struct regcache *re
    registers).  */
 
 static void
-amd64_linux_fetch_inferior_registers (struct regcache *regcache, int regnum)
+amd64_linux_fetch_inferior_registers (struct target_ops *ops,
+				      struct regcache *regcache, int regnum)
 {
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
   int tid;
@@ -193,7 +194,8 @@ amd64_linux_fetch_inferior_registers (st
    registers).  */
 
 static void
-amd64_linux_store_inferior_registers (struct regcache *regcache, int regnum)
+amd64_linux_store_inferior_registers (struct target_ops *ops,
+				      struct regcache *regcache, int regnum)
 {
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
   int tid;
Index: src/gdb/inf-child.c
===================================================================
--- src.orig/gdb/inf-child.c	2009-02-16 00:20:29.000000000 +0000
+++ src/gdb/inf-child.c	2009-02-16 03:26:06.000000000 +0000
@@ -32,7 +32,8 @@
    for all registers.  */
 
 static void
-inf_child_fetch_inferior_registers (struct regcache *regcache, int regnum)
+inf_child_fetch_inferior_registers (struct target_ops *ops,
+				    struct regcache *regcache, int regnum)
 {
   if (regnum == -1)
     {
@@ -49,7 +50,8 @@ inf_child_fetch_inferior_registers (stru
    this for all registers (including the floating point registers).  */
 
 static void
-inf_child_store_inferior_registers (struct regcache *regcache, int regnum)
+inf_child_store_inferior_registers (struct target_ops *ops,
+				    struct regcache *regcache, int regnum)
 {
 }
 
Index: src/gdb/linux-thread-db.c
===================================================================
--- src.orig/gdb/linux-thread-db.c	2009-02-16 00:20:29.000000000 +0000
+++ src/gdb/linux-thread-db.c	2009-02-16 03:40:06.000000000 +0000
@@ -139,7 +139,7 @@ static CORE_ADDR td_create_bp_addr;
 static CORE_ADDR td_death_bp_addr;
 
 /* Prototypes for local functions.  */
-static void thread_db_find_new_threads (void);
+static void thread_db_find_new_threads_1 (void);
 static void attach_thread (ptid_t ptid, const td_thrhandle_t *th_p,
 			   const td_thrinfo_t *ti_p);
 static void detach_thread (ptid_t ptid);
@@ -281,7 +281,7 @@ thread_get_info_callback (const td_thrha
     {
       /* New thread.  Attach to it now (why wait?).  */
       if (!have_threads ())
-	thread_db_find_new_threads ();
+	target_find_new_threads ();
       else
 	attach_thread (thread_ptid, thp, &ti);
       thread_info = find_thread_pid (thread_ptid);
@@ -358,7 +358,7 @@ thread_db_attach_lwp (ptid_t ptid)
      initialized, we may not know its thread ID yet.  Make sure we do
      before we add another thread to the list.  */
   if (!have_threads ())
-    thread_db_find_new_threads ();
+    thread_db_find_new_threads_1 ();
 
   err = td_ta_map_lwp2thr_p (thread_agent, GET_LWP (ptid), &th);
   if (err != TD_OK)
@@ -655,7 +655,7 @@ check_for_thread_db (void)
       using_thread_db = 1;
 
       enable_thread_event_reporting ();
-      thread_db_find_new_threads ();
+      thread_db_find_new_threads_1 ();
       break;
 
     default:
@@ -816,7 +816,7 @@ check_event (ptid_t ptid)
      initialized, we may not know its thread ID yet.  Make sure we do
      before we add another thread to the list.  */
   if (!have_threads ())
-    thread_db_find_new_threads ();
+    thread_db_find_new_threads_1 ();
 
   /* If we are at a create breakpoint, we do not know what new lwp
      was created and cannot specifically locate the event message for it.
@@ -904,7 +904,7 @@ thread_db_wait (struct target_ops *ops,
   /* If we do not know about the main thread yet, this would be a good time to
      find it.  */
   if (ourstatus->kind == TARGET_WAITKIND_STOPPED && !have_threads ())
-    thread_db_find_new_threads ();
+    thread_db_find_new_threads_1 ();
 
   if (ourstatus->kind == TARGET_WAITKIND_STOPPED
       && ourstatus->value.sig == TARGET_SIGNAL_TRAP)
@@ -992,7 +992,7 @@ find_new_threads_callback (const td_thrh
    PTID.  */
 
 static void
-thread_db_find_new_threads (void)
+thread_db_find_new_threads_1 (void)
 {
   td_err_e err;
   struct lwp_info *lp;
@@ -1017,6 +1017,12 @@ thread_db_find_new_threads (void)
     error (_("Cannot find new threads: %s"), thread_db_err_str (err));
 }
 
+static void
+thread_db_find_new_threads (struct target_ops *ops)
+{
+  thread_db_find_new_threads_1 ();
+}
+
 static char *
 thread_db_pid_to_str (struct target_ops *ops, ptid_t ptid)
 {
@@ -1072,7 +1078,7 @@ thread_db_get_thread_local_address (stru
 
   /* If we have not discovered any threads yet, check now.  */
   if (!have_threads ())
-    thread_db_find_new_threads ();
+    thread_db_find_new_threads_1 ();
 
   /* Find the matching thread.  */
   thread_info = find_thread_pid (ptid);
@@ -1147,7 +1153,7 @@ thread_db_get_ada_task_ptid (long lwp, l
 {
   struct thread_info *thread_info;
 
-  thread_db_find_new_threads ();
+  thread_db_find_new_threads_1 ();
   thread_info = iterate_over_threads (thread_db_find_thread_from_tid, &thread);
 
   gdb_assert (thread_info != NULL);
Index: src/gdb/bsd-uthread.c
===================================================================
--- src.orig/gdb/bsd-uthread.c	2009-02-16 00:20:29.000000000 +0000
+++ src/gdb/bsd-uthread.c	2009-02-16 03:26:06.000000000 +0000
@@ -272,21 +272,23 @@ bsd_uthread_solib_unloaded (struct so_li
 static void
 bsd_uthread_mourn_inferior (struct target_ops *ops)
 {
-  struct target_ops *beneath = find_target_beneath (bsd_uthread_ops_hack);
+  struct target_ops *beneath = find_target_beneath (ops);
   beneath->to_mourn_inferior (beneath);
   bsd_uthread_deactivate ();
 }
 
 static void
-bsd_uthread_fetch_registers (struct regcache *regcache, int regnum)
+bsd_uthread_fetch_registers (struct target_ops *ops,
+			     struct regcache *regcache, int regnum)
 {
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
-  struct bsd_uthread_ops *ops = gdbarch_data (gdbarch, bsd_uthread_data);
+  struct bsd_uthread_ops *uthread_ops = gdbarch_data (gdbarch, bsd_uthread_data);
   CORE_ADDR addr = ptid_get_tid (inferior_ptid);
+  struct target_ops *beneath = find_target_beneath (ops);
   CORE_ADDR active_addr;
 
   /* Always fetch the appropriate registers from the layer beneath.  */
-  find_target_beneath (bsd_uthread_ops_hack)->to_fetch_registers (regcache, regnum);
+  beneath->to_fetch_registers (beneath, regcache, regnum);
 
   /* FIXME: That might have gotten us more than we asked for.  Make
      sure we overwrite all relevant registers with values from the
@@ -297,16 +299,18 @@ bsd_uthread_fetch_registers (struct regc
   if (addr != 0 && addr != active_addr)
     {
       bsd_uthread_check_magic (addr);
-      ops->supply_uthread (regcache, regnum,
-			   addr + bsd_uthread_thread_ctx_offset);
+      uthread_ops->supply_uthread (regcache, regnum,
+				   addr + bsd_uthread_thread_ctx_offset);
     }
 }
 
 static void
-bsd_uthread_store_registers (struct regcache *regcache, int regnum)
+bsd_uthread_store_registers (struct target_ops *ops,
+			     struct regcache *regcache, int regnum)
 {
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
-  struct bsd_uthread_ops *ops = gdbarch_data (gdbarch, bsd_uthread_data);
+  struct bsd_uthread_ops *uthread_ops = gdbarch_data (gdbarch, bsd_uthread_data);
+  struct target_ops *beneath = find_target_beneath (ops);
   CORE_ADDR addr = ptid_get_tid (inferior_ptid);
   CORE_ADDR active_addr;
 
@@ -314,14 +318,14 @@ bsd_uthread_store_registers (struct regc
   if (addr != 0 && addr != active_addr)
     {
       bsd_uthread_check_magic (addr);
-      ops->collect_uthread (regcache, regnum,
-			    addr + bsd_uthread_thread_ctx_offset);
+      uthread_ops->collect_uthread (regcache, regnum,
+				    addr + bsd_uthread_thread_ctx_offset);
     }
   else
     {
       /* Updating the thread that is currently running; pass the
          request to the layer beneath.  */
-      find_target_beneath (bsd_uthread_ops_hack)->to_store_registers (regcache, regnum);
+      beneath->to_store_registers (beneath, regcache, regnum);
     }
 }
 
@@ -344,7 +348,7 @@ bsd_uthread_wait (struct target_ops *ops
 		  ptid_t ptid, struct target_waitstatus *status)
 {
   CORE_ADDR addr;
-  struct target_ops *beneath = find_target_beneath (bsd_uthread_ops_hack);
+  struct target_ops *beneath = find_target_beneath (ops);
 
   /* Pass the request to the layer beneath.  */
   ptid = beneath->to_wait (beneath, ptid, status);
@@ -389,15 +393,18 @@ bsd_uthread_wait (struct target_ops *ops
 }
 
 static void
-bsd_uthread_resume (ptid_t ptid, int step, enum target_signal sig)
+bsd_uthread_resume (struct target_ops *ops,
+		    ptid_t ptid, int step, enum target_signal sig)
 {
   /* Pass the request to the layer beneath.  */
-  find_target_beneath (bsd_uthread_ops_hack)->to_resume (ptid, step, sig);
+  struct target_ops *beneath = find_target_beneath (ops);
+  beneath->to_resume (beneath, ptid, step, sig);
 }
 
 static int
-bsd_uthread_thread_alive (ptid_t ptid)
+bsd_uthread_thread_alive (struct target_ops *ops, ptid_t ptid)
 {
+  struct target_ops *beneath = find_target_beneath (ops);
   CORE_ADDR addr = ptid_get_tid (inferior_ptid);
 
   if (addr != 0)
@@ -412,11 +419,11 @@ bsd_uthread_thread_alive (ptid_t ptid)
 	return 0;
     }
 
-  return find_target_beneath (bsd_uthread_ops_hack)->to_thread_alive (ptid);
+  return beneath->to_thread_alive (beneath, ptid);
 }
 
 static void
-bsd_uthread_find_new_threads (void)
+bsd_uthread_find_new_threads (struct target_ops *ops)
 {
   pid_t pid = ptid_get_pid (inferior_ptid);
   int offset = bsd_uthread_thread_next_offset;
Index: src/gdb/inf-ttrace.c
===================================================================
--- src.orig/gdb/inf-ttrace.c	2009-02-16 00:20:29.000000000 +0000
+++ src/gdb/inf-ttrace.c	2009-02-16 03:26:06.000000000 +0000
@@ -39,8 +39,6 @@
 #include "inf-child.h"
 #include "inf-ttrace.h"
 
-/* HACK: Save the ttrace ops returned by inf_ttrace_target.  */
-static struct target_ops *ttrace_ops_hack;
 
 
 /* HP-UX uses a threading model where each user-space thread
@@ -618,7 +616,7 @@ inf_ttrace_me (void)
 /* Start tracing PID.  */
 
 static void
-inf_ttrace_him (int pid)
+inf_ttrace_him (struct target_ops *ops, int pid)
 {
   struct cleanup *old_chain = make_cleanup (do_cleanup_pfds, 0);
   ttevent_t tte;
@@ -646,7 +644,7 @@ inf_ttrace_him (int pid)
 
   do_cleanups (old_chain);
 
-  push_target (ttrace_ops_hack);
+  push_target (ops);
 
   /* On some targets, there must be some explicit synchronization
      between the parent and child processes after the debugger forks,
@@ -669,14 +667,18 @@ static void
 inf_ttrace_create_inferior (struct target_ops *ops, char *exec_file, 
 			    char *allargs, char **env, int from_tty)
 {
+  int pid;
+
   gdb_assert (inf_ttrace_num_lwps == 0);
   gdb_assert (inf_ttrace_num_lwps_in_syscall == 0);
   gdb_assert (inf_ttrace_page_dict.count == 0);
   gdb_assert (inf_ttrace_reenable_page_protections == 0);
   gdb_assert (inf_ttrace_vfork_ppid == -1);
 
-  fork_inferior (exec_file, allargs, env, inf_ttrace_me, inf_ttrace_him,
-		 inf_ttrace_prepare, NULL);
+  pid = fork_inferior (exec_file, allargs, env, inf_ttrace_me, NULL,
+		       inf_ttrace_prepare, NULL);
+
+  inf_ttrace_him (ops, pid);
 }
 
 static void
@@ -703,7 +705,7 @@ inf_ttrace_mourn_inferior (struct target
     }
   inf_ttrace_page_dict.count = 0;
 
-  unpush_target (ttrace_ops_hack);
+  unpush_target (ops);
   generic_mourn_inferior ();
 }
 
@@ -763,7 +765,7 @@ inf_ttrace_attach (struct target_ops *op
 	      (uintptr_t)&tte, sizeof tte, 0) == -1)
     perror_with_name (("ttrace"));
 
-  push_target (ttrace_ops_hack);
+  push_target (ops);
 
   /* We'll bump inf_ttrace_num_lwps up and add the private data to the
      thread as soon as we get to inf_ttrace_wait.  At this point, we
@@ -808,7 +810,7 @@ inf_ttrace_detach (struct target_ops *op
   inferior_ptid = null_ptid;
   detach_inferior (pid);
 
-  unpush_target (ttrace_ops_hack);
+  unpush_target (ops);
 }
 
 static void
@@ -891,7 +893,8 @@ inf_ttrace_resume_callback (struct threa
 }
 
 static void
-inf_ttrace_resume (ptid_t ptid, int step, enum target_signal signal)
+inf_ttrace_resume (struct target_ops *ops,
+		   ptid_t ptid, int step, enum target_signal signal)
 {
   int resume_all;
   ttreq_t request = step ? TT_LWP_SINGLE : TT_LWP_CONTINUE;
@@ -1232,7 +1235,7 @@ inf_ttrace_files_info (struct target_ops
 }
 
 static int
-inf_ttrace_thread_alive (ptid_t ptid)
+inf_ttrace_thread_alive (struct target_ops *ops, ptid_t ptid)
 {
   return 1;
 }
@@ -1294,7 +1297,6 @@ inf_ttrace_target (void)
   t->to_pid_to_str = inf_ttrace_pid_to_str;
   t->to_xfer_partial = inf_ttrace_xfer_partial;
 
-  ttrace_ops_hack = t;
   return t;
 }
 #endif
Index: src/gdb/darwin-nat.c
===================================================================
--- src.orig/gdb/darwin-nat.c	2009-02-16 00:20:29.000000000 +0000
+++ src/gdb/darwin-nat.c	2009-02-16 03:41:52.000000000 +0000
@@ -86,9 +86,6 @@ extern boolean_t exc_server (mach_msg_he
 
 static void darwin_stop (ptid_t);
 
-static void darwin_resume (ptid_t ptid, int step,
-			   enum target_signal signal);
-
 static void darwin_mourn_inferior (struct target_ops *ops);
 
 static int darwin_lookup_task (char *args, task_t * ptask, int *ppid);
@@ -104,8 +101,6 @@ static void darwin_create_inferior (stru
 
 static void darwin_files_info (struct target_ops *ops);
 
-static int darwin_thread_alive (ptid_t tpid);
-
 /* Current inferior.  */
 darwin_inferior *darwin_inf = NULL;
 
@@ -342,7 +337,8 @@ darwin_stop (ptid_t t)
 }
 
 static void
-darwin_resume (ptid_t ptid, int step, enum target_signal signal)
+darwin_resume (struct target_ops *ops,
+	       ptid_t ptid, int step, enum target_signal signal)
 {
   struct target_waitstatus status;
   int pid;
@@ -686,7 +682,7 @@ darwin_stop_inferior (darwin_inferior *i
   MACH_CHECK_ERROR (kret);
 
   if (msg_state == GOT_MESSAGE)
-    darwin_resume (inferior_ptid, 0, 0);
+    darwin_resume (darwin_ops, inferior_ptid, 0, 0);
 
   res = kill (inf->pid, SIGSTOP);
   if (res != 0)
@@ -697,7 +693,7 @@ darwin_stop_inferior (darwin_inferior *i
 }
 
 static void
-darwin_kill_inferior (void)
+darwin_kill_inferior (struct target_ops *ops)
 {
   struct target_waitstatus wstatus;
   ptid_t ptid;
@@ -718,7 +714,7 @@ darwin_kill_inferior (void)
   if (msg_state == GOT_MESSAGE)
     {
       exc_msg.ex_type = 0;
-      darwin_resume (inferior_ptid, 0, 0);
+      darwin_resume (ops, inferior_ptid, 0, 0);
     }
 
   kret = task_resume (darwin_inf->task);
@@ -1023,7 +1019,7 @@ darwin_detach (struct target_ops *ops, c
   if (msg_state == GOT_MESSAGE)
     {
       exc_msg.ex_type = 0;
-      darwin_resume (inferior_ptid, 0, 0);
+      darwin_resume (ops, inferior_ptid, 0, 0);
     }
 
   kret = task_resume (darwin_inf->task);
@@ -1058,7 +1054,7 @@ darwin_pid_to_str (struct target_ops *op
 }
 
 static int
-darwin_thread_alive (ptid_t ptid)
+darwin_thread_alive (struct target_ops *ops, ptid_t ptid)
 {
   return 1;
 }
Index: src/gdb/gnu-nat.c
===================================================================
--- src.orig/gdb/gnu-nat.c	2009-02-16 00:20:29.000000000 +0000
+++ src/gdb/gnu-nat.c	2009-02-16 03:26:06.000000000 +0000
@@ -1955,7 +1955,8 @@ port_msgs_queued (mach_port_t port)
    in multiple events returned by wait).
  */
 static void
-gnu_resume (ptid_t ptid, int step, enum target_signal sig)
+gnu_resume (struct target_ops *ops,
+	    ptid_t ptid, int step, enum target_signal sig)
 {
   struct proc *step_thread = 0;
   int resume_all;
@@ -2262,7 +2263,7 @@ gnu_stop (ptid_t ptid)
 }
 
 static int
-gnu_thread_alive (ptid_t ptid)
+gnu_thread_alive (struct target_ops *ops, ptid_t ptid)
 {
   inf_update_procs (gnu_current_inf);
   return !!inf_tid_to_thread (gnu_current_inf,
@@ -2612,8 +2613,10 @@ gnu_pid_to_str (struct target_ops *ops, 
 }
 
 
-extern void gnu_store_registers (struct regcache *regcache, int regno);
-extern void gnu_fetch_registers (struct regcache *regcache, int regno);
+extern void gnu_store_registers (struct target_ops *ops,
+				 struct regcache *regcache, int regno);
+extern void gnu_fetch_registers (struct target_ops *ops,
+				 struct regcache *regcache, int regno);
 
 struct target_ops gnu_ops;
 
Index: src/gdb/go32-nat.c
===================================================================
--- src.orig/gdb/go32-nat.c	2009-02-16 00:20:30.000000000 +0000
+++ src/gdb/go32-nat.c	2009-02-16 03:26:06.000000000 +0000
@@ -169,11 +169,7 @@ static void go32_open (char *name, int f
 static void go32_close (int quitting);
 static void go32_attach (char *args, int from_tty);
 static void go32_detach (char *args, int from_tty);
-static void go32_resume (ptid_t ptid, int step,
-                         enum target_signal siggnal);
-static void go32_fetch_registers (struct regcache *, int regno);
 static void store_register (const struct regcache *, int regno);
-static void go32_store_registers (struct regcache *, int regno);
 static void go32_prepare_to_store (struct regcache *);
 static int go32_xfer_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len,
 			     int write,
@@ -321,7 +317,8 @@ static int resume_is_step;
 static int resume_signal = -1;
 
 static void
-go32_resume (ptid_t ptid, int step, enum target_signal siggnal)
+go32_resume (struct target_ops *ops,
+	     ptid_t ptid, int step, enum target_signal siggnal)
 {
   int i;
 
@@ -478,7 +475,8 @@ fetch_register (struct regcache *regcach
 }
 
 static void
-go32_fetch_registers (struct regcache *regcache, int regno)
+go32_fetch_registers (struct target_ops *ops,
+		      struct regcache *regcache, int regno)
 {
   if (regno >= 0)
     fetch_register (regcache, regno);
@@ -507,7 +505,8 @@ store_register (const struct regcache *r
 }
 
 static void
-go32_store_registers (struct regcache *regcache, int regno)
+go32_store_registers (struct target_ops *ops,
+		      struct regcache *regcache, int regno)
 {
   unsigned r;
 
@@ -859,7 +858,7 @@ go32_terminal_ours (void)
 }
 
 static int
-go32_thread_alive (ptid_t ptid)
+go32_thread_alive (struct target_ops *ops, ptid_t ptid)
 {
   return 1;
 }
Index: src/gdb/hpux-thread.c
===================================================================
--- src.orig/gdb/hpux-thread.c	2009-02-16 00:20:30.000000000 +0000
+++ src/gdb/hpux-thread.c	2009-02-16 03:26:06.000000000 +0000
@@ -65,9 +65,6 @@ static ptid_t main_ptid;		/* Real proces
 static CORE_ADDR P_cma__g_known_threads;
 static CORE_ADDR P_cma__g_current_thread;
 
-static void hpux_thread_resume (ptid_t ptid, int step,
-                                enum target_signal signo);
-
 static void init_hpux_thread_ops (void);
 
 static struct target_ops hpux_thread_ops;
@@ -171,7 +168,8 @@ hpux_thread_detach (struct target_ops *o
    for procfs.  */
 
 static void
-hpux_thread_resume (ptid_t ptid, int step, enum target_signal signo)
+hpux_thread_resume (struct target_ops *ops,
+		    ptid_t ptid, int step, enum target_signal signo)
 {
   struct cleanup *old_chain;
 
@@ -180,7 +178,7 @@ hpux_thread_resume (ptid_t ptid, int ste
   ptid = main_ptid;
   inferior_ptid = main_ptid;
 
-  deprecated_child_ops.to_resume (ptid, step, signo);
+  deprecated_child_ops.to_resume (&deprecated_child_ops, ptid, step, signo);
 
   cached_thread = 0;
 
@@ -241,7 +239,8 @@ static char regmap[] =
 };
 
 static void
-hpux_thread_fetch_registers (struct regcache *regcache, int regno)
+hpux_thread_fetch_registers (struct target_ops *ops,
+			     struct regcache *regcache, int regno)
 {
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
   cma__t_int_tcb tcb, *tcb_ptr;
@@ -257,7 +256,8 @@ hpux_thread_fetch_registers (struct regc
 
   if (tcb_ptr->state == cma__c_state_running)
     {
-      deprecated_child_ops.to_fetch_registers (regcache, regno);
+      deprecated_child_ops.to_fetch_registers (&deprecated_child_ops,
+					       regcache, regno);
 
       do_cleanups (old_chain);
 
@@ -278,7 +278,8 @@ hpux_thread_fetch_registers (struct regc
   for (regno = first_regno; regno <= last_regno; regno++)
     {
       if (regmap[regno] == -1)
-	deprecated_child_ops.to_fetch_registers (regcache, regno);
+	deprecated_child_ops.to_fetch_registers (&deprecated_child_ops,
+						 regcache, regno);
       else
 	{
 	  unsigned char buf[MAX_REGISTER_SIZE];
@@ -305,7 +306,8 @@ hpux_thread_fetch_registers (struct regc
 }
 
 static void
-hpux_thread_store_registers (struct regcache *regcache, int regno)
+hpux_thread_store_registers (struct target_ops *ops,
+			     struct regcache *regcache, int regno)
 {
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
   cma__t_int_tcb tcb, *tcb_ptr;
@@ -321,7 +323,8 @@ hpux_thread_store_registers (struct regc
 
   if (tcb_ptr->state == cma__c_state_running)
     {
-      deprecated_child_ops.to_store_registers (regcache, regno);
+      deprecated_child_ops.to_store_registers (&deprecated_child_ops,
+					       regcache, regno);
 
       do_cleanups (old_chain);
 
@@ -351,7 +354,11 @@ hpux_thread_store_registers (struct regc
 	  sp = (CORE_ADDR) tcb_ptr->static_ctx.sp - 160;
 
 	  if (regno == HPPA_FLAGS_REGNUM)
-	    deprecated_child_ops.to_store_registers (regcache, regno);	/* Let lower layer handle this... */
+	    {
+	      /* Let lower layer handle this... */
+	      deprecated_child_ops.to_store_registers
+		(&deprecated_child_ops, regcache, regno);
+	    }
 	  else if (regno == HPPA_SP_REGNUM)
 	    {
 	      regcache_raw_collect (regcache, regno, buf);
@@ -502,7 +509,7 @@ hpux_thread_can_run (void)
 }
 
 static int
-hpux_thread_alive (ptid_t ptid)
+hpux_thread_alive (struct target_ops *ops, ptid_t ptid)
 {
   return 1;
 }
Index: src/gdb/i386-linux-nat.c
===================================================================
--- src.orig/gdb/i386-linux-nat.c	2009-02-16 00:20:29.000000000 +0000
+++ src/gdb/i386-linux-nat.c	2009-02-16 03:26:06.000000000 +0000
@@ -450,7 +450,8 @@ static int store_fpxregs (const struct r
    registers).  */
 
 static void
-i386_linux_fetch_inferior_registers (struct regcache *regcache, int regno)
+i386_linux_fetch_inferior_registers (struct target_ops *ops,
+				     struct regcache *regcache, int regno)
 {
   int tid;
 
@@ -522,7 +523,8 @@ i386_linux_fetch_inferior_registers (str
    do this for all registers (including the floating point and SSE
    registers).  */
 static void
-i386_linux_store_inferior_registers (struct regcache *regcache, int regno)
+i386_linux_store_inferior_registers (struct target_ops *ops,
+				     struct regcache *regcache, int regno)
 {
   int tid;
 
@@ -744,7 +746,8 @@ static const unsigned char linux_syscall
    If SIGNAL is nonzero, give it that signal.  */
 
 static void
-i386_linux_resume (ptid_t ptid, int step, enum target_signal signal)
+i386_linux_resume (struct target_ops *ops,
+		   ptid_t ptid, int step, enum target_signal signal)
 {
   int pid = PIDGET (ptid);
 
Index: src/gdb/i386fbsd-nat.c
===================================================================
--- src.orig/gdb/i386fbsd-nat.c	2009-02-16 00:20:29.000000000 +0000
+++ src/gdb/i386fbsd-nat.c	2009-02-16 03:26:06.000000000 +0000
@@ -35,7 +35,8 @@
    single-step it.  If SIGNAL is nonzero, give it that signal.  */
 
 static void
-i386fbsd_resume (ptid_t ptid, int step, enum target_signal signal)
+i386fbsd_resume (struct target_ops *ops,
+		 ptid_t ptid, int step, enum target_signal signal)
 {
   pid_t pid = ptid_get_pid (ptid);
   int request = PT_STEP;
Index: src/gdb/monitor.c
===================================================================
--- src.orig/gdb/monitor.c	2009-02-16 00:20:29.000000000 +0000
+++ src/gdb/monitor.c	2009-02-16 03:26:06.000000000 +0000
@@ -912,7 +912,8 @@ monitor_supply_register (struct regcache
 /* Tell the remote machine to resume.  */
 
 static void
-monitor_resume (ptid_t ptid, int step, enum target_signal sig)
+monitor_resume (struct target_ops *ops,
+		ptid_t ptid, int step, enum target_signal sig)
 {
   /* Some monitors require a different command when starting a program */
   monitor_debug ("MON resume\n");
@@ -1286,7 +1287,8 @@ monitor_dump_regs (struct regcache *regc
 }
 
 static void
-monitor_fetch_registers (struct regcache *regcache, int regno)
+monitor_fetch_registers (struct target_ops *ops,
+			 struct regcache *regcache, int regno)
 {
   monitor_debug ("MON fetchregs\n");
   if (current_monitor->getreg.cmd)
@@ -1368,7 +1370,8 @@ monitor_store_register (struct regcache 
 /* Store the remote registers.  */
 
 static void
-monitor_store_registers (struct regcache *regcache, int regno)
+monitor_store_registers (struct target_ops *ops,
+			 struct regcache *regcache, int regno)
 {
   if (regno >= 0)
     {
@@ -2232,7 +2235,7 @@ monitor_get_dev_name (void)
 /* Check to see if a thread is still alive.  */
 
 static int
-monitor_thread_alive (ptid_t ptid)
+monitor_thread_alive (struct target_ops *ops, ptid_t ptid)
 {
   if (ptid_equal (ptid, monitor_ptid))
     /* The monitor's task is always alive.  */
Index: src/gdb/nto-procfs.c
===================================================================
--- src.orig/gdb/nto-procfs.c	2009-02-16 00:20:29.000000000 +0000
+++ src/gdb/nto-procfs.c	2009-02-16 03:26:06.000000000 +0000
@@ -63,8 +63,6 @@ static int procfs_xfer_memory (CORE_ADDR
 			       struct mem_attrib *attrib,
 			       struct target_ops *);
 
-static void procfs_fetch_registers (struct regcache *, int);
-
 static void notice_signals (void);
 
 static void init_procfs_ops (void);
@@ -219,7 +217,7 @@ procfs_set_thread (ptid_t ptid)
 
 /*  Return nonzero if the thread TH is still alive.  */
 static int
-procfs_thread_alive (ptid_t ptid)
+procfs_thread_alive (struct target_ops *ops, ptid_t ptid)
 {
   pid_t tid;
 
@@ -230,7 +228,7 @@ procfs_thread_alive (ptid_t ptid)
 }
 
 void
-procfs_find_new_threads (void)
+procfs_find_new_threads (struct target_ops *ops)
 {
   procfs_status status;
   pid_t pid;
@@ -547,9 +545,9 @@ procfs_attach (struct target_ops *ops, c
   inf = add_inferior (pid);
   inf->attach_flag = 1;
 
-  push_target (&procfs_ops);
+  push_target (ops);
 
-  procfs_find_new_threads ();
+  procfs_find_new_threads (ops);
 }
 
 static void
@@ -727,7 +725,8 @@ procfs_wait (struct target_ops *ops,
    general register set and floating point registers (if supported)
    and update gdb's idea of their current values.  */
 static void
-procfs_fetch_registers (struct regcache *regcache, int regno)
+procfs_fetch_registers (struct target_ops *ops,
+			struct regcache *regcache, int regno)
 {
   union
   {
@@ -851,7 +850,8 @@ procfs_remove_hw_breakpoint (struct bp_t
 }
 
 static void
-procfs_resume (ptid_t ptid, int step, enum target_signal signo)
+procfs_resume (struct target_ops *ops,
+	       ptid_t ptid, int step, enum target_signal signo)
 {
   int signal_to_pass;
   procfs_status status;
@@ -1092,7 +1092,7 @@ procfs_create_inferior (struct target_op
     close (fds[2]);
 
   inferior_ptid = do_attach (pid_to_ptid (pid));
-  procfs_find_new_threads ();
+  procfs_find_new_threads (ops);
 
   inf = add_inferior (pid);
   inf->attach_flag = 0;
@@ -1105,7 +1105,7 @@ procfs_create_inferior (struct target_op
       /* warning( "Failed to set Kill-on-Last-Close flag: errno = %d(%s)\n",
          errn, strerror(errn) ); */
     }
-  push_target (&procfs_ops);
+  push_target (ops);
   target_terminal_init ();
 
   if (exec_bfd != NULL
@@ -1166,7 +1166,8 @@ get_regset (int regset, char *buf, int b
 }
 
 void
-procfs_store_registers (struct regcache *regcache, int regno)
+procfs_store_registers (struct target_ops *ops,
+			struct regcache *regcache, int regno)
 {
   union
   {
Index: src/gdb/remote-m32r-sdi.c
===================================================================
--- src.orig/gdb/remote-m32r-sdi.c	2009-02-16 00:20:29.000000000 +0000
+++ src/gdb/remote-m32r-sdi.c	2009-02-16 03:44:02.000000000 +0000
@@ -446,7 +446,8 @@ m32r_close (int quitting)
 /* Tell the remote machine to resume.  */
 
 static void
-m32r_resume (ptid_t ptid, int step, enum target_signal sig)
+m32r_resume (struct target_ops *ops,
+	     ptid_t ptid, int step, enum target_signal sig)
 {
   unsigned long pc_addr, bp_addr, ab_addr;
   int ib_breakpoints;
@@ -879,7 +880,7 @@ m32r_detach (struct target_ops *ops, cha
   if (remote_debug)
     fprintf_unfiltered (gdb_stdlog, "m32r_detach(%d)\n", from_tty);
 
-  m32r_resume (inferior_ptid, 0, 0);
+  m32r_resume (ops, inferior_ptid, 0, 0);
 
   /* calls m32r_close to do the real work */
   pop_target ();
@@ -910,30 +911,21 @@ get_reg_id (int regno)
   return regno;
 }
 
-/* Read the remote registers into the block REGS.  */
-
-static void m32r_fetch_register (struct regcache *, int);
-
-static void
-m32r_fetch_registers (struct regcache *regcache)
-{
-  int regno;
-
-  for (regno = 0;
-       regno < gdbarch_num_regs (get_regcache_arch (regcache));
-       regno++)
-    m32r_fetch_register (regcache, regno);
-}
-
 /* Fetch register REGNO, or all registers if REGNO is -1.
    Returns errno value.  */
 static void
-m32r_fetch_register (struct regcache *regcache, int regno)
+m32r_fetch_register (struct target_ops *ops,
+		     struct regcache *regcache, int regno)
 {
   unsigned long val, val2, regid;
 
   if (regno == -1)
-    m32r_fetch_registers (regcache);
+    {
+      for (regno = 0;
+	   regno < gdbarch_num_regs (get_regcache_arch (regcache));
+	   regno++)
+	m32r_fetch_register (ops, regcache, regno);
+    }
   else
     {
       char buffer[MAX_REGISTER_SIZE];
@@ -961,33 +953,22 @@ m32r_fetch_register (struct regcache *re
   return;
 }
 
-/* Store the remote registers from the contents of the block REGS.  */
-
-static void m32r_store_register (struct regcache *, int);
-
-static void
-m32r_store_registers (struct regcache *regcache)
-{
-  int regno;
-
-  for (regno = 0;
-       regno < gdbarch_num_regs (get_regcache_arch (regcache));
-       regno++)
-    m32r_store_register (regcache, regno);
-
-  registers_changed ();
-}
-
 /* Store register REGNO, or all if REGNO == 0.
    Return errno value.  */
 static void
-m32r_store_register (struct regcache *regcache, int regno)
+m32r_store_register (struct target_ops *ops,
+		     struct regcache *regcache, int regno)
 {
   int regid;
   ULONGEST regval, tmp;
 
   if (regno == -1)
-    m32r_store_registers (regcache);
+    {
+      for (regno = 0;
+	   regno < gdbarch_num_regs (get_regcache_arch (regcache));
+	   regno++)
+	m32r_store_register (ops, regcache, regno);
+    }
   else
     {
       regcache_cooked_read_unsigned (regcache, regno, &regval);
@@ -1495,7 +1476,7 @@ m32r_stopped_by_watchpoint (void)
 /* Check to see if a thread is still alive.  */
 
 static int
-m32r_thread_alive (ptid_t ptid)
+m32r_thread_alive (struct target_ops *ops, ptid_t ptid)
 {
   if (ptid_equal (ptid, remote_m32r_ptid))
     /* The main task is always alive.  */
Index: src/gdb/remote-mips.c
===================================================================
--- src.orig/gdb/remote-mips.c	2009-02-16 00:20:29.000000000 +0000
+++ src/gdb/remote-mips.c	2009-02-16 03:26:06.000000000 +0000
@@ -86,17 +86,10 @@ static void mips_close (int quitting);
 
 static void mips_detach (struct target_ops *ops, char *args, int from_tty);
 
-static void mips_resume (ptid_t ptid, int step,
-                         enum target_signal siggnal);
-
 static int mips_map_regno (struct gdbarch *, int);
 
-static void mips_fetch_registers (struct regcache *regcache, int regno);
-
 static void mips_prepare_to_store (struct regcache *regcache);
 
-static void mips_store_registers (struct regcache *regcache, int regno);
-
 static unsigned int mips_fetch_word (CORE_ADDR addr);
 
 static int mips_store_word (CORE_ADDR addr, unsigned int value,
@@ -1667,7 +1660,8 @@ mips_detach (struct target_ops *ops, cha
    where PMON does return a reply.  */
 
 static void
-mips_resume (ptid_t ptid, int step, enum target_signal siggnal)
+mips_resume (struct target_ops *ops,
+	     ptid_t ptid, int step, enum target_signal siggnal)
 {
   int err;
 
@@ -1899,7 +1893,8 @@ mips_map_regno (struct gdbarch *gdbarch,
 /* Fetch the remote registers.  */
 
 static void
-mips_fetch_registers (struct regcache *regcache, int regno)
+mips_fetch_registers (struct target_ops *ops,
+		      struct regcache *regcache, int regno)
 {
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
   unsigned LONGEST val;
@@ -1908,7 +1903,7 @@ mips_fetch_registers (struct regcache *r
   if (regno == -1)
     {
       for (regno = 0; regno < gdbarch_num_regs (gdbarch); regno++)
-	mips_fetch_registers (regcache, regno);
+	mips_fetch_registers (ops, regcache, regno);
       return;
     }
 
@@ -1962,7 +1957,8 @@ mips_prepare_to_store (struct regcache *
 /* Store remote register(s).  */
 
 static void
-mips_store_registers (struct regcache *regcache, int regno)
+mips_store_registers (struct target_ops *ops,
+		      struct regcache *regcache, int regno)
 {
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
   ULONGEST val;
@@ -1971,7 +1967,7 @@ mips_store_registers (struct regcache *r
   if (regno == -1)
     {
       for (regno = 0; regno < gdbarch_num_regs (gdbarch); regno++)
-	mips_store_registers (regcache, regno);
+	mips_store_registers (ops, regcache, regno);
       return;
     }
 
Index: src/gdb/windows-nat.c
===================================================================
--- src.orig/gdb/windows-nat.c	2009-02-16 00:20:29.000000000 +0000
+++ src/gdb/windows-nat.c	2009-02-16 03:26:06.000000000 +0000
@@ -401,7 +401,8 @@ do_windows_fetch_inferior_registers (str
 }
 
 static void
-windows_fetch_inferior_registers (struct regcache *regcache, int r)
+windows_fetch_inferior_registers (struct target_ops *ops,
+				  struct regcache *regcache, int r)
 {
   current_thread = thread_rec (ptid_get_tid (inferior_ptid), TRUE);
   /* Check if current_thread exists.  Windows sometimes uses a non-existent
@@ -427,7 +428,8 @@ do_windows_store_inferior_registers (con
 
 /* Store a new register value into the current thread context */
 static void
-windows_store_inferior_registers (struct regcache *regcache, int r)
+windows_store_inferior_registers (struct target_ops *ops,
+				  struct regcache *regcache, int r)
 {
   current_thread = thread_rec (ptid_get_tid (inferior_ptid), TRUE);
   /* Check if current_thread exists.  Windows sometimes uses a non-existent
@@ -1165,7 +1167,8 @@ fake_create_process (void)
 }
 
 static void
-windows_resume (ptid_t ptid, int step, enum target_signal sig)
+windows_resume (struct target_ops *ops,
+		ptid_t ptid, int step, enum target_signal sig)
 {
   thread_info *th;
   DWORD continue_status = DBG_CONTINUE;
@@ -1224,8 +1227,9 @@ windows_resume (ptid_t ptid, int step, e
       if (step)
 	{
 	  /* Single step by setting t bit */
-	  windows_fetch_inferior_registers (get_current_regcache (),
-					  gdbarch_ps_regnum (current_gdbarch));
+	  windows_fetch_inferior_registers (ops,
+					    get_current_regcache (),
+					    gdbarch_ps_regnum (current_gdbarch));
 	  th->context.EFlags |= FLAG_TRACE_BIT;
 	}
 
@@ -1258,7 +1262,8 @@ windows_resume (ptid_t ptid, int step, e
    handling by WFI (or whatever).
  */
 static int
-get_windows_debug_event (int pid, struct target_waitstatus *ourstatus)
+get_windows_debug_event (struct target_ops *ops,
+			 int pid, struct target_waitstatus *ourstatus)
 {
   BOOL debug_event;
   DWORD continue_status, event_code;
@@ -1475,7 +1480,7 @@ windows_wait (struct target_ops *ops,
          to find a better solution to that problem.  But in the meantime,
          the current approach already greatly mitigate this issue.  */
       SetConsoleCtrlHandler (NULL, TRUE);
-      retval = get_windows_debug_event (pid, ourstatus);
+      retval = get_windows_debug_event (ops, pid, ourstatus);
       SetConsoleCtrlHandler (NULL, FALSE);
 
       if (retval)
@@ -1722,7 +1727,7 @@ windows_detach (struct target_ops *ops, 
   if (has_detach_ability ())
     {
       ptid_t ptid = {-1};
-      windows_resume (ptid, 0, TARGET_SIGNAL_0);
+      windows_resume (ops, ptid, 0, TARGET_SIGNAL_0);
 
       if (!kernel32_DebugActiveProcessStop (current_event.dwProcessId))
 	{
@@ -2267,7 +2272,7 @@ cygwin_get_dr6 (void)
    by "polling" it.  If WaitForSingleObject returns WAIT_OBJECT_0
    it means that the thread has died.  Otherwise it is assumed to be alive. */
 static int
-windows_thread_alive (ptid_t ptid)
+windows_thread_alive (struct target_ops *ops, ptid_t ptid)
 {
   int tid;
 
Index: src/gdb/alphabsd-nat.c
===================================================================
--- src.orig/gdb/alphabsd-nat.c	2009-02-16 00:20:29.000000000 +0000
+++ src/gdb/alphabsd-nat.c	2009-02-16 03:26:06.000000000 +0000
@@ -84,7 +84,8 @@ getregs_supplies (int regno)
    for all registers (including the floating point registers).  */
 
 static void
-alphabsd_fetch_inferior_registers (struct regcache *regcache, int regno)
+alphabsd_fetch_inferior_registers (struct target_ops *ops,
+				   struct regcache *regcache, int regno)
 {
   if (regno == -1 || getregs_supplies (regno))
     {
@@ -115,7 +116,8 @@ alphabsd_fetch_inferior_registers (struc
    this for all registers (including the floating point registers).  */
 
 static void
-alphabsd_store_inferior_registers (struct regcache *regcache, int regno)
+alphabsd_store_inferior_registers (struct target_ops *ops,
+				   struct regcache *regcache, int regno)
 {
   if (regno == -1 || getregs_supplies (regno))
     {
Index: src/gdb/amd64bsd-nat.c
===================================================================
--- src.orig/gdb/amd64bsd-nat.c	2009-02-16 00:20:29.000000000 +0000
+++ src/gdb/amd64bsd-nat.c	2009-02-16 03:26:06.000000000 +0000
@@ -39,7 +39,8 @@
    for all registers (including the floating-point registers).  */
 
 static void
-amd64bsd_fetch_inferior_registers (struct regcache *regcache, int regnum)
+amd64bsd_fetch_inferior_registers (struct target_ops *ops,
+				   struct regcache *regcache, int regnum)
 {
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
 
@@ -72,7 +73,8 @@ amd64bsd_fetch_inferior_registers (struc
    this for all registers (including the floating-point registers).  */
 
 static void
-amd64bsd_store_inferior_registers (struct regcache *regcache, int regnum)
+amd64bsd_store_inferior_registers (struct target_ops *ops,
+				   struct regcache *regcache, int regnum)
 {
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
 
Index: src/gdb/arm-linux-nat.c
===================================================================
--- src.orig/gdb/arm-linux-nat.c	2009-02-16 00:20:29.000000000 +0000
+++ src/gdb/arm-linux-nat.c	2009-02-16 03:26:06.000000000 +0000
@@ -452,7 +452,8 @@ store_wmmx_regs (const struct regcache *
    point registers depending upon the value of regno.  */
 
 static void
-arm_linux_fetch_inferior_registers (struct regcache *regcache, int regno)
+arm_linux_fetch_inferior_registers (struct target_ops *ops,
+				    struct regcache *regcache, int regno)
 {
   if (-1 == regno)
     {
@@ -478,7 +479,8 @@ arm_linux_fetch_inferior_registers (stru
    point registers depending upon the value of regno.  */
 
 static void
-arm_linux_store_inferior_registers (struct regcache *regcache, int regno)
+arm_linux_store_inferior_registers (struct target_ops *ops,
+				    struct regcache *regcache, int regno)
 {
   if (-1 == regno)
     {
Index: src/gdb/armnbsd-nat.c
===================================================================
--- src.orig/gdb/armnbsd-nat.c	2009-02-16 00:20:29.000000000 +0000
+++ src/gdb/armnbsd-nat.c	2009-02-16 03:26:06.000000000 +0000
@@ -194,7 +194,8 @@ fetch_fp_regs (struct regcache *regcache
 }
 
 static void
-armnbsd_fetch_registers (struct regcache *regcache, int regno)
+armnbsd_fetch_registers (struct target_ops *ops,
+			 struct regcache *regcache, int regno)
 {
   if (regno >= 0)
     {
@@ -394,7 +395,8 @@ store_fp_regs (const struct regcache *re
 }
 
 static void
-armnbsd_store_registers (struct regcache *regcache, int regno)
+armnbsd_store_registers (struct target_ops *ops,
+			 struct regcache *regcache, int regno)
 {
   if (regno >= 0)
     {
Index: src/gdb/bsd-kvm.c
===================================================================
--- src.orig/gdb/bsd-kvm.c	2009-02-16 00:20:29.000000000 +0000
+++ src/gdb/bsd-kvm.c	2009-02-16 03:26:06.000000000 +0000
@@ -172,7 +172,8 @@ bsd_kvm_fetch_pcb (struct regcache *regc
 }
 
 static void
-bsd_kvm_fetch_registers (struct regcache *regcache, int regnum)
+bsd_kvm_fetch_registers (struct target_ops *ops,
+			 struct regcache *regcache, int regnum)
 {
   struct nlist nl[2];
 
@@ -310,7 +311,8 @@ bsd_kvm_pcb_cmd (char *arg, int fromtty)
 }
 
 static int
-bsd_kvm_thread_alive (ptid_t ptid)
+bsd_kvm_thread_alive (struct target_ops *ops,
+		      ptid_t ptid)
 {
   return 1;
 }
Index: src/gdb/hppa-hpux-nat.c
===================================================================
--- src.orig/gdb/hppa-hpux-nat.c	2009-02-16 00:20:29.000000000 +0000
+++ src/gdb/hppa-hpux-nat.c	2009-02-16 03:26:06.000000000 +0000
@@ -143,7 +143,8 @@ hppa_hpux_fetch_register (struct regcach
 }
 
 static void
-hppa_hpux_fetch_inferior_registers (struct regcache *regcache, int regnum)
+hppa_hpux_fetch_inferior_registers (struct target_ops *ops,
+				    struct regcache *regcache, int regnum)
 {
   if (regnum == -1)
     for (regnum = 0;
@@ -218,7 +219,8 @@ hppa_hpux_store_register (struct regcach
    this for all registers (including the floating point registers).  */
 
 static void
-hppa_hpux_store_inferior_registers (struct regcache *regcache, int regnum)
+hppa_hpux_store_inferior_registers (struct target_ops *ops,
+				    struct regcache *regcache, int regnum)
 {
   if (regnum == -1)
     for (regnum = 0;
Index: src/gdb/hppa-linux-nat.c
===================================================================
--- src.orig/gdb/hppa-linux-nat.c	2009-02-16 00:20:30.000000000 +0000
+++ src/gdb/hppa-linux-nat.c	2009-02-16 03:26:06.000000000 +0000
@@ -270,7 +270,8 @@ store_register (const struct regcache *r
    point registers depending upon the value of regno.  */
 
 static void
-hppa_linux_fetch_inferior_registers (struct regcache *regcache, int regno)
+hppa_linux_fetch_inferior_registers (struct target_ops *ops,
+				     struct regcache *regcache, int regno)
 {
   if (-1 == regno)
     {
@@ -290,7 +291,8 @@ hppa_linux_fetch_inferior_registers (str
    point registers depending upon the value of regno.  */
 
 static void
-hppa_linux_store_inferior_registers (struct regcache *regcache, int regno)
+hppa_linux_store_inferior_registers (struct target_ops *ops,
+				     struct regcache *regcache, int regno)
 {
   if (-1 == regno)
     {
Index: src/gdb/hppabsd-nat.c
===================================================================
--- src.orig/gdb/hppabsd-nat.c	2009-02-16 00:20:29.000000000 +0000
+++ src/gdb/hppabsd-nat.c	2009-02-16 03:26:06.000000000 +0000
@@ -122,7 +122,8 @@ hppabsd_collect_fpregset (struct regcach
    for all registers (including the floating-point registers).  */
 
 static void
-hppabsd_fetch_registers (struct regcache *regcache, int regnum)
+hppabsd_fetch_registers (struct target_ops *ops,
+			 struct regcache *regcache, int regnum)
 {
   if (regnum == -1 || hppabsd_gregset_supplies_p (regnum))
     {
@@ -151,7 +152,8 @@ hppabsd_fetch_registers (struct regcache
    this for all registers (including the floating-point registers).  */
 
 static void
-hppabsd_store_registers (struct regcache *regcache, int regnum)
+hppabsd_store_registers (struct target_ops *ops,
+			 struct regcache *regcache, int regnum)
 {
   if (regnum == -1 || hppabsd_gregset_supplies_p (regnum))
     {
Index: src/gdb/hppanbsd-nat.c
===================================================================
--- src.orig/gdb/hppanbsd-nat.c	2009-02-16 00:20:29.000000000 +0000
+++ src/gdb/hppanbsd-nat.c	2009-02-16 03:26:06.000000000 +0000
@@ -161,7 +161,8 @@ hppanbsd_collect_fpregset (struct regcac
    for all registers (including the floating-point registers).  */
 
 static void
-hppanbsd_fetch_registers (struct regcache *regcache, int regnum)
+hppanbsd_fetch_registers (struct target_ops *ops,
+			  struct regcache *regcache, int regnum)
 
 {
   if (regnum == -1 || hppanbsd_gregset_supplies_p (regnum))
@@ -191,7 +192,8 @@ hppanbsd_fetch_registers (struct regcach
    this for all registers (including the floating-point registers).  */
 
 static void
-hppanbsd_store_registers (struct regcache *regcache, int regnum)
+hppanbsd_store_registers (struct target_ops *ops,
+			  struct regcache *regcache, int regnum)
 {
   if (regnum == -1 || hppanbsd_gregset_supplies_p (regnum))
     {
Index: src/gdb/i386-darwin-nat.c
===================================================================
--- src.orig/gdb/i386-darwin-nat.c	2009-02-16 00:20:29.000000000 +0000
+++ src/gdb/i386-darwin-nat.c	2009-02-16 03:26:06.000000000 +0000
@@ -43,7 +43,8 @@
    If REGNO is -1, do this for all registers.
    Otherwise, REGNO specifies which register (so we can save time).  */
 static void
-i386_darwin_fetch_inferior_registers (struct regcache *regcache, int regno)
+i386_darwin_fetch_inferior_registers (struct target_ops *ops,
+				      struct regcache *regcache, int regno)
 {
   thread_t current_thread = ptid_get_tid (inferior_ptid);
   int fetched = 0;
@@ -144,7 +145,8 @@ i386_darwin_fetch_inferior_registers (st
    Otherwise, REGNO specifies which register (so we can save time).  */
 
 static void
-i386_darwin_store_inferior_registers (struct regcache *regcache, int regno)
+i386_darwin_store_inferior_registers (struct target_ops *ops,
+				      struct regcache *regcache, int regno)
 {
   thread_t current_thread = ptid_get_tid (inferior_ptid);
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
Index: src/gdb/i386bsd-nat.c
===================================================================
--- src.orig/gdb/i386bsd-nat.c	2009-02-16 00:20:29.000000000 +0000
+++ src/gdb/i386bsd-nat.c	2009-02-16 03:26:06.000000000 +0000
@@ -130,7 +130,8 @@ i386bsd_collect_gregset (const struct re
    for all registers (including the floating point registers).  */
 
 static void
-i386bsd_fetch_inferior_registers (struct regcache *regcache, int regnum)
+i386bsd_fetch_inferior_registers (struct target_ops *ops,
+				  struct regcache *regcache, int regnum)
 {
   if (regnum == -1 || GETREGS_SUPPLIES (regnum))
     {
@@ -180,7 +181,8 @@ i386bsd_fetch_inferior_registers (struct
    this for all registers (including the floating point registers).  */
 
 static void
-i386bsd_store_inferior_registers (struct regcache *regcache, int regnum)
+i386bsd_store_inferior_registers (struct target_ops *ops,
+				  struct regcache *regcache, int regnum)
 {
   if (regnum == -1 || GETREGS_SUPPLIES (regnum))
     {
Index: src/gdb/ia64-linux-nat.c
===================================================================
--- src.orig/gdb/ia64-linux-nat.c	2009-02-16 00:20:29.000000000 +0000
+++ src/gdb/ia64-linux-nat.c	2009-02-16 03:26:06.000000000 +0000
@@ -718,7 +718,8 @@ ia64_linux_fetch_register (struct regcac
    for all registers.  */
 
 static void
-ia64_linux_fetch_registers (struct regcache *regcache, int regnum)
+ia64_linux_fetch_registers (struct target_ops *ops,
+			    struct regcache *regcache, int regnum)
 {
   if (regnum == -1)
     for (regnum = 0;
@@ -775,7 +776,8 @@ ia64_linux_store_register (const struct 
    this for all registers.  */
 
 static void
-ia64_linux_store_registers (struct regcache *regcache, int regnum)
+ia64_linux_store_registers (struct target_ops *ops,
+			    struct regcache *regcache, int regnum)
 {
   if (regnum == -1)
     for (regnum = 0;
Index: src/gdb/m32r-linux-nat.c
===================================================================
--- src.orig/gdb/m32r-linux-nat.c	2009-02-16 00:20:29.000000000 +0000
+++ src/gdb/m32r-linux-nat.c	2009-02-16 03:26:06.000000000 +0000
@@ -194,7 +194,8 @@ fill_fpregset (const struct regcache *re
    registers).  */
 
 static void
-m32r_linux_fetch_inferior_registers (struct regcache *regcache, int regno)
+m32r_linux_fetch_inferior_registers (struct target_ops *ops,
+				     struct regcache *regcache, int regno)
 {
   int tid;
 
@@ -220,7 +221,8 @@ m32r_linux_fetch_inferior_registers (str
    do this for all registers (including the floating point and SSE
    registers).  */
 static void
-m32r_linux_store_inferior_registers (struct regcache *regcache, int regno)
+m32r_linux_store_inferior_registers (struct target_ops *ops,
+				     struct regcache *regcache, int regno)
 {
   int tid;
 
Index: src/gdb/m68kbsd-nat.c
===================================================================
--- src.orig/gdb/m68kbsd-nat.c	2009-02-16 00:20:29.000000000 +0000
+++ src/gdb/m68kbsd-nat.c	2009-02-16 03:26:06.000000000 +0000
@@ -109,7 +109,8 @@ m68kbsd_collect_fpregset (struct regcach
    for all registers (including the floating-point registers).  */
 
 static void
-m68kbsd_fetch_inferior_registers (struct regcache *regcache, int regnum)
+m68kbsd_fetch_inferior_registers (struct target_ops *ops,
+				  struct regcache *regcache, int regnum)
 {
   if (regnum == -1 || m68kbsd_gregset_supplies_p (regnum))
     {
@@ -138,7 +139,8 @@ m68kbsd_fetch_inferior_registers (struct
    this for all registers (including the floating-point registers).  */
 
 static void
-m68kbsd_store_inferior_registers (struct regcache *regcache, int regnum)
+m68kbsd_store_inferior_registers (struct target_ops *ops,
+				  struct regcache *regcache, int regnum)
 {
   if (regnum == -1 || m68kbsd_gregset_supplies_p (regnum))
     {
Index: src/gdb/m68klinux-nat.c
===================================================================
--- src.orig/gdb/m68klinux-nat.c	2009-02-16 00:20:28.000000000 +0000
+++ src/gdb/m68klinux-nat.c	2009-02-16 03:26:06.000000000 +0000
@@ -423,7 +423,8 @@ static void store_fpregs (const struct r
    registers).  */
 
 static void
-m68k_linux_fetch_inferior_registers (struct regcache *regcache, int regno)
+m68k_linux_fetch_inferior_registers (struct target_ops *ops,
+				     struct regcache *regcache, int regno)
 {
   int tid;
 
@@ -479,7 +480,8 @@ m68k_linux_fetch_inferior_registers (str
    do this for all registers (including the floating point and SSE
    registers).  */
 static void
-m68k_linux_store_inferior_registers (struct regcache *regcache, int regno)
+m68k_linux_store_inferior_registers (struct target_ops *ops,
+				     struct regcache *regcache, int regno)
 {
   int tid;
 
Index: src/gdb/m88kbsd-nat.c
===================================================================
--- src.orig/gdb/m88kbsd-nat.c	2009-02-16 00:20:29.000000000 +0000
+++ src/gdb/m88kbsd-nat.c	2009-02-16 03:26:06.000000000 +0000
@@ -63,7 +63,8 @@ m88kbsd_collect_gregset (const struct re
    for all registers.  */
 
 static void
-m88kbsd_fetch_inferior_registers (struct regcache *regcache, int regnum)
+m88kbsd_fetch_inferior_registers (struct target_ops *ops,
+				  struct regcache *regcache, int regnum)
 {
   struct reg regs;
 
@@ -78,7 +79,8 @@ m88kbsd_fetch_inferior_registers (struct
    this for all registers.  */
 
 static void
-m88kbsd_store_inferior_registers (struct regcache *regcache, int regnum)
+m88kbsd_store_inferior_registers (struct target_ops *ops,
+				  struct regcache *regcache, int regnum)
 {
   struct reg regs;
 
Index: src/gdb/mips-linux-nat.c
===================================================================
--- src.orig/gdb/mips-linux-nat.c	2009-02-16 00:20:30.000000000 +0000
+++ src/gdb/mips-linux-nat.c	2009-02-16 03:26:06.000000000 +0000
@@ -47,8 +47,8 @@ static int have_ptrace_regsets = 1;
 /* Saved function pointers to fetch and store a single register using
    PTRACE_PEEKUSER and PTRACE_POKEUSER.  */
 
-void (*super_fetch_registers) (struct regcache *, int);
-void (*super_store_registers) (struct regcache *, int);
+void (*super_fetch_registers) (struct target_ops *, struct regcache *, int);
+void (*super_store_registers) (struct target_ops *, struct regcache *, int);
 
 /* Map gdb internal register number to ptrace ``address''.
    These ``addresses'' are normally defined in <asm/ptrace.h>. 
@@ -304,7 +304,8 @@ mips64_linux_regsets_store_registers (co
    using any working method.  */
 
 static void
-mips64_linux_fetch_registers (struct regcache *regcache, int regnum)
+mips64_linux_fetch_registers (struct target_ops *ops,
+			      struct regcache *regcache, int regnum)
 {
   /* Unless we already know that PTRACE_GETREGS does not work, try it.  */
   if (have_ptrace_regsets)
@@ -320,7 +321,8 @@ mips64_linux_fetch_registers (struct reg
    using any working method.  */
 
 static void
-mips64_linux_store_registers (struct regcache *regcache, int regnum)
+mips64_linux_store_registers (struct target_ops *ops,
+			      struct regcache *regcache, int regnum)
 {
   /* Unless we already know that PTRACE_GETREGS does not work, try it.  */
   if (have_ptrace_regsets)
Index: src/gdb/mips64obsd-nat.c
===================================================================
--- src.orig/gdb/mips64obsd-nat.c	2009-02-16 00:20:29.000000000 +0000
+++ src/gdb/mips64obsd-nat.c	2009-02-16 03:26:06.000000000 +0000
@@ -77,7 +77,8 @@ mips64obsd_collect_gregset (const struct
    for all registers.  */
 
 static void
-mips64obsd_fetch_inferior_registers (struct regcache *regcache, int regnum)
+mips64obsd_fetch_inferior_registers (struct target_ops *ops,
+				     struct regcache *regcache, int regnum)
 {
   struct reg regs;
 
@@ -92,7 +93,8 @@ mips64obsd_fetch_inferior_registers (str
    this for all registers.  */
 
 static void
-mips64obsd_store_inferior_registers (struct regcache *regcache, int regnum)
+mips64obsd_store_inferior_registers (struct target_ops *ops,
+				     struct regcache *regcache, int regnum)
 {
   struct reg regs;
 
Index: src/gdb/mipsnbsd-nat.c
===================================================================
--- src.orig/gdb/mipsnbsd-nat.c	2009-02-16 00:20:29.000000000 +0000
+++ src/gdb/mipsnbsd-nat.c	2009-02-16 03:26:06.000000000 +0000
@@ -40,7 +40,8 @@ getregs_supplies (struct gdbarch *gdbarc
 }
 
 static void
-mipsnbsd_fetch_inferior_registers (struct regcache *regcache, int regno)
+mipsnbsd_fetch_inferior_registers (struct target_ops *ops,
+				   struct regcache *regcache, int regno)
 {
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
   if (regno == -1 || getregs_supplies (gdbarch, regno))
@@ -69,7 +70,8 @@ mipsnbsd_fetch_inferior_registers (struc
 }
 
 static void
-mipsnbsd_store_inferior_registers (struct regcache *regcache, int regno)
+mipsnbsd_store_inferior_registers (struct target_ops *ops,
+				   struct regcache *regcache, int regno)
 {
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
   if (regno == -1 || getregs_supplies (gdbarch, regno))
Index: src/gdb/ppc-linux-nat.c
===================================================================
--- src.orig/gdb/ppc-linux-nat.c	2009-02-16 00:20:29.000000000 +0000
+++ src/gdb/ppc-linux-nat.c	2009-02-16 03:26:06.000000000 +0000
@@ -647,7 +647,8 @@ fetch_ppc_registers (struct regcache *re
    regno == -1, otherwise fetch all general registers or all floating
    point registers depending upon the value of regno.  */
 static void
-ppc_linux_fetch_inferior_registers (struct regcache *regcache, int regno)
+ppc_linux_fetch_inferior_registers (struct target_ops *ops,
+				    struct regcache *regcache, int regno)
 {
   /* Overload thread id onto process id */
   int tid = TIDGET (inferior_ptid);
@@ -1179,7 +1180,8 @@ ppc_linux_watchpoint_addr_within_range (
 }
 
 static void
-ppc_linux_store_inferior_registers (struct regcache *regcache, int regno)
+ppc_linux_store_inferior_registers (struct target_ops *ops,
+				    struct regcache *regcache, int regno)
 {
   /* Overload thread id onto process id */
   int tid = TIDGET (inferior_ptid);
Index: src/gdb/ppcnbsd-nat.c
===================================================================
--- src.orig/gdb/ppcnbsd-nat.c	2009-02-16 00:20:30.000000000 +0000
+++ src/gdb/ppcnbsd-nat.c	2009-02-16 03:26:06.000000000 +0000
@@ -79,7 +79,8 @@ getfpregs_supplies (struct gdbarch *gdba
 }
 
 static void
-ppcnbsd_fetch_inferior_registers (struct regcache *regcache, int regnum)
+ppcnbsd_fetch_inferior_registers (struct target_ops *ops,
+				  struct regcache *regcache, int regnum)
 {
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
 
@@ -109,7 +110,8 @@ ppcnbsd_fetch_inferior_registers (struct
 }
 
 static void
-ppcnbsd_store_inferior_registers (struct regcache *regcache, int regnum)
+ppcnbsd_store_inferior_registers (struct target_ops *ops,
+				  struct regcache *regcache, int regnum)
 {
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
 
Index: src/gdb/ppcobsd-nat.c
===================================================================
--- src.orig/gdb/ppcobsd-nat.c	2009-02-16 00:20:29.000000000 +0000
+++ src/gdb/ppcobsd-nat.c	2009-02-16 03:26:06.000000000 +0000
@@ -73,7 +73,8 @@ getfpregs_supplies (struct gdbarch *gdba
    for all registers.  */
 
 static void
-ppcobsd_fetch_registers (struct regcache *regcache, int regnum)
+ppcobsd_fetch_registers (struct target_ops *ops,
+			 struct regcache *regcache, int regnum)
 {
   struct reg regs;
 
@@ -108,7 +109,8 @@ ppcobsd_fetch_registers (struct regcache
    this for all registers.  */
 
 static void
-ppcobsd_store_registers (struct regcache *regcache, int regnum)
+ppcobsd_store_registers (struct target_ops *ops,
+			 struct regcache *regcache, int regnum)
 {
   struct reg regs;
 
Index: src/gdb/remote-sim.c
===================================================================
--- src.orig/gdb/remote-sim.c	2009-02-16 00:20:29.000000000 +0000
+++ src/gdb/remote-sim.c	2009-02-16 03:26:06.000000000 +0000
@@ -72,10 +72,6 @@ static void gdb_os_evprintf_filtered (ho
 
 static void gdb_os_error (host_callback *, const char *, ...) ATTR_NORETURN;
 
-static void gdbsim_fetch_register (struct regcache *regcache, int regno);
-
-static void gdbsim_store_register (struct regcache *regcache, int regno);
-
 static void gdbsim_kill (void);
 
 static void gdbsim_load (char *prog, int fromtty);
@@ -277,13 +273,14 @@ one2one_register_sim_regno (struct gdbar
 }
 
 static void
-gdbsim_fetch_register (struct regcache *regcache, int regno)
+gdbsim_fetch_register (struct target_ops *ops,
+		       struct regcache *regcache, int regno)
 {
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
   if (regno == -1)
     {
       for (regno = 0; regno < gdbarch_num_regs (gdbarch); regno++)
-	gdbsim_fetch_register (regcache, regno);
+	gdbsim_fetch_register (ops, regcache, regno);
       return;
     }
 
@@ -345,13 +342,14 @@ gdbsim_fetch_register (struct regcache *
 
 
 static void
-gdbsim_store_register (struct regcache *regcache, int regno)
+gdbsim_store_register (struct target_ops *ops,
+		       struct regcache *regcache, int regno)
 {
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
   if (regno == -1)
     {
       for (regno = 0; regno < gdbarch_num_regs (gdbarch); regno++)
-	gdbsim_store_register (regcache, regno);
+	gdbsim_store_register (ops, regcache, regno);
       return;
     }
   else if (gdbarch_register_sim_regno (gdbarch, regno) >= 0)
@@ -860,7 +858,7 @@ simulator_command (char *args, int from_
 /* Check to see if a thread is still alive.  */
 
 static int
-gdbsim_thread_alive (ptid_t ptid)
+gdbsim_thread_alive (struct target_ops *ops, ptid_t ptid)
 {
   if (ptid_equal (ptid, remote_sim_ptid))
     /* The simulators' task is always alive.  */
Index: src/gdb/rs6000-nat.c
===================================================================
--- src.orig/gdb/rs6000-nat.c	2009-02-16 00:20:30.000000000 +0000
+++ src/gdb/rs6000-nat.c	2009-02-16 03:26:06.000000000 +0000
@@ -333,7 +333,8 @@ store_register (const struct regcache *r
    REGNO otherwise. */
 
 static void
-rs6000_fetch_inferior_registers (struct regcache *regcache, int regno)
+rs6000_fetch_inferior_registers (struct target_ops *ops,
+				 struct regcache *regcache, int regno)
 {
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
   if (regno != -1)
@@ -375,7 +376,8 @@ rs6000_fetch_inferior_registers (struct 
    Otherwise, REGNO specifies which register (so we can save time).  */
 
 static void
-rs6000_store_inferior_registers (struct regcache *regcache, int regno)
+rs6000_store_inferior_registers (struct target_ops *ops,
+				 struct regcache *regcache, int regno)
 {
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
   if (regno != -1)
Index: src/gdb/s390-nat.c
===================================================================
--- src.orig/gdb/s390-nat.c	2009-02-16 00:20:29.000000000 +0000
+++ src/gdb/s390-nat.c	2009-02-16 03:26:06.000000000 +0000
@@ -204,7 +204,8 @@ store_fpregs (const struct regcache *reg
 /* Fetch register REGNUM from the child process.  If REGNUM is -1, do
    this for all registers.  */
 static void
-s390_linux_fetch_inferior_registers (struct regcache *regcache, int regnum)
+s390_linux_fetch_inferior_registers (struct target_ops *ops,
+				     struct regcache *regcache, int regnum)
 {
   int tid = s390_inferior_tid ();
 
@@ -220,7 +221,8 @@ s390_linux_fetch_inferior_registers (str
 /* Store register REGNUM back into the child process.  If REGNUM is
    -1, do this for all registers.  */
 static void
-s390_linux_store_inferior_registers (struct regcache *regcache, int regnum)
+s390_linux_store_inferior_registers (struct target_ops *ops,
+				     struct regcache *regcache, int regnum)
 {
   int tid = s390_inferior_tid ();
 
Index: src/gdb/shnbsd-nat.c
===================================================================
--- src.orig/gdb/shnbsd-nat.c	2009-02-16 00:20:29.000000000 +0000
+++ src/gdb/shnbsd-nat.c	2009-02-16 03:26:06.000000000 +0000
@@ -41,7 +41,8 @@
 || (regno) == SR_REGNUM)
 
 static void
-shnbsd_fetch_inferior_registers (struct regcache *regcache, int regno)
+shnbsd_fetch_inferior_registers (struct target_ops *ops,
+				 struct regcache *regcache, int regno)
 {
   if (regno == -1 || GETREGS_SUPPLIES (get_regcache_arch (regcache), regno))
     {
@@ -59,7 +60,8 @@ shnbsd_fetch_inferior_registers (struct 
 }
 
 static void
-shnbsd_store_inferior_registers (struct regcache *regcache, int regno)
+shnbsd_store_inferior_registers (struct target_ops *ops,
+				 struct regcache *regcache, int regno)
 {
   if (regno == -1 || GETREGS_SUPPLIES (get_regcache_arch (regcache), regno))
     {
Index: src/gdb/sparc-nat.c
===================================================================
--- src.orig/gdb/sparc-nat.c	2009-02-16 00:20:29.000000000 +0000
+++ src/gdb/sparc-nat.c	2009-02-16 03:26:06.000000000 +0000
@@ -134,7 +134,8 @@ sparc32_fpregset_supplies_p (int regnum)
    for all registers (including the floating-point registers).  */
 
 void
-sparc_fetch_inferior_registers (struct regcache *regcache, int regnum)
+sparc_fetch_inferior_registers (struct target_ops *ops,
+				struct regcache *regcache, int regnum)
 {
   int pid;
 
@@ -185,7 +186,8 @@ sparc_fetch_inferior_registers (struct r
 }
 
 void
-sparc_store_inferior_registers (struct regcache *regcache, int regnum)
+sparc_store_inferior_registers (struct target_ops *ops,
+				struct regcache *regcache, int regnum)
 {
   int pid;
 
Index: src/gdb/sparc-nat.h
===================================================================
--- src.orig/gdb/sparc-nat.h	2009-02-16 00:20:29.000000000 +0000
+++ src/gdb/sparc-nat.h	2009-02-16 03:26:06.000000000 +0000
@@ -40,7 +40,9 @@ extern int sparc32_fpregset_supplies_p (
 
 extern struct target_ops *sparc_target (void);
 
-extern void sparc_fetch_inferior_registers (struct regcache *, int);
-extern void sparc_store_inferior_registers (struct regcache *, int);
+extern void sparc_fetch_inferior_registers (struct target_ops *,
+					    struct regcache *, int);
+extern void sparc_store_inferior_registers (struct target_ops *,
+					    struct regcache *, int);
 
 #endif /* sparc-nat.h */
Index: src/gdb/spu-linux-nat.c
===================================================================
--- src.orig/gdb/spu-linux-nat.c	2009-02-16 00:20:30.000000000 +0000
+++ src/gdb/spu-linux-nat.c	2009-02-16 03:26:06.000000000 +0000
@@ -452,7 +452,8 @@ spu_child_wait (struct target_ops *ops,
 
 /* Override the fetch_inferior_register routine.  */
 static void
-spu_fetch_inferior_registers (struct regcache *regcache, int regno)
+spu_fetch_inferior_registers (struct target_ops *ops,
+			      struct regcache *regcache, int regno)
 {
   int fd;
   ULONGEST addr;
@@ -493,7 +494,8 @@ spu_fetch_inferior_registers (struct reg
 
 /* Override the store_inferior_register routine.  */
 static void
-spu_store_inferior_registers (struct regcache *regcache, int regno)
+spu_store_inferior_registers (struct target_ops *ops,
+			      struct regcache *regcache, int regno)
 {
   int fd;
   ULONGEST addr;
Index: src/gdb/vaxbsd-nat.c
===================================================================
--- src.orig/gdb/vaxbsd-nat.c	2009-02-16 00:20:29.000000000 +0000
+++ src/gdb/vaxbsd-nat.c	2009-02-16 03:26:06.000000000 +0000
@@ -63,7 +63,8 @@ vaxbsd_collect_gregset (const struct reg
    for all registers.  */
 
 static void
-vaxbsd_fetch_inferior_registers (struct regcache *regcache, int regnum)
+vaxbsd_fetch_inferior_registers (struct target_ops *ops,
+				 struct regcache *regcache, int regnum)
 {
   struct reg regs;
 
@@ -78,7 +79,8 @@ vaxbsd_fetch_inferior_registers (struct 
    this for all registers.  */
 
 static void
-vaxbsd_store_inferior_registers (struct regcache *regcache, int regnum)
+vaxbsd_store_inferior_registers (struct target_ops *ops,
+				 struct regcache *regcache, int regnum)
 {
   struct reg regs;
 
Index: src/gdb/xtensa-linux-nat.c
===================================================================
--- src.orig/gdb/xtensa-linux-nat.c	2009-02-16 00:20:29.000000000 +0000
+++ src/gdb/xtensa-linux-nat.c	2009-02-16 03:26:06.000000000 +0000
@@ -265,7 +265,8 @@ store_xtregs (struct regcache *regcache,
 }
 
 void
-xtensa_linux_fetch_inferior_registers (struct regcache *regcache, int regnum)
+xtensa_linux_fetch_inferior_registers (struct target_ops *ops,
+				       struct regcache *regcache, int regnum)
 {
   if (regnum == -1)
     {
@@ -279,7 +280,8 @@ xtensa_linux_fetch_inferior_registers (s
 }
 
 void
-xtensa_linux_store_inferior_registers (struct regcache *regcache, int regnum)
+xtensa_linux_store_inferior_registers (struct target_ops *ops,
+				       struct regcache *regcache, int regnum)
 {
   if (regnum == -1)
     {
Index: src/gdb/gdbarch.sh
===================================================================
--- src.orig/gdb/gdbarch.sh	2009-02-16 03:33:47.000000000 +0000
+++ src/gdb/gdbarch.sh	2009-02-16 03:33:50.000000000 +0000
@@ -614,6 +614,10 @@ v:struct core_regset_section *:core_regs
 # core file into buffer READBUF with length LEN.
 M:LONGEST:core_xfer_shared_libraries:gdb_byte *readbuf, ULONGEST offset, LONGEST len:readbuf, offset, len
 
+# How the core_stratum layer converts a PTID from a core file to a
+# string.
+M:char *:core_pid_to_str:ptid_t ptid:ptid
+
 # If the elements of C++ vtables are in-place function descriptors rather
 # than normal function pointers (which may point to code or a descriptor),
 # set this to one.
Index: src/gdb/sol2-tdep.c
===================================================================
--- src.orig/gdb/sol2-tdep.c	2009-02-16 03:27:27.000000000 +0000
+++ src/gdb/sol2-tdep.c	2009-02-16 04:43:50.000000000 +0000
@@ -20,6 +20,7 @@
 #include "defs.h"
 #include "frame.h"
 #include "symtab.h"
+#include "inferior.h"
 
 #include "sol2-tdep.h"
 
@@ -34,3 +35,15 @@ sol2_skip_solib_resolver (struct gdbarch
 
   return 0;
 }
+
+/* This is how we want PTIDs from Solaris core files to be
+   printed.  */
+
+char *
+sol2_core_pid_to_str (struct gdbarch *gdbarch, ptid_t ptid)
+{
+  static char buf[80];
+
+  xsnprintf (buf, sizeof buf, "LWP %ld", ptid_get_lwp (ptid));
+  return buf;
+}
Index: src/gdb/sol2-tdep.h
===================================================================
--- src.orig/gdb/sol2-tdep.h	2009-02-16 03:27:43.000000000 +0000
+++ src/gdb/sol2-tdep.h	2009-02-16 03:27:59.000000000 +0000
@@ -24,4 +24,6 @@ struct gdbarch;
 
 CORE_ADDR sol2_skip_solib_resolver (struct gdbarch *, CORE_ADDR);
 
+char *sol2_core_pid_to_str (struct gdbarch *gdbarch, ptid_t ptid);
+
 #endif /* sol2-tdep.h */
Index: src/gdb/gdbarch.c
===================================================================
--- src.orig/gdb/gdbarch.c	2009-02-16 03:33:17.000000000 +0000
+++ src/gdb/gdbarch.c	2009-02-16 03:34:16.000000000 +0000
@@ -226,6 +226,7 @@ struct gdbarch
   int core_reg_section_encodes_pid;
   struct core_regset_section * core_regset_sections;
   gdbarch_core_xfer_shared_libraries_ftype *core_xfer_shared_libraries;
+  gdbarch_core_pid_to_str_ftype *core_pid_to_str;
   int vtable_function_descriptors;
   int vbit_in_delta;
   gdbarch_skip_permanent_breakpoint_ftype *skip_permanent_breakpoint;
@@ -360,6 +361,7 @@ struct gdbarch startup_gdbarch =
   0,  /* core_reg_section_encodes_pid */
   0,  /* core_regset_sections */
   0,  /* core_xfer_shared_libraries */
+  0,  /* core_pid_to_str */
   0,  /* vtable_function_descriptors */
   0,  /* vbit_in_delta */
   0,  /* skip_permanent_breakpoint */
@@ -613,6 +615,7 @@ verify_gdbarch (struct gdbarch *gdbarch)
   /* Skip verify of regset_from_core_section, has predicate */
   /* Skip verify of core_reg_section_encodes_pid, invalid_p == 0 */
   /* Skip verify of core_xfer_shared_libraries, has predicate */
+  /* Skip verify of core_pid_to_str, has predicate */
   /* Skip verify of vtable_function_descriptors, invalid_p == 0 */
   /* Skip verify of vbit_in_delta, invalid_p == 0 */
   /* Skip verify of skip_permanent_breakpoint, has predicate */
@@ -733,6 +736,12 @@ gdbarch_dump (struct gdbarch *gdbarch, s
                       "gdbarch_dump: convert_register_p = <%s>\n",
                       host_address_to_string (gdbarch->convert_register_p));
   fprintf_unfiltered (file,
+                      "gdbarch_dump: gdbarch_core_pid_to_str_p() = %d\n",
+                      gdbarch_core_pid_to_str_p (gdbarch));
+  fprintf_unfiltered (file,
+                      "gdbarch_dump: core_pid_to_str = <%s>\n",
+                      host_address_to_string (gdbarch->core_pid_to_str));
+  fprintf_unfiltered (file,
                       "gdbarch_dump: gdbarch_core_read_description_p() = %d\n",
                       gdbarch_core_read_description_p (gdbarch));
   fprintf_unfiltered (file,
@@ -2963,6 +2972,30 @@ set_gdbarch_core_xfer_shared_libraries (
 }
 
 int
+gdbarch_core_pid_to_str_p (struct gdbarch *gdbarch)
+{
+  gdb_assert (gdbarch != NULL);
+  return gdbarch->core_pid_to_str != NULL;
+}
+
+char *
+gdbarch_core_pid_to_str (struct gdbarch *gdbarch, ptid_t ptid)
+{
+  gdb_assert (gdbarch != NULL);
+  gdb_assert (gdbarch->core_pid_to_str != NULL);
+  if (gdbarch_debug >= 2)
+    fprintf_unfiltered (gdb_stdlog, "gdbarch_core_pid_to_str called\n");
+  return gdbarch->core_pid_to_str (gdbarch, ptid);
+}
+
+void
+set_gdbarch_core_pid_to_str (struct gdbarch *gdbarch,
+                             gdbarch_core_pid_to_str_ftype core_pid_to_str)
+{
+  gdbarch->core_pid_to_str = core_pid_to_str;
+}
+
+int
 gdbarch_vtable_function_descriptors (struct gdbarch *gdbarch)
 {
   gdb_assert (gdbarch != NULL);
Index: src/gdb/gdbarch.h
===================================================================
--- src.orig/gdb/gdbarch.h	2009-02-16 03:33:15.000000000 +0000
+++ src/gdb/gdbarch.h	2009-02-16 03:34:05.000000000 +0000
@@ -661,6 +661,15 @@ typedef LONGEST (gdbarch_core_xfer_share
 extern LONGEST gdbarch_core_xfer_shared_libraries (struct gdbarch *gdbarch, gdb_byte *readbuf, ULONGEST offset, LONGEST len);
 extern void set_gdbarch_core_xfer_shared_libraries (struct gdbarch *gdbarch, gdbarch_core_xfer_shared_libraries_ftype *core_xfer_shared_libraries);
 
+/* How the core_stratum layer converts a PTID from a core file to a
+   string. */
+
+extern int gdbarch_core_pid_to_str_p (struct gdbarch *gdbarch);
+
+typedef char * (gdbarch_core_pid_to_str_ftype) (struct gdbarch *gdbarch, ptid_t ptid);
+extern char * gdbarch_core_pid_to_str (struct gdbarch *gdbarch, ptid_t ptid);
+extern void set_gdbarch_core_pid_to_str (struct gdbarch *gdbarch, gdbarch_core_pid_to_str_ftype *core_pid_to_str);
+
 /* If the elements of C++ vtables are in-place function descriptors rather
    than normal function pointers (which may point to code or a descriptor),
    set this to one. */
Index: src/gdb/amd64-sol2-tdep.c
===================================================================
--- src.orig/gdb/amd64-sol2-tdep.c	2009-02-16 04:44:20.000000000 +0000
+++ src/gdb/amd64-sol2-tdep.c	2009-02-16 04:45:01.000000000 +0000
@@ -117,6 +117,9 @@ amd64_sol2_init_abi (struct gdbarch_info
   /* Solaris encodes the pid of the inferior in regset section
      names.  */
   set_gdbarch_core_reg_section_encodes_pid (gdbarch, 1);
+
+  /* How to print LWP PTIDs from core files.  */
+  set_gdbarch_core_pid_to_str (gdbarch, sol2_core_pid_to_str);
 }
 
 
Index: src/gdb/sparc-sol2-tdep.c
===================================================================
--- src.orig/gdb/sparc-sol2-tdep.c	2009-02-16 04:44:25.000000000 +0000
+++ src/gdb/sparc-sol2-tdep.c	2009-02-16 04:45:22.000000000 +0000
@@ -235,6 +235,9 @@ sparc32_sol2_init_abi (struct gdbarch_in
   /* Solaris encodes the pid of the inferior in regset section
      names.  */
   set_gdbarch_core_reg_section_encodes_pid (gdbarch, 1);
+
+  /* How to print LWP PTIDs from core files.  */
+  set_gdbarch_core_pid_to_str (gdbarch, sol2_core_pid_to_str);
 }
 
 
Index: src/gdb/sparc64-sol2-tdep.c
===================================================================
--- src.orig/gdb/sparc64-sol2-tdep.c	2009-02-16 04:44:31.000000000 +0000
+++ src/gdb/sparc64-sol2-tdep.c	2009-02-16 04:45:42.000000000 +0000
@@ -184,6 +184,9 @@ sparc64_sol2_init_abi (struct gdbarch_in
   /* Solaris encodes the pid of the inferior in regset section
      names.  */
   set_gdbarch_core_reg_section_encodes_pid (gdbarch, 1);
+
+  /* How to print LWP PTIDs from core files.  */
+  set_gdbarch_core_pid_to_str (gdbarch, sol2_core_pid_to_str);
 }
 
 
Index: src/gdb/i386-sol2-tdep.c
===================================================================
--- src.orig/gdb/i386-sol2-tdep.c	2009-02-16 03:22:34.000000000 +0000
+++ src/gdb/i386-sol2-tdep.c	2009-02-16 03:41:29.000000000 +0000
@@ -139,6 +139,9 @@ i386_sol2_init_abi (struct gdbarch_info 
   /* Solaris encodes the pid of the inferior in regset section
      names.  */
   set_gdbarch_core_reg_section_encodes_pid (gdbarch, 1);
+
+  /* How to print LWP PTIDs from core files.  */
+  set_gdbarch_core_pid_to_str (gdbarch, sol2_core_pid_to_str);
 }
 
 


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