/* Low level interface for debugging Solaris threads for GDB, the GNU debugger.
   Copyright 1996, 1997, 1998 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.  */

/* This module implements a sort of half target that sits between the
   machine-independent parts of GDB and the /proc interface (procfs.c) to
   provide access to the Solaris user-mode thread implementation.

   Solaris threads are true user-mode threads, which are invoked via the thr_*
   and pthread_* (native and Posix respectivly) interfaces.  These are mostly
   implemented in user-space, with all thread context kept in various
   structures that live in the user's heap.  These should not be confused with
   lightweight processes (LWPs), which are implemented by the kernel, and
   scheduled without explicit intervention by the process.

   Just to confuse things a little, Solaris threads (both native and Posix) are
   actually implemented using LWPs.  In general, there are going to be more
   threads than LWPs.  There is no fixed correspondence between a thread and an
   LWP.  When a thread wants to run, it gets scheduled onto the first available
   LWP and can therefore migrate from one LWP to another as time goes on.  A
   sleeping thread may not be associated with an LWP at all!

   To make it possible to mess with threads, Sun provides a library called
   libthread_db.so.1 (not to be confused with libthread_db.so.0, which doesn't
   have a published interface).  This interface has an upper part, which it
   provides, and a lower part which I provide.  The upper part consists of the
   td_* routines, which allow me to find all the threads, query their state,
   etc...  The lower part consists of all of the ps_*, which are used by the
   td_* routines to read/write memory, manipulate LWPs, lookup symbols, etc...
   The ps_* routines actually do most of their work by calling functions in
   procfs.c.  */

#include "defs.h"
#include <thread.h>
#include <proc_service.h>
#include <thread_db.h>
#include "gdbthread.h"
#include "target.h"
#include "inferior.h"
#include <fcntl.h>
#include <sys/stat.h>
#include <dlfcn.h>
#include "gdbcmd.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 PARAMS ((int pid));

/* Note that these prototypes differ slightly from those used in procfs.c
   for of two reasons.  One, we can't use gregset_t, as that's got a whole
   different meaning under Solaris (also, see above).  Two, we can't use the
   pointer form here as these are actually arrays of ints (for Sparc's at
   least), and are automatically coerced into pointers to ints when used as
   parameters.  That makes it impossible to avoid a compiler warning when
   passing pr{g fp}regset_t's from a parameter to an argument of one of
   these functions.  */

extern void supply_gregset PARAMS ((const prgregset_t));
extern void fill_gregset PARAMS ((prgregset_t, int));
extern void supply_fpregset PARAMS ((const prfpregset_t *));
extern void fill_fpregset PARAMS ((prfpregset_t *, int));

/* This struct is defined by us, but mainly used for the proc_service interface.
   We don't have much use for it, except as a handy place to get a real pid
   for memory accesses.  */

struct ps_prochandle
  {
    pid_t pid;
  };

struct string_map
  {
    int num;
    char *str;
  };

static struct ps_prochandle main_ph;
static td_thragent_t *main_ta;
static int sol_thread_active = 0;

static struct cleanup *save_inferior_pid PARAMS ((void));
static void restore_inferior_pid PARAMS ((void *pid));
static char *td_err_string PARAMS ((td_err_e errcode));
static char *td_state_string PARAMS ((td_thr_state_e statecode));
static int thread_to_lwp PARAMS ((int thread_id, int default_lwp));
static void sol_thread_resume PARAMS ((int pid, int step,
				       enum target_signal signo));
static int lwp_to_thread PARAMS ((int lwp));
static int sol_thread_alive PARAMS ((int pid));
static void sol_core_close PARAMS ((int quitting));

static void init_sol_thread_ops PARAMS ((void));
static void init_sol_core_ops PARAMS ((void));

/* Default definitions: These must be defined in tm.h 
   if they are to be shared with a process module such as procfs.  */

#define THREAD_FLAG            0x80000000
#define is_thread(ARG)         (((ARG) & THREAD_FLAG) != 0)
#define is_lwp(ARG)            (((ARG) & THREAD_FLAG) == 0)
#define GET_LWP(PID)           TIDGET (PID)
#define GET_THREAD(PID)        (((PID) >> 16) & 0x7fff)
#define BUILD_LWP(TID, PID)    ((TID) << 16 | (PID))

#define BUILD_THREAD(THREAD_ID, PID) (THREAD_FLAG | BUILD_LWP (THREAD_ID, PID))

/* Pointers to routines from lithread_db resolved by dlopen() */

static void
  (*p_td_log) (const int on_off);
static td_err_e
  (*p_td_ta_new) (const struct ps_prochandle * ph_p, td_thragent_t ** ta_pp);
static td_err_e
  (*p_td_ta_delete) (td_thragent_t * ta_p);
static td_err_e
  (*p_td_init) (void);
static td_err_e
  (*p_td_ta_get_ph) (const td_thragent_t * ta_p, struct ps_prochandle ** ph_pp);
static td_err_e
  (*p_td_ta_get_nthreads) (const td_thragent_t * ta_p, int *nthread_p);
static td_err_e
  (*p_td_ta_tsd_iter) (const td_thragent_t * ta_p, td_key_iter_f * cb, void *cbdata_p);
static td_err_e
  (*p_td_ta_thr_iter) (const td_thragent_t * ta_p, td_thr_iter_f * cb, void *cbdata_p, td_thr_state_e state,
	       int ti_pri, sigset_t * ti_sigmask_p, unsigned ti_user_flags);
static td_err_e
  (*p_td_thr_validate) (const td_thrhandle_t * th_p);
static td_err_e
  (*p_td_thr_tsd) (const td_thrhandle_t * th_p, const thread_key_t key, void **data_pp);
static td_err_e
  (*p_td_thr_get_info) (const td_thrhandle_t * th_p, td_thrinfo_t * ti_p);
static td_err_e
  (*p_td_thr_getfpregs) (const td_thrhandle_t * th_p, prfpregset_t * fpregset);
static td_err_e
  (*p_td_thr_getxregsize) (const td_thrhandle_t * th_p, int *xregsize);
