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