* sol-thread.c: Replace use of TM_I386SOL2_H by an expression
[external/binutils.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_LPW.
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 (char *args, int from_tty)
352 {
353   procfs_ops.to_attach (args, from_tty);
354
355   /* Must get symbols from shared libraries before libthread_db can run!  */
356   solib_add (NULL, from_tty, (struct target_ops *) 0, auto_solib_add);
357
358   if (sol_thread_active)
359     {
360       printf_filtered ("sol-thread active.\n");
361       main_ph.ptid = inferior_ptid; /* Save for xfer_memory.  */
362       push_target (&sol_thread_ops);
363       inferior_ptid = lwp_to_thread (inferior_ptid);
364       if (PIDGET (inferior_ptid) == -1)
365         inferior_ptid = main_ph.ptid;
366       else
367         add_thread (inferior_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 (char *args, int from_tty)
383 {
384   inferior_ptid = pid_to_ptid (PIDGET (main_ph.ptid));
385   unpush_target (&sol_thread_ops);
386   procfs_ops.to_detach (args, from_tty);
387 }
388
389 /* Resume execution of process PTID.  If STEP is nozero, then just
390    single step it.  If SIGNAL is nonzero, restart it with that signal
391    activated.  We may have to convert PTID from a thread ID to an LWP
392    ID for procfs.  */
393
394 static void
395 sol_thread_resume (ptid_t ptid, int step, enum target_signal signo)
396 {
397   struct cleanup *old_chain;
398
399   old_chain = save_inferior_ptid ();
400
401   inferior_ptid = thread_to_lwp (inferior_ptid, PIDGET (main_ph.ptid));
402   if (PIDGET (inferior_ptid) == -1)
403     inferior_ptid = procfs_first_available ();
404
405   if (PIDGET (ptid) != -1)
406     {
407       ptid_t save_ptid = ptid;
408
409       ptid = thread_to_lwp (ptid, -2);
410       if (PIDGET (ptid) == -2)          /* Inactive thread.  */
411         error (_("This version of Solaris can't start inactive threads."));
412       if (info_verbose && PIDGET (ptid) == -1)
413         warning (_("Specified thread %ld seems to have terminated"),
414                  GET_THREAD (save_ptid));
415     }
416
417   procfs_ops.to_resume (ptid, step, signo);
418
419   do_cleanups (old_chain);
420 }
421
422 /* Wait for any threads to stop.  We may have to convert PIID from a
423    thread ID to an LWP ID, and vice versa on the way out.  */
424
425 static ptid_t
426 sol_thread_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
427 {
428   ptid_t rtnval;
429   ptid_t save_ptid;
430   struct cleanup *old_chain;
431
432   save_ptid = inferior_ptid;
433   old_chain = save_inferior_ptid ();
434
435   inferior_ptid = thread_to_lwp (inferior_ptid, PIDGET (main_ph.ptid));
436   if (PIDGET (inferior_ptid) == -1)
437     inferior_ptid = procfs_first_available ();
438
439   if (PIDGET (ptid) != -1)
440     {
441       ptid_t save_ptid = ptid;
442
443       ptid = thread_to_lwp (ptid, -2);
444       if (PIDGET (ptid) == -2)          /* Inactive thread.  */
445         error (_("This version of Solaris can't start inactive threads."));
446       if (info_verbose && PIDGET (ptid) == -1)
447         warning (_("Specified thread %ld seems to have terminated"),
448                  GET_THREAD (save_ptid));
449     }
450
451   rtnval = procfs_ops.to_wait (ptid, ourstatus);
452
453   if (ourstatus->kind != TARGET_WAITKIND_EXITED)
454     {
455       /* Map the LWP of interest back to the appropriate thread ID.  */
456       rtnval = lwp_to_thread (rtnval);
457       if (PIDGET (rtnval) == -1)
458         rtnval = save_ptid;
459
460       /* See if we have a new thread.  */
461       if (is_thread (rtnval)
462           && !ptid_equal (rtnval, save_ptid)
463           && !in_thread_list (rtnval))
464         add_thread (rtnval);
465     }
466
467   /* During process initialization, we may get here without the thread
468      package being initialized, since that can only happen after we've
469      found the shared libs.  */
470
471   do_cleanups (old_chain);
472
473   return rtnval;
474 }
475
476 static void
477 sol_thread_fetch_registers (struct regcache *regcache, int regnum)
478 {
479   thread_t thread;
480   td_thrhandle_t thandle;
481   td_err_e val;
482   prgregset_t gregset;
483   prfpregset_t fpregset;
484   gdb_gregset_t *gregset_p = &gregset;
485   gdb_fpregset_t *fpregset_p = &fpregset;
486
487 #if 0
488   int xregsize;
489   caddr_t xregset;
490 #endif
491
492   if (!is_thread (inferior_ptid))
493     {
494       /* It's an LWP; pass the request on to procfs.  */
495       if (target_has_execution)
496         procfs_ops.to_fetch_registers (regcache, regnum);
497       else
498         orig_core_ops.to_fetch_registers (regcache, regnum);
499       return;
500     }
501
502   /* Solaris thread: convert INFERIOR_PTID into a td_thrhandle_t.  */
503   thread = GET_THREAD (inferior_ptid);
504   if (thread == 0)
505     error (_("sol_thread_fetch_registers: thread == 0"));
506
507   val = p_td_ta_map_id2thr (main_ta, thread, &thandle);
508   if (val != TD_OK)
509     error (_("sol_thread_fetch_registers: td_ta_map_id2thr: %s"),
510            td_err_string (val));
511
512   /* Get the general-purpose registers.  */
513
514   val = p_td_thr_getgregs (&thandle, gregset);
515   if (val != TD_OK && val != TD_PARTIALREG)
516     error (_("sol_thread_fetch_registers: td_thr_getgregs %s"),
517            td_err_string (val));
518
519   /* For SPARC, TD_PARTIALREG means that only %i0...%i7, %l0..%l7, %pc
520      and %sp are saved (by a thread context switch).  */
521
522   /* And, now the floating-point registers.  */
523
524   val = p_td_thr_getfpregs (&thandle, &fpregset);
525   if (val != TD_OK && val != TD_NOFPREGS)
526     error (_("sol_thread_fetch_registers: td_thr_getfpregs %s"),
527            td_err_string (val));
528
529   /* Note that we must call supply_gregset and supply_fpregset *after*
530      calling the td routines because the td routines call ps_lget*
531      which affect the values stored in the registers array.  */
532
533   supply_gregset (regcache, (const gdb_gregset_t *) gregset_p);
534   supply_fpregset (regcache, (const gdb_fpregset_t *) fpregset_p);
535
536 #if 0
537   /* FIXME: libthread_db doesn't seem to handle this right.  */
538   val = td_thr_getxregsize (&thandle, &xregsize);
539   if (val != TD_OK && val != TD_NOXREGS)
540     error (_("sol_thread_fetch_registers: td_thr_getxregsize %s"),
541            td_err_string (val));
542
543   if (val == TD_OK)
544     {
545       xregset = alloca (xregsize);
546       val = td_thr_getxregs (&thandle, xregset);
547       if (val != TD_OK)
548         error (_("sol_thread_fetch_registers: td_thr_getxregs %s"),
549                td_err_string (val));
550     }
551 #endif
552 }
553
554 static void
555 sol_thread_store_registers (struct regcache *regcache, int regnum)
556 {
557   thread_t thread;
558   td_thrhandle_t thandle;
559   td_err_e val;
560   prgregset_t gregset;
561   prfpregset_t fpregset;
562 #if 0
563   int xregsize;
564   caddr_t xregset;
565 #endif
566
567   if (!is_thread (inferior_ptid))
568     {
569       /* It's an LWP; pass the request on to procfs.c.  */
570       procfs_ops.to_store_registers (regcache, regnum);
571       return;
572     }
573
574   /* Solaris thread: convert INFERIOR_PTID into a td_thrhandle_t.  */
575   thread = GET_THREAD (inferior_ptid);
576
577   val = p_td_ta_map_id2thr (main_ta, thread, &thandle);
578   if (val != TD_OK)
579     error (_("sol_thread_store_registers: td_ta_map_id2thr %s"),
580            td_err_string (val));
581
582   if (regnum != -1)
583     {
584       /* Not writing all the registers.  */
585       char old_value[MAX_REGISTER_SIZE];
586
587       /* Save new register value.  */
588       regcache_raw_collect (regcache, regnum, old_value);
589
590       val = p_td_thr_getgregs (&thandle, gregset);
591       if (val != TD_OK)
592         error (_("sol_thread_store_registers: td_thr_getgregs %s"),
593                td_err_string (val));
594       val = p_td_thr_getfpregs (&thandle, &fpregset);
595       if (val != TD_OK)
596         error (_("sol_thread_store_registers: td_thr_getfpregs %s"),
597                td_err_string (val));
598
599       /* Restore new register value.  */
600       regcache_raw_supply (regcache, regnum, old_value);
601
602 #if 0
603       /* FIXME: libthread_db doesn't seem to handle this right.  */
604       val = td_thr_getxregsize (&thandle, &xregsize);
605       if (val != TD_OK && val != TD_NOXREGS)
606         error (_("sol_thread_store_registers: td_thr_getxregsize %s"),
607                td_err_string (val));
608
609       if (val == TD_OK)
610         {
611           xregset = alloca (xregsize);
612           val = td_thr_getxregs (&thandle, xregset);
613           if (val != TD_OK)
614             error (_("sol_thread_store_registers: td_thr_getxregs %s"),
615                    td_err_string (val));
616         }
617 #endif
618     }
619
620   fill_gregset (regcache, (gdb_gregset_t *) &gregset, regnum);
621   fill_fpregset (regcache, (gdb_fpregset_t *) &fpregset, regnum);
622
623   val = p_td_thr_setgregs (&thandle, gregset);
624   if (val != TD_OK)
625     error (_("sol_thread_store_registers: td_thr_setgregs %s"),
626            td_err_string (val));
627   val = p_td_thr_setfpregs (&thandle, &fpregset);
628   if (val != TD_OK)
629     error (_("sol_thread_store_registers: td_thr_setfpregs %s"),
630            td_err_string (val));
631
632 #if 0
633   /* FIXME: libthread_db doesn't seem to handle this right.  */
634   val = td_thr_getxregsize (&thandle, &xregsize);
635   if (val != TD_OK && val != TD_NOXREGS)
636     error (_("sol_thread_store_registers: td_thr_getxregsize %s"),
637            td_err_string (val));
638
639   /* ??? Should probably do something about writing the xregs here,
640      but what are they?  */
641 #endif
642 }
643
644 /* Get ready to modify the registers array.  On machines which store
645    individual registers, this doesn't need to do anything.  On
646    machines which store all the registers in one fell swoop, this
647    makes sure that registers contains all the registers from the
648    program being debugged.  */
649
650 static void
651 sol_thread_prepare_to_store (struct regcache *regcache)
652 {
653   procfs_ops.to_prepare_to_store (regcache);
654 }
655
656 /* Transfer LEN bytes between GDB address MYADDR and target address
657    MEMADDR.  If DOWRITE is non-zero, transfer them to the target,
658    otherwise transfer them from the target.  TARGET is unused.
659
660    Returns the number of bytes transferred.  */
661
662 static int
663 sol_thread_xfer_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len,
664                         int dowrite, struct mem_attrib *attrib,
665                         struct target_ops *target)
666 {
667   int retval;
668   struct cleanup *old_chain;
669
670   old_chain = save_inferior_ptid ();
671
672   if (is_thread (inferior_ptid) || !target_thread_alive (inferior_ptid))
673     {
674       /* It's either a thread or an LWP that isn't alive.  Any live
675          LWP will do so use the first available.
676
677          NOTE: We don't need to call switch_to_thread; we're just
678          reading memory.  */
679       inferior_ptid = procfs_first_available ();
680     }
681
682   if (target_has_execution)
683     retval = procfs_ops.deprecated_xfer_memory (memaddr, myaddr, len,
684                                                 dowrite, attrib, target);
685   else
686     retval = orig_core_ops.deprecated_xfer_memory (memaddr, myaddr, len,
687                                                    dowrite, attrib, target);
688
689   do_cleanups (old_chain);
690
691   return retval;
692 }
693
694 /* Perform partial transfers on OBJECT.  See target_read_partial and
695    target_write_partial for details of each variant.  One, and only
696    one, of readbuf or writebuf must be non-NULL.  */
697
698 static LONGEST
699 sol_thread_xfer_partial (struct target_ops *ops, enum target_object object,
700                           const char *annex, gdb_byte *readbuf,
701                           const gdb_byte *writebuf,
702                          ULONGEST offset, LONGEST len)
703 {
704   int retval;
705   struct cleanup *old_chain;
706
707   old_chain = save_inferior_ptid ();
708
709   if (is_thread (inferior_ptid) || !target_thread_alive (inferior_ptid))
710     {
711       /* It's either a thread or an LWP that isn't alive.  Any live
712          LWP will do so use the first available.
713
714          NOTE: We don't need to call switch_to_thread; we're just
715          reading memory.  */
716       inferior_ptid = procfs_first_available ();
717     }
718
719   if (target_has_execution)
720     retval = procfs_ops.to_xfer_partial (ops, object, annex,
721                                          readbuf, writebuf, offset, len);
722   else
723     retval = orig_core_ops.to_xfer_partial (ops, object, annex,
724                                             readbuf, writebuf, offset, len);
725
726   do_cleanups (old_chain);
727
728   return retval;
729 }
730
731 /* Print status information about what we're accessing.  */
732
733 static void
734 sol_thread_files_info (struct target_ops *ignore)
735 {
736   procfs_ops.to_files_info (ignore);
737 }
738
739 static void
740 sol_thread_kill_inferior (void)
741 {
742   procfs_ops.to_kill ();
743 }
744
745 static void
746 sol_thread_notice_signals (ptid_t ptid)
747 {
748   procfs_ops.to_notice_signals (pid_to_ptid (PIDGET (ptid)));
749 }
750
751 /* Fork an inferior process, and start debugging it with /proc.  */
752
753 static void
754 sol_thread_create_inferior (char *exec_file, char *allargs, char **env,
755                             int from_tty)
756 {
757   procfs_ops.to_create_inferior (exec_file, allargs, env, from_tty);
758
759   if (sol_thread_active && !ptid_equal (inferior_ptid, null_ptid))
760     {
761       /* Save for xfer_memory.  */
762       main_ph.ptid = inferior_ptid;
763
764       push_target (&sol_thread_ops);
765
766       inferior_ptid = lwp_to_thread (inferior_ptid);
767       if (PIDGET (inferior_ptid) == -1)
768         inferior_ptid = main_ph.ptid;
769
770       if (!in_thread_list (inferior_ptid))
771         add_thread (inferior_ptid);
772     }
773 }
774
775 /* This routine is called whenever a new symbol table is read in, or
776    when all symbol tables are removed.  libthread_db can only be
777    initialized when it finds the right variables in libthread.so.
778    Since it's a shared library, those variables don't show up until
779    the library gets mapped and the symbol table is read in.  */
780
781 static void
782 sol_thread_new_objfile (struct objfile *objfile)
783 {
784   td_err_e val;
785
786   if (!objfile)
787     {
788       sol_thread_active = 0;
789       return;
790     }
791
792   /* Don't do anything if init failed to resolve the libthread_db
793      library.  */
794   if (!procfs_suppress_run)
795     return;
796
797   /* Now, initialize libthread_db.  This needs to be done after the
798      shared libraries are located because it needs information from
799      the user's thread library.  */
800
801   val = p_td_init ();
802   if (val != TD_OK)
803     {
804       warning (_("sol_thread_new_objfile: td_init: %s"), td_err_string (val));
805       return;
806     }
807
808   val = p_td_ta_new (&main_ph, &main_ta);
809   if (val == TD_NOLIBTHREAD)
810     return;
811   else if (val != TD_OK)
812     {
813       warning (_("sol_thread_new_objfile: td_ta_new: %s"), td_err_string (val));
814       return;
815     }
816
817   sol_thread_active = 1;
818 }
819
820 /* Clean up after the inferior dies.  */
821
822 static void
823 sol_thread_mourn_inferior (void)
824 {
825   unpush_target (&sol_thread_ops);
826   procfs_ops.to_mourn_inferior ();
827 }
828
829 /* Mark our target-struct as eligible for stray "run" and "attach"
830    commands.  */
831
832 static int
833 sol_thread_can_run (void)
834 {
835   return procfs_suppress_run;
836 }
837
838 /*
839
840    LOCAL FUNCTION
841
842    sol_thread_alive     - test thread for "aliveness"
843
844    SYNOPSIS
845
846    static bool sol_thread_alive (ptid_t ptid);
847
848    DESCRIPTION
849
850    returns true if thread still active in inferior.
851
852  */
853
854 /* Return true if PTID is still active in the inferior.  */
855
856 static int
857 sol_thread_alive (ptid_t ptid)
858 {
859   if (is_thread (ptid))
860     {
861       /* It's a (user-level) thread.  */
862       td_err_e val;
863       td_thrhandle_t th;
864       int pid;
865
866       pid = GET_THREAD (ptid);
867       if ((val = p_td_ta_map_id2thr (main_ta, pid, &th)) != TD_OK)
868         return 0;               /* Thread not found.  */
869       if ((val = p_td_thr_validate (&th)) != TD_OK)
870         return 0;               /* Thread not valid.  */
871       return 1;                 /* Known thread.  */
872     }
873   else
874     {
875       /* It's an LPW; pass the request on to procfs.  */
876       if (target_has_execution)
877         return procfs_ops.to_thread_alive (ptid);
878       else
879         return orig_core_ops.to_thread_alive (ptid);
880     }
881 }
882
883 static void
884 sol_thread_stop (void)
885 {
886   procfs_ops.to_stop ();
887 }
888 \f
889 /* These routines implement the lower half of the thread_db interface,
890    i.e. the ps_* routines.  */
891
892 /* Various versions of <proc_service.h> have slightly different
893    function prototypes.  In particular, we have
894
895    NEWER                        OLDER
896    struct ps_prochandle *       const struct ps_prochandle *
897    void*                        char*
898    const void*                  char*
899    int                          size_t
900
901    Which one you have depends on the Solaris version and what patches
902    you've applied.  On the theory that there are only two major
903    variants, we have configure check the prototype of ps_pdwrite (),
904    and use that info to make appropriate typedefs here. */
905
906 #ifdef PROC_SERVICE_IS_OLD
907 typedef const struct ps_prochandle *gdb_ps_prochandle_t;
908 typedef char *gdb_ps_read_buf_t;
909 typedef char *gdb_ps_write_buf_t;
910 typedef int gdb_ps_size_t;
911 typedef psaddr_t gdb_ps_addr_t;
912 #else
913 typedef struct ps_prochandle *gdb_ps_prochandle_t;
914 typedef void *gdb_ps_read_buf_t;
915 typedef const void *gdb_ps_write_buf_t;
916 typedef size_t gdb_ps_size_t;
917 typedef psaddr_t gdb_ps_addr_t;
918 #endif
919
920 /* The next four routines are called by libthread_db to tell us to
921    stop and stop a particular process or lwp.  Since GDB ensures that
922    these are all stopped by the time we call anything in thread_db,
923    these routines need to do nothing.  */
924
925 /* Process stop.  */
926
927 ps_err_e
928 ps_pstop (gdb_ps_prochandle_t ph)
929 {
930   return PS_OK;
931 }
932
933 /* Process continue.  */
934
935 ps_err_e
936 ps_pcontinue (gdb_ps_prochandle_t ph)
937 {
938   return PS_OK;
939 }
940
941 /* LWP stop.  */
942
943 ps_err_e
944 ps_lstop (gdb_ps_prochandle_t ph, lwpid_t lwpid)
945 {
946   return PS_OK;
947 }
948
949 /* LWP continue.  */
950
951 ps_err_e
952 ps_lcontinue (gdb_ps_prochandle_t ph, lwpid_t lwpid)
953 {
954   return PS_OK;
955 }
956
957 /* Looks up the symbol LD_SYMBOL_NAME in the debugger's symbol table.  */
958
959 ps_err_e
960 ps_pglobal_lookup (gdb_ps_prochandle_t ph, const char *ld_object_name,
961                    const char *ld_symbol_name, gdb_ps_addr_t *ld_symbol_addr)
962 {
963   struct minimal_symbol *ms;
964
965   ms = lookup_minimal_symbol (ld_symbol_name, NULL, NULL);
966   if (!ms)
967     return PS_NOSYM;
968
969   *ld_symbol_addr = SYMBOL_VALUE_ADDRESS (ms);
970   return PS_OK;
971 }
972
973 /* Common routine for reading and writing memory.  */
974
975 static ps_err_e
976 rw_common (int dowrite, const struct ps_prochandle *ph, gdb_ps_addr_t addr,
977            char *buf, int size)
978 {
979   struct cleanup *old_chain;
980
981   old_chain = save_inferior_ptid ();
982
983   if (is_thread (inferior_ptid) || !target_thread_alive (inferior_ptid))
984     {
985       /* It's either a thread or an LWP that isn't alive.  Any live
986          LWP will do so use the first available.
987
988          NOTE: We don't need to call switch_to_thread; we're just
989          reading memory.  */
990       inferior_ptid = procfs_first_available ();
991     }
992
993 #if defined (__sparcv9)
994   /* For Sparc64 cross Sparc32, make sure the address has not been
995      accidentally sign-extended (or whatever) to beyond 32 bits.  */
996   if (bfd_get_arch_size (exec_bfd) == 32)
997     addr &= 0xffffffff;
998 #endif
999
1000   while (size > 0)
1001     {
1002       int cc;
1003
1004       /* FIXME: passing 0 as attrib argument.  */
1005       if (target_has_execution)
1006         cc = procfs_ops.deprecated_xfer_memory (addr, buf, size,
1007                                                 dowrite, 0, &procfs_ops);
1008       else
1009         cc = orig_core_ops.deprecated_xfer_memory (addr, buf, size,
1010                                                    dowrite, 0, &core_ops);
1011
1012       if (cc < 0)
1013         {
1014           if (dowrite == 0)
1015             print_sys_errmsg ("rw_common (): read", errno);
1016           else
1017             print_sys_errmsg ("rw_common (): write", errno);
1018
1019           do_cleanups (old_chain);
1020
1021           return PS_ERR;
1022         }
1023       else if (cc == 0)
1024         {
1025           if (dowrite == 0)
1026             warning (_("rw_common (): unable to read at addr 0x%lx"),
1027                      (long) addr);
1028           else
1029             warning (_("rw_common (): unable to write at addr 0x%lx"),
1030                      (long) addr);
1031
1032           do_cleanups (old_chain);
1033
1034           return PS_ERR;
1035         }
1036
1037       size -= cc;
1038       buf += cc;
1039     }
1040
1041   do_cleanups (old_chain);
1042
1043   return PS_OK;
1044 }
1045
1046 /* Copies SIZE bytes from target process .data segment to debugger memory.  */
1047
1048 ps_err_e
1049 ps_pdread (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
1050            gdb_ps_read_buf_t buf, gdb_ps_size_t size)
1051 {
1052   return rw_common (0, ph, addr, buf, size);
1053 }
1054
1055 /* Copies SIZE bytes from debugger memory .data segment to target process.  */
1056
1057 ps_err_e
1058 ps_pdwrite (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
1059             gdb_ps_write_buf_t buf, gdb_ps_size_t size)
1060 {
1061   return rw_common (1, ph, addr, (char *) buf, size);
1062 }
1063
1064 /* Copies SIZE bytes from target process .text segment to debugger memory.  */
1065
1066 ps_err_e
1067 ps_ptread (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
1068            gdb_ps_read_buf_t buf, gdb_ps_size_t size)
1069 {
1070   return rw_common (0, ph, addr, buf, size);
1071 }
1072
1073 /* Copies SIZE bytes from debugger memory .text segment to target process.  */
1074
1075 ps_err_e
1076 ps_ptwrite (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
1077             gdb_ps_write_buf_t buf, gdb_ps_size_t size)
1078 {
1079   return rw_common (1, ph, addr, (char *) buf, size);
1080 }
1081
1082 /* Get general-purpose registers for LWP.  */
1083
1084 ps_err_e
1085 ps_lgetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, prgregset_t gregset)
1086 {
1087   struct cleanup *old_chain;
1088   struct regcache *regcache;
1089
1090   old_chain = save_inferior_ptid ();
1091
1092   inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
1093   regcache = get_thread_regcache (inferior_ptid);
1094
1095   if (target_has_execution)
1096     procfs_ops.to_fetch_registers (regcache, -1);
1097   else
1098     orig_core_ops.to_fetch_registers (regcache, -1);
1099   fill_gregset (regcache, (gdb_gregset_t *) gregset, -1);
1100
1101   do_cleanups (old_chain);
1102
1103   return PS_OK;
1104 }
1105
1106 /* Set general-purpose registers for LWP.  */
1107
1108 ps_err_e
1109 ps_lsetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
1110              const prgregset_t gregset)
1111 {
1112   struct cleanup *old_chain;
1113   struct regcache *regcache;
1114
1115   old_chain = save_inferior_ptid ();
1116
1117   inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
1118   regcache = get_thread_regcache (inferior_ptid);
1119
1120   supply_gregset (regcache, (const gdb_gregset_t *) gregset);
1121   if (target_has_execution)
1122     procfs_ops.to_store_registers (regcache, -1);
1123   else
1124     orig_core_ops.to_store_registers (regcache, -1);
1125
1126   do_cleanups (old_chain);
1127
1128   return PS_OK;
1129 }
1130
1131 /* Log a message (sends to gdb_stderr).  */
1132
1133 void
1134 ps_plog (const char *fmt, ...)
1135 {
1136   va_list args;
1137
1138   va_start (args, fmt);
1139
1140   vfprintf_filtered (gdb_stderr, fmt, args);
1141 }
1142
1143 /* Get size of extra register set.  Currently a noop.  */
1144
1145 ps_err_e
1146 ps_lgetxregsize (gdb_ps_prochandle_t ph, lwpid_t lwpid, int *xregsize)
1147 {
1148 #if 0
1149   int lwp_fd;
1150   int regsize;
1151   ps_err_e val;
1152
1153   val = get_lwp_fd (ph, lwpid, &lwp_fd);
1154   if (val != PS_OK)
1155     return val;
1156
1157   if (ioctl (lwp_fd, PIOCGXREGSIZE, &regsize))
1158     {
1159       if (errno == EINVAL)
1160         return PS_NOFREGS;      /* XXX Wrong code, but this is the closest
1161                                    thing in proc_service.h  */
1162
1163       print_sys_errmsg ("ps_lgetxregsize (): PIOCGXREGSIZE", errno);
1164       return PS_ERR;
1165     }
1166 #endif
1167
1168   return PS_OK;
1169 }
1170
1171 /* Get extra register set.  Currently a noop.  */
1172
1173 ps_err_e
1174 ps_lgetxregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, caddr_t xregset)
1175 {
1176 #if 0
1177   int lwp_fd;
1178   ps_err_e val;
1179
1180   val = get_lwp_fd (ph, lwpid, &lwp_fd);
1181   if (val != PS_OK)
1182     return val;
1183
1184   if (ioctl (lwp_fd, PIOCGXREG, xregset))
1185     {
1186       print_sys_errmsg ("ps_lgetxregs (): PIOCGXREG", errno);
1187       return PS_ERR;
1188     }
1189 #endif
1190
1191   return PS_OK;
1192 }
1193
1194 /* Set extra register set.  Currently a noop.  */
1195
1196 ps_err_e
1197 ps_lsetxregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, caddr_t xregset)
1198 {
1199 #if 0
1200   int lwp_fd;
1201   ps_err_e val;
1202
1203   val = get_lwp_fd (ph, lwpid, &lwp_fd);
1204   if (val != PS_OK)
1205     return val;
1206
1207   if (ioctl (lwp_fd, PIOCSXREG, xregset))
1208     {
1209       print_sys_errmsg ("ps_lsetxregs (): PIOCSXREG", errno);
1210       return PS_ERR;
1211     }
1212 #endif
1213
1214   return PS_OK;
1215 }
1216
1217 /* Get floating-point registers for LWP.  */
1218
1219 ps_err_e
1220 ps_lgetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
1221                prfpregset_t *fpregset)
1222 {
1223   struct cleanup *old_chain;
1224   struct regcache *regcache;
1225
1226   old_chain = save_inferior_ptid ();
1227
1228   inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
1229   regcache = get_thread_regcache (inferior_ptid);
1230
1231   if (target_has_execution)
1232     procfs_ops.to_fetch_registers (regcache, -1);
1233   else
1234     orig_core_ops.to_fetch_registers (regcache, -1);
1235   fill_fpregset (regcache, (gdb_fpregset_t *) fpregset, -1);
1236
1237   do_cleanups (old_chain);
1238
1239   return PS_OK;
1240 }
1241
1242 /* Set floating-point regs for LWP */
1243
1244 ps_err_e
1245 ps_lsetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
1246                const prfpregset_t * fpregset)
1247 {
1248   struct cleanup *old_chain;
1249   struct regcache *regcache;
1250
1251   old_chain = save_inferior_ptid ();
1252
1253   inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
1254   regcache = get_thread_regcache (inferior_ptid);
1255
1256   supply_fpregset (regcache, (const gdb_fpregset_t *) fpregset);
1257   if (target_has_execution)
1258     procfs_ops.to_store_registers (regcache, -1);
1259   else
1260     orig_core_ops.to_store_registers (regcache, -1);
1261
1262   do_cleanups (old_chain);
1263
1264   return PS_OK;
1265 }
1266
1267 #ifdef PR_MODEL_LP64
1268 /* Identify process as 32-bit or 64-bit.  At the moment we're using
1269    BFD to do this.  There might be a more Solaris-specific
1270    (e.g. procfs) method, but this ought to work.  */
1271
1272 ps_err_e
1273 ps_pdmodel (gdb_ps_prochandle_t ph, int *data_model)
1274 {
1275   if (exec_bfd == 0)
1276     *data_model = PR_MODEL_UNKNOWN;
1277   else if (bfd_get_arch_size (exec_bfd) == 32)
1278     *data_model = PR_MODEL_ILP32;
1279   else
1280     *data_model = PR_MODEL_LP64;
1281
1282   return PS_OK;
1283 }
1284 #endif /* PR_MODEL_LP64 */
1285
1286 #if (defined(__i386__) || defined(__x86_64__)) && defined (sun)
1287
1288 /* Reads the local descriptor table of a LWP.
1289
1290    This function is necessary on x86-solaris only.  Without it, the loading
1291    of libthread_db would fail because of ps_lgetLDT being undefined.  */
1292
1293 ps_err_e
1294 ps_lgetLDT (gdb_ps_prochandle_t ph, lwpid_t lwpid,
1295             struct ssd *pldt)
1296 {
1297   /* NOTE: only used on Solaris, therefore OK to refer to procfs.c.  */
1298   extern struct ssd *procfs_find_LDT_entry (ptid_t);
1299   struct ssd *ret;
1300
1301   /* FIXME: can't I get the process ID from the prochandle or
1302      something?  */
1303
1304   if (PIDGET (inferior_ptid) <= 0 || lwpid <= 0)
1305     return PS_BADLID;
1306
1307   ret = procfs_find_LDT_entry (BUILD_LWP (lwpid, PIDGET (inferior_ptid)));
1308   if (ret)
1309     {
1310       memcpy (pldt, ret, sizeof (struct ssd));
1311       return PS_OK;
1312     }
1313   else
1314     /* LDT not found.  */
1315     return PS_ERR;
1316 }
1317 #endif
1318 \f
1319
1320 /* Convert PTID to printable form.  */
1321
1322 char *
1323 solaris_pid_to_str (ptid_t ptid)
1324 {
1325   static char buf[100];
1326
1327   /* In case init failed to resolve the libthread_db library.  */
1328   if (!procfs_suppress_run)
1329     return procfs_pid_to_str (ptid);
1330
1331   if (is_thread (ptid))
1332     {
1333       ptid_t lwp;
1334
1335       lwp = thread_to_lwp (ptid, -2);
1336
1337       if (PIDGET (lwp) == -1)
1338         sprintf (buf, "Thread %ld (defunct)", GET_THREAD (ptid));
1339       else if (PIDGET (lwp) != -2)
1340         sprintf (buf, "Thread %ld (LWP %ld)",
1341                  GET_THREAD (ptid), GET_LWP (lwp));
1342       else
1343         sprintf (buf, "Thread %ld        ", GET_THREAD (ptid));
1344     }
1345   else if (GET_LWP (ptid) != 0)
1346     sprintf (buf, "LWP    %ld        ", GET_LWP (ptid));
1347   else
1348     sprintf (buf, "process %d    ", PIDGET (ptid));
1349
1350   return buf;
1351 }
1352 \f
1353
1354 /* Worker bee for find_new_threads.  Callback function that gets
1355    called once per user-level thread (i.e. not for LWP's).  */
1356
1357 static int
1358 sol_find_new_threads_callback (const td_thrhandle_t *th, void *ignored)
1359 {
1360   td_err_e retval;
1361   td_thrinfo_t ti;
1362   ptid_t ptid;
1363
1364   retval = p_td_thr_get_info (th, &ti);
1365   if (retval != TD_OK)
1366     return -1;
1367
1368   ptid = BUILD_THREAD (ti.ti_tid, PIDGET (inferior_ptid));
1369   if (!in_thread_list (ptid))
1370     add_thread (ptid);
1371
1372   return 0;
1373 }
1374
1375 static void
1376 sol_find_new_threads (void)
1377 {
1378   /* Don't do anything if init failed to resolve the libthread_db
1379      library.  */
1380   if (!procfs_suppress_run)
1381     return;
1382
1383   if (PIDGET (inferior_ptid) == -1)
1384     {
1385       printf_filtered ("No process.\n");
1386       return;
1387     }
1388
1389   /* First Find any new LWP's.  */
1390   procfs_ops.to_find_new_threads ();
1391
1392   /* Then find any new user-level threads.  */
1393   p_td_ta_thr_iter (main_ta, sol_find_new_threads_callback, (void *) 0,
1394                     TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
1395                     TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
1396 }
1397
1398 static void
1399 sol_core_open (char *filename, int from_tty)
1400 {
1401   orig_core_ops.to_open (filename, from_tty);
1402 }
1403
1404 static void
1405 sol_core_close (int quitting)
1406 {
1407   orig_core_ops.to_close (quitting);
1408 }
1409
1410 static void
1411 sol_core_detach (char *args, int from_tty)
1412 {
1413   unpush_target (&core_ops);
1414   orig_core_ops.to_detach (args, from_tty);
1415 }
1416
1417 static void
1418 sol_core_files_info (struct target_ops *t)
1419 {
1420   orig_core_ops.to_files_info (t);
1421 }
1422
1423 /* Worker bee for the "info sol-thread" command.  This is a callback
1424    function that gets called once for each Solaris user-level thread
1425    (i.e. not for LWPs) in the inferior.  Print anything interesting
1426    that we can think of.  */
1427
1428 static int
1429 info_cb (const td_thrhandle_t *th, void *s)
1430 {
1431   td_err_e ret;
1432   td_thrinfo_t ti;
1433
1434   ret = p_td_thr_get_info (th, &ti);
1435   if (ret == TD_OK)
1436     {
1437       printf_filtered ("%s thread #%d, lwp %d, ",
1438                        ti.ti_type == TD_THR_SYSTEM ? "system" : "user  ",
1439                        ti.ti_tid, ti.ti_lid);
1440       switch (ti.ti_state)
1441         {
1442         default:
1443         case TD_THR_UNKNOWN:
1444           printf_filtered ("<unknown state>");
1445           break;
1446         case TD_THR_STOPPED:
1447           printf_filtered ("(stopped)");
1448           break;
1449         case TD_THR_RUN:
1450           printf_filtered ("(run)    ");
1451           break;
1452         case TD_THR_ACTIVE:
1453           printf_filtered ("(active) ");
1454           break;
1455         case TD_THR_ZOMBIE:
1456           printf_filtered ("(zombie) ");
1457           break;
1458         case TD_THR_SLEEP:
1459           printf_filtered ("(asleep) ");
1460           break;
1461         case TD_THR_STOPPED_ASLEEP:
1462           printf_filtered ("(stopped asleep)");
1463           break;
1464         }
1465       /* Print thr_create start function.  */
1466       if (ti.ti_startfunc != 0)
1467         {
1468           struct minimal_symbol *msym;
1469           msym = lookup_minimal_symbol_by_pc (ti.ti_startfunc);
1470           if (msym)
1471             printf_filtered ("   startfunc: %s\n",
1472                              DEPRECATED_SYMBOL_NAME (msym));
1473           else
1474             printf_filtered ("   startfunc: 0x%s\n", paddr (ti.ti_startfunc));
1475         }
1476
1477       /* If thread is asleep, print function that went to sleep.  */
1478       if (ti.ti_state == TD_THR_SLEEP)
1479         {
1480           struct minimal_symbol *msym;
1481           msym = lookup_minimal_symbol_by_pc (ti.ti_pc);
1482           if (msym)
1483             printf_filtered (" - Sleep func: %s\n",
1484                              DEPRECATED_SYMBOL_NAME (msym));
1485           else
1486             printf_filtered (" - Sleep func: 0x%s\n", paddr (ti.ti_startfunc));
1487         }
1488
1489       /* Wrap up line, if necessary.  */
1490       if (ti.ti_state != TD_THR_SLEEP && ti.ti_startfunc == 0)
1491         printf_filtered ("\n"); /* don't you hate counting newlines? */
1492     }
1493   else
1494     warning (_("info sol-thread: failed to get info for thread."));
1495
1496   return 0;
1497 }
1498
1499 /* List some state about each Solaris user-level thread in the
1500    inferior.  */
1501
1502 static void
1503 info_solthreads (char *args, int from_tty)
1504 {
1505   p_td_ta_thr_iter (main_ta, info_cb, args,
1506                     TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
1507                     TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
1508 }
1509
1510 static int
1511 sol_find_memory_regions (int (*func) (CORE_ADDR, unsigned long,
1512                                       int, int, int, void *),
1513                          void *data)
1514 {
1515   return procfs_ops.to_find_memory_regions (func, data);
1516 }
1517
1518 static char *
1519 sol_make_note_section (bfd *obfd, int *note_size)
1520 {
1521   return procfs_ops.to_make_corefile_notes (obfd, note_size);
1522 }
1523
1524 static int
1525 ignore (struct bp_target_info *bp_tgt)
1526 {
1527   return 0;
1528 }
1529
1530 static void
1531 init_sol_thread_ops (void)
1532 {
1533   sol_thread_ops.to_shortname = "solaris-threads";
1534   sol_thread_ops.to_longname = "Solaris threads and pthread.";
1535   sol_thread_ops.to_doc = "Solaris threads and pthread support.";
1536   sol_thread_ops.to_open = sol_thread_open;
1537   sol_thread_ops.to_attach = sol_thread_attach;
1538   sol_thread_ops.to_detach = sol_thread_detach;
1539   sol_thread_ops.to_resume = sol_thread_resume;
1540   sol_thread_ops.to_wait = sol_thread_wait;
1541   sol_thread_ops.to_fetch_registers = sol_thread_fetch_registers;
1542   sol_thread_ops.to_store_registers = sol_thread_store_registers;
1543   sol_thread_ops.to_prepare_to_store = sol_thread_prepare_to_store;
1544   sol_thread_ops.deprecated_xfer_memory = sol_thread_xfer_memory;
1545   sol_thread_ops.to_xfer_partial = sol_thread_xfer_partial;
1546   sol_thread_ops.to_files_info = sol_thread_files_info;
1547   sol_thread_ops.to_insert_breakpoint = memory_insert_breakpoint;
1548   sol_thread_ops.to_remove_breakpoint = memory_remove_breakpoint;
1549   sol_thread_ops.to_terminal_init = terminal_init_inferior;
1550   sol_thread_ops.to_terminal_inferior = terminal_inferior;
1551   sol_thread_ops.to_terminal_ours_for_output = terminal_ours_for_output;
1552   sol_thread_ops.to_terminal_ours = terminal_ours;
1553   sol_thread_ops.to_terminal_save_ours = terminal_save_ours;
1554   sol_thread_ops.to_terminal_info = child_terminal_info;
1555   sol_thread_ops.to_kill = sol_thread_kill_inferior;
1556   sol_thread_ops.to_create_inferior = sol_thread_create_inferior;
1557   sol_thread_ops.to_mourn_inferior = sol_thread_mourn_inferior;
1558   sol_thread_ops.to_can_run = sol_thread_can_run;
1559   sol_thread_ops.to_notice_signals = sol_thread_notice_signals;
1560   sol_thread_ops.to_thread_alive = sol_thread_alive;
1561   sol_thread_ops.to_pid_to_str = solaris_pid_to_str;
1562   sol_thread_ops.to_find_new_threads = sol_find_new_threads;
1563   sol_thread_ops.to_stop = sol_thread_stop;
1564   sol_thread_ops.to_stratum = process_stratum;
1565   sol_thread_ops.to_has_all_memory = 1;
1566   sol_thread_ops.to_has_memory = 1;
1567   sol_thread_ops.to_has_stack = 1;
1568   sol_thread_ops.to_has_registers = 1;
1569   sol_thread_ops.to_has_execution = 1;
1570   sol_thread_ops.to_has_thread_control = tc_none;
1571   sol_thread_ops.to_find_memory_regions = sol_find_memory_regions;
1572   sol_thread_ops.to_make_corefile_notes = sol_make_note_section;
1573   sol_thread_ops.to_magic = OPS_MAGIC;
1574 }
1575
1576 static void
1577 init_sol_core_ops (void)
1578 {
1579   sol_core_ops.to_shortname = "solaris-core";
1580   sol_core_ops.to_longname = "Solaris core threads and pthread.";
1581   sol_core_ops.to_doc = "Solaris threads and pthread support for core files.";
1582   sol_core_ops.to_open = sol_core_open;
1583   sol_core_ops.to_close = sol_core_close;
1584   sol_core_ops.to_attach = sol_thread_attach;
1585   sol_core_ops.to_detach = sol_core_detach;
1586   sol_core_ops.to_fetch_registers = sol_thread_fetch_registers;
1587   sol_core_ops.deprecated_xfer_memory = sol_thread_xfer_memory;
1588   sol_core_ops.to_xfer_partial = sol_thread_xfer_partial;
1589   sol_core_ops.to_files_info = sol_core_files_info;
1590   sol_core_ops.to_insert_breakpoint = ignore;
1591   sol_core_ops.to_remove_breakpoint = ignore;
1592   sol_core_ops.to_create_inferior = sol_thread_create_inferior;
1593   sol_core_ops.to_stratum = core_stratum;
1594   sol_core_ops.to_has_memory = 1;
1595   sol_core_ops.to_has_stack = 1;
1596   sol_core_ops.to_has_registers = 1;
1597   sol_core_ops.to_has_thread_control = tc_none;
1598   sol_core_ops.to_thread_alive = sol_thread_alive;
1599   sol_core_ops.to_pid_to_str = solaris_pid_to_str;
1600   /* On Solaris/x86, when debugging a threaded core file from process
1601      <n>, the following causes "info threads" to produce "procfs:
1602      couldn't find pid <n> in procinfo list" where <n> is the pid of
1603      the process that produced the core file.  Disable it for now. */
1604 #if 0
1605   sol_core_ops.to_find_new_threads = sol_find_new_threads;
1606 #endif
1607   sol_core_ops.to_magic = OPS_MAGIC;
1608 }
1609
1610 /* We suppress the call to add_target of core_ops in corelow because
1611    if there are two targets in the stratum core_stratum,
1612    find_core_target won't know which one to return.  See corelow.c for
1613    an additonal comment on coreops_suppress_target.  */
1614 int coreops_suppress_target = 1;
1615
1616 void
1617 _initialize_sol_thread (void)
1618 {
1619   void *dlhandle;
1620
1621   init_sol_thread_ops ();
1622   init_sol_core_ops ();
1623
1624   dlhandle = dlopen ("libthread_db.so.1", RTLD_NOW);
1625   if (!dlhandle)
1626     goto die;
1627
1628 #define resolve(X) \
1629   if (!(p_##X = dlsym (dlhandle, #X))) \
1630     goto die;
1631
1632   resolve (td_log);
1633   resolve (td_ta_new);
1634   resolve (td_ta_delete);
1635   resolve (td_init);
1636   resolve (td_ta_get_ph);
1637   resolve (td_ta_get_nthreads);
1638   resolve (td_ta_tsd_iter);
1639   resolve (td_ta_thr_iter);
1640   resolve (td_thr_validate);
1641   resolve (td_thr_tsd);
1642   resolve (td_thr_get_info);
1643   resolve (td_thr_getfpregs);
1644   resolve (td_thr_getxregsize);
1645   resolve (td_thr_getxregs);
1646   resolve (td_thr_sigsetmask);
1647   resolve (td_thr_setprio);
1648   resolve (td_thr_setsigpending);
1649   resolve (td_thr_setfpregs);
1650   resolve (td_thr_setxregs);
1651   resolve (td_ta_map_id2thr);
1652   resolve (td_ta_map_lwp2thr);
1653   resolve (td_thr_getgregs);
1654   resolve (td_thr_setgregs);
1655
1656   add_target (&sol_thread_ops);
1657
1658   procfs_suppress_run = 1;
1659
1660   add_cmd ("sol-threads", class_maintenance, info_solthreads,
1661            _("Show info on Solaris user threads."), &maintenanceinfolist);
1662
1663   memcpy (&orig_core_ops, &core_ops, sizeof (struct target_ops));
1664   memcpy (&core_ops, &sol_core_ops, sizeof (struct target_ops));
1665   add_target (&core_ops);
1666
1667   /* Hook into new_objfile notification.  */
1668   observer_attach_new_objfile (sol_thread_new_objfile);
1669   return;
1670
1671  die:
1672   fprintf_unfiltered (gdb_stderr, "\
1673 [GDB will not be able to debug user-mode threads: %s]\n", dlerror ());
1674
1675   if (dlhandle)
1676     dlclose (dlhandle);
1677
1678   /* Allow the user to debug non-threaded core files.  */
1679   add_target (&core_ops);
1680
1681   return;
1682 }