/* Solaris threads debugging interface.

   Copyright (C) 1996-2024 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 3 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, see <http://www.gnu.org/licenses/>.  */

/* 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 respectively) 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 we provide.  The upper part consists of the td_* routines,
   which allow us 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 <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 "cli/cli-cmds.h"
#include "gdbcore.h"
#include "regcache.h"
#include "solib.h"
#include "symfile.h"
#include "observable.h"
#include "procfs.h"
#include "symtab.h"
#include "minsyms.h"
#include "objfiles.h"

static const target_info thread_db_target_info = {
  "solaris-threads",
  N_("Solaris threads and pthread."),
  N_("Solaris threads and pthread support.")
};

class sol_thread_target final : public target_ops
{
public:
  const target_info &info () const override
  { return thread_db_target_info; }

  strata stratum () const override { return thread_stratum; }

  void detach (inferior *, int) override;
  ptid_t wait (ptid_t, struct target_waitstatus *, target_wait_flags) override;
  void resume (ptid_t, int, enum gdb_signal) override;
  void mourn_inferior () override;
  std::string pid_to_str (ptid_t) override;
  ptid_t get_ada_task_ptid (long lwp, ULONGEST thread) override;

  void fetch_registers (struct regcache *, int) override;
  void store_registers (struct regcache *, int) override;

  enum target_xfer_status xfer_partial (enum target_object object,
					const char *annex,
					gdb_byte *readbuf,
					const gdb_byte *writebuf,
					ULONGEST offset, ULONGEST len,
					ULONGEST *xfered_len) override;

  bool thread_alive (ptid_t ptid) override;
  void update_thread_list () override;
};

static sol_thread_target sol_thread_ops;

/* Prototypes for supply_gregset etc.  */
#include "gregset.h"

/* 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
{
  ptid_t ptid;
};

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

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

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

/* Types of the libthread_db functions.  */

typedef void (td_log_ftype)(const int on_off);
typedef td_err_e (td_ta_new_ftype)(const struct ps_prochandle *ph_p,
				   td_thragent_t **ta_pp);
typedef td_err_e (td_ta_delete_ftype)(td_thragent_t *ta_p);
typedef td_err_e (td_init_ftype)(void);
typedef td_err_e (td_ta_get_ph_ftype)(const td_thragent_t *ta_p,
				      struct ps_prochandle **ph_pp);
typedef td_err_e (td_ta_get_nthreads_ftype)(const td_thragent_t *ta_p,
					    int *nthread_p);
typedef td_err_e (td_ta_tsd_iter_ftype)(const td_thragent_t *ta_p,
					td_key_iter_f *cb, void *cbdata_p);
typedef td_err_e (td_ta_thr_iter_ftype)(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);
typedef td_err_e (td_thr_validate_ftype)(const td_thrhandle_t *th_p);
typedef td_err_e (td_thr_tsd_ftype)(const td_thrhandle_t * th_p,
				    const thread_key_t key, void **data_pp);
typedef td_err_e (td_thr_get_info_ftype)(const td_thrhandle_t *th_p,
					 td_thrinfo_t *ti_p);
typedef td_err_e (td_thr_getfpregs_ftype)(const td_thrhandle_t *th_p,
					  prfpregset_t *fpregset);
typedef td_err_e (td_thr_getxregsize_ftype)(const td_thrhandle_t *th_p,
					    int *xregsize);
typedef td_err_e (td_thr_getxregs_ftype)(const td_thrhandle_t *th_p,
					 const caddr_t xregset);
typedef td_err_e (td_thr_sigsetmask_ftype)(const td_thrhandle_t *th_p,
					   const sigset_t ti_sigmask);
typedef td_err_e (td_thr_setprio_ftype)(const td_thrhandle_t *th_p,
					const int ti_pri);
typedef td_err_e (td_thr_setsigpending_ftype)(const td_thrhandle_t *th_p,
					      const uchar_t ti_pending_flag,
					      const sigset_t ti_pending);
typedef td_err_e (td_thr_setfpregs_ftype)(const td_thrhandle_t *th_p,
					  const prfpregset_t *fpregset);
typedef td_err_e (td_thr_setxregs_ftype)(const td_thrhandle_t *th_p,
					 const caddr_t xregset);
typedef td_err_e (td_ta_map_id2thr_ftype)(const td_thragent_t *ta_p,
					  thread_t tid,
					  td_thrhandle_t *th_p);