static td_err_e
  (*p_td_thr_getxregs) (const td_thrhandle_t * th_p, const caddr_t xregset);
static td_err_e
  (*p_td_thr_sigsetmask) (const td_thrhandle_t * th_p, const sigset_t ti_sigmask);
static td_err_e
  (*p_td_thr_setprio) (const td_thrhandle_t * th_p, const int ti_pri);
static td_err_e
  (*p_td_thr_setsigpending) (const td_thrhandle_t * th_p, const uchar_t ti_pending_flag, const sigset_t ti_pending);
static td_err_e
  (*p_td_thr_setfpregs) (const td_thrhandle_t * th_p, const prfpregset_t * fpregset);
static td_err_e
  (*p_td_thr_setxregs) (const td_thrhandle_t * th_p, const caddr_t xregset);
static td_err_e
  (*p_td_ta_map_id2thr) (const td_thragent_t * ta_p, thread_t tid, td_thrhandle_t * th_p);
static td_err_e
  (*p_td_ta_map_lwp2thr) (const td_thragent_t * ta_p, lwpid_t lwpid, td_thrhandle_t * th_p);
static td_err_e
  (*p_td_thr_getgregs) (const td_thrhandle_t * th_p, prgregset_t regset);
static td_err_e
  (*p_td_thr_setgregs) (const td_thrhandle_t * th_p, const prgregset_t regset);

/*

   LOCAL FUNCTION

   td_err_string - Convert a thread_db error code to a string

   SYNOPSIS

   char * td_err_string (errcode)

   DESCRIPTION

   Return the thread_db error string associated with errcode.  If errcode
   is unknown, then return a message.

 */

static char *
td_err_string (errcode)
     td_err_e errcode;
{
  static struct string_map
    td_err_table[] =
  {
    {TD_OK, "generic \"call succeeded\""},
    {TD_ERR, "generic error."},
    {TD_NOTHR, "no thread can be found to satisfy query"},
    {TD_NOSV, "no synch. variable can be found to satisfy query"},
    {TD_NOLWP, "no lwp can be found to satisfy query"},
    {TD_BADPH, "invalid process handle"},
    {TD_BADTH, "invalid thread handle"},
    {TD_BADSH, "invalid synchronization handle"},
    {TD_BADTA, "invalid thread agent"},
    {TD_BADKEY, "invalid key"},
    {TD_NOMSG, "td_thr_event_getmsg() called when there was no message"},
    {TD_NOFPREGS, "FPU register set not available for given thread"},
    {TD_NOLIBTHREAD, "application not linked with libthread"},
    {TD_NOEVENT, "requested event is not supported"},
    {TD_NOCAPAB, "capability not available"},
    {TD_DBERR, "Debugger service failed"},
    {TD_NOAPLIC, "Operation not applicable to"},
    {TD_NOTSD, "No thread specific data for this thread"},
    {TD_MALLOC, "Malloc failed"},
    {TD_PARTIALREG, "Only part of register set was writen/read"},
    {TD_NOXREGS, "X register set not available for given thread"}
  };
  const int td_err_size = sizeof td_err_table / sizeof (struct string_map);
  int i;
  static char buf[50];

  for (i = 0; i < td_err_size; i++)
    if (td_err_table[i].num == errcode)
      return td_err_table[i].str;

  sprintf (buf, "Unknown thread_db error code: %d", errcode);

  return buf;
}

/*

   LOCAL FUNCTION

   td_state_string - Convert a thread_db state code to a string

   SYNOPSIS

   char * td_state_string (statecode)

   DESCRIPTION

   Return the thread_db state string associated with statecode.  If
   statecode is unknown, then return a message.

 */

static char *
td_state_string (statecode)
     td_thr_state_e statecode;
{
  static struct string_map
    td_thr_state_table[] =
  {
    {TD_THR_ANY_STATE, "any state"},
    {TD_THR_UNKNOWN, "unknown"},
    {TD_THR_STOPPED, "stopped"},
    {TD_THR_RUN, "run"},
    {TD_THR_ACTIVE, "active"},
    {TD_THR_ZOMBIE, "zombie"},
    {TD_THR_SLEEP, "sleep"},
    {TD_THR_STOPPED_ASLEEP, "stopped asleep"}
  };
  const int td_thr_state_table_size = sizeof td_thr_state_table / sizeof (struct string_map);
  int i;
  static char buf[50];

  for (i = 0; i < td_thr_state_table_size; i++)
    if (td_thr_state_table[i].num == statecode)
      return td_thr_state_table[i].str;

  sprintf (buf, "Unknown thread_db state code: %d", statecode);

  return buf;
}

/*

   LOCAL FUNCTION

   thread_to_lwp - Convert a Posix or Solaris thread id to a LWP id.

   SYNOPSIS

   int thread_to_lwp (thread_id, default_lwp)

   DESCRIPTION

   This function converts a Posix or Solaris thread id to a lightweight
   process id.  If thread_id is non-existent, that's an error.  If it's
   an inactive thread, then we return default_lwp.

   NOTES

   This function probably shouldn't call error()...

 */

static int
thread_to_lwp (thread_id, default_lwp)
     int thread_id;
     int default_lwp;
{
  td_thrinfo_t ti;
  td_thrhandle_t th;
  td_err_e val;

  if (is_lwp (thread_id))
    return thread_id;		/* It's already an LWP id */

  /* It's a thread.  Convert to lwp */

  val = p_td_ta_map_id2thr (main_ta, GET_THREAD (thread_id), &th);
  if (val == TD_NOTHR)
    return -1;			/* thread must have terminated */
  else if (val != TD_OK)
    error ("thread_to_lwp: td_ta_map_id2thr %s", td_err_string (val));

  val = p_td_thr_get_info (&th, &ti);
  if (val == TD_NOTHR)
    return -1;			/* thread must have terminated */
  else if (val != TD_OK)
    error ("thread_to_lwp: td_thr_get_info: %s", td_err_string (val));

  if (ti.ti_state != TD_THR_ACTIVE)
    {
      if (default_lwp != -1)
	return default_lwp;
      error ("thread_to_lwp: thread state not active: %s",
	     td_state_string (ti.ti_state));
    }

  return BUILD_LWP (ti.ti_lid, PIDGET (thread_id));
}

