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