OSDN Git Service

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