/*

   LOCAL FUNCTION

   lwp_to_thread - Convert a LWP id to a Posix or Solaris thread id.

   SYNOPSIS

   int lwp_to_thread (lwp_id)

   DESCRIPTION

   This function converts a lightweight process id to a Posix or Solaris
   thread id.  If thread_id is non-existent, that's an error.

   NOTES

   This function probably shouldn't call error()...

 */

static int
lwp_to_thread (lwp)
     int lwp;
{
  td_thrinfo_t ti;
  td_thrhandle_t th;
  td_err_e val;

  if (is_thread (lwp))
    return lwp;			/* It's already a thread id */

  /* It's an lwp.  Convert it to a thread id.  */

  if (!sol_thread_alive (lwp))
    return -1;			/* defunct lwp */

  val = p_td_ta_map_lwp2thr (main_ta, GET_LWP (lwp), &th);
  if (val == TD_NOTHR)
    return -1;			/* thread must have terminated */
  else if (val != TD_OK)
    error ("lwp_to_thread: td_ta_map_lwp2thr: %s.", td_err_string (val));

  val = p_td_thr_validate (&th);
  if (val == TD_NOTHR)
    return lwp;			/* libthread doesn't know about it, just return lwp */
  else if (val != TD_OK)
    error ("lwp_to_thread: td_thr_validate: %s.", td_err_string (val));

  val = p_td_thr_get_info (&th, &ti);
  if (val == TD_NOTHR)
    return -1;			/* thread must have terminated */
  else if (val != TD_OK)
    error ("lwp_to_thread: td_thr_get_info: %s.", td_err_string (val));

  return BUILD_THREAD (ti.ti_tid, PIDGET (lwp));
}

/*

   LOCAL FUNCTION

   save_inferior_pid - Save inferior_pid on the cleanup list
   restore_inferior_pid - Restore inferior_pid from the cleanup list

   SYNOPSIS

   struct cleanup *save_inferior_pid ()
   void restore_inferior_pid (int pid)

   DESCRIPTION

   These two functions act in unison to restore inferior_pid in
   case of an error.

   NOTES

   inferior_pid is a global variable that needs to be changed by many of
   these routines before calling functions in procfs.c.  In order to
   guarantee that inferior_pid gets restored (in case of errors), you
   need to call save_inferior_pid before changing it.  At the end of the
   function, you should invoke do_cleanups to restore it.

 */


static struct cleanup *
save_inferior_pid ()
{
  return make_cleanup (restore_inferior_pid, (void *) inferior_pid);
}

static void
restore_inferior_pid (pid)
     void *pid;
{
  inferior_pid = (int) pid;
}


/* 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.  */


/* ARGSUSED */
static void
sol_thread_open (arg, from_tty)
     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 (args, from_tty)
     char *args;
     int from_tty;
{
  procfs_ops.to_attach (args, from_tty);
  /* Must get symbols from solibs before libthread_db can run! */
  SOLIB_ADD ((char *) 0, from_tty, (struct target_ops *) 0);
  if (sol_thread_active)
    {
      printf_filtered ("sol-thread active.\n");
      main_ph.pid = inferior_pid;	/* Save for xfer_memory */
      push_target (&sol_thread_ops);
      inferior_pid = lwp_to_thread (inferior_pid);
      if (inferior_pid == -1)
	inferior_pid = main_ph.pid;
      else
	add_thread (inferior_pid);
    }
  /* XXX - might want to iterate over all the threads and register them. */
}

/* Take a program previously attached to and detaches it.
   The program resumes execution and will no longer stop
   on signals, etc.  We'd better not have left any breakpoints
   in the program or it'll die when it hits one.  For this
   to work, it may be necessary for the process to have been
   previously attached.  It *might* work if the program was
   started via the normal ptrace (PTRACE_TRACEME).  */

static void
sol_thread_detach (args, from_tty)
     char *args;
     int from_tty;
{
  inferior_pid = PIDGET (main_ph.pid);
  unpush_target (&sol_thread_ops);
  procfs_ops.to_detach (args, from_tty);
}

/* Resume execution of process PID.  If STEP is nozero, then
   just single step it.  If SIGNAL is nonzero, restart it with that
   signal activated.  We may have to convert pid from a thread-id to an LWP id
   for procfs.  */

static void
sol_thread_resume (pid, step, signo)
     int pid;
     int step;
     enum target_signal signo;
{
  struct cleanup *old_chain;

  old_chain = save_inferior_pid ();

  inferior_pid = thread_to_lwp (inferior_pid, main_ph.pid);
  if (inferior_pid == -1)
    inferior_pid = procfs_first_available ();

  if (pid != -1)
    {
      int save_pid = pid;

      pid = thread_to_lwp (pid, -2);
      if (pid == -2)		/* Inactive thread */
	error ("This version of Solaris can't start inactive threads.");
      if (info_verbose && pid == -1)
	warning ("Specified thread %d seems to have terminated",
		 GET_THREAD (save_pid));
    }

  procfs_ops.to_resume (pid, step, signo);

  do_cleanups (old_chain);
}

/* Wait for any threads to stop.  We may have to convert PID from a thread id
   to a LWP id, and vice versa on the way out.  */

static int
sol_thread_wait (pid, ourstatus)
     int pid;
     struct target_waitstatus *ourstatus;
{
  int rtnval;
  int save_pid;
  struct cleanup *old_chain;

  save_pid = inferior_pid;
  old_chain = save_inferior_pid ();

  inferior_pid = thread_to_lwp (inferior_pid, main_ph.pid);
  if (inferior_pid == -1)
    inferior_pid = procfs_first_available ();

  if (pid != -1)
    {
      int save_pid = pid;

      pid = thread_to_lwp (pid, -2);
      if (pid == -2)		/* Inactive thread */
	error ("This version of Solaris can't start inactive threads.");
      if (info_verbose && pid == -1)
	warning ("Specified thread %d seems to have terminated",
		 GET_THREAD (save_pid));
    }

