OSDN Git Service

* sol-thread.c (GET_LWP, GET_THREAD, BUILD_LWP, BUILD_THREAD):
[pf3gnuchains/pf3gnuchains4x.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)         TIDGET (PID)
130 #define BUILD_LWP(TID, PID)     MERGEPID (PID, TID)
131
132 #define BUILD_THREAD(TID, PID)  (MERGEPID (PID, TID) | THREAD_FLAG)
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, psaddr_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, psaddr_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, psaddr_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, psaddr_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, psaddr_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, psaddr_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   /* FIXME: can't I get the process ID from the prochandle or something?
1332    */
1333
1334   if (inferior_pid <= 0 || lwpid <= 0)
1335     return PS_BADLID;
1336
1337   ret = procfs_find_LDT_entry (BUILD_LWP (lwpid, PIDGET (inferior_pid)));
1338   if (ret)
1339     {
1340       memcpy (pldt, ret, sizeof (struct ssd));
1341       return PS_OK;
1342     }
1343   else  /* LDT not found. */
1344     return PS_ERR;
1345 }
1346 #endif /* TM_I386SOL2_H */
1347 \f
1348 /* Convert a pid to printable form. */
1349
1350 char *
1351 solaris_pid_to_str (pid)
1352      int pid;
1353 {
1354   static char buf[100];
1355
1356   /* in case init failed to resolve the libthread_db library */
1357   if (!procfs_suppress_run)
1358     return procfs_pid_to_str (pid);
1359
1360   if (is_thread (pid))
1361     {
1362       int lwp;
1363
1364       lwp = thread_to_lwp (pid, -2);
1365
1366       if (lwp == -1)
1367         sprintf (buf, "Thread %d (defunct)", GET_THREAD (pid));
1368       else if (lwp != -2)
1369         sprintf (buf, "Thread %d (LWP %d)", GET_THREAD (pid), GET_LWP (lwp));
1370       else
1371         sprintf (buf, "Thread %d        ", GET_THREAD (pid));
1372     }
1373   else if (GET_LWP (pid) != 0)
1374     sprintf (buf, "LWP    %d        ", GET_LWP (pid));
1375   else
1376     sprintf (buf, "process %d    ", PIDGET (pid));
1377
1378   return buf;
1379 }
1380 \f
1381
1382 /* Worker bee for find_new_threads
1383    Callback function that gets called once per USER thread (i.e., not
1384    kernel) thread. */
1385
1386 static int
1387 sol_find_new_threads_callback (th, ignored)
1388      const td_thrhandle_t *th;
1389      void *ignored;
1390 {
1391   td_err_e retval;
1392   td_thrinfo_t ti;
1393   int pid;
1394
1395   if ((retval = p_td_thr_get_info (th, &ti)) != TD_OK)
1396     {
1397       return -1;
1398     }
1399   pid = BUILD_THREAD (ti.ti_tid, PIDGET (inferior_pid));
1400   if (!in_thread_list (pid))
1401     add_thread (pid);
1402
1403   return 0;
1404 }
1405
1406 static void
1407 sol_find_new_threads ()
1408 {
1409   /* don't do anything if init failed to resolve the libthread_db library */
1410   if (!procfs_suppress_run)
1411     return;
1412
1413   if (inferior_pid == -1)
1414     {
1415       printf_filtered ("No process.\n");
1416       return;
1417     }
1418   procfs_find_new_threads ();   /* first find new kernel threads. */
1419   p_td_ta_thr_iter (main_ta, sol_find_new_threads_callback, (void *) 0,
1420                     TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
1421                     TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
1422 }
1423
1424 static void
1425 sol_core_open (filename, from_tty)
1426      char *filename;
1427      int from_tty;
1428 {
1429   orig_core_ops.to_open (filename, from_tty);
1430 }
1431
1432 static void
1433 sol_core_close (quitting)
1434      int quitting;
1435 {
1436   orig_core_ops.to_close (quitting);
1437 }
1438
1439 static void
1440 sol_core_detach (args, from_tty)
1441      char *args;
1442      int from_tty;
1443 {
1444   unpush_target (&core_ops);
1445   orig_core_ops.to_detach (args, from_tty);
1446 }
1447
1448 static void
1449 sol_core_files_info (t)
1450      struct target_ops *t;
1451 {
1452   orig_core_ops.to_files_info (t);
1453 }
1454
1455 /* Worker bee for info sol-thread command.  This is a callback function that
1456    gets called once for each Solaris thread (ie. not kernel thread) in the 
1457    inferior.  Print anything interesting that we can think of.  */
1458
1459 static int
1460 info_cb (th, s)
1461      const td_thrhandle_t *th;
1462      void *s;
1463 {
1464   td_err_e ret;
1465   td_thrinfo_t ti;
1466
1467   if ((ret = p_td_thr_get_info (th, &ti)) == TD_OK)
1468     {
1469       printf_filtered ("%s thread #%d, lwp %d, ",
1470                        ti.ti_type == TD_THR_SYSTEM ? "system" : "user  ",
1471                        ti.ti_tid, ti.ti_lid);
1472       switch (ti.ti_state)
1473         {
1474         default:
1475         case TD_THR_UNKNOWN:
1476           printf_filtered ("<unknown state>");
1477           break;
1478         case TD_THR_STOPPED:
1479           printf_filtered ("(stopped)");
1480           break;
1481         case TD_THR_RUN:
1482           printf_filtered ("(run)    ");
1483           break;
1484         case TD_THR_ACTIVE:
1485           printf_filtered ("(active) ");
1486           break;
1487         case TD_THR_ZOMBIE:
1488           printf_filtered ("(zombie) ");
1489           break;
1490         case TD_THR_SLEEP:
1491           printf_filtered ("(asleep) ");
1492           break;
1493         case TD_THR_STOPPED_ASLEEP:
1494           printf_filtered ("(stopped asleep)");
1495           break;
1496         }
1497       /* Print thr_create start function: */
1498       if (ti.ti_startfunc != 0)
1499         {
1500           struct minimal_symbol *msym;
1501           msym = lookup_minimal_symbol_by_pc (ti.ti_startfunc);
1502           if (msym)
1503             printf_filtered ("   startfunc: %s\n", SYMBOL_NAME (msym));
1504           else
1505             printf_filtered ("   startfunc: 0x%s\n", paddr (ti.ti_startfunc));
1506         }
1507
1508       /* If thread is asleep, print function that went to sleep: */
1509       if (ti.ti_state == TD_THR_SLEEP)
1510         {
1511           struct minimal_symbol *msym;
1512           msym = lookup_minimal_symbol_by_pc (ti.ti_pc);
1513           if (msym)
1514             printf_filtered (" - Sleep func: %s\n", SYMBOL_NAME (msym));
1515           else
1516             printf_filtered (" - Sleep func: 0x%s\n", paddr (ti.ti_startfunc));
1517         }
1518
1519       /* Wrap up line, if necessary */
1520       if (ti.ti_state != TD_THR_SLEEP && ti.ti_startfunc == 0)
1521         printf_filtered ("\n"); /* don't you hate counting newlines? */
1522     }
1523   else
1524     warning ("info sol-thread: failed to get info for thread.");
1525
1526   return 0;
1527 }
1528
1529 /* List some state about each Solaris user thread in the inferior.  */
1530
1531 static void
1532 info_solthreads (args, from_tty)
1533      char *args;
1534      int from_tty;
1535 {
1536   p_td_ta_thr_iter (main_ta, info_cb, args,
1537                     TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
1538                     TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
1539 }
1540
1541 static int
1542 ignore (addr, contents)
1543      CORE_ADDR addr;
1544      char *contents;
1545 {
1546   return 0;
1547 }
1548
1549
1550 static void
1551 init_sol_thread_ops ()
1552 {
1553   sol_thread_ops.to_shortname = "solaris-threads";
1554   sol_thread_ops.to_longname = "Solaris threads and pthread.";
1555   sol_thread_ops.to_doc = "Solaris threads and pthread support.";
1556   sol_thread_ops.to_open = sol_thread_open;
1557   sol_thread_ops.to_close = 0;
1558   sol_thread_ops.to_attach = sol_thread_attach;
1559   sol_thread_ops.to_detach = sol_thread_detach;
1560   sol_thread_ops.to_resume = sol_thread_resume;
1561   sol_thread_ops.to_wait = sol_thread_wait;
1562   sol_thread_ops.to_fetch_registers = sol_thread_fetch_registers;
1563   sol_thread_ops.to_store_registers = sol_thread_store_registers;
1564   sol_thread_ops.to_prepare_to_store = sol_thread_prepare_to_store;
1565   sol_thread_ops.to_xfer_memory = sol_thread_xfer_memory;
1566   sol_thread_ops.to_files_info = sol_thread_files_info;
1567   sol_thread_ops.to_insert_breakpoint = memory_insert_breakpoint;
1568   sol_thread_ops.to_remove_breakpoint = memory_remove_breakpoint;
1569   sol_thread_ops.to_terminal_init = terminal_init_inferior;
1570   sol_thread_ops.to_terminal_inferior = terminal_inferior;
1571   sol_thread_ops.to_terminal_ours_for_output = terminal_ours_for_output;
1572   sol_thread_ops.to_terminal_ours = terminal_ours;
1573   sol_thread_ops.to_terminal_info = child_terminal_info;
1574   sol_thread_ops.to_kill = sol_thread_kill_inferior;
1575   sol_thread_ops.to_load = 0;
1576   sol_thread_ops.to_lookup_symbol = 0;
1577   sol_thread_ops.to_create_inferior = sol_thread_create_inferior;
1578   sol_thread_ops.to_mourn_inferior = sol_thread_mourn_inferior;
1579   sol_thread_ops.to_can_run = sol_thread_can_run;
1580   sol_thread_ops.to_notice_signals = sol_thread_notice_signals;
1581   sol_thread_ops.to_thread_alive = sol_thread_alive;
1582   sol_thread_ops.to_pid_to_str = solaris_pid_to_str;
1583   sol_thread_ops.to_find_new_threads = sol_find_new_threads;
1584   sol_thread_ops.to_stop = sol_thread_stop;
1585   sol_thread_ops.to_stratum = process_stratum;
1586   sol_thread_ops.to_has_all_memory = 1;
1587   sol_thread_ops.to_has_memory = 1;
1588   sol_thread_ops.to_has_stack = 1;
1589   sol_thread_ops.to_has_registers = 1;
1590   sol_thread_ops.to_has_execution = 1;
1591   sol_thread_ops.to_has_thread_control = tc_none;
1592   sol_thread_ops.to_sections = 0;
1593   sol_thread_ops.to_sections_end = 0;
1594   sol_thread_ops.to_magic = OPS_MAGIC;
1595 }
1596
1597
1598 static void
1599 init_sol_core_ops ()
1600 {
1601   sol_core_ops.to_shortname = "solaris-core";
1602   sol_core_ops.to_longname = "Solaris core threads and pthread.";
1603   sol_core_ops.to_doc = "Solaris threads and pthread support for core files.";
1604   sol_core_ops.to_open = sol_core_open;
1605   sol_core_ops.to_close = sol_core_close;
1606   sol_core_ops.to_attach = sol_thread_attach;
1607   sol_core_ops.to_detach = sol_core_detach;
1608   /* sol_core_ops.to_resume  = 0; */
1609   /* sol_core_ops.to_wait  = 0;  */
1610   sol_core_ops.to_fetch_registers = sol_thread_fetch_registers;
1611   /* sol_core_ops.to_store_registers  = 0; */
1612   /* sol_core_ops.to_prepare_to_store  = 0; */
1613   sol_core_ops.to_xfer_memory = sol_thread_xfer_memory;
1614   sol_core_ops.to_files_info = sol_core_files_info;
1615   sol_core_ops.to_insert_breakpoint = ignore;
1616   sol_core_ops.to_remove_breakpoint = ignore;
1617   /* sol_core_ops.to_terminal_init  = 0; */
1618   /* sol_core_ops.to_terminal_inferior  = 0; */
1619   /* sol_core_ops.to_terminal_ours_for_output  = 0; */
1620   /* sol_core_ops.to_terminal_ours  = 0; */
1621   /* sol_core_ops.to_terminal_info  = 0; */
1622   /* sol_core_ops.to_kill  = 0; */
1623   /* sol_core_ops.to_load  = 0; */
1624   /* sol_core_ops.to_lookup_symbol  = 0; */
1625   sol_core_ops.to_create_inferior = sol_thread_create_inferior;
1626   sol_core_ops.to_stratum = core_stratum;
1627   sol_core_ops.to_has_all_memory = 0;
1628   sol_core_ops.to_has_memory = 1;
1629   sol_core_ops.to_has_stack = 1;
1630   sol_core_ops.to_has_registers = 1;
1631   sol_core_ops.to_has_execution = 0;
1632   sol_core_ops.to_has_thread_control = tc_none;
1633   sol_core_ops.to_pid_to_str = solaris_pid_to_str;
1634   sol_core_ops.to_sections = 0;
1635   sol_core_ops.to_sections_end = 0;
1636   sol_core_ops.to_magic = OPS_MAGIC;
1637 }
1638
1639 /* we suppress the call to add_target of core_ops in corelow because
1640    if there are two targets in the stratum core_stratum, find_core_target
1641    won't know which one to return.  see corelow.c for an additonal
1642    comment on coreops_suppress_target. */
1643 int coreops_suppress_target = 1;
1644
1645 void
1646 _initialize_sol_thread ()
1647 {
1648   void *dlhandle;
1649
1650   init_sol_thread_ops ();
1651   init_sol_core_ops ();
1652
1653   dlhandle = dlopen ("libthread_db.so.1", RTLD_NOW);
1654   if (!dlhandle)
1655     goto die;
1656
1657 #define resolve(X) \
1658   if (!(p_##X = dlsym (dlhandle, #X))) \
1659     goto die;
1660
1661   resolve (td_log);
1662   resolve (td_ta_new);
1663   resolve (td_ta_delete);
1664   resolve (td_init);
1665   resolve (td_ta_get_ph);
1666   resolve (td_ta_get_nthreads);
1667   resolve (td_ta_tsd_iter);
1668   resolve (td_ta_thr_iter);
1669   resolve (td_thr_validate);
1670   resolve (td_thr_tsd);
1671   resolve (td_thr_get_info);
1672   resolve (td_thr_getfpregs);
1673   resolve (td_thr_getxregsize);
1674   resolve (td_thr_getxregs);
1675   resolve (td_thr_sigsetmask);
1676   resolve (td_thr_setprio);
1677   resolve (td_thr_setsigpending);
1678   resolve (td_thr_setfpregs);
1679   resolve (td_thr_setxregs);
1680   resolve (td_ta_map_id2thr);
1681   resolve (td_ta_map_lwp2thr);
1682   resolve (td_thr_getgregs);
1683   resolve (td_thr_setgregs);
1684
1685   add_target (&sol_thread_ops);
1686
1687   procfs_suppress_run = 1;
1688
1689   add_cmd ("sol-threads", class_maintenance, info_solthreads,
1690            "Show info on Solaris user threads.\n", &maintenanceinfolist);
1691
1692   memcpy (&orig_core_ops, &core_ops, sizeof (struct target_ops));
1693   memcpy (&core_ops, &sol_core_ops, sizeof (struct target_ops));
1694   add_target (&core_ops);
1695
1696   /* Hook into new_objfile notification. */
1697   target_new_objfile_chain = target_new_objfile_hook;
1698   target_new_objfile_hook  = sol_thread_new_objfile;
1699   return;
1700
1701 die:
1702
1703   fprintf_unfiltered (gdb_stderr, "[GDB will not be able to debug user-mode threads: %s]\n", dlerror ());
1704
1705   if (dlhandle)
1706     dlclose (dlhandle);
1707
1708   /* allow the user to debug non-threaded core files */
1709   add_target (&core_ops);
1710
1711   return;
1712 }