]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/gdb/gdb/sol-thread.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / gdb / gdb / sol-thread.c
1 /* Low level interface for debugging Solaris threads for GDB, the GNU debugger.
2    Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
3    Free Software Foundation, Inc.
4
5    This file is part of GDB.
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 59 Temple Place - Suite 330,
20    Boston, MA 02111-1307, USA.  */
21
22 /* This module implements a sort of half target that sits between the
23    machine-independent parts of GDB and the /proc interface (procfs.c) to
24    provide access to the Solaris user-mode thread implementation.
25
26    Solaris threads are true user-mode threads, which are invoked via the thr_*
27    and pthread_* (native and Posix respectivly) interfaces.  These are mostly
28    implemented in user-space, with all thread context kept in various
29    structures that live in the user's heap.  These should not be confused with
30    lightweight processes (LWPs), which are implemented by the kernel, and
31    scheduled without explicit intervention by the process.
32
33    Just to confuse things a little, Solaris threads (both native and Posix) are
34    actually implemented using LWPs.  In general, there are going to be more
35    threads than LWPs.  There is no fixed correspondence between a thread and an
36    LWP.  When a thread wants to run, it gets scheduled onto the first available
37    LWP and can therefore migrate from one LWP to another as time goes on.  A
38    sleeping thread may not be associated with an LWP at all!
39
40    To make it possible to mess with threads, Sun provides a library called
41    libthread_db.so.1 (not to be confused with libthread_db.so.0, which doesn't
42    have a published interface).  This interface has an upper part, which it
43    provides, and a lower part which I provide.  The upper part consists of the
44    td_* routines, which allow me to find all the threads, query their state,
45    etc...  The lower part consists of all of the ps_*, which are used by the
46    td_* routines to read/write memory, manipulate LWPs, lookup symbols, etc...
47    The ps_* routines actually do most of their work by calling functions in
48    procfs.c.  */
49
50 #include "defs.h"
51 #include <thread.h>
52 #include <proc_service.h>
53 #include <thread_db.h>
54 #include "gdbthread.h"
55 #include "target.h"
56 #include "inferior.h"
57 #include <fcntl.h>
58 #include "gdb_stat.h"
59 #include <dlfcn.h>
60 #include "gdbcmd.h"
61 #include "gdbcore.h"
62 #include "regcache.h"
63 #include "symfile.h"
64
65 #include "gdb_string.h"
66
67 extern struct target_ops sol_thread_ops;        /* Forward declaration */
68 extern struct target_ops sol_core_ops;  /* Forward declaration */
69
70 /* place to store core_ops before we overwrite it */
71 static struct target_ops orig_core_ops;
72
73 struct target_ops sol_thread_ops;
74 struct target_ops sol_core_ops;
75
76 extern int procfs_suppress_run;
77 extern struct target_ops procfs_ops;    /* target vector for procfs.c */
78 extern struct target_ops core_ops;      /* target vector for corelow.c */
79 extern char *procfs_pid_to_str (ptid_t ptid);
80
81 /* Prototypes for supply_gregset etc. */
82 #include "gregset.h"
83
84 /* This struct is defined by us, but mainly used for the proc_service interface.
85    We don't have much use for it, except as a handy place to get a real pid
86    for memory accesses.  */
87
88 struct ps_prochandle
89   {
90     ptid_t ptid;
91   };
92
93 struct string_map
94   {
95     int num;
96     char *str;
97   };
98
99 static struct ps_prochandle main_ph;
100 static td_thragent_t *main_ta;
101 static int sol_thread_active = 0;
102
103 static char *td_err_string (td_err_e errcode);
104 static char *td_state_string (td_thr_state_e statecode);
105 static ptid_t thread_to_lwp (ptid_t thread_id, int default_lwp);
106 static void sol_thread_resume (ptid_t ptid, int step, enum target_signal signo);
107 static ptid_t lwp_to_thread (ptid_t lwp);
108 static int sol_thread_alive (ptid_t ptid);
109 static void sol_core_close (int quitting);
110
111 static void init_sol_thread_ops (void);
112 static void init_sol_core_ops (void);
113
114 /* Default definitions: These must be defined in tm.h
115    if they are to be shared with a process module such as procfs.  */
116
117 #define GET_PID(ptid)           ptid_get_pid (ptid)
118 #define GET_LWP(ptid)           ptid_get_lwp (ptid)
119 #define GET_THREAD(ptid)        ptid_get_tid (ptid)
120
121 #define is_lwp(ptid)            (GET_LWP (ptid) != 0)
122 #define is_thread(ptid)         (GET_THREAD (ptid) != 0)
123
124 #define BUILD_LWP(lwp, pid)     ptid_build (pid, lwp, 0)
125 #define BUILD_THREAD(tid, pid)  ptid_build (pid, 0, tid)
126
127 /* Pointers to routines from lithread_db resolved by dlopen() */
128
129 static void     (*p_td_log)               (const int on_off);
130 static td_err_e (*p_td_ta_new)            (const struct ps_prochandle * ph_p,
131                                            td_thragent_t ** ta_pp);
132 static td_err_e (*p_td_ta_delete)         (td_thragent_t * ta_p);
133 static td_err_e (*p_td_init)              (void);
134 static td_err_e (*p_td_ta_get_ph)         (const td_thragent_t * ta_p,
135                                            struct ps_prochandle ** ph_pp);
136 static td_err_e (*p_td_ta_get_nthreads)   (const td_thragent_t * ta_p,
137                                            int *nthread_p);
138 static td_err_e (*p_td_ta_tsd_iter)       (const td_thragent_t * ta_p,
139                                            td_key_iter_f * cb,
140                                            void *cbdata_p);
141 static td_err_e (*p_td_ta_thr_iter)       (const td_thragent_t * ta_p,
142                                            td_thr_iter_f * cb,
143                                            void *cbdata_p,
144                                            td_thr_state_e state,
145                                            int ti_pri,
146                                            sigset_t * ti_sigmask_p,
147                                            unsigned ti_user_flags);
148 static td_err_e (*p_td_thr_validate)      (const td_thrhandle_t * th_p);
149 static td_err_e (*p_td_thr_tsd)           (const td_thrhandle_t * th_p,
150                                            const thread_key_t key,
151                                            void **data_pp);
152 static td_err_e (*p_td_thr_get_info)      (const td_thrhandle_t * th_p,
153                                            td_thrinfo_t * ti_p);
154 static td_err_e (*p_td_thr_getfpregs)     (const td_thrhandle_t * th_p,
155                                            prfpregset_t * fpregset);
156 static td_err_e (*p_td_thr_getxregsize)   (const td_thrhandle_t * th_p,
157                                            int *xregsize);
158 static td_err_e (*p_td_thr_getxregs)      (const td_thrhandle_t * th_p,
159                                            const caddr_t xregset);
160 static td_err_e (*p_td_thr_sigsetmask)    (const td_thrhandle_t * th_p,
161                                            const sigset_t ti_sigmask);
162 static td_err_e (*p_td_thr_setprio)       (const td_thrhandle_t * th_p,
163                                            const int ti_pri);
164 static td_err_e (*p_td_thr_setsigpending) (const td_thrhandle_t * th_p,
165                                            const uchar_t ti_pending_flag,
166                                            const sigset_t ti_pending);
167 static td_err_e (*p_td_thr_setfpregs)     (const td_thrhandle_t * th_p,
168                                            const prfpregset_t * fpregset);
169 static td_err_e (*p_td_thr_setxregs)      (const td_thrhandle_t * th_p,
170                                            const caddr_t xregset);
171 static td_err_e (*p_td_ta_map_id2thr)     (const td_thragent_t * ta_p,
172                                            thread_t tid,
173                                            td_thrhandle_t * th_p);
174 static td_err_e (*p_td_ta_map_lwp2thr)    (const td_thragent_t * ta_p,
175                                            lwpid_t lwpid,
176                                            td_thrhandle_t * th_p);
177 static td_err_e (*p_td_thr_getgregs)      (const td_thrhandle_t * th_p,
178                                            prgregset_t regset);
179 static td_err_e (*p_td_thr_setgregs)      (const td_thrhandle_t * th_p,
180                                            const prgregset_t regset);
181
182 /*
183
184    LOCAL FUNCTION
185
186    td_err_string - Convert a thread_db error code to a string
187
188    SYNOPSIS
189
190    char * td_err_string (errcode)
191
192    DESCRIPTION
193
194    Return the thread_db error string associated with errcode.  If errcode
195    is unknown, then return a message.
196
197  */
198
199 static char *
200 td_err_string (td_err_e errcode)
201 {
202   static struct string_map
203     td_err_table[] =
204   {
205     {TD_OK, "generic \"call succeeded\""},
206     {TD_ERR, "generic error."},
207     {TD_NOTHR, "no thread can be found to satisfy query"},
208     {TD_NOSV, "no synch. variable can be found to satisfy query"},
209     {TD_NOLWP, "no lwp can be found to satisfy query"},
210     {TD_BADPH, "invalid process handle"},
211     {TD_BADTH, "invalid thread handle"},
212     {TD_BADSH, "invalid synchronization handle"},
213     {TD_BADTA, "invalid thread agent"},
214     {TD_BADKEY, "invalid key"},
215     {TD_NOMSG, "td_thr_event_getmsg() called when there was no message"},
216     {TD_NOFPREGS, "FPU register set not available for given thread"},
217     {TD_NOLIBTHREAD, "application not linked with libthread"},
218     {TD_NOEVENT, "requested event is not supported"},
219     {TD_NOCAPAB, "capability not available"},
220     {TD_DBERR, "Debugger service failed"},
221     {TD_NOAPLIC, "Operation not applicable to"},
222     {TD_NOTSD, "No thread specific data for this thread"},
223     {TD_MALLOC, "Malloc failed"},
224     {TD_PARTIALREG, "Only part of register set was written/read"},
225     {TD_NOXREGS, "X register set not available for given thread"}
226   };
227   const int td_err_size = sizeof td_err_table / sizeof (struct string_map);
228   int i;
229   static char buf[50];
230
231   for (i = 0; i < td_err_size; i++)
232     if (td_err_table[i].num == errcode)
233       return td_err_table[i].str;
234
235   sprintf (buf, "Unknown thread_db error code: %d", errcode);
236
237   return buf;
238 }
239 \f
240 /*
241
242    LOCAL FUNCTION
243
244    td_state_string - Convert a thread_db state code to a string
245
246    SYNOPSIS
247
248    char * td_state_string (statecode)
249
250    DESCRIPTION
251
252    Return the thread_db state string associated with statecode.  If
253    statecode is unknown, then return a message.
254
255  */
256
257 static char *
258 td_state_string (td_thr_state_e statecode)
259 {
260   static struct string_map
261     td_thr_state_table[] =
262   {
263     {TD_THR_ANY_STATE, "any state"},
264     {TD_THR_UNKNOWN, "unknown"},
265     {TD_THR_STOPPED, "stopped"},
266     {TD_THR_RUN, "run"},
267     {TD_THR_ACTIVE, "active"},
268     {TD_THR_ZOMBIE, "zombie"},
269     {TD_THR_SLEEP, "sleep"},
270     {TD_THR_STOPPED_ASLEEP, "stopped asleep"}
271   };
272   const int td_thr_state_table_size = sizeof td_thr_state_table / sizeof (struct string_map);
273   int i;
274   static char buf[50];
275
276   for (i = 0; i < td_thr_state_table_size; i++)
277     if (td_thr_state_table[i].num == statecode)
278       return td_thr_state_table[i].str;
279
280   sprintf (buf, "Unknown thread_db state code: %d", statecode);
281
282   return buf;
283 }
284 \f
285 /*
286
287    LOCAL FUNCTION
288
289    thread_to_lwp - Convert a Posix or Solaris thread id to a LWP id.
290
291    SYNOPSIS
292
293    tpid_t thread_to_lwp (thread_id, default_lwp)
294
295    DESCRIPTION
296
297    This function converts a Posix or Solaris thread id to a lightweight
298    process id.  If thread_id is non-existent, that's an error.  If it's
299    an inactive thread, then we return default_lwp.
300
301    NOTES
302
303    This function probably shouldn't call error()...
304
305  */
306
307 static ptid_t
308 thread_to_lwp (ptid_t thread_id, int default_lwp)
309 {
310   td_thrinfo_t ti;
311   td_thrhandle_t th;
312   td_err_e val;
313
314   if (is_lwp (thread_id))
315     return thread_id;           /* It's already an LWP id */
316
317   /* It's a thread.  Convert to lwp */
318
319   val = p_td_ta_map_id2thr (main_ta, GET_THREAD (thread_id), &th);
320   if (val == TD_NOTHR)
321     return pid_to_ptid (-1);            /* thread must have terminated */
322   else if (val != TD_OK)
323     error ("thread_to_lwp: td_ta_map_id2thr %s", td_err_string (val));
324
325   val = p_td_thr_get_info (&th, &ti);
326   if (val == TD_NOTHR)
327     return pid_to_ptid (-1);            /* thread must have terminated */
328   else if (val != TD_OK)
329     error ("thread_to_lwp: td_thr_get_info: %s", td_err_string (val));
330
331   if (ti.ti_state != TD_THR_ACTIVE)
332     {
333       if (default_lwp != -1)
334         return pid_to_ptid (default_lwp);
335       error ("thread_to_lwp: thread state not active: %s",
336              td_state_string (ti.ti_state));
337     }
338
339   return BUILD_LWP (ti.ti_lid, PIDGET (thread_id));
340 }
341 \f
342 /*
343
344    LOCAL FUNCTION
345
346    lwp_to_thread - Convert a LWP id to a Posix or Solaris thread id.
347
348    SYNOPSIS
349
350    int lwp_to_thread (lwp_id)
351
352    DESCRIPTION
353
354    This function converts a lightweight process id to a Posix or Solaris
355    thread id.  If thread_id is non-existent, that's an error.
356
357    NOTES
358
359    This function probably shouldn't call error()...
360
361  */
362
363 static ptid_t
364 lwp_to_thread (ptid_t lwp)
365 {
366   td_thrinfo_t ti;
367   td_thrhandle_t th;
368   td_err_e val;
369
370   if (is_thread (lwp))
371     return lwp;                 /* It's already a thread id */
372
373   /* It's an lwp.  Convert it to a thread id.  */
374
375   if (!sol_thread_alive (lwp))
376     return pid_to_ptid (-1);    /* defunct lwp */
377
378   val = p_td_ta_map_lwp2thr (main_ta, GET_LWP (lwp), &th);
379   if (val == TD_NOTHR)
380     return pid_to_ptid (-1);    /* thread must have terminated */
381   else if (val != TD_OK)
382     error ("lwp_to_thread: td_ta_map_lwp2thr: %s.", td_err_string (val));
383
384   val = p_td_thr_validate (&th);
385   if (val == TD_NOTHR)
386     return lwp;                 /* libthread doesn't know about it;
387                                    just return lwp */
388   else if (val != TD_OK)
389     error ("lwp_to_thread: td_thr_validate: %s.", td_err_string (val));
390
391   val = p_td_thr_get_info (&th, &ti);
392   if (val == TD_NOTHR)
393     return pid_to_ptid (-1);    /* thread must have terminated */
394   else if (val != TD_OK)
395     error ("lwp_to_thread: td_thr_get_info: %s.", td_err_string (val));
396
397   return BUILD_THREAD (ti.ti_tid, PIDGET (lwp));
398 }
399 \f
400
401 /* Most target vector functions from here on actually just pass through to
402    procfs.c, as they don't need to do anything specific for threads.  */
403
404 static void
405 sol_thread_open (char *arg, int from_tty)
406 {
407   procfs_ops.to_open (arg, from_tty);
408 }
409
410 /* Attach to process PID, then initialize for debugging it
411    and wait for the trace-trap that results from attaching.  */
412
413 static void
414 sol_thread_attach (char *args, int from_tty)
415 {
416   procfs_ops.to_attach (args, from_tty);
417
418   /* Must get symbols from solibs before libthread_db can run! */
419   SOLIB_ADD ((char *) 0, from_tty, (struct target_ops *) 0, auto_solib_add);
420
421   if (sol_thread_active)
422     {
423       printf_filtered ("sol-thread active.\n");
424       main_ph.ptid = inferior_ptid;             /* Save for xfer_memory */
425       push_target (&sol_thread_ops);
426       inferior_ptid = lwp_to_thread (inferior_ptid);
427       if (PIDGET (inferior_ptid) == -1)
428         inferior_ptid = main_ph.ptid;
429       else
430         add_thread (inferior_ptid);
431     }
432   /* XXX - might want to iterate over all the threads and register them. */
433 }
434
435 /* Take a program previously attached to and detaches it.
436    The program resumes execution and will no longer stop
437    on signals, etc.  We'd better not have left any breakpoints
438    in the program or it'll die when it hits one.  For this
439    to work, it may be necessary for the process to have been
440    previously attached.  It *might* work if the program was
441    started via the normal ptrace (PTRACE_TRACEME).  */
442
443 static void
444 sol_thread_detach (char *args, int from_tty)
445 {
446   inferior_ptid = pid_to_ptid (PIDGET (main_ph.ptid));
447   unpush_target (&sol_thread_ops);
448   procfs_ops.to_detach (args, from_tty);
449 }
450
451 /* Resume execution of process PID.  If STEP is nozero, then
452    just single step it.  If SIGNAL is nonzero, restart it with that
453    signal activated.  We may have to convert pid from a thread-id to an LWP id
454    for procfs.  */
455
456 static void
457 sol_thread_resume (ptid_t ptid, int step, enum target_signal signo)
458 {
459   struct cleanup *old_chain;
460
461   old_chain = save_inferior_ptid ();
462
463   inferior_ptid = thread_to_lwp (inferior_ptid, PIDGET (main_ph.ptid));
464   if (PIDGET (inferior_ptid) == -1)
465     inferior_ptid = procfs_first_available ();
466
467   if (PIDGET (ptid) != -1)
468     {
469       ptid_t save_ptid = ptid;
470
471       ptid = thread_to_lwp (ptid, -2);
472       if (PIDGET (ptid) == -2)          /* Inactive thread */
473         error ("This version of Solaris can't start inactive threads.");
474       if (info_verbose && PIDGET (ptid) == -1)
475         warning ("Specified thread %ld seems to have terminated",
476                  GET_THREAD (save_ptid));
477     }
478
479   procfs_ops.to_resume (ptid, step, signo);
480
481   do_cleanups (old_chain);
482 }
483
484 /* Wait for any threads to stop.  We may have to convert PID from a thread id
485    to a LWP id, and vice versa on the way out.  */
486
487 static ptid_t
488 sol_thread_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
489 {
490   ptid_t rtnval;
491   ptid_t save_ptid;
492   struct cleanup *old_chain;
493
494   save_ptid = inferior_ptid;
495   old_chain = save_inferior_ptid ();
496
497   inferior_ptid = thread_to_lwp (inferior_ptid, PIDGET (main_ph.ptid));
498   if (PIDGET (inferior_ptid) == -1)
499     inferior_ptid = procfs_first_available ();
500
501   if (PIDGET (ptid) != -1)
502     {
503       ptid_t save_ptid = ptid;
504
505       ptid = thread_to_lwp (ptid, -2);
506       if (PIDGET (ptid) == -2)          /* Inactive thread */
507         error ("This version of Solaris can't start inactive threads.");
508       if (info_verbose && PIDGET (ptid) == -1)
509         warning ("Specified thread %ld seems to have terminated",
510                  GET_THREAD (save_ptid));
511     }
512
513   rtnval = procfs_ops.to_wait (ptid, ourstatus);
514
515   if (ourstatus->kind != TARGET_WAITKIND_EXITED)
516     {
517       /* Map the LWP of interest back to the appropriate thread ID */
518       rtnval = lwp_to_thread (rtnval);
519       if (PIDGET (rtnval) == -1)
520         rtnval = save_ptid;
521
522       /* See if we have a new thread */
523       if (is_thread (rtnval)
524           && !ptid_equal (rtnval, save_ptid)
525           && !in_thread_list (rtnval))
526         {
527           printf_filtered ("[New %s]\n", target_pid_to_str (rtnval));
528           add_thread (rtnval);
529         }
530     }
531
532   /* During process initialization, we may get here without the thread package
533      being initialized, since that can only happen after we've found the shared
534      libs.  */
535
536   do_cleanups (old_chain);
537
538   return rtnval;
539 }
540
541 static void
542 sol_thread_fetch_registers (int regno)
543 {
544   thread_t thread;
545   td_thrhandle_t thandle;
546   td_err_e val;
547   prgregset_t gregset;
548   prfpregset_t fpregset;
549 #if 0
550   int xregsize;
551   caddr_t xregset;
552 #endif
553
554   if (!is_thread (inferior_ptid))
555     {                           /* LWP: pass the request on to procfs.c */
556       if (target_has_execution)
557         procfs_ops.to_fetch_registers (regno);
558       else
559         orig_core_ops.to_fetch_registers (regno);
560       return;
561     }
562
563   /* Solaris thread: convert inferior_ptid into a td_thrhandle_t */
564
565   thread = GET_THREAD (inferior_ptid);
566
567   if (thread == 0)
568     error ("sol_thread_fetch_registers:  thread == 0");
569
570   val = p_td_ta_map_id2thr (main_ta, thread, &thandle);
571   if (val != TD_OK)
572     error ("sol_thread_fetch_registers: td_ta_map_id2thr: %s",
573            td_err_string (val));
574
575   /* Get the integer regs */
576
577   val = p_td_thr_getgregs (&thandle, gregset);
578   if (val != TD_OK
579       && val != TD_PARTIALREG)
580     error ("sol_thread_fetch_registers: td_thr_getgregs %s",
581            td_err_string (val));
582
583   /* For the sparc, TD_PARTIALREG means that only i0->i7, l0->l7, pc and sp
584      are saved (by a thread context switch).  */
585
586   /* And, now the fp regs */
587
588   val = p_td_thr_getfpregs (&thandle, &fpregset);
589   if (val != TD_OK
590       && val != TD_NOFPREGS)
591     error ("sol_thread_fetch_registers: td_thr_getfpregs %s",
592            td_err_string (val));
593
594 /* Note that we must call supply_{g fp}regset *after* calling the td routines
595    because the td routines call ps_lget* which affect the values stored in the
596    registers array.  */
597
598   supply_gregset  ((gdb_gregset_t *)  &gregset);
599   supply_fpregset ((gdb_fpregset_t *) &fpregset);
600
601 #if 0
602 /* thread_db doesn't seem to handle this right */
603   val = td_thr_getxregsize (&thandle, &xregsize);
604   if (val != TD_OK && val != TD_NOXREGS)
605     error ("sol_thread_fetch_registers: td_thr_getxregsize %s",
606            td_err_string (val));
607
608   if (val == TD_OK)
609     {
610       xregset = alloca (xregsize);
611       val = td_thr_getxregs (&thandle, xregset);
612       if (val != TD_OK)
613         error ("sol_thread_fetch_registers: td_thr_getxregs %s",
614                td_err_string (val));
615     }
616 #endif
617 }
618
619 static void
620 sol_thread_store_registers (int regno)
621 {
622   thread_t thread;
623   td_thrhandle_t thandle;
624   td_err_e val;
625   prgregset_t  gregset;
626   prfpregset_t fpregset;
627 #if 0
628   int xregsize;
629   caddr_t xregset;
630 #endif
631
632   if (!is_thread (inferior_ptid))
633     {                           /* LWP: pass the request on to procfs.c */
634       procfs_ops.to_store_registers (regno);
635       return;
636     }
637
638   /* Solaris thread: convert inferior_ptid into a td_thrhandle_t */
639
640   thread = GET_THREAD (inferior_ptid);
641
642   val = p_td_ta_map_id2thr (main_ta, thread, &thandle);
643   if (val != TD_OK)
644     error ("sol_thread_store_registers: td_ta_map_id2thr %s",
645            td_err_string (val));
646
647   if (regno != -1)
648     {                           /* Not writing all the regs */
649       char old_value[MAX_REGISTER_SIZE];
650
651       /* Save new register value.  */
652       regcache_collect (regno, old_value);
653
654       val = p_td_thr_getgregs (&thandle, gregset);
655       if (val != TD_OK)
656         error ("sol_thread_store_registers: td_thr_getgregs %s",
657                td_err_string (val));
658       val = p_td_thr_getfpregs (&thandle, &fpregset);
659       if (val != TD_OK)
660         error ("sol_thread_store_registers: td_thr_getfpregs %s",
661                td_err_string (val));
662
663       /* Restore new register value.  */
664       supply_register (regno, old_value);
665
666 #if 0
667 /* thread_db doesn't seem to handle this right */
668       val = td_thr_getxregsize (&thandle, &xregsize);
669       if (val != TD_OK && val != TD_NOXREGS)
670         error ("sol_thread_store_registers: td_thr_getxregsize %s",
671                td_err_string (val));
672
673       if (val == TD_OK)
674         {
675           xregset = alloca (xregsize);
676           val = td_thr_getxregs (&thandle, xregset);
677           if (val != TD_OK)
678             error ("sol_thread_store_registers: td_thr_getxregs %s",
679                    td_err_string (val));
680         }
681 #endif
682     }
683
684   fill_gregset  ((gdb_gregset_t *)  &gregset,  regno);
685   fill_fpregset ((gdb_fpregset_t *) &fpregset, regno);
686
687   val = p_td_thr_setgregs (&thandle, gregset);
688   if (val != TD_OK)
689     error ("sol_thread_store_registers: td_thr_setgregs %s",
690            td_err_string (val));
691   val = p_td_thr_setfpregs (&thandle, &fpregset);
692   if (val != TD_OK)
693     error ("sol_thread_store_registers: td_thr_setfpregs %s",
694            td_err_string (val));
695
696 #if 0
697 /* thread_db doesn't seem to handle this right */
698   val = td_thr_getxregsize (&thandle, &xregsize);
699   if (val != TD_OK && val != TD_NOXREGS)
700     error ("sol_thread_store_registers: td_thr_getxregsize %s",
701            td_err_string (val));
702
703   /* Should probably do something about writing the xregs here, but what are
704      they? */
705 #endif
706 }
707
708 /* Get ready to modify the registers array.  On machines which store
709    individual registers, this doesn't need to do anything.  On machines
710    which store all the registers in one fell swoop, this makes sure
711    that registers contains all the registers from the program being
712    debugged.  */
713
714 static void
715 sol_thread_prepare_to_store (void)
716 {
717   procfs_ops.to_prepare_to_store ();
718 }
719
720 /* Transfer LEN bytes between GDB address MYADDR and target address
721    MEMADDR.  If DOWRITE is non-zero, transfer them to the target,
722    otherwise transfer them from the target.  TARGET is unused.
723
724    Returns the number of bytes transferred. */
725
726 static int
727 sol_thread_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int dowrite,
728                         struct mem_attrib *attrib,
729                         struct target_ops *target)
730 {
731   int retval;
732   struct cleanup *old_chain;
733
734   old_chain = save_inferior_ptid ();
735
736   if (is_thread (inferior_ptid) ||      /* A thread */
737       !target_thread_alive (inferior_ptid))     /* An lwp, but not alive */
738     inferior_ptid = procfs_first_available ();  /* Find any live lwp.  */
739   /* Note: don't need to call switch_to_thread; we're just reading memory.  */
740
741   if (target_has_execution)
742     retval = procfs_ops.to_xfer_memory (memaddr, myaddr, len,
743                                         dowrite, attrib, target);
744   else
745     retval = orig_core_ops.to_xfer_memory (memaddr, myaddr, len,
746                                            dowrite, attrib, target);
747
748   do_cleanups (old_chain);
749
750   return retval;
751 }
752
753 /* Perform partial transfers on OBJECT.  See target_read_partial
754    and target_write_partial for details of each variant.  One, and
755    only one, of readbuf or writebuf must be non-NULL.  */
756
757 static LONGEST
758 sol_thread_xfer_partial (struct target_ops *ops, enum target_object object,
759                           const char *annex, void *readbuf,
760                           const void *writebuf, ULONGEST offset, LONGEST len)
761 {
762   int retval;
763   struct cleanup *old_chain;
764
765   old_chain = save_inferior_ptid ();
766
767   if (is_thread (inferior_ptid) ||      /* A thread */
768       !target_thread_alive (inferior_ptid))     /* An lwp, but not alive */
769     inferior_ptid = procfs_first_available ();  /* Find any live lwp.  */
770   /* Note: don't need to call switch_to_thread; we're just reading memory.  */
771
772   if (target_has_execution)
773     retval = procfs_ops.to_xfer_partial (ops, object, annex,
774                                          readbuf, writebuf, offset, len);
775   else
776     retval = orig_core_ops.to_xfer_partial (ops, object, annex,
777                                             readbuf, writebuf, offset, len);
778
779   do_cleanups (old_chain);
780
781   return retval;
782 }
783
784 /* Print status information about what we're accessing.  */
785
786 static void
787 sol_thread_files_info (struct target_ops *ignore)
788 {
789   procfs_ops.to_files_info (ignore);
790 }
791
792 static void
793 sol_thread_kill_inferior (void)
794 {
795   procfs_ops.to_kill ();
796 }
797
798 static void
799 sol_thread_notice_signals (ptid_t ptid)
800 {
801   procfs_ops.to_notice_signals (pid_to_ptid (PIDGET (ptid)));
802 }
803
804 /* Fork an inferior process, and start debugging it with /proc.  */
805
806 static void
807 sol_thread_create_inferior (char *exec_file, char *allargs, char **env)
808 {
809   procfs_ops.to_create_inferior (exec_file, allargs, env);
810
811   if (sol_thread_active && !ptid_equal (inferior_ptid, null_ptid))
812     {
813       main_ph.ptid = inferior_ptid;     /* Save for xfer_memory */
814
815       push_target (&sol_thread_ops);
816
817       inferior_ptid = lwp_to_thread (inferior_ptid);
818       if (PIDGET (inferior_ptid) == -1)
819         inferior_ptid = main_ph.ptid;
820
821       if (!in_thread_list (inferior_ptid))
822         add_thread (inferior_ptid);
823     }
824 }
825
826 /* This routine is called whenever a new symbol table is read in, or when all
827    symbol tables are removed.  libthread_db can only be initialized when it
828    finds the right variables in libthread.so.  Since it's a shared library,
829    those variables don't show up until the library gets mapped and the symbol
830    table is read in.  */
831
832 /* This new_objfile event is now managed by a chained function pointer.
833  * It is the callee's responsability to call the next client on the chain.
834  */
835
836 /* Saved pointer to previous owner of the new_objfile event. */
837 static void (*target_new_objfile_chain) (struct objfile *);
838
839 void
840 sol_thread_new_objfile (struct objfile *objfile)
841 {
842   td_err_e val;
843
844   if (!objfile)
845     {
846       sol_thread_active = 0;
847       goto quit;
848     }
849
850   /* don't do anything if init failed to resolve the libthread_db library */
851   if (!procfs_suppress_run)
852     goto quit;
853
854   /* Now, initialize the thread debugging library.  This needs to be done after
855      the shared libraries are located because it needs information from the
856      user's thread library.  */
857
858   val = p_td_init ();
859   if (val != TD_OK)
860     {
861       warning ("sol_thread_new_objfile: td_init: %s", td_err_string (val));
862       goto quit;
863     }
864
865   val = p_td_ta_new (&main_ph, &main_ta);
866   if (val == TD_NOLIBTHREAD)
867     goto quit;
868   else if (val != TD_OK)
869     {
870       warning ("sol_thread_new_objfile: td_ta_new: %s", td_err_string (val));
871       goto quit;
872     }
873
874   sol_thread_active = 1;
875 quit:
876   /* Call predecessor on chain, if any. */
877   if (target_new_objfile_chain)
878     target_new_objfile_chain (objfile);
879 }
880
881 /* Clean up after the inferior dies.  */
882
883 static void
884 sol_thread_mourn_inferior (void)
885 {
886   unpush_target (&sol_thread_ops);
887   procfs_ops.to_mourn_inferior ();
888 }
889
890 /* Mark our target-struct as eligible for stray "run" and "attach" commands.  */
891
892 static int
893 sol_thread_can_run (void)
894 {
895   return procfs_suppress_run;
896 }
897
898 /*
899
900    LOCAL FUNCTION
901
902    sol_thread_alive     - test thread for "aliveness"
903
904    SYNOPSIS
905
906    static bool sol_thread_alive (ptid_t ptid);
907
908    DESCRIPTION
909
910    returns true if thread still active in inferior.
911
912  */
913
914 static int
915 sol_thread_alive (ptid_t ptid)
916 {
917   if (is_thread (ptid))         /* non-kernel thread */
918     {
919       td_err_e val;
920       td_thrhandle_t th;
921       int pid;
922
923       pid = GET_THREAD (ptid);
924       if ((val = p_td_ta_map_id2thr (main_ta, pid, &th)) != TD_OK)
925         return 0;               /* thread not found */
926       if ((val = p_td_thr_validate (&th)) != TD_OK)
927         return 0;               /* thread not valid */
928       return 1;                 /* known thread: return true */
929     }
930   else
931     /* kernel thread (LWP): let procfs test it */
932     {
933       if (target_has_execution)
934         return procfs_ops.to_thread_alive (ptid);
935       else
936         return orig_core_ops.to_thread_alive (ptid);
937     }
938 }
939
940 static void
941 sol_thread_stop (void)
942 {
943   procfs_ops.to_stop ();
944 }
945 \f
946 /* These routines implement the lower half of the thread_db interface.  Ie: the
947    ps_* routines.  */
948
949 /* Various versions of <proc_service.h> have slightly
950    different function prototypes.  In particular, we have
951
952    NEWER                        OLDER
953    struct ps_prochandle *       const struct ps_prochandle *
954    void*                        char*
955    const void*          char*
956    int                  size_t
957
958    Which one you have depends on solaris version and what
959    patches you've applied.  On the theory that there are
960    only two major variants, we have configure check the
961    prototype of ps_pdwrite (), and use that info to make
962    appropriate typedefs here. */
963
964 #ifdef PROC_SERVICE_IS_OLD
965 typedef const struct ps_prochandle *gdb_ps_prochandle_t;
966 typedef char *gdb_ps_read_buf_t;
967 typedef char *gdb_ps_write_buf_t;
968 typedef int gdb_ps_size_t;
969 typedef paddr_t gdb_ps_addr_t;
970 #else
971 typedef struct ps_prochandle *gdb_ps_prochandle_t;
972 typedef void *gdb_ps_read_buf_t;
973 typedef const void *gdb_ps_write_buf_t;
974 typedef size_t gdb_ps_size_t;
975 typedef psaddr_t gdb_ps_addr_t;
976 #endif
977
978
979 /* The next four routines are called by thread_db to tell us to stop and stop
980    a particular process or lwp.  Since GDB ensures that these are all stopped
981    by the time we call anything in thread_db, these routines need to do
982    nothing.  */
983
984 /* Process stop */
985
986 ps_err_e
987 ps_pstop (gdb_ps_prochandle_t ph)
988 {
989   return PS_OK;
990 }
991
992 /* Process continue */
993
994 ps_err_e
995 ps_pcontinue (gdb_ps_prochandle_t ph)
996 {
997   return PS_OK;
998 }
999
1000 /* LWP stop */
1001
1002 ps_err_e
1003 ps_lstop (gdb_ps_prochandle_t ph, lwpid_t lwpid)
1004 {
1005   return PS_OK;
1006 }
1007
1008 /* LWP continue */
1009
1010 ps_err_e
1011 ps_lcontinue (gdb_ps_prochandle_t ph, lwpid_t lwpid)
1012 {
1013   return PS_OK;
1014 }
1015
1016 /* Looks up the symbol LD_SYMBOL_NAME in the debugger's symbol table.  */
1017
1018 ps_err_e
1019 ps_pglobal_lookup (gdb_ps_prochandle_t ph, const char *ld_object_name,
1020                    const char *ld_symbol_name, gdb_ps_addr_t * ld_symbol_addr)
1021 {
1022   struct minimal_symbol *ms;
1023
1024   ms = lookup_minimal_symbol (ld_symbol_name, NULL, NULL);
1025
1026   if (!ms)
1027     return PS_NOSYM;
1028
1029   *ld_symbol_addr = SYMBOL_VALUE_ADDRESS (ms);
1030
1031   return PS_OK;
1032 }
1033
1034 /* Common routine for reading and writing memory.  */
1035
1036 static ps_err_e
1037 rw_common (int dowrite, const struct ps_prochandle *ph, gdb_ps_addr_t addr,
1038            char *buf, int size)
1039 {
1040   struct cleanup *old_chain;
1041
1042   old_chain = save_inferior_ptid ();
1043
1044   if (is_thread (inferior_ptid) ||      /* A thread */
1045       !target_thread_alive (inferior_ptid))     /* An lwp, but not alive */
1046     inferior_ptid = procfs_first_available ();  /* Find any live lwp.  */
1047   /* Note: don't need to call switch_to_thread; we're just reading memory.  */
1048
1049 #if defined (__sparcv9)
1050   /* For Sparc64 cross Sparc32, make sure the address has not been
1051      accidentally sign-extended (or whatever) to beyond 32 bits.  */
1052   if (bfd_get_arch_size (exec_bfd) == 32)
1053     addr &= 0xffffffff;
1054 #endif
1055
1056   while (size > 0)
1057     {
1058       int cc;
1059
1060       /* FIXME: passing 0 as attrib argument.  */
1061       if (target_has_execution)
1062         cc = procfs_ops.to_xfer_memory (addr, buf, size,
1063                                         dowrite, 0, &procfs_ops);
1064       else
1065         cc = orig_core_ops.to_xfer_memory (addr, buf, size,
1066                                            dowrite, 0, &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_ptid ();
1147
1148   inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
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_ptid ();
1170
1171   inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
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_ptid ();
1279
1280   inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
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_ptid ();
1302
1303   inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
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 (ptid_t);
1346   struct ssd *ret;
1347
1348   /* FIXME: can't I get the process ID from the prochandle or something?
1349    */
1350
1351   if (PIDGET (inferior_ptid) <= 0 || lwpid <= 0)
1352     return PS_BADLID;
1353
1354   ret = procfs_find_LDT_entry (BUILD_LWP (lwpid, PIDGET (inferior_ptid)));
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 (ptid_t ptid)
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 (ptid);
1375
1376   if (is_thread (ptid))
1377     {
1378       ptid_t lwp;
1379
1380       lwp = thread_to_lwp (ptid, -2);
1381
1382       if (PIDGET (lwp) == -1)
1383         sprintf (buf, "Thread %ld (defunct)", GET_THREAD (ptid));
1384       else if (PIDGET (lwp) != -2)
1385         sprintf (buf, "Thread %ld (LWP %ld)", GET_THREAD (ptid), GET_LWP (lwp));
1386       else
1387         sprintf (buf, "Thread %ld        ", GET_THREAD (ptid));
1388     }
1389   else if (GET_LWP (ptid) != 0)
1390     sprintf (buf, "LWP    %ld        ", GET_LWP (ptid));
1391   else
1392     sprintf (buf, "process %d    ", PIDGET (ptid));
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   ptid_t ptid;
1408
1409   if ((retval = p_td_thr_get_info (th, &ti)) != TD_OK)
1410     {
1411       return -1;
1412     }
1413   ptid = BUILD_THREAD (ti.ti_tid, PIDGET (inferior_ptid));
1414   if (!in_thread_list (ptid))
1415     add_thread (ptid);
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 (PIDGET (inferior_ptid) == -1)
1428     {
1429       printf_filtered ("No process.\n");
1430       return;
1431     }
1432   procfs_ops.to_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", DEPRECATED_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", DEPRECATED_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 sol_find_memory_regions (int (*func) (CORE_ADDR,
1547                                       unsigned long,
1548                                       int, int, int,
1549                                       void *),
1550                          void *data)
1551 {
1552   return procfs_ops.to_find_memory_regions (func, data);
1553 }
1554
1555 static char *
1556 sol_make_note_section (bfd *obfd, int *note_size)
1557 {
1558   return procfs_ops.to_make_corefile_notes (obfd, note_size);
1559 }
1560
1561 static int
1562 ignore (CORE_ADDR addr, char *contents)
1563 {
1564   return 0;
1565 }
1566
1567
1568 static void
1569 init_sol_thread_ops (void)
1570 {
1571   sol_thread_ops.to_shortname = "solaris-threads";
1572   sol_thread_ops.to_longname = "Solaris threads and pthread.";
1573   sol_thread_ops.to_doc = "Solaris threads and pthread support.";
1574   sol_thread_ops.to_open = sol_thread_open;
1575   sol_thread_ops.to_attach = sol_thread_attach;
1576   sol_thread_ops.to_detach = sol_thread_detach;
1577   sol_thread_ops.to_resume = sol_thread_resume;
1578   sol_thread_ops.to_wait = sol_thread_wait;
1579   sol_thread_ops.to_fetch_registers = sol_thread_fetch_registers;
1580   sol_thread_ops.to_store_registers = sol_thread_store_registers;
1581   sol_thread_ops.to_prepare_to_store = sol_thread_prepare_to_store;
1582   sol_thread_ops.to_xfer_memory = sol_thread_xfer_memory;
1583   sol_thread_ops.to_xfer_partial = sol_thread_xfer_partial;
1584   sol_thread_ops.to_files_info = sol_thread_files_info;
1585   sol_thread_ops.to_insert_breakpoint = memory_insert_breakpoint;
1586   sol_thread_ops.to_remove_breakpoint = memory_remove_breakpoint;
1587   sol_thread_ops.to_terminal_init = terminal_init_inferior;
1588   sol_thread_ops.to_terminal_inferior = terminal_inferior;
1589   sol_thread_ops.to_terminal_ours_for_output = terminal_ours_for_output;
1590   sol_thread_ops.to_terminal_ours = terminal_ours;
1591   sol_thread_ops.to_terminal_save_ours = terminal_save_ours;
1592   sol_thread_ops.to_terminal_info = child_terminal_info;
1593   sol_thread_ops.to_kill = sol_thread_kill_inferior;
1594   sol_thread_ops.to_create_inferior = sol_thread_create_inferior;
1595   sol_thread_ops.to_mourn_inferior = sol_thread_mourn_inferior;
1596   sol_thread_ops.to_can_run = sol_thread_can_run;
1597   sol_thread_ops.to_notice_signals = sol_thread_notice_signals;
1598   sol_thread_ops.to_thread_alive = sol_thread_alive;
1599   sol_thread_ops.to_pid_to_str = solaris_pid_to_str;
1600   sol_thread_ops.to_find_new_threads = sol_find_new_threads;
1601   sol_thread_ops.to_stop = sol_thread_stop;
1602   sol_thread_ops.to_stratum = process_stratum;
1603   sol_thread_ops.to_has_all_memory = 1;
1604   sol_thread_ops.to_has_memory = 1;
1605   sol_thread_ops.to_has_stack = 1;
1606   sol_thread_ops.to_has_registers = 1;
1607   sol_thread_ops.to_has_execution = 1;
1608   sol_thread_ops.to_has_thread_control = tc_none;
1609   sol_thread_ops.to_find_memory_regions = sol_find_memory_regions;
1610   sol_thread_ops.to_make_corefile_notes = sol_make_note_section;
1611   sol_thread_ops.to_magic = OPS_MAGIC;
1612 }
1613
1614
1615 static void
1616 init_sol_core_ops (void)
1617 {
1618   sol_core_ops.to_shortname = "solaris-core";
1619   sol_core_ops.to_longname = "Solaris core threads and pthread.";
1620   sol_core_ops.to_doc = "Solaris threads and pthread support for core files.";
1621   sol_core_ops.to_open = sol_core_open;
1622   sol_core_ops.to_close = sol_core_close;
1623   sol_core_ops.to_attach = sol_thread_attach;
1624   sol_core_ops.to_detach = sol_core_detach;
1625   sol_core_ops.to_fetch_registers = sol_thread_fetch_registers;
1626   sol_core_ops.to_xfer_memory = sol_thread_xfer_memory;
1627   sol_core_ops.to_xfer_partial = sol_thread_xfer_partial;
1628   sol_core_ops.to_files_info = sol_core_files_info;
1629   sol_core_ops.to_insert_breakpoint = ignore;
1630   sol_core_ops.to_remove_breakpoint = ignore;
1631   sol_core_ops.to_create_inferior = sol_thread_create_inferior;
1632   sol_core_ops.to_stratum = core_stratum;
1633   sol_core_ops.to_has_memory = 1;
1634   sol_core_ops.to_has_stack = 1;
1635   sol_core_ops.to_has_registers = 1;
1636   sol_core_ops.to_has_thread_control = tc_none;
1637   sol_core_ops.to_thread_alive = sol_thread_alive;
1638   sol_core_ops.to_pid_to_str = solaris_pid_to_str;
1639   /* On Solaris/x86, when debugging a threaded core file from process <n>,
1640      the following causes "info threads" to produce "procfs: couldn't find pid
1641      <n> in procinfo list" where <n> is the pid of the process that produced
1642      the core file.  Disable it for now. */
1643   /* sol_core_ops.to_find_new_threads = sol_find_new_threads; */
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 }