  rtnval = procfs_ops.to_wait (pid, ourstatus);

  if (ourstatus->kind != TARGET_WAITKIND_EXITED)
    {
      /* Map the LWP of interest back to the appropriate thread ID */
      rtnval = lwp_to_thread (rtnval);
      if (rtnval == -1)
	rtnval = save_pid;

      /* See if we have a new thread */
      if (is_thread (rtnval)
	  && rtnval != save_pid
	  && !in_thread_list (rtnval))
	{
	  printf_filtered ("[New %s]\n", target_pid_to_str (rtnval));
	  add_thread (rtnval);
	}
    }

  /* During process initialization, we may get here without the thread package
     being initialized, since that can only happen after we've found the shared
     libs.  */

  do_cleanups (old_chain);

  return rtnval;
}

static void
sol_thread_fetch_registers (regno)
     int regno;
{
  thread_t thread;
  td_thrhandle_t thandle;
  td_err_e val;
  prgregset_t gregset;
  prfpregset_t fpregset;
#if 0
  int xregsize;
  caddr_t xregset;
#endif

  if (!is_thread (inferior_pid))
    {				/* LWP: pass the request on to procfs.c */
      if (target_has_execution)
	procfs_ops.to_fetch_registers (regno);
      else
	orig_core_ops.to_fetch_registers (regno);
      return;
    }

  /* Solaris thread: convert inferior_pid into a td_thrhandle_t */

  thread = GET_THREAD (inferior_pid);

  if (thread == 0)
    error ("sol_thread_fetch_registers:  thread == 0");

  val = p_td_ta_map_id2thr (main_ta, thread, &thandle);
  if (val != TD_OK)
    error ("sol_thread_fetch_registers: td_ta_map_id2thr: %s",
	   td_err_string (val));

  /* Get the integer regs */

  val = p_td_thr_getgregs (&thandle, gregset);
  if (val != TD_OK
      && val != TD_PARTIALREG)
    error ("sol_thread_fetch_registers: td_thr_getgregs %s",
	   td_err_string (val));

  /* For the sparc, TD_PARTIALREG means that only i0->i7, l0->l7, pc and sp
     are saved (by a thread context switch).  */

  /* And, now the fp regs */

  val = p_td_thr_getfpregs (&thandle, &fpregset);
  if (val != TD_OK
      && val != TD_NOFPREGS)
    error ("sol_thread_fetch_registers: td_thr_getfpregs %s",
	   td_err_string (val));

/* Note that we must call supply_{g fp}regset *after* calling the td routines
   because the td routines call ps_lget* which affect the values stored in the
   registers array.  */

  supply_gregset (gregset);
  supply_fpregset (&fpregset);

#if 0
/* thread_db doesn't seem to handle this right */
  val = td_thr_getxregsize (&thandle, &xregsize);
  if (val != TD_OK && val != TD_NOXREGS)
    error ("sol_thread_fetch_registers: td_thr_getxregsize %s",
	   td_err_string (val));

  if (val == TD_OK)
    {
      xregset = alloca (xregsize);
      val = td_thr_getxregs (&thandle, xregset);
      if (val != TD_OK)
	error ("sol_thread_fetch_registers: td_thr_getxregs %s",
	       td_err_string (val));
    }
#endif
}