typedef td_err_e (td_ta_map_lwp2thr_ftype)(const td_thragent_t *ta_p,
					   lwpid_t lwpid,
					   td_thrhandle_t *th_p);
typedef td_err_e (td_thr_getgregs_ftype)(const td_thrhandle_t *th_p,
					 prgregset_t regset);
typedef td_err_e (td_thr_setgregs_ftype)(const td_thrhandle_t *th_p,
					 const prgregset_t regset);

/* Pointers to routines from libthread_db resolved by dlopen().  */

static td_log_ftype *p_td_log;
static td_ta_new_ftype *p_td_ta_new;
static td_ta_delete_ftype *p_td_ta_delete;
static td_init_ftype *p_td_init;
static td_ta_get_ph_ftype *p_td_ta_get_ph;
static td_ta_get_nthreads_ftype *p_td_ta_get_nthreads;
static td_ta_tsd_iter_ftype *p_td_ta_tsd_iter;
static td_ta_thr_iter_ftype *p_td_ta_thr_iter;
static td_thr_validate_ftype *p_td_thr_validate;
static td_thr_tsd_ftype *p_td_thr_tsd;
static td_thr_get_info_ftype *p_td_thr_get_info;
static td_thr_getfpregs_ftype *p_td_thr_getfpregs;
static td_thr_getxregsize_ftype *p_td_thr_getxregsize;
static td_thr_getxregs_ftype *p_td_thr_getxregs;
static td_thr_sigsetmask_ftype *p_td_thr_sigsetmask;
static td_thr_setprio_ftype *p_td_thr_setprio;
static td_thr_setsigpending_ftype *p_td_thr_setsigpending;
static td_thr_setfpregs_ftype *p_td_thr_setfpregs;
static td_thr_setxregs_ftype *p_td_thr_setxregs;
static td_ta_map_id2thr_ftype *p_td_ta_map_id2thr;
static td_ta_map_lwp2thr_ftype *p_td_ta_map_lwp2thr;
static td_thr_getgregs_ftype *p_td_thr_getgregs;
static td_thr_setgregs_ftype *p_td_thr_setgregs;


/* Return the libthread_db error string associated with ERRCODE.  If
   ERRCODE is unknown, return an appropriate message.  */

static const char *
td_err_string (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 written/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;

  xsnprintf (buf, sizeof (buf), "Unknown libthread_db error code: %d",
	     errcode);

  return buf;
}

/* Return the libthread_db state string associated with STATECODE.
   If STATECODE is unknown, return an appropriate message.  */

static const char *
td_state_string (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;

  xsnprintf (buf, sizeof (buf), "Unknown libthread_db state code: %d",
	     statecode);

  return buf;
}


/* Convert a POSIX or Solaris thread ID into a LWP ID.  If THREAD_ID
   doesn't exist, that's an error.  If it's an inactive thread, return
   DEFAULT_LWP.

   NOTE: This function probably shouldn't call error().  */

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

  if (thread_id.lwp_p ())
    return thread_id;		/* It's already an LWP ID.  */

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

  val = p_td_ta_map_id2thr (main_ta, thread_id.tid (), &th);
  if (val == TD_NOTHR)
    return ptid_t (-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 ptid_t (-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 ptid_t (default_lwp);
      error (_("thread_to_lwp: thread state not active: %s"),
	     td_state_string (ti.ti_state));
    }

  return ptid_t (thread_id.pid (), ti.ti_lid, 0);
}

/* Convert an LWP ID into a POSIX or Solaris thread ID.  If LWP_ID
   doesn't exists, that's an error.

   NOTE: This function probably shouldn't call error().  */

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

  if (lwp.tid_p ())
    return lwp;			/* It's already a thread ID.  */

  /* It's an LWP.  Convert it to a thread ID.  */

  if (!target_thread_alive (lwp))
    return ptid_t (-1);	/* Must be a defunct LPW.  */

  val = p_td_ta_map_lwp2thr (main_ta, lwp.lwp (), &th);
  if (val == TD_NOTHR)
    return ptid_t (-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;			/* Unknown to libthread; just return LPW,  */
  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 ptid_t (-1);	/* Thread must have terminated.  */
  else if (val != TD_OK)
    error (_("lwp_to_thread: td_thr_get_info: %s."), td_err_string (val));

  return ptid_t (lwp.pid (), 0 , ti.ti_tid);
}


