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