static void
sol_thread_store_registers (regno)
     int regno;
{
  thread_t thread;
  td_thrhandle_t thandle;
  td_err_e val;
  prgregset_t regset;
  prfpregset_t fpregset;
#if 0
  int xregsize;
  caddr_t xregset;
#endif

  if (!is_thread (inferior_pid))
    {				/* LWP: pass the request on to procfs.c */
      procfs_ops.to_store_registers (regno);
      return;
    }

  /* Solaris thread: convert inferior_pid into a td_thrhandle_t */

  thread = GET_THREAD (inferior_pid);

  val = p_td_ta_map_id2thr (main_ta, thread, &thandle);
  if (val != TD_OK)
    error ("sol_thread_store_registers: td_ta_map_id2thr %s",
	   td_err_string (val));

  if (regno != -1)
    {				/* Not writing all the regs */
      /* save new register value */
      char old_value[REGISTER_SIZE];
      memcpy (old_value, &registers[REGISTER_BYTE (regno)], REGISTER_SIZE);

      val = p_td_thr_getgregs (&thandle, regset);
      if (val != TD_OK)
	error ("sol_thread_store_registers: td_thr_getgregs %s",
	       td_err_string (val));
      val = p_td_thr_getfpregs (&thandle, &fpregset);
      if (val != TD_OK)
	error ("sol_thread_store_registers: td_thr_getfpregs %s",
	       td_err_string (val));

      /* restore new register value */
      memcpy (&registers[REGISTER_BYTE (regno)], old_value, REGISTER_SIZE);

#if 0
/* thread_db doesn't seem to handle this right */
      val = td_thr_getxregsize (&thandle, &xregsize);
      if (val != TD_OK && val != TD_NOXREGS)
	error ("sol_thread_store_registers: td_thr_getxregsize %s",
	       td_err_string (val));

      if (val == TD_OK)
	{
	  xregset = alloca (xregsize);
	  val = td_thr_getxregs (&thandle, xregset);
	  if (val != TD_OK)
	    error ("sol_thread_store_registers: td_thr_getxregs %s",
		   td_err_string (val));
	}
#endif
    }

  fill_gregset (regset, regno);
  fill_fpregset (&fpregset, regno);

  val = p_td_thr_setgregs (&thandle, regset);
  if (val != TD_OK)
    error ("sol_thread_store_registers: td_thr_setgregs %s",
	   td_err_string (val));
  val = p_td_thr_setfpregs (&thandle, &fpregset);
  if (val != TD_OK)
    error ("sol_thread_store_registers: td_thr_setfpregs %s",
	   td_err_string (val));

#if 0
/* thread_db doesn't seem to handle this right */
  val = td_thr_getxregsize (&thandle, &xregsize);
  if (val != TD_OK && val != TD_NOXREGS)
    error ("sol_thread_store_registers: td_thr_getxregsize %s",
	   td_err_string (val));

  /* Should probably do something about writing the xregs here, but what are
     they? */
#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 ()
{
  procfs_ops.to_prepare_to_store ();
}

static int
sol_thread_xfer_memory (memaddr, myaddr, len, dowrite, target)
     CORE_ADDR memaddr;
     char *myaddr;
     int len;
     int dowrite;
     struct target_ops *target;	/* ignored */
{
  int retval;
  struct cleanup *old_chain;

  old_chain = save_inferior_pid ();

  if (is_thread (inferior_pid) ||	/* A thread */
      !target_thread_alive (inferior_pid))	/* An lwp, but not alive */
    inferior_pid = procfs_first_available ();	/* Find any live lwp.  */
  /* Note: don't need to call switch_to_thread; we're just reading memory.  */

  if (target_has_execution)
    retval = procfs_ops.to_xfer_memory (memaddr, myaddr, len, dowrite, target);
  else
    retval = orig_core_ops.to_xfer_memory (memaddr, myaddr, len,
					   dowrite, target);

  do_cleanups (old_chain);

  return retval;
}

/* Print status information about what we're accessing.  */

static void
sol_thread_files_info (ignore)
     struct target_ops *ignore;
{
  procfs_ops.to_files_info (ignore);
}

static void
sol_thread_kill_inferior ()
{
  procfs_ops.to_kill ();
}

static void
sol_thread_notice_signals (pid)
     int pid;
{
  procfs_ops.to_notice_signals (PIDGET (pid));
}

/* Fork an inferior process, and start debugging it with /proc.  */

static void
sol_thread_create_inferior (exec_file, allargs, env)
     char *exec_file;
     char *allargs;
     char **env;
{
  procfs_ops.to_create_inferior (exec_file, allargs, env);

  if (sol_thread_active && inferior_pid != 0)
    {
      main_ph.pid = inferior_pid;	/* Save for xfer_memory */

      push_target (&sol_thread_ops);

      inferior_pid = lwp_to_thread (inferior_pid);
      if (inferior_pid == -1)
	inferior_pid = main_ph.pid;

      add_thread (inferior_pid);
    }
}

/* This routine is called whenever a new symbol table is read in, or when all
   symbol tables are removed.  libthread_db can only be initialized when it
   finds the right variables in libthread.so.  Since it's a shared library,
   those variables don't show up until the library gets mapped and the symbol
   table is read in.  */

/* This new_objfile event is now managed by a chained function pointer. 
 * It is the callee's responsability to call the next client on the chain.
 */

/* Saved pointer to previous owner of the new_objfile event. */
static void (*target_new_objfile_chain) PARAMS ((struct objfile *));

void
sol_thread_new_objfile (objfile)
     struct objfile *objfile;
{
  td_err_e val;

  if (!objfile)
    {
      sol_thread_active = 0;
      goto quit;
    }

  /* don't do anything if init failed to resolve the libthread_db library */
  if (!procfs_suppress_run)
    goto quit;

  /* Now, initialize the thread debugging library.  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));
      goto quit;
    }

  val = p_td_ta_new (&main_ph, &main_ta);
  if (val == TD_NOLIBTHREAD)
    goto quit;
  else if (val != TD_OK)
    {
      warning ("sol_thread_new_objfile: td_ta_new: %s", td_err_string (val));
      goto quit;
    }

  sol_thread_active = 1;
quit:
  /* Call predecessor on chain, if any. */
  if (target_new_objfile_chain)
    target_new_objfile_chain (objfile);
}

/* Clean up after the inferior dies.  */

static void
sol_thread_mourn_inferior ()
{
  unpush_target (&sol_thread_ops);
  procfs_ops.to_mourn_inferior ();
}

/* Mark our target-struct as eligible for stray "run" and "attach" commands.  */

static int
sol_thread_can_run ()
{
  return procfs_suppress_run;
}

/* 

   LOCAL FUNCTION

   sol_thread_alive     - test thread for "aliveness"

   SYNOPSIS

   static bool sol_thread_alive (int pid);

   DESCRIPTION

   returns true if thread still active in inferior.

 */

static int
sol_thread_alive (pid)
     int pid;
{
  if (is_thread (pid))		/* non-kernel thread */
    {
      td_err_e val;
      td_thrhandle_t th;

      pid = GET_THREAD (pid);
      if ((val = p_td_ta_map_id2thr (main_ta, pid, &th)) != TD_OK)
	return 0;		/* thread not found */
      if ((val = p_td_thr_validate (&th)) != TD_OK)
	return 0;		/* thread not valid */
      return 1;			/* known thread: return true */
    }
  else
    /* kernel thread (LWP): let procfs test it */
    {
      if (target_has_execution)
	return procfs_ops.to_thread_alive (pid);
      else
	return orig_core_ops.to_thread_alive (pid);
    }
}

static void
sol_thread_stop ()
{
  procfs_ops.to_stop ();
}

/* These routines implement the lower half of the thread_db interface.  Ie: the
   ps_* routines.  */

/* Various versions of <proc_service.h> have slightly
   different function prototypes.  In particular, we have

   NEWER                        OLDER
   struct ps_prochandle *       const struct ps_prochandle *
   void*                        char*
   const void*          char*
   int                  size_t

   Which one you have depends on solaris version and what
   patches you've applied.  On the theory that there are
   only two major variants, we have configure check the
   prototype of ps_pdwrite (), and use that info to make
   appropriate typedefs here. */

#ifdef PROC_SERVICE_IS_OLD
typedef const struct ps_prochandle *gdb_ps_prochandle_t;
typedef char *gdb_ps_read_buf_t;
typedef char *gdb_ps_write_buf_t;
typedef int gdb_ps_size_t;
#else
typedef struct ps_prochandle *gdb_ps_prochandle_t;
typedef void *gdb_ps_read_buf_t;
typedef const void *gdb_ps_write_buf_t;
typedef size_t gdb_ps_size_t;
#endif


/* The next four routines are called by thread_db to tell us to stop and stop
   a particular process or lwp.  Since GDB ensures that these are all stopped
   by the time we call anything in thread_db, these routines need to do
   nothing.  */

/* Process stop */

ps_err_e
ps_pstop (gdb_ps_prochandle_t ph)
{
  return PS_OK;
}

/* Process continue */

ps_err_e
ps_pcontinue (gdb_ps_prochandle_t ph)
{
  return PS_OK;
}

/* LWP stop */

ps_err_e
ps_lstop (gdb_ps_prochandle_t ph, lwpid_t lwpid)
{
  return PS_OK;
}

/* LWP continue */

ps_err_e
ps_lcontinue (gdb_ps_prochandle_t ph, lwpid_t lwpid)
{
  return PS_OK;
}

/* Looks up the symbol LD_SYMBOL_NAME in the debugger's symbol table.  */

ps_err_e
ps_pglobal_lookup (gdb_ps_prochandle_t ph, const char *ld_object_name,
		   const char *ld_symbol_name, paddr_t * ld_symbol_addr)
{
  struct minimal_symbol *ms;

  ms = lookup_minimal_symbol (ld_symbol_name, NULL, NULL);

  if (!ms)
    return PS_NOSYM;

  *ld_symbol_addr = SYMBOL_VALUE_ADDRESS (ms);

  return PS_OK;
}

/* Common routine for reading and writing memory.  */

static ps_err_e
rw_common (int dowrite, const struct ps_prochandle *ph, paddr_t addr,
	   char *buf, int size)
{
  struct cleanup *old_chain;

  old_chain = save_inferior_pid ();

  if (is_thread (inferior_pid) ||	/* A thread */
      !target_thread_alive (inferior_pid))	/* An lwp, but not alive */
    inferior_pid = procfs_first_available ();	/* Find any live lwp.  */
  /* Note: don't need to call switch_to_thread; we're just reading memory.  */

  while (size > 0)
    {
      int cc;

      if (target_has_execution)
	cc = procfs_ops.to_xfer_memory (addr, buf, size, dowrite, &procfs_ops);
      else
	cc = orig_core_ops.to_xfer_memory (addr, buf, size, dowrite, &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;
	}
      size -= cc;
      buf += cc;
    }

  do_cleanups (old_chain);

  return PS_OK;
}

/* Copies SIZE bytes from target process .data segment to debugger memory.  */

ps_err_e
ps_pdread (gdb_ps_prochandle_t ph, paddr_t addr,
	   gdb_ps_read_buf_t buf, gdb_ps_size_t size)
{
  return rw_common (0, ph, addr, buf, size);
}

/* Copies SIZE bytes from debugger memory .data segment to target process.  */

ps_err_e
ps_pdwrite (gdb_ps_prochandle_t ph, paddr_t addr,
	    gdb_ps_write_buf_t buf, gdb_ps_size_t size)
{
  return rw_common (1, ph, addr, (char *) buf, size);
}

/* Copies SIZE bytes from target process .text segment to debugger memory.  */

ps_err_e
ps_ptread (gdb_ps_prochandle_t ph, paddr_t addr,
	   gdb_ps_read_buf_t buf, gdb_ps_size_t size)
{
  return rw_common (0, ph, addr, buf, size);
}

/* Copies SIZE bytes from debugger memory .text segment to target process.  */

ps_err_e
ps_ptwrite (gdb_ps_prochandle_t ph, paddr_t addr,
	    gdb_ps_write_buf_t buf, gdb_ps_size_t size)
{
  return rw_common (1, ph, addr, (char *) buf, size);
}

/* Get integer regs for LWP */

ps_err_e
ps_lgetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
	     prgregset_t gregset)
{
  struct cleanup *old_chain;

  old_chain = save_inferior_pid ();

  inferior_pid = BUILD_LWP (lwpid, PIDGET (inferior_pid));

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

  do_cleanups (old_chain);

  return PS_OK;
}