/* Most target vector functions from here on actually just pass
   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
   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).  */

void
sol_thread_target::detach (inferior *inf, int from_tty)
{
  target_ops *beneath = this->beneath ();

  sol_thread_active = 0;
  inferior_ptid = ptid_t (main_ph.ptid.pid ());
  inf->unpush_target (this);
  beneath->detach (inf, from_tty);
}

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

void
sol_thread_target::resume (ptid_t ptid, int step, enum gdb_signal signo)
{
  scoped_restore save_inferior_ptid = make_scoped_restore (&inferior_ptid);

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

  if (ptid.pid () != -1)
    {
      ptid_t save_ptid = ptid;

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

  beneath ()->resume (ptid, step, signo);
}

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

ptid_t
sol_thread_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
			 target_wait_flags options)
{
  if (ptid.pid () != -1)
    {
      ptid_t ptid_for_warning = ptid;

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

  ptid_t rtnval = beneath ()->wait (ptid, ourstatus, options);

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

      /* See if we have a new thread.  */
      if (rtnval.tid_p ())
	{
	  thread_info *thr = current_inferior ()->find_thread (rtnval);
	  if (thr == NULL || thr->state == THREAD_EXITED)
	    {
	      process_stratum_target *proc_target
		= current_inferior ()->process_target ();
	      add_thread (proc_target, 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.  */

  return rtnval;
}

void
sol_thread_target::fetch_registers (struct regcache *regcache, int regnum)
{
  thread_t thread;
  td_thrhandle_t thandle;
  td_err_e val;
  prgregset_t gregset;
  prfpregset_t fpregset;
  gdb_gregset_t *gregset_p = &gregset;
  gdb_fpregset_t *fpregset_p = &fpregset;
  ptid_t ptid = regcache->ptid ();

  if (!ptid.tid_p ())
    {
      /* It's an LWP; pass the request on to the layer beneath.  */
      beneath ()->fetch_registers (regcache, regnum);
      return;
    }

  /* Solaris thread: convert PTID into a td_thrhandle_t.  */
  thread = ptid.tid ();
  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 general-purpose registers.  */

  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 SPARC, TD_PARTIALREG means that only %i0...%i7, %l0..%l7, %pc
     and %sp are saved (by a thread context switch).  */

  /* And, now the floating-point registers.  */

  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_gregset and supply_fpregset *after*
     calling the td routines because the td routines call ps_lget*
     which affect the values stored in the registers array.  */

  supply_gregset (regcache, (const gdb_gregset_t *) gregset_p);
  supply_fpregset (regcache, (const gdb_fpregset_t *) fpregset_p);
}

void
sol_thread_target::store_registers (struct regcache *regcache, int regnum)
{
  thread_t thread;
  td_thrhandle_t thandle;
  td_err_e val;
  prgregset_t gregset;
  prfpregset_t fpregset;
  ptid_t ptid = regcache->ptid ();

  if (!ptid.tid_p ())
    {
      /* It's an LWP; pass the request on to the layer beneath.  */
      beneath ()->store_registers (regcache, regnum);
      return;
    }

  /* Solaris thread: convert PTID into a td_thrhandle_t.  */
  thread = ptid.tid ();

  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 (regnum != -1)
    {
      val = p_td_thr_getgregs (&thandle, gregset);
      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));
    }

  fill_gregset (regcache, (gdb_gregset_t *) &gregset, regnum);
  fill_fpregset (regcache, (gdb_fpregset_t *) &fpregset, regnum);

  val = p_td_thr_setgregs (&thandle, gregset);
  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));
}

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

enum target_xfer_status
sol_thread_target::xfer_partial (enum target_object object,
				 const char *annex, gdb_byte *readbuf,
				 const gdb_byte *writebuf,
				 ULONGEST offset, ULONGEST len,
				 ULONGEST *xfered_len)
{
  scoped_restore save_inferior_ptid = make_scoped_restore (&inferior_ptid);

  if (inferior_ptid.tid_p () || !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 ();
    }

  return beneath ()->xfer_partial (object, annex, readbuf,
				   writebuf, offset, len, xfered_len);
}

