2012-04-18 Pedro Alves <palves@redhat.com>
[external/binutils.git] / gdb / sol-thread.c
1 /* Solaris threads debugging interface.
2
3    Copyright (C) 1996-2005, 2007-2012 Free Software Foundation, Inc.
4
5    This file is part of GDB.
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19
20 /* This module implements a sort of half target that sits between the
21    machine-independent parts of GDB and the /proc interface (procfs.c)
22    to provide access to the Solaris user-mode thread implementation.
23
24    Solaris threads are true user-mode threads, which are invoked via
25    the thr_* and pthread_* (native and POSIX respectivly) interfaces.
26    These are mostly implemented in user-space, with all thread context
27    kept in various structures that live in the user's heap.  These
28    should not be confused with lightweight processes (LWPs), which are
29    implemented by the kernel, and scheduled without explicit
30    intervention by the process.
31
32    Just to confuse things a little, Solaris threads (both native and
33    POSIX) are actually implemented using LWPs.  In general, there are
34    going to be more threads than LWPs.  There is no fixed
35    correspondence between a thread and an LWP.  When a thread wants to
36    run, it gets scheduled onto the first available LWP and can
37    therefore migrate from one LWP to another as time goes on.  A
38    sleeping thread may not be associated with an LWP at all!
39
40    To make it possible to mess with threads, Sun provides a library
41    called libthread_db.so.1 (not to be confused with
42    libthread_db.so.0, which doesn't have a published interface).  This
43    interface has an upper part, which it provides, and a lower part
44    which we provide.  The upper part consists of the td_* routines,
45    which allow us to find all the threads, query their state, etc...
46    The lower part consists of all of the ps_*, which are used by the
47    td_* routines to read/write memory, manipulate LWPs, lookup
48    symbols, etc...  The ps_* routines actually do most of their work
49    by calling functions in procfs.c.  */
50
51 #include "defs.h"
52 #include <thread.h>
53 #include <proc_service.h>
54 #include <thread_db.h>
55 #include "gdbthread.h"
56 #include "target.h"
57 #include "inferior.h"
58 #include <fcntl.h>
59 #include "gdb_stat.h"
60 #include <dlfcn.h>
61 #include "gdbcmd.h"
62 #include "gdbcore.h"
63 #include "regcache.h"
64 #include "solib.h"
65 #include "symfile.h"
66 #include "observer.h"
67 #include "gdb_string.h"
68 #include "procfs.h"
69
70 struct target_ops sol_thread_ops;
71
72 extern char *procfs_pid_to_str (struct target_ops *ops, ptid_t ptid);
73
74 /* Prototypes for supply_gregset etc.  */
75 #include "gregset.h"
76
77 /* This struct is defined by us, but mainly used for the proc_service
78    interface.  We don't have much use for it, except as a handy place
79    to get a real PID for memory accesses.  */
80
81 struct ps_prochandle
82 {
83   ptid_t ptid;
84 };
85
86 struct string_map
87 {
88   int num;
89   char *str;
90 };
91
92 static struct ps_prochandle main_ph;
93 static td_thragent_t *main_ta;
94 static int sol_thread_active = 0;
95
96 static void init_sol_thread_ops (void);
97
98 /* Default definitions: These must be defined in tm.h if they are to
99    be shared with a process module such as procfs.  */
100
101 #define GET_PID(ptid)           ptid_get_pid (ptid)
102 #define GET_LWP(ptid)           ptid_get_lwp (ptid)
103 #define GET_THREAD(ptid)        ptid_get_tid (ptid)
104
105 #define is_lwp(ptid)            (GET_LWP (ptid) != 0)
106 #define is_thread(ptid)         (GET_THREAD (ptid) != 0)
107
108 #define BUILD_LWP(lwp, pid)     ptid_build (pid, lwp, 0)
109 #define BUILD_THREAD(tid, pid)  ptid_build (pid, 0, tid)
110
111 /* Pointers to routines from libthread_db resolved by dlopen().  */
112
113 static void (*p_td_log)(const int on_off);
114 static td_err_e (*p_td_ta_new)(const struct ps_prochandle *ph_p,
115                                td_thragent_t **ta_pp);
116 static td_err_e (*p_td_ta_delete)(td_thragent_t *ta_p);
117 static td_err_e (*p_td_init)(void);
118 static td_err_e (*p_td_ta_get_ph)(const td_thragent_t *ta_p,
119                                   struct ps_prochandle **ph_pp);
120 static td_err_e (*p_td_ta_get_nthreads)(const td_thragent_t *ta_p,
121                                         int *nthread_p);
122 static td_err_e (*p_td_ta_tsd_iter)(const td_thragent_t *ta_p,
123                                     td_key_iter_f *cb, void *cbdata_p);
124 static td_err_e (*p_td_ta_thr_iter)(const td_thragent_t *ta_p,
125                                     td_thr_iter_f *cb, void *cbdata_p,
126                                     td_thr_state_e state, int ti_pri,
127                                     sigset_t *ti_sigmask_p,
128                                     unsigned ti_user_flags);
129 static td_err_e (*p_td_thr_validate)(const td_thrhandle_t *th_p);
130 static td_err_e (*p_td_thr_tsd)(const td_thrhandle_t * th_p,
131                                 const thread_key_t key, void **data_pp);
132 static td_err_e (*p_td_thr_get_info)(const td_thrhandle_t *th_p,
133                                      td_thrinfo_t *ti_p);
134 static td_err_e (*p_td_thr_getfpregs)(const td_thrhandle_t *th_p,
135                                       prfpregset_t *fpregset);
136 static td_err_e (*p_td_thr_getxregsize)(const td_thrhandle_t *th_p,
137                                         int *xregsize);
138 static td_err_e (*p_td_thr_getxregs)(const td_thrhandle_t *th_p,
139                                      const caddr_t xregset);
140 static td_err_e (*p_td_thr_sigsetmask)(const td_thrhandle_t *th_p,
141                                        const sigset_t ti_sigmask);
142 static td_err_e (*p_td_thr_setprio)(const td_thrhandle_t *th_p,
143                                     const int ti_pri);
144 static td_err_e (*p_td_thr_setsigpending)(const td_thrhandle_t *th_p,
145                                           const uchar_t ti_pending_flag,
146                                           const sigset_t ti_pending);
147 static td_err_e (*p_td_thr_setfpregs)(const td_thrhandle_t *th_p,
148                                       const prfpregset_t *fpregset);
149 static td_err_e (*p_td_thr_setxregs)(const td_thrhandle_t *th_p,
150                                      const caddr_t xregset);
151 static td_err_e (*p_td_ta_map_id2thr)(const td_thragent_t *ta_p,
152                                       thread_t tid,
153                                       td_thrhandle_t *th_p);
154 static td_err_e (*p_td_ta_map_lwp2thr)(const td_thragent_t *ta_p,
155                                        lwpid_t lwpid,
156                                        td_thrhandle_t *th_p);
157 static td_err_e (*p_td_thr_getgregs)(const td_thrhandle_t *th_p,
158                                      prgregset_t regset);
159 static td_err_e (*p_td_thr_setgregs)(const td_thrhandle_t *th_p,
160                                      const prgregset_t regset);
161 \f
162
163 /* Return the libthread_db error string associated with ERRCODE.  If
164    ERRCODE is unknown, return an appropriate message.  */
165
166 static char *
167 td_err_string (td_err_e errcode)
168 {
169   static struct string_map td_err_table[] =
170   {
171     { TD_OK, "generic \"call succeeded\"" },
172     { TD_ERR, "generic error." },
173     { TD_NOTHR, "no thread can be found to satisfy query" },
174     { TD_NOSV, "no synch. variable can be found to satisfy query" },
175     { TD_NOLWP, "no lwp can be found to satisfy query" },
176     { TD_BADPH, "invalid process handle" },
177     { TD_BADTH, "invalid thread handle" },
178     { TD_BADSH, "invalid synchronization handle" },
179     { TD_BADTA, "invalid thread agent" },
180     { TD_BADKEY, "invalid key" },
181     { TD_NOMSG, "td_thr_event_getmsg() called when there was no message" },
182     { TD_NOFPREGS, "FPU register set not available for given thread" },
183     { TD_NOLIBTHREAD, "application not linked with libthread" },
184     { TD_NOEVENT, "requested event is not supported" },
185     { TD_NOCAPAB, "capability not available" },
186     { TD_DBERR, "Debugger service failed" },
187     { TD_NOAPLIC, "Operation not applicable to" },
188     { TD_NOTSD, "No thread specific data for this thread" },
189     { TD_MALLOC, "Malloc failed" },
190     { TD_PARTIALREG, "Only part of register set was written/read" },
191     { TD_NOXREGS, "X register set not available for given thread" }
192   };
193   const int td_err_size = sizeof td_err_table / sizeof (struct string_map);
194   int i;
195   static char buf[50];
196
197   for (i = 0; i < td_err_size; i++)
198     if (td_err_table[i].num == errcode)
199       return td_err_table[i].str;
200
201   sprintf (buf, "Unknown libthread_db error code: %d", errcode);
202
203   return buf;
204 }
205
206 /* Return the libthread_db state string assicoated with STATECODE.
207    If STATECODE is unknown, return an appropriate message.  */
208
209 static char *
210 td_state_string (td_thr_state_e statecode)
211 {
212   static struct string_map td_thr_state_table[] =
213   {
214     { TD_THR_ANY_STATE, "any state" },
215     { TD_THR_UNKNOWN, "unknown" },
216     { TD_THR_STOPPED, "stopped" },
217     { TD_THR_RUN, "run" },
218     { TD_THR_ACTIVE, "active" },
219     { TD_THR_ZOMBIE, "zombie" },
220     { TD_THR_SLEEP, "sleep" },
221     { TD_THR_STOPPED_ASLEEP, "stopped asleep" }
222   };
223   const int td_thr_state_table_size =
224     sizeof td_thr_state_table / sizeof (struct string_map);
225   int i;
226   static char buf[50];
227
228   for (i = 0; i < td_thr_state_table_size; i++)
229     if (td_thr_state_table[i].num == statecode)
230       return td_thr_state_table[i].str;
231
232   sprintf (buf, "Unknown libthread_db state code: %d", statecode);
233
234   return buf;
235 }
236 \f
237
238 /* Convert a POSIX or Solaris thread ID into a LWP ID.  If THREAD_ID
239    doesn't exist, that's an error.  If it's an inactive thread, return
240    DEFAULT_LWP.
241
242    NOTE: This function probably shouldn't call error().  */
243
244 static ptid_t
245 thread_to_lwp (ptid_t thread_id, int default_lwp)
246 {
247   td_thrinfo_t ti;
248   td_thrhandle_t th;
249   td_err_e val;
250
251   if (is_lwp (thread_id))
252     return thread_id;           /* It's already an LWP ID.  */
253
254   /* It's a thread.  Convert to LWP.  */
255
256   val = p_td_ta_map_id2thr (main_ta, GET_THREAD (thread_id), &th);
257   if (val == TD_NOTHR)
258     return pid_to_ptid (-1);    /* Thread must have terminated.  */
259   else if (val != TD_OK)
260     error (_("thread_to_lwp: td_ta_map_id2thr %s"), td_err_string (val));
261
262   val = p_td_thr_get_info (&th, &ti);
263   if (val == TD_NOTHR)
264     return pid_to_ptid (-1);    /* Thread must have terminated.  */
265   else if (val != TD_OK)
266     error (_("thread_to_lwp: td_thr_get_info: %s"), td_err_string (val));
267
268   if (ti.ti_state != TD_THR_ACTIVE)
269     {
270       if (default_lwp != -1)
271         return pid_to_ptid (default_lwp);
272       error (_("thread_to_lwp: thread state not active: %s"),
273              td_state_string (ti.ti_state));
274     }
275
276   return BUILD_LWP (ti.ti_lid, PIDGET (thread_id));
277 }
278
279 /* Convert an LWP ID into a POSIX or Solaris thread ID.  If LWP_ID
280    doesn't exists, that's an error.
281
282    NOTE: This function probably shouldn't call error().  */
283
284 static ptid_t
285 lwp_to_thread (ptid_t lwp)
286 {
287   td_thrinfo_t ti;
288   td_thrhandle_t th;
289   td_err_e val;
290
291   if (is_thread (lwp))
292     return lwp;                 /* It's already a thread ID.  */
293
294   /* It's an LWP.  Convert it to a thread ID.  */
295
296   if (!target_thread_alive (lwp))
297     return pid_to_ptid (-1);    /* Must be a defunct LPW.  */
298
299   val = p_td_ta_map_lwp2thr (main_ta, GET_LWP (lwp), &th);
300   if (val == TD_NOTHR)
301     return pid_to_ptid (-1);    /* Thread must have terminated.  */
302   else if (val != TD_OK)
303     error (_("lwp_to_thread: td_ta_map_lwp2thr: %s."), td_err_string (val));
304
305   val = p_td_thr_validate (&th);
306   if (val == TD_NOTHR)
307     return lwp;                 /* Unknown to libthread; just return LPW,  */
308   else if (val != TD_OK)
309     error (_("lwp_to_thread: td_thr_validate: %s."), td_err_string (val));
310
311   val = p_td_thr_get_info (&th, &ti);
312   if (val == TD_NOTHR)
313     return pid_to_ptid (-1);    /* Thread must have terminated.  */
314   else if (val != TD_OK)
315     error (_("lwp_to_thread: td_thr_get_info: %s."), td_err_string (val));
316
317   return BUILD_THREAD (ti.ti_tid, PIDGET (lwp));
318 }
319 \f
320
321 /* Most target vector functions from here on actually just pass
322    through to the layer beneath, as they don't need to do anything
323    specific for threads.  */
324
325 /* Take a program previously attached to and detaches it.  The program
326    resumes execution and will no longer stop on signals, etc.  We'd
327    better not have left any breakpoints in the program or it'll die
328    when it hits one.  For this to work, it may be necessary for the
329    process to have been previously attached.  It *might* work if the
330    program was started via the normal ptrace (PTRACE_TRACEME).  */
331
332 static void
333 sol_thread_detach (struct target_ops *ops, char *args, int from_tty)
334 {
335   struct target_ops *beneath = find_target_beneath (ops);
336
337   sol_thread_active = 0;
338   inferior_ptid = pid_to_ptid (PIDGET (main_ph.ptid));
339   unpush_target (ops);
340   beneath->to_detach (beneath, args, from_tty);
341 }
342
343 /* Resume execution of process PTID.  If STEP is nozero, then just
344    single step it.  If SIGNAL is nonzero, restart it with that signal
345    activated.  We may have to convert PTID from a thread ID to an LWP
346    ID for procfs.  */
347
348 static void
349 sol_thread_resume (struct target_ops *ops,
350                    ptid_t ptid, int step, enum target_signal signo)
351 {
352   struct cleanup *old_chain;
353   struct target_ops *beneath = find_target_beneath (ops);
354
355   old_chain = save_inferior_ptid ();
356
357   inferior_ptid = thread_to_lwp (inferior_ptid, PIDGET (main_ph.ptid));
358   if (PIDGET (inferior_ptid) == -1)
359     inferior_ptid = procfs_first_available ();
360
361   if (PIDGET (ptid) != -1)
362     {
363       ptid_t save_ptid = ptid;
364
365       ptid = thread_to_lwp (ptid, -2);
366       if (PIDGET (ptid) == -2)          /* Inactive thread.  */
367         error (_("This version of Solaris can't start inactive threads."));
368       if (info_verbose && PIDGET (ptid) == -1)
369         warning (_("Specified thread %ld seems to have terminated"),
370                  GET_THREAD (save_ptid));
371     }
372
373   beneath->to_resume (beneath, ptid, step, signo);
374
375   do_cleanups (old_chain);
376 }
377
378 /* Wait for any threads to stop.  We may have to convert PTID from a
379    thread ID to an LWP ID, and vice versa on the way out.  */
380
381 static ptid_t
382 sol_thread_wait (struct target_ops *ops,
383                  ptid_t ptid, struct target_waitstatus *ourstatus, int options)
384 {
385   ptid_t rtnval;
386   ptid_t save_ptid;
387   struct target_ops *beneath = find_target_beneath (ops);
388   struct cleanup *old_chain;
389
390   save_ptid = inferior_ptid;
391   old_chain = save_inferior_ptid ();
392
393   inferior_ptid = thread_to_lwp (inferior_ptid, PIDGET (main_ph.ptid));
394   if (PIDGET (inferior_ptid) == -1)
395     inferior_ptid = procfs_first_available ();
396
397   if (PIDGET (ptid) != -1)
398     {
399       ptid_t save_ptid = ptid;
400
401       ptid = thread_to_lwp (ptid, -2);
402       if (PIDGET (ptid) == -2)          /* Inactive thread.  */
403         error (_("This version of Solaris can't start inactive threads."));
404       if (info_verbose && PIDGET (ptid) == -1)
405         warning (_("Specified thread %ld seems to have terminated"),
406                  GET_THREAD (save_ptid));
407     }
408
409   rtnval = beneath->to_wait (beneath, ptid, ourstatus, options);
410
411   if (ourstatus->kind != TARGET_WAITKIND_EXITED)
412     {
413       /* Map the LWP of interest back to the appropriate thread ID.  */
414       rtnval = lwp_to_thread (rtnval);
415       if (PIDGET (rtnval) == -1)
416         rtnval = save_ptid;
417
418       /* See if we have a new thread.  */
419       if (is_thread (rtnval)
420           && !ptid_equal (rtnval, save_ptid)
421           && (!in_thread_list (rtnval)
422               || is_exited (rtnval)))
423         add_thread (rtnval);
424     }
425
426   /* During process initialization, we may get here without the thread
427      package being initialized, since that can only happen after we've
428      found the shared libs.  */
429
430   do_cleanups (old_chain);
431
432   return rtnval;
433 }
434
435 static void
436 sol_thread_fetch_registers (struct target_ops *ops,
437                             struct regcache *regcache, int regnum)
438 {
439   thread_t thread;
440   td_thrhandle_t thandle;
441   td_err_e val;
442   prgregset_t gregset;
443   prfpregset_t fpregset;
444   gdb_gregset_t *gregset_p = &gregset;
445   gdb_fpregset_t *fpregset_p = &fpregset;
446   struct target_ops *beneath = find_target_beneath (ops);
447
448 #if 0
449   int xregsize;
450   caddr_t xregset;
451 #endif
452
453   if (!is_thread (inferior_ptid))
454     {
455       /* It's an LWP; pass the request on to the layer beneath.  */
456       beneath->to_fetch_registers (beneath, regcache, regnum);
457       return;
458     }
459
460   /* Solaris thread: convert INFERIOR_PTID into a td_thrhandle_t.  */
461   thread = GET_THREAD (inferior_ptid);
462   if (thread == 0)
463     error (_("sol_thread_fetch_registers: thread == 0"));
464
465   val = p_td_ta_map_id2thr (main_ta, thread, &thandle);
466   if (val != TD_OK)
467     error (_("sol_thread_fetch_registers: td_ta_map_id2thr: %s"),
468            td_err_string (val));
469
470   /* Get the general-purpose registers.  */
471
472   val = p_td_thr_getgregs (&thandle, gregset);
473   if (val != TD_OK && val != TD_PARTIALREG)
474     error (_("sol_thread_fetch_registers: td_thr_getgregs %s"),
475            td_err_string (val));
476
477   /* For SPARC, TD_PARTIALREG means that only %i0...%i7, %l0..%l7, %pc
478      and %sp are saved (by a thread context switch).  */
479
480   /* And, now the floating-point registers.  */
481
482   val = p_td_thr_getfpregs (&thandle, &fpregset);
483   if (val != TD_OK && val != TD_NOFPREGS)
484     error (_("sol_thread_fetch_registers: td_thr_getfpregs %s"),
485            td_err_string (val));
486
487   /* Note that we must call supply_gregset and supply_fpregset *after*
488      calling the td routines because the td routines call ps_lget*
489      which affect the values stored in the registers array.  */
490
491   supply_gregset (regcache, (const gdb_gregset_t *) gregset_p);
492   supply_fpregset (regcache, (const gdb_fpregset_t *) fpregset_p);
493
494 #if 0
495   /* FIXME: libthread_db doesn't seem to handle this right.  */
496   val = td_thr_getxregsize (&thandle, &xregsize);
497   if (val != TD_OK && val != TD_NOXREGS)
498     error (_("sol_thread_fetch_registers: td_thr_getxregsize %s"),
499            td_err_string (val));
500
501   if (val == TD_OK)
502     {
503       xregset = alloca (xregsize);
504       val = td_thr_getxregs (&thandle, xregset);
505       if (val != TD_OK)
506         error (_("sol_thread_fetch_registers: td_thr_getxregs %s"),
507                td_err_string (val));
508     }
509 #endif
510 }
511
512 static void
513 sol_thread_store_registers (struct target_ops *ops,
514                             struct regcache *regcache, int regnum)
515 {
516   thread_t thread;
517   td_thrhandle_t thandle;
518   td_err_e val;
519   prgregset_t gregset;
520   prfpregset_t fpregset;
521 #if 0
522   int xregsize;
523   caddr_t xregset;
524 #endif
525
526   if (!is_thread (inferior_ptid))
527     {
528       struct target_ops *beneath = find_target_beneath (ops);
529
530       /* It's an LWP; pass the request on to the layer beneath.  */
531       beneath->to_store_registers (beneath, regcache, regnum);
532       return;
533     }
534
535   /* Solaris thread: convert INFERIOR_PTID into a td_thrhandle_t.  */
536   thread = GET_THREAD (inferior_ptid);
537
538   val = p_td_ta_map_id2thr (main_ta, thread, &thandle);
539   if (val != TD_OK)
540     error (_("sol_thread_store_registers: td_ta_map_id2thr %s"),
541            td_err_string (val));
542
543   if (regnum != -1)
544     {
545       /* Not writing all the registers.  */
546       char old_value[MAX_REGISTER_SIZE];
547
548       /* Save new register value.  */
549       regcache_raw_collect (regcache, regnum, old_value);
550
551       val = p_td_thr_getgregs (&thandle, gregset);
552       if (val != TD_OK)
553         error (_("sol_thread_store_registers: td_thr_getgregs %s"),
554                td_err_string (val));
555       val = p_td_thr_getfpregs (&thandle, &fpregset);
556       if (val != TD_OK)
557         error (_("sol_thread_store_registers: td_thr_getfpregs %s"),
558                td_err_string (val));
559
560       /* Restore new register value.  */
561       regcache_raw_supply (regcache, regnum, old_value);
562
563 #if 0
564       /* FIXME: libthread_db doesn't seem to handle this right.  */
565       val = td_thr_getxregsize (&thandle, &xregsize);
566       if (val != TD_OK && val != TD_NOXREGS)
567         error (_("sol_thread_store_registers: td_thr_getxregsize %s"),
568                td_err_string (val));
569
570       if (val == TD_OK)
571         {
572           xregset = alloca (xregsize);
573           val = td_thr_getxregs (&thandle, xregset);
574           if (val != TD_OK)
575             error (_("sol_thread_store_registers: td_thr_getxregs %s"),
576                    td_err_string (val));
577         }
578 #endif
579     }
580
581   fill_gregset (regcache, (gdb_gregset_t *) &gregset, regnum);
582   fill_fpregset (regcache, (gdb_fpregset_t *) &fpregset, regnum);
583
584   val = p_td_thr_setgregs (&thandle, gregset);
585   if (val != TD_OK)
586     error (_("sol_thread_store_registers: td_thr_setgregs %s"),
587            td_err_string (val));
588   val = p_td_thr_setfpregs (&thandle, &fpregset);
589   if (val != TD_OK)
590     error (_("sol_thread_store_registers: td_thr_setfpregs %s"),
591            td_err_string (val));
592
593 #if 0
594   /* FIXME: libthread_db doesn't seem to handle this right.  */
595   val = td_thr_getxregsize (&thandle, &xregsize);
596   if (val != TD_OK && val != TD_NOXREGS)
597     error (_("sol_thread_store_registers: td_thr_getxregsize %s"),
598            td_err_string (val));
599
600   /* ??? Should probably do something about writing the xregs here,
601      but what are they?  */
602 #endif
603 }
604
605 /* Perform partial transfers on OBJECT.  See target_read_partial and
606    target_write_partial for details of each variant.  One, and only
607    one, of readbuf or writebuf must be non-NULL.  */
608
609 static LONGEST
610 sol_thread_xfer_partial (struct target_ops *ops, enum target_object object,
611                           const char *annex, gdb_byte *readbuf,
612                           const gdb_byte *writebuf,
613                          ULONGEST offset, LONGEST len)
614 {
615   int retval;
616   struct cleanup *old_chain;
617   struct target_ops *beneath = find_target_beneath (ops);
618
619   old_chain = save_inferior_ptid ();
620
621   if (is_thread (inferior_ptid) || !target_thread_alive (inferior_ptid))
622     {
623       /* It's either a thread or an LWP that isn't alive.  Any live
624          LWP will do so use the first available.
625
626          NOTE: We don't need to call switch_to_thread; we're just
627          reading memory.  */
628       inferior_ptid = procfs_first_available ();
629     }
630
631   retval = beneath->to_xfer_partial (beneath, object, annex,
632                                      readbuf, writebuf, offset, len);
633
634   do_cleanups (old_chain);
635
636   return retval;
637 }
638
639 static void
640 check_for_thread_db (void)
641 {
642   td_err_e err;
643   ptid_t ptid;
644
645   /* Do nothing if we couldn't load libthread_db.so.1.  */
646   if (p_td_ta_new == NULL)
647     return;
648
649   if (sol_thread_active)
650     /* Nothing to do.  The thread library was already detected and the
651        target vector was already activated.  */
652     return;
653
654   /* Now, initialize libthread_db.  This needs to be done after the
655      shared libraries are located because it needs information from
656      the user's thread library.  */
657
658   err = p_td_init ();
659   if (err != TD_OK)
660     {
661       warning (_("sol_thread_new_objfile: td_init: %s"), td_err_string (err));
662       return;
663     }
664
665   /* Now attempt to open a connection to the thread library.  */
666   err = p_td_ta_new (&main_ph, &main_ta);
667   switch (err)
668     {
669     case TD_NOLIBTHREAD:
670       /* No thread library was detected.  */
671       break;
672
673     case TD_OK:
674       printf_unfiltered (_("[Thread debugging using libthread_db enabled]\n"));
675
676       /* The thread library was detected.  Activate the sol_thread target.  */
677       push_target (&sol_thread_ops);
678       sol_thread_active = 1;
679
680       main_ph.ptid = inferior_ptid; /* Save for xfer_memory.  */
681       ptid = lwp_to_thread (inferior_ptid);
682       if (PIDGET (ptid) != -1)
683         inferior_ptid = ptid;
684
685       target_find_new_threads ();
686       break;
687
688     default:
689       warning (_("Cannot initialize thread debugging library: %s"),
690                td_err_string (err));
691       break;
692     }
693 }
694
695 /* This routine is called whenever a new symbol table is read in, or
696    when all symbol tables are removed.  libthread_db can only be
697    initialized when it finds the right variables in libthread.so.
698    Since it's a shared library, those variables don't show up until
699    the library gets mapped and the symbol table is read in.  */
700
701 static void
702 sol_thread_new_objfile (struct objfile *objfile)
703 {
704   if (objfile != NULL)
705     check_for_thread_db ();
706 }
707
708 /* Clean up after the inferior dies.  */
709
710 static void
711 sol_thread_mourn_inferior (struct target_ops *ops)
712 {
713   struct target_ops *beneath = find_target_beneath (ops);
714
715   sol_thread_active = 0;
716
717   unpush_target (ops);
718
719   beneath->to_mourn_inferior (beneath);
720 }
721
722 /* Return true if PTID is still active in the inferior.  */
723
724 static int
725 sol_thread_alive (struct target_ops *ops, ptid_t ptid)
726 {
727   if (is_thread (ptid))
728     {
729       /* It's a (user-level) thread.  */
730       td_err_e val;
731       td_thrhandle_t th;
732       int pid;
733
734       pid = GET_THREAD (ptid);
735       if ((val = p_td_ta_map_id2thr (main_ta, pid, &th)) != TD_OK)
736         return 0;               /* Thread not found.  */
737       if ((val = p_td_thr_validate (&th)) != TD_OK)
738         return 0;               /* Thread not valid.  */
739       return 1;                 /* Known thread.  */
740     }
741   else
742     {
743       struct target_ops *beneath = find_target_beneath (ops);
744
745       /* It's an LPW; pass the request on to the layer below.  */
746       return beneath->to_thread_alive (beneath, ptid);
747     }
748 }
749
750 \f
751 /* These routines implement the lower half of the thread_db interface,
752    i.e. the ps_* routines.  */
753
754 /* Various versions of <proc_service.h> have slightly different
755    function prototypes.  In particular, we have
756
757    NEWER                        OLDER
758    struct ps_prochandle *       const struct ps_prochandle *
759    void*                        char*
760    const void*                  char*
761    int                          size_t
762
763    Which one you have depends on the Solaris version and what patches
764    you've applied.  On the theory that there are only two major
765    variants, we have configure check the prototype of ps_pdwrite (),
766    and use that info to make appropriate typedefs here.  */
767
768 #ifdef PROC_SERVICE_IS_OLD
769 typedef const struct ps_prochandle *gdb_ps_prochandle_t;
770 typedef char *gdb_ps_read_buf_t;
771 typedef char *gdb_ps_write_buf_t;
772 typedef int gdb_ps_size_t;
773 typedef psaddr_t gdb_ps_addr_t;
774 #else
775 typedef struct ps_prochandle *gdb_ps_prochandle_t;
776 typedef void *gdb_ps_read_buf_t;
777 typedef const void *gdb_ps_write_buf_t;
778 typedef size_t gdb_ps_size_t;
779 typedef psaddr_t gdb_ps_addr_t;
780 #endif
781
782 /* The next four routines are called by libthread_db to tell us to
783    stop and stop a particular process or lwp.  Since GDB ensures that
784    these are all stopped by the time we call anything in thread_db,
785    these routines need to do nothing.  */
786
787 /* Process stop.  */
788
789 ps_err_e
790 ps_pstop (gdb_ps_prochandle_t ph)
791 {
792   return PS_OK;
793 }
794
795 /* Process continue.  */
796
797 ps_err_e
798 ps_pcontinue (gdb_ps_prochandle_t ph)
799 {
800   return PS_OK;
801 }
802
803 /* LWP stop.  */
804
805 ps_err_e
806 ps_lstop (gdb_ps_prochandle_t ph, lwpid_t lwpid)
807 {
808   return PS_OK;
809 }
810
811 /* LWP continue.  */
812
813 ps_err_e
814 ps_lcontinue (gdb_ps_prochandle_t ph, lwpid_t lwpid)
815 {
816   return PS_OK;
817 }
818
819 /* Looks up the symbol LD_SYMBOL_NAME in the debugger's symbol table.  */
820
821 ps_err_e
822 ps_pglobal_lookup (gdb_ps_prochandle_t ph, const char *ld_object_name,
823                    const char *ld_symbol_name, gdb_ps_addr_t *ld_symbol_addr)
824 {
825   struct minimal_symbol *ms;
826
827   ms = lookup_minimal_symbol (ld_symbol_name, NULL, NULL);
828   if (!ms)
829     return PS_NOSYM;
830
831   *ld_symbol_addr = SYMBOL_VALUE_ADDRESS (ms);
832   return PS_OK;
833 }
834
835 /* Common routine for reading and writing memory.  */
836
837 static ps_err_e
838 rw_common (int dowrite, const struct ps_prochandle *ph, gdb_ps_addr_t addr,
839            char *buf, int size)
840 {
841   int ret;
842   struct cleanup *old_chain;
843
844   old_chain = save_inferior_ptid ();
845
846   if (is_thread (inferior_ptid) || !target_thread_alive (inferior_ptid))
847     {
848       /* It's either a thread or an LWP that isn't alive.  Any live
849          LWP will do so use the first available.
850
851          NOTE: We don't need to call switch_to_thread; we're just
852          reading memory.  */
853       inferior_ptid = procfs_first_available ();
854     }
855
856 #if defined (__sparcv9)
857   /* For Sparc64 cross Sparc32, make sure the address has not been
858      accidentally sign-extended (or whatever) to beyond 32 bits.  */
859   if (bfd_get_arch_size (exec_bfd) == 32)
860     addr &= 0xffffffff;
861 #endif
862
863   if (dowrite)
864     ret = target_write_memory (addr, buf, size);
865   else
866     ret = target_read_memory (addr, buf, size);
867
868   do_cleanups (old_chain);
869
870   return (ret == 0 ? PS_OK : PS_ERR);
871 }
872
873 /* Copies SIZE bytes from target process .data segment to debugger memory.  */
874
875 ps_err_e
876 ps_pdread (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
877            gdb_ps_read_buf_t buf, gdb_ps_size_t size)
878 {
879   return rw_common (0, ph, addr, buf, size);
880 }
881
882 /* Copies SIZE bytes from debugger memory .data segment to target process.  */
883
884 ps_err_e
885 ps_pdwrite (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
886             gdb_ps_write_buf_t buf, gdb_ps_size_t size)
887 {
888   return rw_common (1, ph, addr, (char *) buf, size);
889 }
890
891 /* Copies SIZE bytes from target process .text segment to debugger memory.  */
892
893 ps_err_e
894 ps_ptread (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
895            gdb_ps_read_buf_t buf, gdb_ps_size_t size)
896 {
897   return rw_common (0, ph, addr, buf, size);
898 }
899
900 /* Copies SIZE bytes from debugger memory .text segment to target process.  */
901
902 ps_err_e
903 ps_ptwrite (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
904             gdb_ps_write_buf_t buf, gdb_ps_size_t size)
905 {
906   return rw_common (1, ph, addr, (char *) buf, size);
907 }
908
909 /* Get general-purpose registers for LWP.  */
910
911 ps_err_e
912 ps_lgetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, prgregset_t gregset)
913 {
914   struct cleanup *old_chain;
915   struct regcache *regcache;
916
917   old_chain = save_inferior_ptid ();
918
919   inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
920   regcache = get_thread_arch_regcache (inferior_ptid, target_gdbarch);
921
922   target_fetch_registers (regcache, -1);
923   fill_gregset (regcache, (gdb_gregset_t *) gregset, -1);
924
925   do_cleanups (old_chain);
926
927   return PS_OK;
928 }
929
930 /* Set general-purpose registers for LWP.  */
931
932 ps_err_e
933 ps_lsetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
934              const prgregset_t gregset)
935 {
936   struct cleanup *old_chain;
937   struct regcache *regcache;
938
939   old_chain = save_inferior_ptid ();
940
941   inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
942   regcache = get_thread_arch_regcache (inferior_ptid, target_gdbarch);
943
944   supply_gregset (regcache, (const gdb_gregset_t *) gregset);
945   target_store_registers (regcache, -1);
946
947   do_cleanups (old_chain);
948
949   return PS_OK;
950 }
951
952 /* Log a message (sends to gdb_stderr).  */
953
954 void
955 ps_plog (const char *fmt, ...)
956 {
957   va_list args;
958
959   va_start (args, fmt);
960
961   vfprintf_filtered (gdb_stderr, fmt, args);
962 }
963
964 /* Get size of extra register set.  Currently a noop.  */
965
966 ps_err_e
967 ps_lgetxregsize (gdb_ps_prochandle_t ph, lwpid_t lwpid, int *xregsize)
968 {
969 #if 0
970   int lwp_fd;
971   int regsize;
972   ps_err_e val;
973
974   val = get_lwp_fd (ph, lwpid, &lwp_fd);
975   if (val != PS_OK)
976     return val;
977
978   if (ioctl (lwp_fd, PIOCGXREGSIZE, &regsize))
979     {
980       if (errno == EINVAL)
981         return PS_NOFREGS;      /* XXX Wrong code, but this is the closest
982                                    thing in proc_service.h  */
983
984       print_sys_errmsg ("ps_lgetxregsize (): PIOCGXREGSIZE", errno);
985       return PS_ERR;
986     }
987 #endif
988
989   return PS_OK;
990 }
991
992 /* Get extra register set.  Currently a noop.  */
993
994 ps_err_e
995 ps_lgetxregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, caddr_t xregset)
996 {
997 #if 0
998   int lwp_fd;
999   ps_err_e val;
1000
1001   val = get_lwp_fd (ph, lwpid, &lwp_fd);
1002   if (val != PS_OK)
1003     return val;
1004
1005   if (ioctl (lwp_fd, PIOCGXREG, xregset))
1006     {
1007       print_sys_errmsg ("ps_lgetxregs (): PIOCGXREG", errno);
1008       return PS_ERR;
1009     }
1010 #endif
1011
1012   return PS_OK;
1013 }
1014
1015 /* Set extra register set.  Currently a noop.  */
1016
1017 ps_err_e
1018 ps_lsetxregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, caddr_t xregset)
1019 {
1020 #if 0
1021   int lwp_fd;
1022   ps_err_e val;
1023
1024   val = get_lwp_fd (ph, lwpid, &lwp_fd);
1025   if (val != PS_OK)
1026     return val;
1027
1028   if (ioctl (lwp_fd, PIOCSXREG, xregset))
1029     {
1030       print_sys_errmsg ("ps_lsetxregs (): PIOCSXREG", errno);
1031       return PS_ERR;
1032     }
1033 #endif
1034
1035   return PS_OK;
1036 }
1037
1038 /* Get floating-point registers for LWP.  */
1039
1040 ps_err_e
1041 ps_lgetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
1042                prfpregset_t *fpregset)
1043 {
1044   struct cleanup *old_chain;
1045   struct regcache *regcache;
1046
1047   old_chain = save_inferior_ptid ();
1048
1049   inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
1050   regcache = get_thread_arch_regcache (inferior_ptid, target_gdbarch);
1051
1052   target_fetch_registers (regcache, -1);
1053   fill_fpregset (regcache, (gdb_fpregset_t *) fpregset, -1);
1054
1055   do_cleanups (old_chain);
1056
1057   return PS_OK;
1058 }
1059
1060 /* Set floating-point regs for LWP.  */
1061
1062 ps_err_e
1063 ps_lsetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
1064                const prfpregset_t * fpregset)
1065 {
1066   struct cleanup *old_chain;
1067   struct regcache *regcache;
1068
1069   old_chain = save_inferior_ptid ();
1070
1071   inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
1072   regcache = get_thread_arch_regcache (inferior_ptid, target_gdbarch);
1073
1074   supply_fpregset (regcache, (const gdb_fpregset_t *) fpregset);
1075   target_store_registers (regcache, -1);
1076
1077   do_cleanups (old_chain);
1078
1079   return PS_OK;
1080 }
1081
1082 #ifdef PR_MODEL_LP64
1083 /* Identify process as 32-bit or 64-bit.  At the moment we're using
1084    BFD to do this.  There might be a more Solaris-specific
1085    (e.g. procfs) method, but this ought to work.  */
1086
1087 ps_err_e
1088 ps_pdmodel (gdb_ps_prochandle_t ph, int *data_model)
1089 {
1090   if (exec_bfd == 0)
1091     *data_model = PR_MODEL_UNKNOWN;
1092   else if (bfd_get_arch_size (exec_bfd) == 32)
1093     *data_model = PR_MODEL_ILP32;
1094   else
1095     *data_model = PR_MODEL_LP64;
1096
1097   return PS_OK;
1098 }
1099 #endif /* PR_MODEL_LP64 */
1100
1101 #if (defined(__i386__) || defined(__x86_64__)) && defined (sun)
1102
1103 /* Reads the local descriptor table of a LWP.
1104
1105    This function is necessary on x86-solaris only.  Without it, the loading
1106    of libthread_db would fail because of ps_lgetLDT being undefined.  */
1107
1108 ps_err_e
1109 ps_lgetLDT (gdb_ps_prochandle_t ph, lwpid_t lwpid,
1110             struct ssd *pldt)
1111 {
1112   /* NOTE: only used on Solaris, therefore OK to refer to procfs.c.  */
1113   extern struct ssd *procfs_find_LDT_entry (ptid_t);
1114   struct ssd *ret;
1115
1116   /* FIXME: can't I get the process ID from the prochandle or
1117      something?  */
1118
1119   if (PIDGET (inferior_ptid) <= 0 || lwpid <= 0)
1120     return PS_BADLID;
1121
1122   ret = procfs_find_LDT_entry (BUILD_LWP (lwpid, PIDGET (inferior_ptid)));
1123   if (ret)
1124     {
1125       memcpy (pldt, ret, sizeof (struct ssd));
1126       return PS_OK;
1127     }
1128   else
1129     /* LDT not found.  */
1130     return PS_ERR;
1131 }
1132 #endif
1133 \f
1134
1135 /* Convert PTID to printable form.  */
1136
1137 char *
1138 solaris_pid_to_str (struct target_ops *ops, ptid_t ptid)
1139 {
1140   static char buf[100];
1141
1142   if (is_thread (ptid))
1143     {
1144       ptid_t lwp;
1145
1146       lwp = thread_to_lwp (ptid, -2);
1147
1148       if (PIDGET (lwp) == -1)
1149         sprintf (buf, "Thread %ld (defunct)", GET_THREAD (ptid));
1150       else if (PIDGET (lwp) != -2)
1151         sprintf (buf, "Thread %ld (LWP %ld)",
1152                  GET_THREAD (ptid), GET_LWP (lwp));
1153       else
1154         sprintf (buf, "Thread %ld        ", GET_THREAD (ptid));
1155     }
1156   else if (GET_LWP (ptid) != 0)
1157     sprintf (buf, "LWP    %ld        ", GET_LWP (ptid));
1158   else
1159     sprintf (buf, "process %d    ", PIDGET (ptid));
1160
1161   return buf;
1162 }
1163 \f
1164
1165 /* Worker bee for find_new_threads.  Callback function that gets
1166    called once per user-level thread (i.e. not for LWP's).  */
1167
1168 static int
1169 sol_find_new_threads_callback (const td_thrhandle_t *th, void *ignored)
1170 {
1171   td_err_e retval;
1172   td_thrinfo_t ti;
1173   ptid_t ptid;
1174
1175   retval = p_td_thr_get_info (th, &ti);
1176   if (retval != TD_OK)
1177     return -1;
1178
1179   ptid = BUILD_THREAD (ti.ti_tid, PIDGET (inferior_ptid));
1180   if (!in_thread_list (ptid) || is_exited (ptid))
1181     add_thread (ptid);
1182
1183   return 0;
1184 }
1185
1186 static void
1187 sol_find_new_threads (struct target_ops *ops)
1188 {
1189   struct target_ops *beneath = find_target_beneath (ops);
1190
1191   /* First Find any new LWP's.  */
1192   if (beneath->to_find_new_threads != NULL)
1193     beneath->to_find_new_threads (beneath);
1194
1195   /* Then find any new user-level threads.  */
1196   p_td_ta_thr_iter (main_ta, sol_find_new_threads_callback, (void *) 0,
1197                     TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
1198                     TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
1199 }
1200
1201 /* Worker bee for the "info sol-thread" command.  This is a callback
1202    function that gets called once for each Solaris user-level thread
1203    (i.e. not for LWPs) in the inferior.  Print anything interesting
1204    that we can think of.  */
1205
1206 static int
1207 info_cb (const td_thrhandle_t *th, void *s)
1208 {
1209   td_err_e ret;
1210   td_thrinfo_t ti;
1211
1212   ret = p_td_thr_get_info (th, &ti);
1213   if (ret == TD_OK)
1214     {
1215       printf_filtered ("%s thread #%d, lwp %d, ",
1216                        ti.ti_type == TD_THR_SYSTEM ? "system" : "user  ",
1217                        ti.ti_tid, ti.ti_lid);
1218       switch (ti.ti_state)
1219         {
1220         default:
1221         case TD_THR_UNKNOWN:
1222           printf_filtered ("<unknown state>");
1223           break;
1224         case TD_THR_STOPPED:
1225           printf_filtered ("(stopped)");
1226           break;
1227         case TD_THR_RUN:
1228           printf_filtered ("(run)    ");
1229           break;
1230         case TD_THR_ACTIVE:
1231           printf_filtered ("(active) ");
1232           break;
1233         case TD_THR_ZOMBIE:
1234           printf_filtered ("(zombie) ");
1235           break;
1236         case TD_THR_SLEEP:
1237           printf_filtered ("(asleep) ");
1238           break;
1239         case TD_THR_STOPPED_ASLEEP:
1240           printf_filtered ("(stopped asleep)");
1241           break;
1242         }
1243       /* Print thr_create start function.  */
1244       if (ti.ti_startfunc != 0)
1245         {
1246           struct minimal_symbol *msym;
1247           msym = lookup_minimal_symbol_by_pc (ti.ti_startfunc);
1248           if (msym)
1249             printf_filtered ("   startfunc: %s\n",
1250                              SYMBOL_PRINT_NAME (msym));
1251           else
1252             printf_filtered ("   startfunc: %s\n",
1253                              paddress (target_gdbarch, ti.ti_startfunc));
1254         }
1255
1256       /* If thread is asleep, print function that went to sleep.  */
1257       if (ti.ti_state == TD_THR_SLEEP)
1258         {
1259           struct minimal_symbol *msym;
1260           msym = lookup_minimal_symbol_by_pc (ti.ti_pc);
1261           if (msym)
1262             printf_filtered (" - Sleep func: %s\n",
1263                              SYMBOL_PRINT_NAME (msym));
1264           else
1265             printf_filtered (" - Sleep func: %s\n",
1266                              paddress (target_gdbarch, ti.ti_startfunc));
1267         }
1268
1269       /* Wrap up line, if necessary.  */
1270       if (ti.ti_state != TD_THR_SLEEP && ti.ti_startfunc == 0)
1271         printf_filtered ("\n"); /* don't you hate counting newlines?  */
1272     }
1273   else
1274     warning (_("info sol-thread: failed to get info for thread."));
1275
1276   return 0;
1277 }
1278
1279 /* List some state about each Solaris user-level thread in the
1280    inferior.  */
1281
1282 static void
1283 info_solthreads (char *args, int from_tty)
1284 {
1285   p_td_ta_thr_iter (main_ta, info_cb, args,
1286                     TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
1287                     TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
1288 }
1289
1290 /* Callback routine used to find a thread based on the TID part of
1291    its PTID.  */
1292
1293 static int
1294 thread_db_find_thread_from_tid (struct thread_info *thread, void *data)
1295 {
1296   long *tid = (long *) data;
1297
1298   if (ptid_get_tid (thread->ptid) == *tid)
1299     return 1;
1300
1301   return 0;
1302 }
1303
1304 static ptid_t
1305 sol_get_ada_task_ptid (long lwp, long thread)
1306 {
1307   struct thread_info *thread_info =
1308     iterate_over_threads (thread_db_find_thread_from_tid, &thread);
1309
1310   if (thread_info == NULL)
1311     {
1312       /* The list of threads is probably not up to date.  Find any
1313          thread that is missing from the list, and try again.  */
1314       sol_find_new_threads (&current_target);
1315       thread_info = iterate_over_threads (thread_db_find_thread_from_tid,
1316                                           &thread);
1317     }
1318
1319   gdb_assert (thread_info != NULL);
1320
1321   return (thread_info->ptid);
1322 }
1323
1324 static void
1325 init_sol_thread_ops (void)
1326 {
1327   sol_thread_ops.to_shortname = "solaris-threads";
1328   sol_thread_ops.to_longname = "Solaris threads and pthread.";
1329   sol_thread_ops.to_doc = "Solaris threads and pthread support.";
1330   sol_thread_ops.to_detach = sol_thread_detach;
1331   sol_thread_ops.to_resume = sol_thread_resume;
1332   sol_thread_ops.to_wait = sol_thread_wait;
1333   sol_thread_ops.to_fetch_registers = sol_thread_fetch_registers;
1334   sol_thread_ops.to_store_registers = sol_thread_store_registers;
1335   sol_thread_ops.to_xfer_partial = sol_thread_xfer_partial;
1336   sol_thread_ops.to_mourn_inferior = sol_thread_mourn_inferior;
1337   sol_thread_ops.to_thread_alive = sol_thread_alive;
1338   sol_thread_ops.to_pid_to_str = solaris_pid_to_str;
1339   sol_thread_ops.to_find_new_threads = sol_find_new_threads;
1340   sol_thread_ops.to_stratum = thread_stratum;
1341   sol_thread_ops.to_get_ada_task_ptid = sol_get_ada_task_ptid;
1342   sol_thread_ops.to_magic = OPS_MAGIC;
1343 }
1344
1345 void
1346 _initialize_sol_thread (void)
1347 {
1348   void *dlhandle;
1349
1350   init_sol_thread_ops ();
1351
1352   dlhandle = dlopen ("libthread_db.so.1", RTLD_NOW);
1353   if (!dlhandle)
1354     goto die;
1355
1356 #define resolve(X) \
1357   if (!(p_##X = dlsym (dlhandle, #X))) \
1358     goto die;
1359
1360   resolve (td_log);
1361   resolve (td_ta_new);
1362   resolve (td_ta_delete);
1363   resolve (td_init);
1364   resolve (td_ta_get_ph);
1365   resolve (td_ta_get_nthreads);
1366   resolve (td_ta_tsd_iter);
1367   resolve (td_ta_thr_iter);
1368   resolve (td_thr_validate);
1369   resolve (td_thr_tsd);
1370   resolve (td_thr_get_info);
1371   resolve (td_thr_getfpregs);
1372   resolve (td_thr_getxregsize);
1373   resolve (td_thr_getxregs);
1374   resolve (td_thr_sigsetmask);
1375   resolve (td_thr_setprio);
1376   resolve (td_thr_setsigpending);
1377   resolve (td_thr_setfpregs);
1378   resolve (td_thr_setxregs);
1379   resolve (td_ta_map_id2thr);
1380   resolve (td_ta_map_lwp2thr);
1381   resolve (td_thr_getgregs);
1382   resolve (td_thr_setgregs);
1383
1384   add_target (&sol_thread_ops);
1385
1386   add_cmd ("sol-threads", class_maintenance, info_solthreads,
1387            _("Show info on Solaris user threads."), &maintenanceinfolist);
1388
1389   /* Hook into new_objfile notification.  */
1390   observer_attach_new_objfile (sol_thread_new_objfile);
1391   return;
1392
1393  die:
1394   fprintf_unfiltered (gdb_stderr, "\
1395 [GDB will not be able to debug user-mode threads: %s]\n", dlerror ());
1396
1397   if (dlhandle)
1398     dlclose (dlhandle);
1399
1400   return;
1401 }