/* Set integer regs for LWP */

ps_err_e
ps_lsetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
	     const prgregset_t gregset)
{
  struct cleanup *old_chain;

  old_chain = save_inferior_pid ();

  inferior_pid = BUILD_LWP (lwpid, PIDGET (inferior_pid));

  supply_gregset (gregset);
  if (target_has_execution)
    procfs_ops.to_store_registers (-1);
  else
    orig_core_ops.to_store_registers (-1);

  do_cleanups (old_chain);

  return PS_OK;
}

/* Log a message (sends to gdb_stderr).  */

void
ps_plog (const char *fmt,...)
{
  va_list args;

  va_start (args, fmt);

  vfprintf_filtered (gdb_stderr, fmt, args);
}

/* Get size of extra register set.  Currently a noop.  */

ps_err_e
ps_lgetxregsize (gdb_ps_prochandle_t ph, lwpid_t lwpid, int *xregsize)
{
#if 0
  int lwp_fd;
  int regsize;
  ps_err_e val;

  val = get_lwp_fd (ph, lwpid, &lwp_fd);
  if (val != PS_OK)
    return val;

  if (ioctl (lwp_fd, PIOCGXREGSIZE, &regsize))
    {
      if (errno == EINVAL)
	return PS_NOFREGS;	/* XXX Wrong code, but this is the closest
				   thing in proc_service.h  */

      print_sys_errmsg ("ps_lgetxregsize (): PIOCGXREGSIZE", errno);
      return PS_ERR;
    }
#endif

  return PS_OK;
}

/* Get extra register set.  Currently a noop.  */

ps_err_e
ps_lgetxregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, caddr_t xregset)
{
#if 0
  int lwp_fd;
  ps_err_e val;

  val = get_lwp_fd (ph, lwpid, &lwp_fd);
  if (val != PS_OK)
    return val;

  if (ioctl (lwp_fd, PIOCGXREG, xregset))
    {
      print_sys_errmsg ("ps_lgetxregs (): PIOCGXREG", errno);
      return PS_ERR;
    }
#endif

  return PS_OK;
}

/* Set extra register set.  Currently a noop.  */

