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