static void
check_for_thread_db (void)
{
  td_err_e err;
  ptid_t ptid;

  /* Don't attempt to use thread_db for remote targets.  */
  if (!(target_can_run () || current_program_space->core_bfd () != nullptr))
    return;

  /* Do nothing if we couldn't load libthread_db.so.1.  */
  if (p_td_ta_new == NULL)
    return;

  if (sol_thread_active)
    /* Nothing to do.  The thread library was already detected and the
       target vector was already activated.  */
    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.  */

  err = p_td_init ();
  if (err != TD_OK)
    {
      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;

    case TD_OK:
      gdb_printf (_("[Thread debugging using libthread_db enabled]\n"));

      /* The thread library was detected.  Activate the sol_thread target.  */
      current_inferior ()->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 (ptid.pid () != -1)
	inferior_ptid = ptid;

      target_update_thread_list ();
      break;

    default:
      warning (_("Cannot initialize thread debugging library: %s"),
	       td_err_string (err));
      break;
    }
}

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

static void
sol_thread_new_objfile (struct objfile *objfile)
{
  check_for_thread_db ();
}

/* Clean up after the inferior dies.  */

void
sol_thread_target::mourn_inferior ()
{
  target_ops *beneath = this->beneath ();

  sol_thread_active = 0;

  current_inferior ()->unpush_target (this);

  beneath->mourn_inferior ();
}

/* Return true if PTID is still active in the inferior.  */

bool
sol_thread_target::thread_alive (ptid_t ptid)
{
  if (ptid.tid_p ())
    {
      /* It's a (user-level) thread.  */
      td_err_e val;
      td_thrhandle_t th;
      int pid;

      pid = ptid.tid ();
      val = p_td_ta_map_id2thr (main_ta, pid, &th);
      if (val != TD_OK)
	return false;		/* Thread not found.  */
      val = p_td_thr_validate (&th);
      if (val != TD_OK)
	return false;		/* Thread not valid.  */
      return true;		/* Known thread.  */
    }
  else
    {
      /* It's an LPW; pass the request on to the layer below.  */
      return beneath ()->thread_alive (ptid);
    }
}


/* These routines implement the lower half of the thread_db interface,
   i.e. the ps_* routines.  */

/* The next four routines are called by libthread_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 (struct ps_prochandle *ph)
{
  return PS_OK;
}

/* Process continue.  */

ps_err_e
ps_pcontinue (struct ps_prochandle *ph)
{
  return PS_OK;
}

/* LWP stop.  */

ps_err_e
ps_lstop (struct ps_prochandle *ph, lwpid_t lwpid)
{
  return PS_OK;
}

/* LWP continue.  */