ps_err_e
ps_lsetxregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, caddr_t xregset)
{
#if 0
  int lwp_fd;
  ps_err_e val;

  val = get_lwp_fd (ph, lwpid, &lwp_fd);
  if (val != PS_OK)
    return val;

  if (ioctl (lwp_fd, PIOCSXREG, xregset))
    {
      print_sys_errmsg ("ps_lsetxregs (): PIOCSXREG", errno);
      return PS_ERR;
    }
#endif

  return PS_OK;
}

/* Get floating-point regs for LWP */

ps_err_e
ps_lgetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
	       prfpregset_t * fpregset)
{
  struct cleanup *old_chain;

  old_chain = save_inferior_pid ();

  inferior_pid = BUILD_LWP (lwpid, PIDGET (inferior_pid));

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

  do_cleanups (old_chain);

  return PS_OK;
}

/* Set floating-point regs for LWP */

ps_err_e
ps_lsetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
	       const prfpregset_t * fpregset)
{
  struct cleanup *old_chain;

  old_chain = save_inferior_pid ();

  inferior_pid = BUILD_LWP (lwpid, PIDGET (inferior_pid));

  supply_fpregset (fpregset);
  if (target_has_execution)
    procfs_ops.to_store_registers (-1);
  else
    orig_core_ops.to_store_registers (-1);

  do_cleanups (old_chain);

  return PS_OK;
}

#ifdef TM_I386SOL2_H

/* Get local descriptor table.  */

#include <sys/procfs.h>
#include <sys/reg.h>
#include <sys/sysi86.h>

static int nldt_allocated = 0;
static struct ssd *ldt_bufp = NULL;

/* Reads the local descriptor table of a LWP.  */

ps_err_e
ps_lgetLDT (gdb_ps_prochandle_t ph, lwpid_t lwpid,
	    struct ssd *pldt)
{
  gregset_t gregset;
  int lwp_fd;
  ps_err_e val;
  int nldt;
  int i;

  /* Get procfs file descriptor for the LWP.  */
  lwp_fd = procfs_get_pid_fd (BUILD_LWP (lwpid, PIDGET (inferior_pid)));
  if (lwp_fd < 0)
    return PS_BADLID;

  /* Fetch registers und LDT descriptors.  */
  if (ioctl (lwp_fd, PIOCGREG, &gregset) == -1)
    return PS_ERR;

  if (ioctl (lwp_fd, PIOCNLDT, &nldt) == -1)
    return PS_ERR;

  if (nldt_allocated < nldt)
    {
      ldt_bufp
	= (struct ssd *) xrealloc (ldt_bufp, (nldt + 1) * sizeof (struct ssd));
      nldt_allocated = nldt;
    }

  if (ioctl (lwp_fd, PIOCLDT, ldt_bufp) == -1)
    return PS_ERR;

  /* Search LDT for the LWP via register GS.  */
  for (i = 0; i < nldt; i++)
    {
      if (ldt_bufp[i].sel == (gregset[GS] & 0xffff))
	{
	  *pldt = ldt_bufp[i];
	  return PS_OK;
	}
    }

  /* LDT not found.  */
  return PS_ERR;
}
#endif /* TM_I386SOL2_H */

/* Convert a pid to printable form. */

char *
solaris_pid_to_str (pid)
     int pid;
{
  static char buf[100];

  /* in case init failed to resolve the libthread_db library */
  if (!procfs_suppress_run)
    return procfs_pid_to_str (pid);

  if (is_thread (pid))
    {
      int lwp;

      lwp = thread_to_lwp (pid, -2);

      if (lwp == -1)
	sprintf (buf, "Thread %d (defunct)", GET_THREAD (pid));
      else if (lwp != -2)
	sprintf (buf, "Thread %d (LWP %d)", GET_THREAD (pid), GET_LWP (lwp));
      else
	sprintf (buf, "Thread %d        ", GET_THREAD (pid));
    }
  else if (GET_LWP (pid) != 0)
    sprintf (buf, "LWP    %d        ", GET_LWP (pid));
  else
    sprintf (buf, "process %d    ", PIDGET (pid));

  return buf;
}


/* Worker bee for find_new_threads
   Callback function that gets called once per USER thread (i.e., not
   kernel) thread. */

static int
sol_find_new_threads_callback (th, ignored)
     const td_thrhandle_t *th;
     void *ignored;
{
  td_err_e retval;
  td_thrinfo_t ti;
  int pid;

  if ((retval = p_td_thr_get_info (th, &ti)) != TD_OK)
    {
      return -1;
    }
  pid = BUILD_THREAD (ti.ti_tid, PIDGET (inferior_pid));
  if (!in_thread_list (pid))
    add_thread (pid);

  return 0;
}

