OSDN Git Service

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