ps_err_e
ps_lcontinue (struct ps_prochandle *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 (struct ps_prochandle *ph, const char *ld_object_name,
		   const char *ld_symbol_name, psaddr_t *ld_symbol_addr)
{
  bound_minimal_symbol ms
    = lookup_minimal_symbol (current_program_space, ld_symbol_name);
  if (!ms.minsym)
    return PS_NOSYM;

  *ld_symbol_addr = ms.value_address ();
  return PS_OK;
}

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

static ps_err_e
rw_common (int dowrite, const struct ps_prochandle *ph, psaddr_t addr,
	   gdb_byte *buf, int size)
{
  int ret;

  scoped_restore save_inferior_ptid = make_scoped_restore (&inferior_ptid);

  if (inferior_ptid.tid_p () || !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 defined (__sparcv9)
  /* For Sparc64 cross Sparc32, make sure the address has not been
     accidentally sign-extended (or whatever) to beyond 32 bits.  */
  if (bfd_get_arch_size (current_program_space->exec_bfd ()) == 32)
    addr &= 0xffffffff;
#endif

  if (dowrite)
    ret = target_write_memory (addr, (gdb_byte *) buf, size);
  else
    ret = target_read_memory (addr, (gdb_byte *) buf, size);

  return (ret == 0 ? PS_OK : PS_ERR);
}

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

ps_err_e
ps_pdread (struct ps_prochandle *ph, psaddr_t addr, void *buf, size_t size)
{
  return rw_common (0, ph, addr, (gdb_byte *) buf, size);
}

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

ps_err_e
ps_pdwrite (struct ps_prochandle *ph, psaddr_t addr,
	    const void *buf, size_t size)
{
  return rw_common (1, ph, addr, (gdb_byte *) buf, size);
}

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

ps_err_e
ps_ptread (struct ps_prochandle *ph, psaddr_t addr, void *buf, size_t size)
{
  return rw_common (0, ph, addr, (gdb_byte *) buf, size);
}

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

ps_err_e
ps_ptwrite (struct ps_prochandle *ph, psaddr_t addr,
	    const void *buf, size_t size)
{
  return rw_common (1, ph, addr, (gdb_byte *) buf, size);
}

/* Get general-purpose registers for LWP.  */

ps_err_e
ps_lgetregs (struct ps_prochandle *ph, lwpid_t lwpid, prgregset_t gregset)
{
  ptid_t ptid = ptid_t (current_inferior ()->pid, lwpid, 0);
  regcache *regcache = get_thread_arch_regcache (current_inferior (), ptid,
						 current_inferior ()->arch ());

  target_fetch_registers (regcache, -1);
  fill_gregset (regcache, (gdb_gregset_t *) gregset, -1);

  return PS_OK;
}

/* Set general-purpose registers for LWP.  */

ps_err_e
ps_lsetregs (struct ps_prochandle *ph, lwpid_t lwpid,
	     const prgregset_t gregset)
{
  ptid_t ptid = ptid_t (current_inferior ()->pid, lwpid, 0);
  regcache *regcache = get_thread_arch_regcache (current_inferior (), ptid,
						 current_inferior ()->arch ());

  supply_gregset (regcache, (const gdb_gregset_t *) gregset);
  target_store_registers (regcache, -1);

  return PS_OK;
}

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

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

  va_start (args, fmt);

  gdb_vprintf (gdb_stderr, fmt, args);
}

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

ps_err_e
ps_lgetxregsize (struct ps_prochandle *ph, lwpid_t lwpid, int *xregsize)
{
  return PS_OK;
}

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

ps_err_e
ps_lgetxregs (struct ps_prochandle *ph, lwpid_t lwpid, caddr_t xregset)
{
  return PS_OK;
}

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

ps_err_e
ps_lsetxregs (struct ps_prochandle *ph, lwpid_t lwpid, caddr_t xregset)
{
  return PS_OK;
}

/* Get floating-point registers for LWP.  */

ps_err_e
ps_lgetfpregs (struct ps_prochandle *ph, lwpid_t lwpid,
	       prfpregset_t *fpregset)
{
  ptid_t ptid = ptid_t (current_inferior ()->pid, lwpid, 0);
  regcache *regcache = get_thread_arch_regcache (current_inferior (), ptid,
						 current_inferior ()->arch ());

  target_fetch_registers (regcache, -1);
  fill_fpregset (regcache, (gdb_fpregset_t *) fpregset, -1);

  return PS_OK;
}

/* Set floating-point regs for LWP.  */

ps_err_e
ps_lsetfpregs (struct ps_prochandle *ph, lwpid_t lwpid,
	       const prfpregset_t * fpregset)
{
  ptid_t ptid = ptid_t (current_inferior ()->pid, lwpid, 0);
  regcache *regcache = get_thread_arch_regcache (current_inferior (), ptid,
						 current_inferior ()->arch ());

  supply_fpregset (regcache, (const gdb_fpregset_t *) fpregset);
  target_store_registers (regcache, -1);

  return PS_OK;
}

/* Identify process as 32-bit or 64-bit.  At the moment we're using
   BFD to do this.  There might be a more Solaris-specific
   (e.g. procfs) method, but this ought to work.  */

ps_err_e
ps_pdmodel (struct ps_prochandle *ph, int *data_model)
{
  if (current_program_space->exec_bfd () == 0)
    *data_model = PR_MODEL_UNKNOWN;
  else if (bfd_get_arch_size (current_program_space->exec_bfd ()) == 32)
    *data_model = PR_MODEL_ILP32;
  else
    *data_model = PR_MODEL_LP64;

  return PS_OK;
}


/* Convert PTID to printable form.  */

std::string
sol_thread_target::pid_to_str (ptid_t ptid)
{
  if (ptid.tid_p ())
    {
      ptid_t lwp;

      lwp = thread_to_lwp (ptid, -2);

      if (lwp.pid () == -1)
	return string_printf ("Thread %s (defunct)",
			      pulongest (ptid.tid ()));
      else if (lwp.pid () != -2)
	return string_printf ("Thread %s (LWP %ld)",
			      pulongest (ptid.tid ()), lwp.lwp ());
      else
	return string_printf ("Thread %s          ",
			      pulongest (ptid.tid ()));
    }
  else if (ptid.lwp () != 0)
    return string_printf ("LWP    %ld        ", ptid.lwp ());
  else
    return string_printf ("process %d    ", ptid.pid ());
}


/* Worker bee for update_thread_list.  Callback function that gets
   called once per user-level thread (i.e. not for LWP's).  */

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

  retval = p_td_thr_get_info (th, &ti);
  if (retval != TD_OK)
    return -1;

  ptid_t ptid = ptid_t (current_inferior ()->pid, 0, ti.ti_tid);
  thread_info *thr = current_inferior ()->find_thread (ptid);
  if (thr == NULL || thr->state == THREAD_EXITED)
    {
      process_stratum_target *proc_target
	= current_inferior ()->process_target ();
      add_thread (proc_target, ptid);
    }

  return 0;
}