static void
sol_find_new_threads ()
{
  /* don't do anything if init failed to resolve the libthread_db library */
  if (!procfs_suppress_run)
    return;

  if (inferior_pid == -1)
    {
      printf_filtered ("No process.\n");
      return;
    }
  procfs_find_new_threads ();	/* first find new kernel threads. */
  p_td_ta_thr_iter (main_ta, sol_find_new_threads_callback, (void *) 0,
		    TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
		    TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
}

static void
sol_core_open (filename, from_tty)
     char *filename;
     int from_tty;
{
  orig_core_ops.to_open (filename, from_tty);
}

static void
sol_core_close (quitting)
     int quitting;
{
  orig_core_ops.to_close (quitting);
}

static void
sol_core_detach (args, from_tty)
     char *args;
     int from_tty;
{
  unpush_target (&core_ops);
  orig_core_ops.to_detach (args, from_tty);
}

static void
sol_core_files_info (t)
     struct target_ops *t;
{
  orig_core_ops.to_files_info (t);
}

/* Worker bee for info sol-thread command.  This is a callback function that
   gets called once for each Solaris thread (ie. not kernel thread) in the 
   inferior.  Print anything interesting that we can think of.  */

static int
info_cb (th, s)
     const td_thrhandle_t *th;
     void *s;
{
  td_err_e ret;
  td_thrinfo_t ti;

  if ((ret = p_td_thr_get_info (th, &ti)) == TD_OK)
    {
      printf_filtered ("%s thread #%d, lwp %d, ",
		       ti.ti_type == TD_THR_SYSTEM ? "system" : "user  ",
		       ti.ti_tid, ti.ti_lid);
      switch (ti.ti_state)
	{
	default:
	case TD_THR_UNKNOWN:
	  printf_filtered ("<unknown state>");
	  break;
	case TD_THR_STOPPED:
	  printf_filtered ("(stopped)");
	  break;
	case TD_THR_RUN:
	  printf_filtered ("(run)    ");
	  break;
	case TD_THR_ACTIVE:
	  printf_filtered ("(active) ");
	  break;
	case TD_THR_ZOMBIE:
	  printf_filtered ("(zombie) ");
	  break;
	case TD_THR_SLEEP:
	  printf_filtered ("(asleep) ");
	  break;
	case TD_THR_STOPPED_ASLEEP:
	  printf_filtered ("(stopped asleep)");
	  break;
	}
      /* Print thr_create start function: */
      if (ti.ti_startfunc != 0)
	{
	  struct minimal_symbol *msym;
	  msym = lookup_minimal_symbol_by_pc (ti.ti_startfunc);
	  if (msym)
	    printf_filtered ("   startfunc: %s\n", SYMBOL_NAME (msym));
	  else
	    printf_filtered ("   startfunc: 0x%s\n", paddr (ti.ti_startfunc));
	}

      /* If thread is asleep, print function that went to sleep: */
      if (ti.ti_state == TD_THR_SLEEP)
	{
	  struct minimal_symbol *msym;
	  msym = lookup_minimal_symbol_by_pc (ti.ti_pc);
	  if (msym)
	    printf_filtered (" - Sleep func: %s\n", SYMBOL_NAME (msym));
	  else
	    printf_filtered (" - Sleep func: 0x%s\n", paddr (ti.ti_startfunc));
	}

      /* Wrap up line, if necessary */
      if (ti.ti_state != TD_THR_SLEEP && ti.ti_startfunc == 0)
	printf_filtered ("\n");	/* don't you hate counting newlines? */
    }
  else
    warning ("info sol-thread: failed to get info for thread.");

  return 0;
}

/* List some state about each Solaris user thread in the inferior.  */

static void
info_solthreads (args, from_tty)
     char *args;
     int from_tty;
{
  p_td_ta_thr_iter (main_ta, info_cb, args,
		    TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
		    TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
}

static int
ignore (addr, contents)
     CORE_ADDR addr;
     char *contents;
{
  return 0;
}


static void
init_sol_thread_ops ()
{
  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_close = 0;
  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.to_xfer_memory = sol_thread_xfer_memory;
  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_info = child_terminal_info;
  sol_thread_ops.to_kill = sol_thread_kill_inferior;
  sol_thread_ops.to_load = 0;
  sol_thread_ops.to_lookup_symbol = 0;
  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_sections = 0;
  sol_thread_ops.to_sections_end = 0;
  sol_thread_ops.to_magic = OPS_MAGIC;
}


static void
init_sol_core_ops ()
{
  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_resume  = 0; */
  /* sol_core_ops.to_wait  = 0;  */
  sol_core_ops.to_fetch_registers = sol_thread_fetch_registers;
  /* sol_core_ops.to_store_registers  = 0; */
  /* sol_core_ops.to_prepare_to_store  = 0; */
  sol_core_ops.to_xfer_memory = sol_thread_xfer_memory;
  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_terminal_init  = 0; */
  /* sol_core_ops.to_terminal_inferior  = 0; */
  /* sol_core_ops.to_terminal_ours_for_output  = 0; */
  /* sol_core_ops.to_terminal_ours  = 0; */
  /* sol_core_ops.to_terminal_info  = 0; */
  /* sol_core_ops.to_kill  = 0; */
  /* sol_core_ops.to_load  = 0; */
  /* sol_core_ops.to_lookup_symbol  = 0; */
  sol_core_ops.to_create_inferior = sol_thread_create_inferior;
  sol_core_ops.to_stratum = core_stratum;
  sol_core_ops.to_has_all_memory = 0;
  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_execution = 0;
  sol_core_ops.to_has_thread_control = tc_none;
  sol_core_ops.to_pid_to_str = solaris_pid_to_str;
  sol_core_ops.to_sections = 0;
  sol_core_ops.to_sections_end = 0;
  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 *dlhandle;

  init_sol_thread_ops ();
  init_sol_core_ops ();

  dlhandle = dlopen ("libthread_db.so.1", RTLD_NOW);
  if (!dlhandle)
    goto die;

#define resolve(X) \
  if (!(p_##X = dlsym (dlhandle, #X))) \
    goto die;

  resolve (td_log);
  resolve (td_ta_new);
  resolve (td_ta_delete);
  resolve (td_init);
  resolve (td_ta_get_ph);
  resolve (td_ta_get_nthreads);
  resolve (td_ta_tsd_iter);
  resolve (td_ta_thr_iter);
  resolve (td_thr_validate);
  resolve (td_thr_tsd);
  resolve (td_thr_get_info);
  resolve (td_thr_getfpregs);
  resolve (td_thr_getxregsize);
  resolve (td_thr_getxregs);
  resolve (td_thr_sigsetmask);
  resolve (td_thr_setprio);
  resolve (td_thr_setsigpending);
  resolve (td_thr_setfpregs);
  resolve (td_thr_setxregs);
  resolve (td_ta_map_id2thr);
  resolve (td_ta_map_lwp2thr);
  resolve (td_thr_getgregs);
  resolve (td_thr_setgregs);

  add_target (&sol_thread_ops);

  procfs_suppress_run = 1;

  add_cmd ("sol-threads", class_maintenance, info_solthreads,
	   "Show info on Solaris user threads.\n", &maintenanceinfolist);

  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. */
  target_new_objfile_chain = target_new_objfile_hook;
  target_new_objfile_hook  = sol_thread_new_objfile;
  return;

die:

  fprintf_unfiltered (gdb_stderr, "[GDB will not be able to debug user-mode threads: %s]\n", dlerror ());

  if (dlhandle)
    dlclose (dlhandle);

  /* allow the user to debug non-threaded core files */
  add_target (&core_ops);

  return;
}
