1/* Solaris threads debugging interface.
2
3   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
4   2007 Free Software Foundation, Inc.
5
6   This file is part of GDB.
7
8   This program is free software; you can redistribute it and/or modify
9   it under the terms of the GNU General Public License as published by
10   the Free Software Foundation; either version 3 of the License, or
11   (at your option) any later version.
12
13   This program is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   GNU General Public License for more details.
17
18   You should have received a copy of the GNU General Public License
19   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
20
21/* This module implements a sort of half target that sits between the
22   machine-independent parts of GDB and the /proc interface (procfs.c)
23   to provide access to the Solaris user-mode thread implementation.
24
25   Solaris threads are true user-mode threads, which are invoked via
26   the thr_* and pthread_* (native and POSIX respectivly) interfaces.
27   These are mostly implemented in user-space, with all thread context
28   kept in various structures that live in the user's heap.  These
29   should not be confused with lightweight processes (LWPs), which are
30   implemented by the kernel, and scheduled without explicit
31   intervention by the process.
32
33   Just to confuse things a little, Solaris threads (both native and
34   POSIX) are actually implemented using LWPs.  In general, there are
35   going to be more threads than LWPs.  There is no fixed
36   correspondence between a thread and an LWP.  When a thread wants to
37   run, it gets scheduled onto the first available LWP and can
38   therefore migrate from one LWP to another as time goes on.  A
39   sleeping thread may not be associated with an LWP at all!
40
41   To make it possible to mess with threads, Sun provides a library
42   called libthread_db.so.1 (not to be confused with
43   libthread_db.so.0, which doesn't have a published interface).  This
44   interface has an upper part, which it provides, and a lower part
45   which we provide.  The upper part consists of the td_* routines,
46   which allow us to find all the threads, query their state, etc...
47   The lower part consists of all of the ps_*, which are used by the
48   td_* routines to read/write memory, manipulate LWPs, lookup
49   symbols, etc...  The ps_* routines actually do most of their work
50   by calling functions in procfs.c.  */
51
52#include "defs.h"
53#include <thread.h>
54#include <proc_service.h>
55#include <thread_db.h>
56#include "gdbthread.h"
57#include "target.h"
58#include "inferior.h"
59#include <fcntl.h>
60#include "gdb_stat.h"
61#include <dlfcn.h>
62#include "gdbcmd.h"
63#include "gdbcore.h"
64#include "regcache.h"
65#include "solib.h"
66#include "symfile.h"
67#include "observer.h"
68
69#include "gdb_string.h"
70
71extern struct target_ops sol_thread_ops;	/* Forward declaration */
72extern struct target_ops sol_core_ops;	/* Forward declaration */
73
74/* place to store core_ops before we overwrite it */
75static struct target_ops orig_core_ops;
76
77struct target_ops sol_thread_ops;
78struct target_ops sol_core_ops;
79
80extern int procfs_suppress_run;
81extern struct target_ops procfs_ops;	/* target vector for procfs.c */
82extern struct target_ops core_ops;	/* target vector for corelow.c */
83extern char *procfs_pid_to_str (ptid_t ptid);
84
85/* Prototypes for supply_gregset etc. */
86#include "gregset.h"
87
88/* This struct is defined by us, but mainly used for the proc_service
89   interface.  We don't have much use for it, except as a handy place
90   to get a real PID for memory accesses.  */
91
92struct ps_prochandle
93{
94  ptid_t ptid;
95};
96
97struct string_map
98{
99  int num;
100  char *str;
101};
102
103static struct ps_prochandle main_ph;
104static td_thragent_t *main_ta;
105static int sol_thread_active = 0;
106
107static void sol_thread_resume (ptid_t ptid, int step, enum target_signal signo);
108static int sol_thread_alive (ptid_t ptid);
109static void sol_core_close (int quitting);
110
111static void init_sol_thread_ops (void);
112static void init_sol_core_ops (void);
113
114/* Default definitions: These must be defined in tm.h if they are to
115   be shared with a process module such as procfs.  */
116
117#define GET_PID(ptid)		ptid_get_pid (ptid)
118#define GET_LWP(ptid)		ptid_get_lwp (ptid)
119#define GET_THREAD(ptid)	ptid_get_tid (ptid)
120
121#define is_lwp(ptid)		(GET_LWP (ptid) != 0)
122#define is_thread(ptid)		(GET_THREAD (ptid) != 0)
123
124#define BUILD_LWP(lwp, pid)	ptid_build (pid, lwp, 0)
125#define BUILD_THREAD(tid, pid)	ptid_build (pid, 0, tid)
126
127/* Pointers to routines from libthread_db resolved by dlopen().  */
128
129static void (*p_td_log)(const int on_off);
130static td_err_e (*p_td_ta_new)(const struct ps_prochandle *ph_p,
131			       td_thragent_t **ta_pp);
132static td_err_e (*p_td_ta_delete)(td_thragent_t *ta_p);
133static td_err_e (*p_td_init)(void);
134static td_err_e (*p_td_ta_get_ph)(const td_thragent_t *ta_p,
135				  struct ps_prochandle **ph_pp);
136static td_err_e (*p_td_ta_get_nthreads)(const td_thragent_t *ta_p,
137					int *nthread_p);
138static td_err_e (*p_td_ta_tsd_iter)(const td_thragent_t *ta_p,
139				    td_key_iter_f *cb, void *cbdata_p);
140static td_err_e (*p_td_ta_thr_iter)(const td_thragent_t *ta_p,
141				    td_thr_iter_f *cb, void *cbdata_p,
142				    td_thr_state_e state, int ti_pri,
143				    sigset_t *ti_sigmask_p,
144				    unsigned ti_user_flags);
145static td_err_e (*p_td_thr_validate)(const td_thrhandle_t *th_p);
146static td_err_e (*p_td_thr_tsd)(const td_thrhandle_t * th_p,
147				const thread_key_t key, void **data_pp);
148static td_err_e (*p_td_thr_get_info)(const td_thrhandle_t *th_p,
149				     td_thrinfo_t *ti_p);
150static td_err_e (*p_td_thr_getfpregs)(const td_thrhandle_t *th_p,
151				      prfpregset_t *fpregset);
152static td_err_e (*p_td_thr_getxregsize)(const td_thrhandle_t *th_p,
153					int *xregsize);
154static td_err_e (*p_td_thr_getxregs)(const td_thrhandle_t *th_p,
155				     const caddr_t xregset);
156static td_err_e (*p_td_thr_sigsetmask)(const td_thrhandle_t *th_p,
157				       const sigset_t ti_sigmask);
158static td_err_e (*p_td_thr_setprio)(const td_thrhandle_t *th_p,
159				    const int ti_pri);
160static td_err_e (*p_td_thr_setsigpending)(const td_thrhandle_t *th_p,
161					  const uchar_t ti_pending_flag,
162					  const sigset_t ti_pending);
163static td_err_e (*p_td_thr_setfpregs)(const td_thrhandle_t *th_p,
164				      const prfpregset_t *fpregset);
165static td_err_e (*p_td_thr_setxregs)(const td_thrhandle_t *th_p,
166				     const caddr_t xregset);
167static td_err_e (*p_td_ta_map_id2thr)(const td_thragent_t *ta_p,
168				      thread_t tid,
169				      td_thrhandle_t *th_p);
170static td_err_e (*p_td_ta_map_lwp2thr)(const td_thragent_t *ta_p,
171				       lwpid_t lwpid,
172				       td_thrhandle_t *th_p);
173static td_err_e (*p_td_thr_getgregs)(const td_thrhandle_t *th_p,
174				     prgregset_t regset);
175static td_err_e (*p_td_thr_setgregs)(const td_thrhandle_t *th_p,
176				     const prgregset_t regset);
177
178
179/* Return the libthread_db error string associated with ERRCODE.  If
180   ERRCODE is unknown, return an appropriate message.  */
181
182static char *
183td_err_string (td_err_e errcode)
184{
185  static struct string_map td_err_table[] =
186  {
187    { TD_OK, "generic \"call succeeded\"" },
188    { TD_ERR, "generic error." },
189    { TD_NOTHR, "no thread can be found to satisfy query" },
190    { TD_NOSV, "no synch. variable can be found to satisfy query" },
191    { TD_NOLWP, "no lwp can be found to satisfy query" },
192    { TD_BADPH, "invalid process handle" },
193    { TD_BADTH, "invalid thread handle" },
194    { TD_BADSH, "invalid synchronization handle" },
195    { TD_BADTA, "invalid thread agent" },
196    { TD_BADKEY, "invalid key" },
197    { TD_NOMSG, "td_thr_event_getmsg() called when there was no message" },
198    { TD_NOFPREGS, "FPU register set not available for given thread" },
199    { TD_NOLIBTHREAD, "application not linked with libthread" },
200    { TD_NOEVENT, "requested event is not supported" },
201    { TD_NOCAPAB, "capability not available" },
202    { TD_DBERR, "Debugger service failed" },
203    { TD_NOAPLIC, "Operation not applicable to" },
204    { TD_NOTSD, "No thread specific data for this thread" },
205    { TD_MALLOC, "Malloc failed" },
206    { TD_PARTIALREG, "Only part of register set was written/read" },
207    { TD_NOXREGS, "X register set not available for given thread" }
208  };
209  const int td_err_size = sizeof td_err_table / sizeof (struct string_map);
210  int i;
211  static char buf[50];
212
213  for (i = 0; i < td_err_size; i++)
214    if (td_err_table[i].num == errcode)
215      return td_err_table[i].str;
216
217  sprintf (buf, "Unknown libthread_db error code: %d", errcode);
218
219  return buf;
220}
221
222/* Return the the libthread_db state string assicoated with STATECODE.
223   If STATECODE is unknown, return an appropriate message.  */
224
225static char *
226td_state_string (td_thr_state_e statecode)
227{
228  static struct string_map td_thr_state_table[] =
229  {
230    { TD_THR_ANY_STATE, "any state" },
231    { TD_THR_UNKNOWN, "unknown" },
232    { TD_THR_STOPPED, "stopped" },
233    { TD_THR_RUN, "run" },
234    { TD_THR_ACTIVE, "active" },
235    { TD_THR_ZOMBIE, "zombie" },
236    { TD_THR_SLEEP, "sleep" },
237    { TD_THR_STOPPED_ASLEEP, "stopped asleep" }
238  };
239  const int td_thr_state_table_size =
240    sizeof td_thr_state_table / sizeof (struct string_map);
241  int i;
242  static char buf[50];
243
244  for (i = 0; i < td_thr_state_table_size; i++)
245    if (td_thr_state_table[i].num == statecode)
246      return td_thr_state_table[i].str;
247
248  sprintf (buf, "Unknown libthread_db state code: %d", statecode);
249
250  return buf;
251}
252
253
254/* Convert a POSIX or Solaris thread ID into a LWP ID.  If THREAD_ID
255   doesn't exist, that's an error.  If it's an inactive thread, return
256   DEFAULT_LPW.
257
258   NOTE: This function probably shouldn't call error().  */
259
260static ptid_t
261thread_to_lwp (ptid_t thread_id, int default_lwp)
262{
263  td_thrinfo_t ti;
264  td_thrhandle_t th;
265  td_err_e val;
266
267  if (is_lwp (thread_id))
268    return thread_id;		/* It's already an LWP ID.  */
269
270  /* It's a thread.  Convert to LWP.  */
271
272  val = p_td_ta_map_id2thr (main_ta, GET_THREAD (thread_id), &th);
273  if (val == TD_NOTHR)
274    return pid_to_ptid (-1);	/* Thread must have terminated.  */
275  else if (val != TD_OK)
276    error (_("thread_to_lwp: td_ta_map_id2thr %s"), td_err_string (val));
277
278  val = p_td_thr_get_info (&th, &ti);
279  if (val == TD_NOTHR)
280    return pid_to_ptid (-1);	/* Thread must have terminated.  */
281  else if (val != TD_OK)
282    error (_("thread_to_lwp: td_thr_get_info: %s"), td_err_string (val));
283
284  if (ti.ti_state != TD_THR_ACTIVE)
285    {
286      if (default_lwp != -1)
287	return pid_to_ptid (default_lwp);
288      error (_("thread_to_lwp: thread state not active: %s"),
289	     td_state_string (ti.ti_state));
290    }
291
292  return BUILD_LWP (ti.ti_lid, PIDGET (thread_id));
293}
294
295/* Convert an LWP ID into a POSIX or Solaris thread ID.  If LWP_ID
296   doesn't exists, that's an error.
297
298   NOTE: This function probably shouldn't call error().  */
299
300static ptid_t
301lwp_to_thread (ptid_t lwp)
302{
303  td_thrinfo_t ti;
304  td_thrhandle_t th;
305  td_err_e val;
306
307  if (is_thread (lwp))
308    return lwp;			/* It's already a thread ID.  */
309
310  /* It's an LWP.  Convert it to a thread ID.  */
311
312  if (!sol_thread_alive (lwp))
313    return pid_to_ptid (-1);	/* Must be a defunct LPW.  */
314
315  val = p_td_ta_map_lwp2thr (main_ta, GET_LWP (lwp), &th);
316  if (val == TD_NOTHR)
317    return pid_to_ptid (-1);	/* Thread must have terminated.  */
318  else if (val != TD_OK)
319    error (_("lwp_to_thread: td_ta_map_lwp2thr: %s."), td_err_string (val));
320
321  val = p_td_thr_validate (&th);
322  if (val == TD_NOTHR)
323    return lwp;			/* Unknown to libthread; just return LPW,  */
324  else if (val != TD_OK)
325    error (_("lwp_to_thread: td_thr_validate: %s."), td_err_string (val));
326
327  val = p_td_thr_get_info (&th, &ti);
328  if (val == TD_NOTHR)
329    return pid_to_ptid (-1);	/* Thread must have terminated.  */
330  else if (val != TD_OK)
331    error (_("lwp_to_thread: td_thr_get_info: %s."), td_err_string (val));
332
333  return BUILD_THREAD (ti.ti_tid, PIDGET (lwp));
334}
335
336
337/* Most target vector functions from here on actually just pass
338   through to procfs.c, as they don't need to do anything specific for
339   threads.  */
340
341static void
342sol_thread_open (char *arg, int from_tty)
343{
344  procfs_ops.to_open (arg, from_tty);
345}
346
347/* Attach to process PID, then initialize for debugging it and wait
348   for the trace-trap that results from attaching.  */
349
350static void
351sol_thread_attach (char *args, int from_tty)
352{
353  procfs_ops.to_attach (args, from_tty);
354
355  /* Must get symbols from shared libraries before libthread_db can run!  */
356  solib_add (NULL, from_tty, (struct target_ops *) 0, auto_solib_add);
357
358  if (sol_thread_active)
359    {
360      printf_filtered ("sol-thread active.\n");
361      main_ph.ptid = inferior_ptid; /* Save for xfer_memory.  */
362      push_target (&sol_thread_ops);
363      inferior_ptid = lwp_to_thread (inferior_ptid);
364      if (PIDGET (inferior_ptid) == -1)
365	inferior_ptid = main_ph.ptid;
366      else
367	add_thread (inferior_ptid);
368    }
369
370  /* FIXME: Might want to iterate over all the threads and register
371     them.  */
372}
373
374/* Take a program previously attached to and detaches it.  The program
375   resumes execution and will no longer stop on signals, etc.  We'd
376   better not have left any breakpoints in the program or it'll die
377   when it hits one.  For this to work, it may be necessary for the
378   process to have been previously attached.  It *might* work if the
379   program was started via the normal ptrace (PTRACE_TRACEME).  */
380
381static void
382sol_thread_detach (char *args, int from_tty)
383{
384  inferior_ptid = pid_to_ptid (PIDGET (main_ph.ptid));
385  unpush_target (&sol_thread_ops);
386  procfs_ops.to_detach (args, from_tty);
387}
388
389/* Resume execution of process PTID.  If STEP is nozero, then just
390   single step it.  If SIGNAL is nonzero, restart it with that signal
391   activated.  We may have to convert PTID from a thread ID to an LWP
392   ID for procfs.  */
393
394static void
395sol_thread_resume (ptid_t ptid, int step, enum target_signal signo)
396{
397  struct cleanup *old_chain;
398
399  old_chain = save_inferior_ptid ();
400
401  inferior_ptid = thread_to_lwp (inferior_ptid, PIDGET (main_ph.ptid));
402  if (PIDGET (inferior_ptid) == -1)
403    inferior_ptid = procfs_first_available ();
404
405  if (PIDGET (ptid) != -1)
406    {
407      ptid_t save_ptid = ptid;
408
409      ptid = thread_to_lwp (ptid, -2);
410      if (PIDGET (ptid) == -2)		/* Inactive thread.  */
411	error (_("This version of Solaris can't start inactive threads."));
412      if (info_verbose && PIDGET (ptid) == -1)
413	warning (_("Specified thread %ld seems to have terminated"),
414		 GET_THREAD (save_ptid));
415    }
416
417  procfs_ops.to_resume (ptid, step, signo);
418
419  do_cleanups (old_chain);
420}
421
422/* Wait for any threads to stop.  We may have to convert PIID from a
423   thread ID to an LWP ID, and vice versa on the way out.  */
424
425static ptid_t
426sol_thread_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
427{
428  ptid_t rtnval;
429  ptid_t save_ptid;
430  struct cleanup *old_chain;
431
432  save_ptid = inferior_ptid;
433  old_chain = save_inferior_ptid ();
434
435  inferior_ptid = thread_to_lwp (inferior_ptid, PIDGET (main_ph.ptid));
436  if (PIDGET (inferior_ptid) == -1)
437    inferior_ptid = procfs_first_available ();
438
439  if (PIDGET (ptid) != -1)
440    {
441      ptid_t save_ptid = ptid;
442
443      ptid = thread_to_lwp (ptid, -2);
444      if (PIDGET (ptid) == -2)		/* Inactive thread.  */
445	error (_("This version of Solaris can't start inactive threads."));
446      if (info_verbose && PIDGET (ptid) == -1)
447	warning (_("Specified thread %ld seems to have terminated"),
448		 GET_THREAD (save_ptid));
449    }
450
451  rtnval = procfs_ops.to_wait (ptid, ourstatus);
452
453  if (ourstatus->kind != TARGET_WAITKIND_EXITED)
454    {
455      /* Map the LWP of interest back to the appropriate thread ID.  */
456      rtnval = lwp_to_thread (rtnval);
457      if (PIDGET (rtnval) == -1)
458	rtnval = save_ptid;
459
460      /* See if we have a new thread.  */
461      if (is_thread (rtnval)
462	  && !ptid_equal (rtnval, save_ptid)
463	  && !in_thread_list (rtnval))
464	{
465	  printf_filtered ("[New %s]\n", target_pid_to_str (rtnval));
466	  add_thread (rtnval);
467	}
468    }
469
470  /* During process initialization, we may get here without the thread
471     package being initialized, since that can only happen after we've
472     found the shared libs.  */
473
474  do_cleanups (old_chain);
475
476  return rtnval;
477}
478
479static void
480sol_thread_fetch_registers (struct regcache *regcache, int regnum)
481{
482  thread_t thread;
483  td_thrhandle_t thandle;
484  td_err_e val;
485  prgregset_t gregset;
486  prfpregset_t fpregset;
487  gdb_gregset_t *gregset_p = &gregset;
488  gdb_fpregset_t *fpregset_p = &fpregset;
489
490#if 0
491  int xregsize;
492  caddr_t xregset;
493#endif
494
495  if (!is_thread (inferior_ptid))
496    {
497      /* It's an LWP; pass the request on to procfs.  */
498      if (target_has_execution)
499	procfs_ops.to_fetch_registers (regcache, regnum);
500      else
501	orig_core_ops.to_fetch_registers (regcache, regnum);
502      return;
503    }
504
505  /* Solaris thread: convert INFERIOR_PTID into a td_thrhandle_t.  */
506  thread = GET_THREAD (inferior_ptid);
507  if (thread == 0)
508    error (_("sol_thread_fetch_registers: thread == 0"));
509
510  val = p_td_ta_map_id2thr (main_ta, thread, &thandle);
511  if (val != TD_OK)
512    error (_("sol_thread_fetch_registers: td_ta_map_id2thr: %s"),
513	   td_err_string (val));
514
515  /* Get the general-purpose registers.  */
516
517  val = p_td_thr_getgregs (&thandle, gregset);
518  if (val != TD_OK && val != TD_PARTIALREG)
519    error (_("sol_thread_fetch_registers: td_thr_getgregs %s"),
520	   td_err_string (val));
521
522  /* For SPARC, TD_PARTIALREG means that only %i0...%i7, %l0..%l7, %pc
523     and %sp are saved (by a thread context switch).  */
524
525  /* And, now the floating-point registers.  */
526
527  val = p_td_thr_getfpregs (&thandle, &fpregset);
528  if (val != TD_OK && val != TD_NOFPREGS)
529    error (_("sol_thread_fetch_registers: td_thr_getfpregs %s"),
530	   td_err_string (val));
531
532  /* Note that we must call supply_gregset and supply_fpregset *after*
533     calling the td routines because the td routines call ps_lget*
534     which affect the values stored in the registers array.  */
535
536  supply_gregset (regcache, (const gdb_gregset_t *) gregset_p);
537  supply_fpregset (regcache, (const gdb_fpregset_t *) fpregset_p);
538
539#if 0
540  /* FIXME: libthread_db doesn't seem to handle this right.  */
541  val = td_thr_getxregsize (&thandle, &xregsize);
542  if (val != TD_OK && val != TD_NOXREGS)
543    error (_("sol_thread_fetch_registers: td_thr_getxregsize %s"),
544	   td_err_string (val));
545
546  if (val == TD_OK)
547    {
548      xregset = alloca (xregsize);
549      val = td_thr_getxregs (&thandle, xregset);
550      if (val != TD_OK)
551	error (_("sol_thread_fetch_registers: td_thr_getxregs %s"),
552	       td_err_string (val));
553    }
554#endif
555}
556
557static void
558sol_thread_store_registers (struct regcache *regcache, int regnum)
559{
560  thread_t thread;
561  td_thrhandle_t thandle;
562  td_err_e val;
563  prgregset_t gregset;
564  prfpregset_t fpregset;
565#if 0
566  int xregsize;
567  caddr_t xregset;
568#endif
569
570  if (!is_thread (inferior_ptid))
571    {
572      /* It's an LWP; pass the request on to procfs.c.  */
573      procfs_ops.to_store_registers (regcache, regnum);
574      return;
575    }
576
577  /* Solaris thread: convert INFERIOR_PTID into a td_thrhandle_t.  */
578  thread = GET_THREAD (inferior_ptid);
579
580  val = p_td_ta_map_id2thr (main_ta, thread, &thandle);
581  if (val != TD_OK)
582    error (_("sol_thread_store_registers: td_ta_map_id2thr %s"),
583	   td_err_string (val));
584
585  if (regnum != -1)
586    {
587      /* Not writing all the registers.  */
588      char old_value[MAX_REGISTER_SIZE];
589
590      /* Save new register value.  */
591      regcache_raw_collect (regcache, regnum, old_value);
592
593      val = p_td_thr_getgregs (&thandle, gregset);
594      if (val != TD_OK)
595	error (_("sol_thread_store_registers: td_thr_getgregs %s"),
596	       td_err_string (val));
597      val = p_td_thr_getfpregs (&thandle, &fpregset);
598      if (val != TD_OK)
599	error (_("sol_thread_store_registers: td_thr_getfpregs %s"),
600	       td_err_string (val));
601
602      /* Restore new register value.  */
603      regcache_raw_supply (regcache, regnum, old_value);
604
605#if 0
606      /* FIXME: libthread_db doesn't seem to handle this right.  */
607      val = td_thr_getxregsize (&thandle, &xregsize);
608      if (val != TD_OK && val != TD_NOXREGS)
609	error (_("sol_thread_store_registers: td_thr_getxregsize %s"),
610	       td_err_string (val));
611
612      if (val == TD_OK)
613	{
614	  xregset = alloca (xregsize);
615	  val = td_thr_getxregs (&thandle, xregset);
616	  if (val != TD_OK)
617	    error (_("sol_thread_store_registers: td_thr_getxregs %s"),
618		   td_err_string (val));
619	}
620#endif
621    }
622
623  fill_gregset (regcache, (gdb_gregset_t *) &gregset, regnum);
624  fill_fpregset (regcache, (gdb_fpregset_t *) &fpregset, regnum);
625
626  val = p_td_thr_setgregs (&thandle, gregset);
627  if (val != TD_OK)
628    error (_("sol_thread_store_registers: td_thr_setgregs %s"),
629	   td_err_string (val));
630  val = p_td_thr_setfpregs (&thandle, &fpregset);
631  if (val != TD_OK)
632    error (_("sol_thread_store_registers: td_thr_setfpregs %s"),
633	   td_err_string (val));
634
635#if 0
636  /* FIXME: libthread_db doesn't seem to handle this right.  */
637  val = td_thr_getxregsize (&thandle, &xregsize);
638  if (val != TD_OK && val != TD_NOXREGS)
639    error (_("sol_thread_store_registers: td_thr_getxregsize %s"),
640	   td_err_string (val));
641
642  /* ??? Should probably do something about writing the xregs here,
643     but what are they?  */
644#endif
645}
646
647/* Get ready to modify the registers array.  On machines which store
648   individual registers, this doesn't need to do anything.  On
649   machines which store all the registers in one fell swoop, this
650   makes sure that registers contains all the registers from the
651   program being debugged.  */
652
653static void
654sol_thread_prepare_to_store (struct regcache *regcache)
655{
656  procfs_ops.to_prepare_to_store (regcache);
657}
658
659/* Transfer LEN bytes between GDB address MYADDR and target address
660   MEMADDR.  If DOWRITE is non-zero, transfer them to the target,
661   otherwise transfer them from the target.  TARGET is unused.
662
663   Returns the number of bytes transferred.  */
664
665static int
666sol_thread_xfer_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len,
667			int dowrite, struct mem_attrib *attrib,
668			struct target_ops *target)
669{
670  int retval;
671  struct cleanup *old_chain;
672
673  old_chain = save_inferior_ptid ();
674
675  if (is_thread (inferior_ptid) || !target_thread_alive (inferior_ptid))
676    {
677      /* It's either a thread or an LWP that isn't alive.  Any live
678         LWP will do so use the first available.
679
680	 NOTE: We don't need to call switch_to_thread; we're just
681	 reading memory.  */
682      inferior_ptid = procfs_first_available ();
683    }
684
685  if (target_has_execution)
686    retval = procfs_ops.deprecated_xfer_memory (memaddr, myaddr, len,
687						dowrite, attrib, target);
688  else
689    retval = orig_core_ops.deprecated_xfer_memory (memaddr, myaddr, len,
690						   dowrite, attrib, target);
691
692  do_cleanups (old_chain);
693
694  return retval;
695}
696
697/* Perform partial transfers on OBJECT.  See target_read_partial and
698   target_write_partial for details of each variant.  One, and only
699   one, of readbuf or writebuf must be non-NULL.  */
700
701static LONGEST
702sol_thread_xfer_partial (struct target_ops *ops, enum target_object object,
703			  const char *annex, gdb_byte *readbuf,
704			  const gdb_byte *writebuf,
705			 ULONGEST offset, LONGEST len)
706{
707  int retval;
708  struct cleanup *old_chain;
709
710  old_chain = save_inferior_ptid ();
711
712  if (is_thread (inferior_ptid) || !target_thread_alive (inferior_ptid))
713    {
714      /* It's either a thread or an LWP that isn't alive.  Any live
715         LWP will do so use the first available.
716
717	 NOTE: We don't need to call switch_to_thread; we're just
718	 reading memory.  */
719      inferior_ptid = procfs_first_available ();
720    }
721
722  if (target_has_execution)
723    retval = procfs_ops.to_xfer_partial (ops, object, annex,
724					 readbuf, writebuf, offset, len);
725  else
726    retval = orig_core_ops.to_xfer_partial (ops, object, annex,
727					    readbuf, writebuf, offset, len);
728
729  do_cleanups (old_chain);
730
731  return retval;
732}
733
734/* Print status information about what we're accessing.  */
735
736static void
737sol_thread_files_info (struct target_ops *ignore)
738{
739  procfs_ops.to_files_info (ignore);
740}
741
742static void
743sol_thread_kill_inferior (void)
744{
745  procfs_ops.to_kill ();
746}
747
748static void
749sol_thread_notice_signals (ptid_t ptid)
750{
751  procfs_ops.to_notice_signals (pid_to_ptid (PIDGET (ptid)));
752}
753
754/* Fork an inferior process, and start debugging it with /proc.  */
755
756static void
757sol_thread_create_inferior (char *exec_file, char *allargs, char **env,
758			    int from_tty)
759{
760  procfs_ops.to_create_inferior (exec_file, allargs, env, from_tty);
761
762  if (sol_thread_active && !ptid_equal (inferior_ptid, null_ptid))
763    {
764      /* Save for xfer_memory.  */
765      main_ph.ptid = inferior_ptid;
766
767      push_target (&sol_thread_ops);
768
769      inferior_ptid = lwp_to_thread (inferior_ptid);
770      if (PIDGET (inferior_ptid) == -1)
771	inferior_ptid = main_ph.ptid;
772
773      if (!in_thread_list (inferior_ptid))
774	add_thread (inferior_ptid);
775    }
776}
777
778/* This routine is called whenever a new symbol table is read in, or
779   when all symbol tables are removed.  libthread_db can only be
780   initialized when it finds the right variables in libthread.so.
781   Since it's a shared library, those variables don't show up until
782   the library gets mapped and the symbol table is read in.  */
783
784static void
785sol_thread_new_objfile (struct objfile *objfile)
786{
787  td_err_e val;
788
789  if (!objfile)
790    {
791      sol_thread_active = 0;
792      return;
793    }
794
795  /* Don't do anything if init failed to resolve the libthread_db
796     library.  */
797  if (!procfs_suppress_run)
798    return;
799
800  /* Now, initialize libthread_db.  This needs to be done after the
801     shared libraries are located because it needs information from
802     the user's thread library.  */
803
804  val = p_td_init ();
805  if (val != TD_OK)
806    {
807      warning (_("sol_thread_new_objfile: td_init: %s"), td_err_string (val));
808      return;
809    }
810
811  val = p_td_ta_new (&main_ph, &main_ta);
812  if (val == TD_NOLIBTHREAD)
813    return;
814  else if (val != TD_OK)
815    {
816      warning (_("sol_thread_new_objfile: td_ta_new: %s"), td_err_string (val));
817      return;
818    }
819
820  sol_thread_active = 1;
821}
822
823/* Clean up after the inferior dies.  */
824
825static void
826sol_thread_mourn_inferior (void)
827{
828  unpush_target (&sol_thread_ops);
829  procfs_ops.to_mourn_inferior ();
830}
831
832/* Mark our target-struct as eligible for stray "run" and "attach"
833   commands.  */
834
835static int
836sol_thread_can_run (void)
837{
838  return procfs_suppress_run;
839}
840
841/*
842
843   LOCAL FUNCTION
844
845   sol_thread_alive     - test thread for "aliveness"
846
847   SYNOPSIS
848
849   static bool sol_thread_alive (ptid_t ptid);
850
851   DESCRIPTION
852
853   returns true if thread still active in inferior.
854
855 */
856
857/* Return true if PTID is still active in the inferior.  */
858
859static int
860sol_thread_alive (ptid_t ptid)
861{
862  if (is_thread (ptid))
863    {
864      /* It's a (user-level) thread.  */
865      td_err_e val;
866      td_thrhandle_t th;
867      int pid;
868
869      pid = GET_THREAD (ptid);
870      if ((val = p_td_ta_map_id2thr (main_ta, pid, &th)) != TD_OK)
871	return 0;		/* Thread not found.  */
872      if ((val = p_td_thr_validate (&th)) != TD_OK)
873	return 0;		/* Thread not valid.  */
874      return 1;			/* Known thread.  */
875    }
876  else
877    {
878      /* It's an LPW; pass the request on to procfs.  */
879      if (target_has_execution)
880	return procfs_ops.to_thread_alive (ptid);
881      else
882	return orig_core_ops.to_thread_alive (ptid);
883    }
884}
885
886static void
887sol_thread_stop (void)
888{
889  procfs_ops.to_stop ();
890}
891
892/* These routines implement the lower half of the thread_db interface,
893   i.e. the ps_* routines.  */
894
895/* Various versions of <proc_service.h> have slightly different
896   function prototypes.  In particular, we have
897
898   NEWER                        OLDER
899   struct ps_prochandle *       const struct ps_prochandle *
900   void*                        char*
901   const void*          	char*
902   int                  	size_t
903
904   Which one you have depends on the Solaris version and what patches
905   you've applied.  On the theory that there are only two major
906   variants, we have configure check the prototype of ps_pdwrite (),
907   and use that info to make appropriate typedefs here. */
908
909#ifdef PROC_SERVICE_IS_OLD
910typedef const struct ps_prochandle *gdb_ps_prochandle_t;
911typedef char *gdb_ps_read_buf_t;
912typedef char *gdb_ps_write_buf_t;
913typedef int gdb_ps_size_t;
914typedef psaddr_t gdb_ps_addr_t;
915#else
916typedef struct ps_prochandle *gdb_ps_prochandle_t;
917typedef void *gdb_ps_read_buf_t;
918typedef const void *gdb_ps_write_buf_t;
919typedef size_t gdb_ps_size_t;
920typedef psaddr_t gdb_ps_addr_t;
921#endif
922
923/* The next four routines are called by libthread_db to tell us to
924   stop and stop a particular process or lwp.  Since GDB ensures that
925   these are all stopped by the time we call anything in thread_db,
926   these routines need to do nothing.  */
927
928/* Process stop.  */
929
930ps_err_e
931ps_pstop (gdb_ps_prochandle_t ph)
932{
933  return PS_OK;
934}
935
936/* Process continue.  */
937
938ps_err_e
939ps_pcontinue (gdb_ps_prochandle_t ph)
940{
941  return PS_OK;
942}
943
944/* LWP stop.  */
945
946ps_err_e
947ps_lstop (gdb_ps_prochandle_t ph, lwpid_t lwpid)
948{
949  return PS_OK;
950}
951
952/* LWP continue.  */
953
954ps_err_e
955ps_lcontinue (gdb_ps_prochandle_t ph, lwpid_t lwpid)
956{
957  return PS_OK;
958}
959
960/* Looks up the symbol LD_SYMBOL_NAME in the debugger's symbol table.  */
961
962ps_err_e
963ps_pglobal_lookup (gdb_ps_prochandle_t ph, const char *ld_object_name,
964		   const char *ld_symbol_name, gdb_ps_addr_t *ld_symbol_addr)
965{
966  struct minimal_symbol *ms;
967
968  ms = lookup_minimal_symbol (ld_symbol_name, NULL, NULL);
969  if (!ms)
970    return PS_NOSYM;
971
972  *ld_symbol_addr = SYMBOL_VALUE_ADDRESS (ms);
973  return PS_OK;
974}
975
976/* Common routine for reading and writing memory.  */
977
978static ps_err_e
979rw_common (int dowrite, const struct ps_prochandle *ph, gdb_ps_addr_t addr,
980	   char *buf, int size)
981{
982  struct cleanup *old_chain;
983
984  old_chain = save_inferior_ptid ();
985
986  if (is_thread (inferior_ptid) || !target_thread_alive (inferior_ptid))
987    {
988      /* It's either a thread or an LWP that isn't alive.  Any live
989         LWP will do so use the first available.
990
991	 NOTE: We don't need to call switch_to_thread; we're just
992	 reading memory.  */
993      inferior_ptid = procfs_first_available ();
994    }
995
996#if defined (__sparcv9)
997  /* For Sparc64 cross Sparc32, make sure the address has not been
998     accidentally sign-extended (or whatever) to beyond 32 bits.  */
999  if (bfd_get_arch_size (exec_bfd) == 32)
1000    addr &= 0xffffffff;
1001#endif
1002
1003  while (size > 0)
1004    {
1005      int cc;
1006
1007      /* FIXME: passing 0 as attrib argument.  */
1008      if (target_has_execution)
1009	cc = procfs_ops.deprecated_xfer_memory (addr, buf, size,
1010						dowrite, 0, &procfs_ops);
1011      else
1012	cc = orig_core_ops.deprecated_xfer_memory (addr, buf, size,
1013						   dowrite, 0, &core_ops);
1014
1015      if (cc < 0)
1016	{
1017	  if (dowrite == 0)
1018	    print_sys_errmsg ("rw_common (): read", errno);
1019	  else
1020	    print_sys_errmsg ("rw_common (): write", errno);
1021
1022	  do_cleanups (old_chain);
1023
1024	  return PS_ERR;
1025	}
1026      else if (cc == 0)
1027	{
1028	  if (dowrite == 0)
1029	    warning (_("rw_common (): unable to read at addr 0x%lx"),
1030		     (long) addr);
1031	  else
1032	    warning (_("rw_common (): unable to write at addr 0x%lx"),
1033		     (long) addr);
1034
1035	  do_cleanups (old_chain);
1036
1037	  return PS_ERR;
1038	}
1039
1040      size -= cc;
1041      buf += cc;
1042    }
1043
1044  do_cleanups (old_chain);
1045
1046  return PS_OK;
1047}
1048
1049/* Copies SIZE bytes from target process .data segment to debugger memory.  */
1050
1051ps_err_e
1052ps_pdread (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
1053	   gdb_ps_read_buf_t buf, gdb_ps_size_t size)
1054{
1055  return rw_common (0, ph, addr, buf, size);
1056}
1057
1058/* Copies SIZE bytes from debugger memory .data segment to target process.  */
1059
1060ps_err_e
1061ps_pdwrite (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
1062	    gdb_ps_write_buf_t buf, gdb_ps_size_t size)
1063{
1064  return rw_common (1, ph, addr, (char *) buf, size);
1065}
1066
1067/* Copies SIZE bytes from target process .text segment to debugger memory.  */
1068
1069ps_err_e
1070ps_ptread (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
1071	   gdb_ps_read_buf_t buf, gdb_ps_size_t size)
1072{
1073  return rw_common (0, ph, addr, buf, size);
1074}
1075
1076/* Copies SIZE bytes from debugger memory .text segment to target process.  */
1077
1078ps_err_e
1079ps_ptwrite (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
1080	    gdb_ps_write_buf_t buf, gdb_ps_size_t size)
1081{
1082  return rw_common (1, ph, addr, (char *) buf, size);
1083}
1084
1085/* Get general-purpose registers for LWP.  */
1086
1087ps_err_e
1088ps_lgetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, prgregset_t gregset)
1089{
1090  struct cleanup *old_chain;
1091  struct regcache *regcache;
1092
1093  old_chain = save_inferior_ptid ();
1094
1095  inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
1096  regcache = get_thread_regcache (inferior_ptid);
1097
1098  if (target_has_execution)
1099    procfs_ops.to_fetch_registers (regcache, -1);
1100  else
1101    orig_core_ops.to_fetch_registers (regcache, -1);
1102  fill_gregset (regcache, (gdb_gregset_t *) gregset, -1);
1103
1104  do_cleanups (old_chain);
1105
1106  return PS_OK;
1107}
1108
1109/* Set general-purpose registers for LWP.  */
1110
1111ps_err_e
1112ps_lsetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
1113	     const prgregset_t gregset)
1114{
1115  struct cleanup *old_chain;
1116  struct regcache *regcache;
1117
1118  old_chain = save_inferior_ptid ();
1119
1120  inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
1121  regcache = get_thread_regcache (inferior_ptid);
1122
1123  supply_gregset (regcache, (const gdb_gregset_t *) gregset);
1124  if (target_has_execution)
1125    procfs_ops.to_store_registers (regcache, -1);
1126  else
1127    orig_core_ops.to_store_registers (regcache, -1);
1128
1129  do_cleanups (old_chain);
1130
1131  return PS_OK;
1132}
1133
1134/* Log a message (sends to gdb_stderr).  */
1135
1136void
1137ps_plog (const char *fmt, ...)
1138{
1139  va_list args;
1140
1141  va_start (args, fmt);
1142
1143  vfprintf_filtered (gdb_stderr, fmt, args);
1144}
1145
1146/* Get size of extra register set.  Currently a noop.  */
1147
1148ps_err_e
1149ps_lgetxregsize (gdb_ps_prochandle_t ph, lwpid_t lwpid, int *xregsize)
1150{
1151#if 0
1152  int lwp_fd;
1153  int regsize;
1154  ps_err_e val;
1155
1156  val = get_lwp_fd (ph, lwpid, &lwp_fd);
1157  if (val != PS_OK)
1158    return val;
1159
1160  if (ioctl (lwp_fd, PIOCGXREGSIZE, &regsize))
1161    {
1162      if (errno == EINVAL)
1163	return PS_NOFREGS;	/* XXX Wrong code, but this is the closest
1164				   thing in proc_service.h  */
1165
1166      print_sys_errmsg ("ps_lgetxregsize (): PIOCGXREGSIZE", errno);
1167      return PS_ERR;
1168    }
1169#endif
1170
1171  return PS_OK;
1172}
1173
1174/* Get extra register set.  Currently a noop.  */
1175
1176ps_err_e
1177ps_lgetxregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, caddr_t xregset)
1178{
1179#if 0
1180  int lwp_fd;
1181  ps_err_e val;
1182
1183  val = get_lwp_fd (ph, lwpid, &lwp_fd);
1184  if (val != PS_OK)
1185    return val;
1186
1187  if (ioctl (lwp_fd, PIOCGXREG, xregset))
1188    {
1189      print_sys_errmsg ("ps_lgetxregs (): PIOCGXREG", errno);
1190      return PS_ERR;
1191    }
1192#endif
1193
1194  return PS_OK;
1195}
1196
1197/* Set extra register set.  Currently a noop.  */
1198
1199ps_err_e
1200ps_lsetxregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, caddr_t xregset)
1201{
1202#if 0
1203  int lwp_fd;
1204  ps_err_e val;
1205
1206  val = get_lwp_fd (ph, lwpid, &lwp_fd);
1207  if (val != PS_OK)
1208    return val;
1209
1210  if (ioctl (lwp_fd, PIOCSXREG, xregset))
1211    {
1212      print_sys_errmsg ("ps_lsetxregs (): PIOCSXREG", errno);
1213      return PS_ERR;
1214    }
1215#endif
1216
1217  return PS_OK;
1218}
1219
1220/* Get floating-point registers for LWP.  */
1221
1222ps_err_e
1223ps_lgetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
1224	       prfpregset_t *fpregset)
1225{
1226  struct cleanup *old_chain;
1227  struct regcache *regcache;
1228
1229  old_chain = save_inferior_ptid ();
1230
1231  inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
1232  regcache = get_thread_regcache (inferior_ptid);
1233
1234  if (target_has_execution)
1235    procfs_ops.to_fetch_registers (regcache, -1);
1236  else
1237    orig_core_ops.to_fetch_registers (regcache, -1);
1238  fill_fpregset (regcache, (gdb_fpregset_t *) fpregset, -1);
1239
1240  do_cleanups (old_chain);
1241
1242  return PS_OK;
1243}
1244
1245/* Set floating-point regs for LWP */
1246
1247ps_err_e
1248ps_lsetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
1249	       const prfpregset_t * fpregset)
1250{
1251  struct cleanup *old_chain;
1252  struct regcache *regcache;
1253
1254  old_chain = save_inferior_ptid ();
1255
1256  inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
1257  regcache = get_thread_regcache (inferior_ptid);
1258
1259  supply_fpregset (regcache, (const gdb_fpregset_t *) fpregset);
1260  if (target_has_execution)
1261    procfs_ops.to_store_registers (regcache, -1);
1262  else
1263    orig_core_ops.to_store_registers (regcache, -1);
1264
1265  do_cleanups (old_chain);
1266
1267  return PS_OK;
1268}
1269
1270#ifdef PR_MODEL_LP64
1271/* Identify process as 32-bit or 64-bit.  At the moment we're using
1272   BFD to do this.  There might be a more Solaris-specific
1273   (e.g. procfs) method, but this ought to work.  */
1274
1275ps_err_e
1276ps_pdmodel (gdb_ps_prochandle_t ph, int *data_model)
1277{
1278  if (exec_bfd == 0)
1279    *data_model = PR_MODEL_UNKNOWN;
1280  else if (bfd_get_arch_size (exec_bfd) == 32)
1281    *data_model = PR_MODEL_ILP32;
1282  else
1283    *data_model = PR_MODEL_LP64;
1284
1285  return PS_OK;
1286}
1287#endif /* PR_MODEL_LP64 */
1288
1289#ifdef TM_I386SOL2_H
1290
1291/* Reads the local descriptor table of a LWP.  */
1292
1293ps_err_e
1294ps_lgetLDT (gdb_ps_prochandle_t ph, lwpid_t lwpid,
1295	    struct ssd *pldt)
1296{
1297  /* NOTE: only used on Solaris, therefore OK to refer to procfs.c.  */
1298  extern struct ssd *procfs_find_LDT_entry (ptid_t);
1299  struct ssd *ret;
1300
1301  /* FIXME: can't I get the process ID from the prochandle or
1302     something?  */
1303
1304  if (PIDGET (inferior_ptid) <= 0 || lwpid <= 0)
1305    return PS_BADLID;
1306
1307  ret = procfs_find_LDT_entry (BUILD_LWP (lwpid, PIDGET (inferior_ptid)));
1308  if (ret)
1309    {
1310      memcpy (pldt, ret, sizeof (struct ssd));
1311      return PS_OK;
1312    }
1313  else
1314    /* LDT not found.  */
1315    return PS_ERR;
1316}
1317#endif /* TM_I386SOL2_H */
1318
1319
1320/* Convert PTID to printable form.  */
1321
1322char *
1323solaris_pid_to_str (ptid_t ptid)
1324{
1325  static char buf[100];
1326
1327  /* In case init failed to resolve the libthread_db library.  */
1328  if (!procfs_suppress_run)
1329    return procfs_pid_to_str (ptid);
1330
1331  if (is_thread (ptid))
1332    {
1333      ptid_t lwp;
1334
1335      lwp = thread_to_lwp (ptid, -2);
1336
1337      if (PIDGET (lwp) == -1)
1338	sprintf (buf, "Thread %ld (defunct)", GET_THREAD (ptid));
1339      else if (PIDGET (lwp) != -2)
1340	sprintf (buf, "Thread %ld (LWP %ld)",
1341		 GET_THREAD (ptid), GET_LWP (lwp));
1342      else
1343	sprintf (buf, "Thread %ld        ", GET_THREAD (ptid));
1344    }
1345  else if (GET_LWP (ptid) != 0)
1346    sprintf (buf, "LWP    %ld        ", GET_LWP (ptid));
1347  else
1348    sprintf (buf, "process %d    ", PIDGET (ptid));
1349
1350  return buf;
1351}
1352
1353
1354/* Worker bee for find_new_threads.  Callback function that gets
1355   called once per user-level thread (i.e. not for LWP's).  */
1356
1357static int
1358sol_find_new_threads_callback (const td_thrhandle_t *th, void *ignored)
1359{
1360  td_err_e retval;
1361  td_thrinfo_t ti;
1362  ptid_t ptid;
1363
1364  retval = p_td_thr_get_info (th, &ti);
1365  if (retval != TD_OK)
1366    return -1;
1367
1368  ptid = BUILD_THREAD (ti.ti_tid, PIDGET (inferior_ptid));
1369  if (!in_thread_list (ptid))
1370    add_thread (ptid);
1371
1372  return 0;
1373}
1374
1375static void
1376sol_find_new_threads (void)
1377{
1378  /* Don't do anything if init failed to resolve the libthread_db
1379     library.  */
1380  if (!procfs_suppress_run)
1381    return;
1382
1383  if (PIDGET (inferior_ptid) == -1)
1384    {
1385      printf_filtered ("No process.\n");
1386      return;
1387    }
1388
1389  /* First Find any new LWP's.  */
1390  procfs_ops.to_find_new_threads ();
1391
1392  /* Then find any new user-level threads.  */
1393  p_td_ta_thr_iter (main_ta, sol_find_new_threads_callback, (void *) 0,
1394		    TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
1395		    TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
1396}
1397
1398static void
1399sol_core_open (char *filename, int from_tty)
1400{
1401  orig_core_ops.to_open (filename, from_tty);
1402}
1403
1404static void
1405sol_core_close (int quitting)
1406{
1407  orig_core_ops.to_close (quitting);
1408}
1409
1410static void
1411sol_core_detach (char *args, int from_tty)
1412{
1413  unpush_target (&core_ops);
1414  orig_core_ops.to_detach (args, from_tty);
1415}
1416
1417static void
1418sol_core_files_info (struct target_ops *t)
1419{
1420  orig_core_ops.to_files_info (t);
1421}
1422
1423/* Worker bee for the "info sol-thread" command.  This is a callback
1424   function that gets called once for each Solaris user-level thread
1425   (i.e. not for LWPs) in the inferior.  Print anything interesting
1426   that we can think of.  */
1427
1428static int
1429info_cb (const td_thrhandle_t *th, void *s)
1430{
1431  td_err_e ret;
1432  td_thrinfo_t ti;
1433
1434  ret = p_td_thr_get_info (th, &ti);
1435  if (ret == TD_OK)
1436    {
1437      printf_filtered ("%s thread #%d, lwp %d, ",
1438		       ti.ti_type == TD_THR_SYSTEM ? "system" : "user  ",
1439		       ti.ti_tid, ti.ti_lid);
1440      switch (ti.ti_state)
1441	{
1442	default:
1443	case TD_THR_UNKNOWN:
1444	  printf_filtered ("<unknown state>");
1445	  break;
1446	case TD_THR_STOPPED:
1447	  printf_filtered ("(stopped)");
1448	  break;
1449	case TD_THR_RUN:
1450	  printf_filtered ("(run)    ");
1451	  break;
1452	case TD_THR_ACTIVE:
1453	  printf_filtered ("(active) ");
1454	  break;
1455	case TD_THR_ZOMBIE:
1456	  printf_filtered ("(zombie) ");
1457	  break;
1458	case TD_THR_SLEEP:
1459	  printf_filtered ("(asleep) ");
1460	  break;
1461	case TD_THR_STOPPED_ASLEEP:
1462	  printf_filtered ("(stopped asleep)");
1463	  break;
1464	}
1465      /* Print thr_create start function.  */
1466      if (ti.ti_startfunc != 0)
1467	{
1468	  struct minimal_symbol *msym;
1469	  msym = lookup_minimal_symbol_by_pc (ti.ti_startfunc);
1470	  if (msym)
1471	    printf_filtered ("   startfunc: %s\n",
1472			     DEPRECATED_SYMBOL_NAME (msym));
1473	  else
1474	    printf_filtered ("   startfunc: 0x%s\n", paddr (ti.ti_startfunc));
1475	}
1476
1477      /* If thread is asleep, print function that went to sleep.  */
1478      if (ti.ti_state == TD_THR_SLEEP)
1479	{
1480	  struct minimal_symbol *msym;
1481	  msym = lookup_minimal_symbol_by_pc (ti.ti_pc);
1482	  if (msym)
1483	    printf_filtered (" - Sleep func: %s\n",
1484			     DEPRECATED_SYMBOL_NAME (msym));
1485	  else
1486	    printf_filtered (" - Sleep func: 0x%s\n", paddr (ti.ti_startfunc));
1487	}
1488
1489      /* Wrap up line, if necessary.  */
1490      if (ti.ti_state != TD_THR_SLEEP && ti.ti_startfunc == 0)
1491	printf_filtered ("\n");	/* don't you hate counting newlines? */
1492    }
1493  else
1494    warning (_("info sol-thread: failed to get info for thread."));
1495
1496  return 0;
1497}
1498
1499/* List some state about each Solaris user-level thread in the
1500   inferior.  */
1501
1502static void
1503info_solthreads (char *args, int from_tty)
1504{
1505  p_td_ta_thr_iter (main_ta, info_cb, args,
1506		    TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
1507		    TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
1508}
1509
1510static int
1511sol_find_memory_regions (int (*func) (CORE_ADDR, unsigned long,
1512				      int, int, int, void *),
1513			 void *data)
1514{
1515  return procfs_ops.to_find_memory_regions (func, data);
1516}
1517
1518static char *
1519sol_make_note_section (bfd *obfd, int *note_size)
1520{
1521  return procfs_ops.to_make_corefile_notes (obfd, note_size);
1522}
1523
1524static int
1525ignore (struct bp_target_info *bp_tgt)
1526{
1527  return 0;
1528}
1529
1530static void
1531init_sol_thread_ops (void)
1532{
1533  sol_thread_ops.to_shortname = "solaris-threads";
1534  sol_thread_ops.to_longname = "Solaris threads and pthread.";
1535  sol_thread_ops.to_doc = "Solaris threads and pthread support.";
1536  sol_thread_ops.to_open = sol_thread_open;
1537  sol_thread_ops.to_attach = sol_thread_attach;
1538  sol_thread_ops.to_detach = sol_thread_detach;
1539  sol_thread_ops.to_resume = sol_thread_resume;
1540  sol_thread_ops.to_wait = sol_thread_wait;
1541  sol_thread_ops.to_fetch_registers = sol_thread_fetch_registers;
1542  sol_thread_ops.to_store_registers = sol_thread_store_registers;
1543  sol_thread_ops.to_prepare_to_store = sol_thread_prepare_to_store;
1544  sol_thread_ops.deprecated_xfer_memory = sol_thread_xfer_memory;
1545  sol_thread_ops.to_xfer_partial = sol_thread_xfer_partial;
1546  sol_thread_ops.to_files_info = sol_thread_files_info;
1547  sol_thread_ops.to_insert_breakpoint = memory_insert_breakpoint;
1548  sol_thread_ops.to_remove_breakpoint = memory_remove_breakpoint;
1549  sol_thread_ops.to_terminal_init = terminal_init_inferior;
1550  sol_thread_ops.to_terminal_inferior = terminal_inferior;
1551  sol_thread_ops.to_terminal_ours_for_output = terminal_ours_for_output;
1552  sol_thread_ops.to_terminal_ours = terminal_ours;
1553  sol_thread_ops.to_terminal_save_ours = terminal_save_ours;
1554  sol_thread_ops.to_terminal_info = child_terminal_info;
1555  sol_thread_ops.to_kill = sol_thread_kill_inferior;
1556  sol_thread_ops.to_create_inferior = sol_thread_create_inferior;
1557  sol_thread_ops.to_mourn_inferior = sol_thread_mourn_inferior;
1558  sol_thread_ops.to_can_run = sol_thread_can_run;
1559  sol_thread_ops.to_notice_signals = sol_thread_notice_signals;
1560  sol_thread_ops.to_thread_alive = sol_thread_alive;
1561  sol_thread_ops.to_pid_to_str = solaris_pid_to_str;
1562  sol_thread_ops.to_find_new_threads = sol_find_new_threads;
1563  sol_thread_ops.to_stop = sol_thread_stop;
1564  sol_thread_ops.to_stratum = process_stratum;
1565  sol_thread_ops.to_has_all_memory = 1;
1566  sol_thread_ops.to_has_memory = 1;
1567  sol_thread_ops.to_has_stack = 1;
1568  sol_thread_ops.to_has_registers = 1;
1569  sol_thread_ops.to_has_execution = 1;
1570  sol_thread_ops.to_has_thread_control = tc_none;
1571  sol_thread_ops.to_find_memory_regions = sol_find_memory_regions;
1572  sol_thread_ops.to_make_corefile_notes = sol_make_note_section;
1573  sol_thread_ops.to_magic = OPS_MAGIC;
1574}
1575
1576static void
1577init_sol_core_ops (void)
1578{
1579  sol_core_ops.to_shortname = "solaris-core";
1580  sol_core_ops.to_longname = "Solaris core threads and pthread.";
1581  sol_core_ops.to_doc = "Solaris threads and pthread support for core files.";
1582  sol_core_ops.to_open = sol_core_open;
1583  sol_core_ops.to_close = sol_core_close;
1584  sol_core_ops.to_attach = sol_thread_attach;
1585  sol_core_ops.to_detach = sol_core_detach;
1586  sol_core_ops.to_fetch_registers = sol_thread_fetch_registers;
1587  sol_core_ops.deprecated_xfer_memory = sol_thread_xfer_memory;
1588  sol_core_ops.to_xfer_partial = sol_thread_xfer_partial;
1589  sol_core_ops.to_files_info = sol_core_files_info;
1590  sol_core_ops.to_insert_breakpoint = ignore;
1591  sol_core_ops.to_remove_breakpoint = ignore;
1592  sol_core_ops.to_create_inferior = sol_thread_create_inferior;
1593  sol_core_ops.to_stratum = core_stratum;
1594  sol_core_ops.to_has_memory = 1;
1595  sol_core_ops.to_has_stack = 1;
1596  sol_core_ops.to_has_registers = 1;
1597  sol_core_ops.to_has_thread_control = tc_none;
1598  sol_core_ops.to_thread_alive = sol_thread_alive;
1599  sol_core_ops.to_pid_to_str = solaris_pid_to_str;
1600  /* On Solaris/x86, when debugging a threaded core file from process
1601     <n>, the following causes "info threads" to produce "procfs:
1602     couldn't find pid <n> in procinfo list" where <n> is the pid of
1603     the process that produced the core file.  Disable it for now. */
1604#if 0
1605  sol_core_ops.to_find_new_threads = sol_find_new_threads;
1606#endif
1607  sol_core_ops.to_magic = OPS_MAGIC;
1608}
1609
1610/* We suppress the call to add_target of core_ops in corelow because
1611   if there are two targets in the stratum core_stratum,
1612   find_core_target won't know which one to return.  See corelow.c for
1613   an additonal comment on coreops_suppress_target.  */
1614int coreops_suppress_target = 1;
1615
1616void
1617_initialize_sol_thread (void)
1618{
1619  void *dlhandle;
1620
1621  init_sol_thread_ops ();
1622  init_sol_core_ops ();
1623
1624  dlhandle = dlopen ("libthread_db.so.1", RTLD_NOW);
1625  if (!dlhandle)
1626    goto die;
1627
1628#define resolve(X) \
1629  if (!(p_##X = dlsym (dlhandle, #X))) \
1630    goto die;
1631
1632  resolve (td_log);
1633  resolve (td_ta_new);
1634  resolve (td_ta_delete);
1635  resolve (td_init);
1636  resolve (td_ta_get_ph);
1637  resolve (td_ta_get_nthreads);
1638  resolve (td_ta_tsd_iter);
1639  resolve (td_ta_thr_iter);
1640  resolve (td_thr_validate);
1641  resolve (td_thr_tsd);
1642  resolve (td_thr_get_info);
1643  resolve (td_thr_getfpregs);
1644  resolve (td_thr_getxregsize);
1645  resolve (td_thr_getxregs);
1646  resolve (td_thr_sigsetmask);
1647  resolve (td_thr_setprio);
1648  resolve (td_thr_setsigpending);
1649  resolve (td_thr_setfpregs);
1650  resolve (td_thr_setxregs);
1651  resolve (td_ta_map_id2thr);
1652  resolve (td_ta_map_lwp2thr);
1653  resolve (td_thr_getgregs);
1654  resolve (td_thr_setgregs);
1655
1656  add_target (&sol_thread_ops);
1657
1658  procfs_suppress_run = 1;
1659
1660  add_cmd ("sol-threads", class_maintenance, info_solthreads,
1661	   _("Show info on Solaris user threads."), &maintenanceinfolist);
1662
1663  memcpy (&orig_core_ops, &core_ops, sizeof (struct target_ops));
1664  memcpy (&core_ops, &sol_core_ops, sizeof (struct target_ops));
1665  add_target (&core_ops);
1666
1667  /* Hook into new_objfile notification.  */
1668  observer_attach_new_objfile (sol_thread_new_objfile);
1669  return;
1670
1671 die:
1672  fprintf_unfiltered (gdb_stderr, "\
1673[GDB will not be able to debug user-mode threads: %s]\n", dlerror ());
1674
1675  if (dlhandle)
1676    dlclose (dlhandle);
1677
1678  /* Allow the user to debug non-threaded core files.  */
1679  add_target (&core_ops);
1680
1681  return;
1682}
1683