void
sol_thread_target::update_thread_list ()
{
  /* Delete dead threads.  */
  prune_threads ();

  /* Find any new LWP's.  */
  beneath ()->update_thread_list ();

  /* Then find any new user-level threads.  */
  p_td_ta_thr_iter (main_ta, sol_update_thread_list_callback, (void *) 0,
		    TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
		    TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
}

/* 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
   that we can think of.  */

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

  ret = p_td_thr_get_info (th, &ti);
  if (ret == TD_OK)
    {
      gdb_printf ("%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:
	  gdb_printf ("<unknown state>");
	  break;
	case TD_THR_STOPPED:
	  gdb_printf ("(stopped)");
	  break;
	case TD_THR_RUN:
	  gdb_printf ("(run)    ");
	  break;
	case TD_THR_ACTIVE:
	  gdb_printf ("(active) ");
	  break;
	case TD_THR_ZOMBIE:
	  gdb_printf ("(zombie) ");
	  break;
	case TD_THR_SLEEP:
	  gdb_printf ("(asleep) ");
	  break;
	case TD_THR_STOPPED_ASLEEP:
	  gdb_printf ("(stopped asleep)");
	  break;
	}
      /* Print thr_create start function.  */
      if (ti.ti_startfunc != 0)
	{
	  const bound_minimal_symbol msym
	    = lookup_minimal_symbol_by_pc (ti.ti_startfunc);

	  gdb_printf ("   startfunc=%s",
		      msym.minsym
		      ? msym.minsym->print_name ()
		      : paddress (current_inferior ()->arch (),
				  ti.ti_startfunc));
	}

      /* If thread is asleep, print function that went to sleep.  */
      if (ti.ti_state == TD_THR_SLEEP)
	{
	  const bound_minimal_symbol msym
	    = lookup_minimal_symbol_by_pc (ti.ti_pc);

	  gdb_printf ("   sleepfunc=%s",
		      msym.minsym
		      ? msym.minsym->print_name ()
		      : paddress (current_inferior ()->arch (), ti.ti_pc));
	}

      gdb_printf ("\n");
    }
  else
    warning (_("info sol-thread: failed to get info for thread."));

  return 0;
}

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

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

/* Callback routine used to find a thread based on the TID part of
   its PTID.  */

static int
thread_db_find_thread_from_tid (struct thread_info *thread, void *data)
{
  ULONGEST *tid = (ULONGEST *) data;

  if (thread->ptid.tid () == *tid)
    return 1;

  return 0;
}

ptid_t
sol_thread_target::get_ada_task_ptid (long lwp, ULONGEST thread)
{
  struct thread_info *thread_info =
    iterate_over_threads (thread_db_find_thread_from_tid, &thread);

  if (thread_info == NULL)
    {
      /* The list of threads is probably not up to date.  Find any
	 thread that is missing from the list, and try again.  */
      update_thread_list ();
      thread_info = iterate_over_threads (thread_db_find_thread_from_tid,
					  &thread);
    }

  gdb_assert (thread_info != NULL);

  return (thread_info->ptid);
}

void _initialize_sol_thread ();
void
_initialize_sol_thread ()
{
  void *dlhandle;

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

#define resolve(X) \
  if (!(p_##X = (X ## _ftype *) 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_cmd ("sol-threads", class_maintenance, info_solthreads,
	   _("Show info on Solaris user threads."), &maintenanceinfolist);

  /* Hook into new_objfile notification.  */
  gdb::observers::new_objfile.attach (sol_thread_new_objfile, "sol-thread");
  return;

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

  if (dlhandle)
    dlclose (dlhandle);

  return;
}
