Fix gdb C++ compilation on Solaris (PR build/20712)
[external/binutils.git] / gdb / sol-thread.c
1 /* Solaris threads debugging interface.
2
3    Copyright (C) 1996-2016 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 <sys/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 "procfs.h"
68 #include "symtab.h"
69 #include "minsyms.h"
70 #include "objfiles.h"
71
72 struct target_ops sol_thread_ops;
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 /* Types of the libthread_db functions.  */
102
103 typedef void (td_log_ftype)(const int on_off);
104 typedef td_err_e (td_ta_new_ftype)(const struct ps_prochandle *ph_p,
105                                    td_thragent_t **ta_pp);
106 typedef td_err_e (td_ta_delete_ftype)(td_thragent_t *ta_p);
107 typedef td_err_e (td_init_ftype)(void);
108 typedef td_err_e (td_ta_get_ph_ftype)(const td_thragent_t *ta_p,
109                                       struct ps_prochandle **ph_pp);
110 typedef td_err_e (td_ta_get_nthreads_ftype)(const td_thragent_t *ta_p,
111                                             int *nthread_p);
112 typedef td_err_e (td_ta_tsd_iter_ftype)(const td_thragent_t *ta_p,
113                                         td_key_iter_f *cb, void *cbdata_p);
114 typedef td_err_e (td_ta_thr_iter_ftype)(const td_thragent_t *ta_p,
115                                         td_thr_iter_f *cb, void *cbdata_p,
116                                         td_thr_state_e state, int ti_pri,
117                                         sigset_t *ti_sigmask_p,
118                                         unsigned ti_user_flags);
119 typedef td_err_e (td_thr_validate_ftype)(const td_thrhandle_t *th_p);
120 typedef td_err_e (td_thr_tsd_ftype)(const td_thrhandle_t * th_p,
121                                     const thread_key_t key, void **data_pp);
122 typedef td_err_e (td_thr_get_info_ftype)(const td_thrhandle_t *th_p,
123                                          td_thrinfo_t *ti_p);
124 typedef td_err_e (td_thr_getfpregs_ftype)(const td_thrhandle_t *th_p,
125                                           prfpregset_t *fpregset);
126 typedef td_err_e (td_thr_getxregsize_ftype)(const td_thrhandle_t *th_p,
127                                             int *xregsize);
128 typedef td_err_e (td_thr_getxregs_ftype)(const td_thrhandle_t *th_p,
129                                          const caddr_t xregset);
130 typedef td_err_e (td_thr_sigsetmask_ftype)(const td_thrhandle_t *th_p,
131                                            const sigset_t ti_sigmask);
132 typedef td_err_e (td_thr_setprio_ftype)(const td_thrhandle_t *th_p,
133                                         const int ti_pri);
134 typedef td_err_e (td_thr_setsigpending_ftype)(const td_thrhandle_t *th_p,
135                                               const uchar_t ti_pending_flag,
136                                               const sigset_t ti_pending);
137 typedef td_err_e (td_thr_setfpregs_ftype)(const td_thrhandle_t *th_p,
138                                           const prfpregset_t *fpregset);
139 typedef td_err_e (td_thr_setxregs_ftype)(const td_thrhandle_t *th_p,
140                                          const caddr_t xregset);
141 typedef td_err_e (td_ta_map_id2thr_ftype)(const td_thragent_t *ta_p,
142                                           thread_t tid,
143                                           td_thrhandle_t *th_p);
144 typedef td_err_e (td_ta_map_lwp2thr_ftype)(const td_thragent_t *ta_p,
145                                            lwpid_t lwpid,
146                                            td_thrhandle_t *th_p);
147 typedef td_err_e (td_thr_getgregs_ftype)(const td_thrhandle_t *th_p,
148                                          prgregset_t regset);
149 typedef td_err_e (td_thr_setgregs_ftype)(const td_thrhandle_t *th_p,
150                                          const prgregset_t regset);
151
152 /* Pointers to routines from libthread_db resolved by dlopen().  */
153
154 static td_log_ftype *p_td_log;
155 static td_ta_new_ftype *p_td_ta_new;
156 static td_ta_delete_ftype *p_td_ta_delete;
157 static td_init_ftype *p_td_init;
158 static td_ta_get_ph_ftype *p_td_ta_get_ph;
159 static td_ta_get_nthreads_ftype *p_td_ta_get_nthreads;
160 static td_ta_tsd_iter_ftype *p_td_ta_tsd_iter;
161 static td_ta_thr_iter_ftype *p_td_ta_thr_iter;
162 static td_thr_validate_ftype *p_td_thr_validate;
163 static td_thr_tsd_ftype *p_td_thr_tsd;
164 static td_thr_get_info_ftype *p_td_thr_get_info;
165 static td_thr_getfpregs_ftype *p_td_thr_getfpregs;
166 static td_thr_getxregsize_ftype *p_td_thr_getxregsize;
167 static td_thr_getxregs_ftype *p_td_thr_getxregs;
168 static td_thr_sigsetmask_ftype *p_td_thr_sigsetmask;
169 static td_thr_setprio_ftype *p_td_thr_setprio;
170 static td_thr_setsigpending_ftype *p_td_thr_setsigpending;
171 static td_thr_setfpregs_ftype *p_td_thr_setfpregs;
172 static td_thr_setxregs_ftype *p_td_thr_setxregs;
173 static td_ta_map_id2thr_ftype *p_td_ta_map_id2thr;
174 static td_ta_map_lwp2thr_ftype *p_td_ta_map_lwp2thr;
175 static td_thr_getgregs_ftype *p_td_thr_getgregs;
176 static td_thr_setgregs_ftype *p_td_thr_setgregs;
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   xsnprintf (buf, sizeof (buf), "Unknown libthread_db error code: %d",
218              errcode);
219
220   return buf;
221 }
222
223 /* Return the libthread_db state string assicoated with STATECODE.
224    If STATECODE is unknown, return an appropriate message.  */
225
226 static char *
227 td_state_string (td_thr_state_e statecode)
228 {
229   static struct string_map td_thr_state_table[] =
230   {
231     { TD_THR_ANY_STATE, "any state" },
232     { TD_THR_UNKNOWN, "unknown" },
233     { TD_THR_STOPPED, "stopped" },
234     { TD_THR_RUN, "run" },
235     { TD_THR_ACTIVE, "active" },
236     { TD_THR_ZOMBIE, "zombie" },
237     { TD_THR_SLEEP, "sleep" },
238     { TD_THR_STOPPED_ASLEEP, "stopped asleep" }
239   };
240   const int td_thr_state_table_size =
241     sizeof td_thr_state_table / sizeof (struct string_map);
242   int i;
243   static char buf[50];
244
245   for (i = 0; i < td_thr_state_table_size; i++)
246     if (td_thr_state_table[i].num == statecode)
247       return td_thr_state_table[i].str;
248
249   xsnprintf (buf, sizeof (buf), "Unknown libthread_db state code: %d",
250              statecode);
251
252   return buf;
253 }
254 \f
255
256 /* Convert a POSIX or Solaris thread ID into a LWP ID.  If THREAD_ID
257    doesn't exist, that's an error.  If it's an inactive thread, return
258    DEFAULT_LWP.
259
260    NOTE: This function probably shouldn't call error().  */
261
262 static ptid_t
263 thread_to_lwp (ptid_t thread_id, int default_lwp)
264 {
265   td_thrinfo_t ti;
266   td_thrhandle_t th;
267   td_err_e val;
268
269   if (ptid_lwp_p (thread_id))
270     return thread_id;           /* It's already an LWP ID.  */
271
272   /* It's a thread.  Convert to LWP.  */
273
274   val = p_td_ta_map_id2thr (main_ta, ptid_get_tid (thread_id), &th);
275   if (val == TD_NOTHR)
276     return pid_to_ptid (-1);    /* Thread must have terminated.  */
277   else if (val != TD_OK)
278     error (_("thread_to_lwp: td_ta_map_id2thr %s"), td_err_string (val));
279
280   val = p_td_thr_get_info (&th, &ti);
281   if (val == TD_NOTHR)
282     return pid_to_ptid (-1);    /* Thread must have terminated.  */
283   else if (val != TD_OK)
284     error (_("thread_to_lwp: td_thr_get_info: %s"), td_err_string (val));
285
286   if (ti.ti_state != TD_THR_ACTIVE)
287     {
288       if (default_lwp != -1)
289         return pid_to_ptid (default_lwp);
290       error (_("thread_to_lwp: thread state not active: %s"),
291              td_state_string (ti.ti_state));
292     }
293
294   return ptid_build (ptid_get_pid (thread_id), ti.ti_lid, 0);
295 }
296
297 /* Convert an LWP ID into a POSIX or Solaris thread ID.  If LWP_ID
298    doesn't exists, that's an error.
299
300    NOTE: This function probably shouldn't call error().  */
301
302 static ptid_t
303 lwp_to_thread (ptid_t lwp)
304 {
305   td_thrinfo_t ti;
306   td_thrhandle_t th;
307   td_err_e val;
308
309   if (ptid_tid_p (lwp))
310     return lwp;                 /* It's already a thread ID.  */
311
312   /* It's an LWP.  Convert it to a thread ID.  */
313
314   if (!target_thread_alive (lwp))
315     return pid_to_ptid (-1);    /* Must be a defunct LPW.  */
316
317   val = p_td_ta_map_lwp2thr (main_ta, ptid_get_lwp (lwp), &th);
318   if (val == TD_NOTHR)
319     return pid_to_ptid (-1);    /* Thread must have terminated.  */
320   else if (val != TD_OK)
321     error (_("lwp_to_thread: td_ta_map_lwp2thr: %s."), td_err_string (val));
322
323   val = p_td_thr_validate (&th);
324   if (val == TD_NOTHR)
325     return lwp;                 /* Unknown to libthread; just return LPW,  */
326   else if (val != TD_OK)
327     error (_("lwp_to_thread: td_thr_validate: %s."), td_err_string (val));
328
329   val = p_td_thr_get_info (&th, &ti);
330   if (val == TD_NOTHR)
331     return pid_to_ptid (-1);    /* Thread must have terminated.  */
332   else if (val != TD_OK)
333     error (_("lwp_to_thread: td_thr_get_info: %s."), td_err_string (val));
334
335   return ptid_build (ptid_get_pid (lwp), 0 , ti.ti_tid);
336 }
337 \f
338
339 /* Most target vector functions from here on actually just pass
340    through to the layer beneath, as they don't need to do anything
341    specific for threads.  */
342
343 /* Take a program previously attached to and detaches it.  The program
344    resumes execution and will no longer stop on signals, etc.  We'd
345    better not have left any breakpoints in the program or it'll die
346    when it hits one.  For this to work, it may be necessary for the
347    process to have been previously attached.  It *might* work if the
348    program was started via the normal ptrace (PTRACE_TRACEME).  */
349
350 static void
351 sol_thread_detach (struct target_ops *ops, const char *args, int from_tty)
352 {
353   struct target_ops *beneath = find_target_beneath (ops);
354
355   sol_thread_active = 0;
356   inferior_ptid = pid_to_ptid (ptid_get_pid (main_ph.ptid));
357   unpush_target (ops);
358   beneath->to_detach (beneath, args, from_tty);
359 }
360
361 /* Resume execution of process PTID.  If STEP is nozero, then just
362    single step it.  If SIGNAL is nonzero, restart it with that signal
363    activated.  We may have to convert PTID from a thread ID to an LWP
364    ID for procfs.  */
365
366 static void
367 sol_thread_resume (struct target_ops *ops,
368                    ptid_t ptid, int step, enum gdb_signal signo)
369 {
370   struct cleanup *old_chain;
371   struct target_ops *beneath = find_target_beneath (ops);
372
373   old_chain = save_inferior_ptid ();
374
375   inferior_ptid = thread_to_lwp (inferior_ptid, ptid_get_pid (main_ph.ptid));
376   if (ptid_get_pid (inferior_ptid) == -1)
377     inferior_ptid = procfs_first_available ();
378
379   if (ptid_get_pid (ptid) != -1)
380     {
381       ptid_t save_ptid = ptid;
382
383       ptid = thread_to_lwp (ptid, -2);
384       if (ptid_get_pid (ptid) == -2)            /* Inactive thread.  */
385         error (_("This version of Solaris can't start inactive threads."));
386       if (info_verbose && ptid_get_pid (ptid) == -1)
387         warning (_("Specified thread %ld seems to have terminated"),
388                  ptid_get_tid (save_ptid));
389     }
390
391   beneath->to_resume (beneath, ptid, step, signo);
392
393   do_cleanups (old_chain);
394 }
395
396 /* Wait for any threads to stop.  We may have to convert PTID from a
397    thread ID to an LWP ID, and vice versa on the way out.  */
398
399 static ptid_t
400 sol_thread_wait (struct target_ops *ops,
401                  ptid_t ptid, struct target_waitstatus *ourstatus, int options)
402 {
403   ptid_t rtnval;
404   ptid_t save_ptid;
405   struct target_ops *beneath = find_target_beneath (ops);
406   struct cleanup *old_chain;
407
408   save_ptid = inferior_ptid;
409   old_chain = save_inferior_ptid ();
410
411   inferior_ptid = thread_to_lwp (inferior_ptid, ptid_get_pid (main_ph.ptid));
412   if (ptid_get_pid (inferior_ptid) == -1)
413     inferior_ptid = procfs_first_available ();
414
415   if (ptid_get_pid (ptid) != -1)
416     {
417       ptid_t save_ptid = ptid;
418
419       ptid = thread_to_lwp (ptid, -2);
420       if (ptid_get_pid (ptid) == -2)            /* Inactive thread.  */
421         error (_("This version of Solaris can't start inactive threads."));
422       if (info_verbose && ptid_get_pid (ptid) == -1)
423         warning (_("Specified thread %ld seems to have terminated"),
424                  ptid_get_tid (save_ptid));
425     }
426
427   rtnval = beneath->to_wait (beneath, ptid, ourstatus, options);
428
429   if (ourstatus->kind != TARGET_WAITKIND_EXITED)
430     {
431       /* Map the LWP of interest back to the appropriate thread ID.  */
432       rtnval = lwp_to_thread (rtnval);
433       if (ptid_get_pid (rtnval) == -1)
434         rtnval = save_ptid;
435
436       /* See if we have a new thread.  */
437       if (ptid_tid_p (rtnval)
438           && !ptid_equal (rtnval, save_ptid)
439           && (!in_thread_list (rtnval)
440               || is_exited (rtnval)))
441         add_thread (rtnval);
442     }
443
444   /* During process initialization, we may get here without the thread
445      package being initialized, since that can only happen after we've
446      found the shared libs.  */
447
448   do_cleanups (old_chain);
449
450   return rtnval;
451 }
452
453 static void
454 sol_thread_fetch_registers (struct target_ops *ops,
455                             struct regcache *regcache, int regnum)
456 {
457   thread_t thread;
458   td_thrhandle_t thandle;
459   td_err_e val;
460   prgregset_t gregset;
461   prfpregset_t fpregset;
462   gdb_gregset_t *gregset_p = &gregset;
463   gdb_fpregset_t *fpregset_p = &fpregset;
464   struct target_ops *beneath = find_target_beneath (ops);
465
466   if (!ptid_tid_p (inferior_ptid))
467     {
468       /* It's an LWP; pass the request on to the layer beneath.  */
469       beneath->to_fetch_registers (beneath, regcache, regnum);
470       return;
471     }
472
473   /* Solaris thread: convert INFERIOR_PTID into a td_thrhandle_t.  */
474   thread = ptid_get_tid (inferior_ptid);
475   if (thread == 0)
476     error (_("sol_thread_fetch_registers: thread == 0"));
477
478   val = p_td_ta_map_id2thr (main_ta, thread, &thandle);
479   if (val != TD_OK)
480     error (_("sol_thread_fetch_registers: td_ta_map_id2thr: %s"),
481            td_err_string (val));
482
483   /* Get the general-purpose registers.  */
484
485   val = p_td_thr_getgregs (&thandle, gregset);
486   if (val != TD_OK && val != TD_PARTIALREG)
487     error (_("sol_thread_fetch_registers: td_thr_getgregs %s"),
488            td_err_string (val));
489
490   /* For SPARC, TD_PARTIALREG means that only %i0...%i7, %l0..%l7, %pc
491      and %sp are saved (by a thread context switch).  */
492
493   /* And, now the floating-point registers.  */
494
495   val = p_td_thr_getfpregs (&thandle, &fpregset);
496   if (val != TD_OK && val != TD_NOFPREGS)
497     error (_("sol_thread_fetch_registers: td_thr_getfpregs %s"),
498            td_err_string (val));
499
500   /* Note that we must call supply_gregset and supply_fpregset *after*
501      calling the td routines because the td routines call ps_lget*
502      which affect the values stored in the registers array.  */
503
504   supply_gregset (regcache, (const gdb_gregset_t *) gregset_p);
505   supply_fpregset (regcache, (const gdb_fpregset_t *) fpregset_p);
506 }
507
508 static void
509 sol_thread_store_registers (struct target_ops *ops,
510                             struct regcache *regcache, int regnum)
511 {
512   thread_t thread;
513   td_thrhandle_t thandle;
514   td_err_e val;
515   prgregset_t gregset;
516   prfpregset_t fpregset;
517
518   if (!ptid_tid_p (inferior_ptid))
519     {
520       struct target_ops *beneath = find_target_beneath (ops);
521
522       /* It's an LWP; pass the request on to the layer beneath.  */
523       beneath->to_store_registers (beneath, regcache, regnum);
524       return;
525     }
526
527   /* Solaris thread: convert INFERIOR_PTID into a td_thrhandle_t.  */
528   thread = ptid_get_tid (inferior_ptid);
529
530   val = p_td_ta_map_id2thr (main_ta, thread, &thandle);
531   if (val != TD_OK)
532     error (_("sol_thread_store_registers: td_ta_map_id2thr %s"),
533            td_err_string (val));
534
535   if (regnum != -1)
536     {
537       /* Not writing all the registers.  */
538       char old_value[MAX_REGISTER_SIZE];
539
540       /* Save new register value.  */
541       regcache_raw_collect (regcache, regnum, old_value);
542
543       val = p_td_thr_getgregs (&thandle, gregset);
544       if (val != TD_OK)
545         error (_("sol_thread_store_registers: td_thr_getgregs %s"),
546                td_err_string (val));
547       val = p_td_thr_getfpregs (&thandle, &fpregset);
548       if (val != TD_OK)
549         error (_("sol_thread_store_registers: td_thr_getfpregs %s"),
550                td_err_string (val));
551
552       /* Restore new register value.  */
553       regcache_raw_supply (regcache, regnum, old_value);
554     }
555
556   fill_gregset (regcache, (gdb_gregset_t *) &gregset, regnum);
557   fill_fpregset (regcache, (gdb_fpregset_t *) &fpregset, regnum);
558
559   val = p_td_thr_setgregs (&thandle, gregset);
560   if (val != TD_OK)
561     error (_("sol_thread_store_registers: td_thr_setgregs %s"),
562            td_err_string (val));
563   val = p_td_thr_setfpregs (&thandle, &fpregset);
564   if (val != TD_OK)
565     error (_("sol_thread_store_registers: td_thr_setfpregs %s"),
566            td_err_string (val));
567 }
568
569 /* Perform partial transfers on OBJECT.  See target_read_partial and
570    target_write_partial for details of each variant.  One, and only
571    one, of readbuf or writebuf must be non-NULL.  */
572
573 static enum target_xfer_status
574 sol_thread_xfer_partial (struct target_ops *ops, enum target_object object,
575                           const char *annex, gdb_byte *readbuf,
576                           const gdb_byte *writebuf,
577                          ULONGEST offset, ULONGEST len, ULONGEST *xfered_len)
578 {
579   enum target_xfer_status retval;
580   struct cleanup *old_chain;
581   struct target_ops *beneath = find_target_beneath (ops);
582
583   old_chain = save_inferior_ptid ();
584
585   if (ptid_tid_p (inferior_ptid) || !target_thread_alive (inferior_ptid))
586     {
587       /* It's either a thread or an LWP that isn't alive.  Any live
588          LWP will do so use the first available.
589
590          NOTE: We don't need to call switch_to_thread; we're just
591          reading memory.  */
592       inferior_ptid = procfs_first_available ();
593     }
594
595   retval = beneath->to_xfer_partial (beneath, object, annex, readbuf,
596                                      writebuf, offset, len, xfered_len);
597
598   do_cleanups (old_chain);
599
600   return retval;
601 }
602
603 static void
604 check_for_thread_db (void)
605 {
606   td_err_e err;
607   ptid_t ptid;
608
609   /* Don't attempt to use thread_db for remote targets.  */
610   if (!(target_can_run (&current_target) || core_bfd))
611     return;
612
613   /* Do nothing if we couldn't load libthread_db.so.1.  */
614   if (p_td_ta_new == NULL)
615     return;
616
617   if (sol_thread_active)
618     /* Nothing to do.  The thread library was already detected and the
619        target vector was already activated.  */
620     return;
621
622   /* Now, initialize libthread_db.  This needs to be done after the
623      shared libraries are located because it needs information from
624      the user's thread library.  */
625
626   err = p_td_init ();
627   if (err != TD_OK)
628     {
629       warning (_("sol_thread_new_objfile: td_init: %s"), td_err_string (err));
630       return;
631     }
632
633   /* Now attempt to open a connection to the thread library.  */
634   err = p_td_ta_new (&main_ph, &main_ta);
635   switch (err)
636     {
637     case TD_NOLIBTHREAD:
638       /* No thread library was detected.  */
639       break;
640
641     case TD_OK:
642       printf_unfiltered (_("[Thread debugging using libthread_db enabled]\n"));
643
644       /* The thread library was detected.  Activate the sol_thread target.  */
645       push_target (&sol_thread_ops);
646       sol_thread_active = 1;
647
648       main_ph.ptid = inferior_ptid; /* Save for xfer_memory.  */
649       ptid = lwp_to_thread (inferior_ptid);
650       if (ptid_get_pid (ptid) != -1)
651         inferior_ptid = ptid;
652
653       target_update_thread_list ();
654       break;
655
656     default:
657       warning (_("Cannot initialize thread debugging library: %s"),
658                td_err_string (err));
659       break;
660     }
661 }
662
663 /* This routine is called whenever a new symbol table is read in, or
664    when all symbol tables are removed.  libthread_db can only be
665    initialized when it finds the right variables in libthread.so.
666    Since it's a shared library, those variables don't show up until
667    the library gets mapped and the symbol table is read in.  */
668
669 static void
670 sol_thread_new_objfile (struct objfile *objfile)
671 {
672   if (objfile != NULL)
673     check_for_thread_db ();
674 }
675
676 /* Clean up after the inferior dies.  */
677
678 static void
679 sol_thread_mourn_inferior (struct target_ops *ops)
680 {
681   struct target_ops *beneath = find_target_beneath (ops);
682
683   sol_thread_active = 0;
684
685   unpush_target (ops);
686
687   beneath->to_mourn_inferior (beneath);
688 }
689
690 /* Return true if PTID is still active in the inferior.  */
691
692 static int
693 sol_thread_alive (struct target_ops *ops, ptid_t ptid)
694 {
695   if (ptid_tid_p (ptid))
696     {
697       /* It's a (user-level) thread.  */
698       td_err_e val;
699       td_thrhandle_t th;
700       int pid;
701
702       pid = ptid_get_tid (ptid);
703       if ((val = p_td_ta_map_id2thr (main_ta, pid, &th)) != TD_OK)
704         return 0;               /* Thread not found.  */
705       if ((val = p_td_thr_validate (&th)) != TD_OK)
706         return 0;               /* Thread not valid.  */
707       return 1;                 /* Known thread.  */
708     }
709   else
710     {
711       struct target_ops *beneath = find_target_beneath (ops);
712
713       /* It's an LPW; pass the request on to the layer below.  */
714       return beneath->to_thread_alive (beneath, ptid);
715     }
716 }
717
718 \f
719 /* These routines implement the lower half of the thread_db interface,
720    i.e. the ps_* routines.  */
721
722 /* Various versions of <proc_service.h> have slightly different
723    function prototypes.  In particular, we have
724
725    NEWER                        OLDER
726    struct ps_prochandle *       const struct ps_prochandle *
727    void*                        char*
728    const void*                  char*
729    int                          size_t
730
731    Which one you have depends on the Solaris version and what patches
732    you've applied.  On the theory that there are only two major
733    variants, we have configure check the prototype of ps_pdwrite (),
734    and use that info to make appropriate typedefs here.  */
735
736 #ifdef PROC_SERVICE_IS_OLD
737 typedef const struct ps_prochandle *gdb_ps_prochandle_t;
738 typedef char *gdb_ps_read_buf_t;
739 typedef char *gdb_ps_write_buf_t;
740 typedef int gdb_ps_size_t;
741 typedef psaddr_t gdb_ps_addr_t;
742 #else
743 typedef struct ps_prochandle *gdb_ps_prochandle_t;
744 typedef void *gdb_ps_read_buf_t;
745 typedef const void *gdb_ps_write_buf_t;
746 typedef size_t gdb_ps_size_t;
747 typedef psaddr_t gdb_ps_addr_t;
748 #endif
749
750 /* The next four routines are called by libthread_db to tell us to
751    stop and stop a particular process or lwp.  Since GDB ensures that
752    these are all stopped by the time we call anything in thread_db,
753    these routines need to do nothing.  */
754
755 /* Process stop.  */
756
757 ps_err_e
758 ps_pstop (gdb_ps_prochandle_t ph)
759 {
760   return PS_OK;
761 }
762
763 /* Process continue.  */
764
765 ps_err_e
766 ps_pcontinue (gdb_ps_prochandle_t ph)
767 {
768   return PS_OK;
769 }
770
771 /* LWP stop.  */
772
773 ps_err_e
774 ps_lstop (gdb_ps_prochandle_t ph, lwpid_t lwpid)
775 {
776   return PS_OK;
777 }
778
779 /* LWP continue.  */
780
781 ps_err_e
782 ps_lcontinue (gdb_ps_prochandle_t ph, lwpid_t lwpid)
783 {
784   return PS_OK;
785 }
786
787 /* Looks up the symbol LD_SYMBOL_NAME in the debugger's symbol table.  */
788
789 ps_err_e
790 ps_pglobal_lookup (gdb_ps_prochandle_t ph, const char *ld_object_name,
791                    const char *ld_symbol_name, gdb_ps_addr_t *ld_symbol_addr)
792 {
793   struct bound_minimal_symbol ms;
794
795   ms = lookup_minimal_symbol (ld_symbol_name, NULL, NULL);
796   if (!ms.minsym)
797     return PS_NOSYM;
798
799   *ld_symbol_addr = BMSYMBOL_VALUE_ADDRESS (ms);
800   return PS_OK;
801 }
802
803 /* Common routine for reading and writing memory.  */
804
805 static ps_err_e
806 rw_common (int dowrite, const struct ps_prochandle *ph, gdb_ps_addr_t addr,
807            gdb_byte *buf, int size)
808 {
809   int ret;
810   struct cleanup *old_chain;
811
812   old_chain = save_inferior_ptid ();
813
814   if (ptid_tid_p (inferior_ptid) || !target_thread_alive (inferior_ptid))
815     {
816       /* It's either a thread or an LWP that isn't alive.  Any live
817          LWP will do so use the first available.
818
819          NOTE: We don't need to call switch_to_thread; we're just
820          reading memory.  */
821       inferior_ptid = procfs_first_available ();
822     }
823
824 #if defined (__sparcv9)
825   /* For Sparc64 cross Sparc32, make sure the address has not been
826      accidentally sign-extended (or whatever) to beyond 32 bits.  */
827   if (bfd_get_arch_size (exec_bfd) == 32)
828     addr &= 0xffffffff;
829 #endif
830
831   if (dowrite)
832     ret = target_write_memory (addr, (gdb_byte *) buf, size);
833   else
834     ret = target_read_memory (addr, (gdb_byte *) buf, size);
835
836   do_cleanups (old_chain);
837
838   return (ret == 0 ? PS_OK : PS_ERR);
839 }
840
841 /* Copies SIZE bytes from target process .data segment to debugger memory.  */
842
843 ps_err_e
844 ps_pdread (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
845            gdb_ps_read_buf_t buf, gdb_ps_size_t size)
846 {
847   return rw_common (0, ph, addr, (gdb_byte *) buf, size);
848 }
849
850 /* Copies SIZE bytes from debugger memory .data segment to target process.  */
851
852 ps_err_e
853 ps_pdwrite (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
854             gdb_ps_write_buf_t buf, gdb_ps_size_t size)
855 {
856   return rw_common (1, ph, addr, (gdb_byte *) buf, size);
857 }
858
859 /* Copies SIZE bytes from target process .text segment to debugger memory.  */
860
861 ps_err_e
862 ps_ptread (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
863            gdb_ps_read_buf_t buf, gdb_ps_size_t size)
864 {
865   return rw_common (0, ph, addr, (gdb_byte *) buf, size);
866 }
867
868 /* Copies SIZE bytes from debugger memory .text segment to target process.  */
869
870 ps_err_e
871 ps_ptwrite (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
872             gdb_ps_write_buf_t buf, gdb_ps_size_t size)
873 {
874   return rw_common (1, ph, addr, (gdb_byte *) buf, size);
875 }
876
877 /* Get general-purpose registers for LWP.  */
878
879 ps_err_e
880 ps_lgetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, prgregset_t gregset)
881 {
882   struct cleanup *old_chain;
883   struct regcache *regcache;
884
885   old_chain = save_inferior_ptid ();
886
887   inferior_ptid = ptid_build (ptid_get_pid (inferior_ptid), lwpid, 0);
888   regcache = get_thread_arch_regcache (inferior_ptid, target_gdbarch ());
889
890   target_fetch_registers (regcache, -1);
891   fill_gregset (regcache, (gdb_gregset_t *) gregset, -1);
892
893   do_cleanups (old_chain);
894
895   return PS_OK;
896 }
897
898 /* Set general-purpose registers for LWP.  */
899
900 ps_err_e
901 ps_lsetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
902              const prgregset_t gregset)
903 {
904   struct cleanup *old_chain;
905   struct regcache *regcache;
906
907   old_chain = save_inferior_ptid ();
908
909   inferior_ptid = ptid_build (ptid_get_pid (inferior_ptid), lwpid, 0);
910   regcache = get_thread_arch_regcache (inferior_ptid, target_gdbarch ());
911
912   supply_gregset (regcache, (const gdb_gregset_t *) gregset);
913   target_store_registers (regcache, -1);
914
915   do_cleanups (old_chain);
916
917   return PS_OK;
918 }
919
920 /* Log a message (sends to gdb_stderr).  */
921
922 void
923 ps_plog (const char *fmt, ...)
924 {
925   va_list args;
926
927   va_start (args, fmt);
928
929   vfprintf_filtered (gdb_stderr, fmt, args);
930 }
931
932 /* Get size of extra register set.  Currently a noop.  */
933
934 ps_err_e
935 ps_lgetxregsize (gdb_ps_prochandle_t ph, lwpid_t lwpid, int *xregsize)
936 {
937   return PS_OK;
938 }
939
940 /* Get extra register set.  Currently a noop.  */
941
942 ps_err_e
943 ps_lgetxregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, caddr_t xregset)
944 {
945   return PS_OK;
946 }
947
948 /* Set extra register set.  Currently a noop.  */
949
950 ps_err_e
951 ps_lsetxregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, caddr_t xregset)
952 {
953   return PS_OK;
954 }
955
956 /* Get floating-point registers for LWP.  */
957
958 ps_err_e
959 ps_lgetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
960                prfpregset_t *fpregset)
961 {
962   struct cleanup *old_chain;
963   struct regcache *regcache;
964
965   old_chain = save_inferior_ptid ();
966
967   inferior_ptid = ptid_build (ptid_get_pid (inferior_ptid), lwpid, 0);
968   regcache = get_thread_arch_regcache (inferior_ptid, target_gdbarch ());
969
970   target_fetch_registers (regcache, -1);
971   fill_fpregset (regcache, (gdb_fpregset_t *) fpregset, -1);
972
973   do_cleanups (old_chain);
974
975   return PS_OK;
976 }
977
978 /* Set floating-point regs for LWP.  */
979
980 ps_err_e
981 ps_lsetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
982                const prfpregset_t * fpregset)
983 {
984   struct cleanup *old_chain;
985   struct regcache *regcache;
986
987   old_chain = save_inferior_ptid ();
988
989   inferior_ptid = ptid_build (ptid_get_pid (inferior_ptid), lwpid, 0);
990   regcache = get_thread_arch_regcache (inferior_ptid, target_gdbarch ());
991
992   supply_fpregset (regcache, (const gdb_fpregset_t *) fpregset);
993   target_store_registers (regcache, -1);
994
995   do_cleanups (old_chain);
996
997   return PS_OK;
998 }
999
1000 #ifdef PR_MODEL_LP64
1001 /* Identify process as 32-bit or 64-bit.  At the moment we're using
1002    BFD to do this.  There might be a more Solaris-specific
1003    (e.g. procfs) method, but this ought to work.  */
1004
1005 ps_err_e
1006 ps_pdmodel (gdb_ps_prochandle_t ph, int *data_model)
1007 {
1008   if (exec_bfd == 0)
1009     *data_model = PR_MODEL_UNKNOWN;
1010   else if (bfd_get_arch_size (exec_bfd) == 32)
1011     *data_model = PR_MODEL_ILP32;
1012   else
1013     *data_model = PR_MODEL_LP64;
1014
1015   return PS_OK;
1016 }
1017 #endif /* PR_MODEL_LP64 */
1018
1019 #if (defined(__i386__) || defined(__x86_64__)) && defined (sun)
1020
1021 /* Reads the local descriptor table of a LWP.
1022
1023    This function is necessary on x86-solaris only.  Without it, the loading
1024    of libthread_db would fail because of ps_lgetLDT being undefined.  */
1025
1026 ps_err_e
1027 ps_lgetLDT (gdb_ps_prochandle_t ph, lwpid_t lwpid,
1028             struct ssd *pldt)
1029 {
1030   /* NOTE: only used on Solaris, therefore OK to refer to procfs.c.  */
1031   struct ssd *ret;
1032
1033   /* FIXME: can't I get the process ID from the prochandle or
1034      something?  */
1035
1036   if (ptid_get_pid (inferior_ptid) <= 0 || lwpid <= 0)
1037     return PS_BADLID;
1038
1039   ret = procfs_find_LDT_entry (ptid_build (ptid_get_pid (inferior_ptid),
1040                                lwpid, 0));
1041   if (ret)
1042     {
1043       memcpy (pldt, ret, sizeof (struct ssd));
1044       return PS_OK;
1045     }
1046   else
1047     /* LDT not found.  */
1048     return PS_ERR;
1049 }
1050 #endif
1051 \f
1052
1053 /* Convert PTID to printable form.  */
1054
1055 static char *
1056 solaris_pid_to_str (struct target_ops *ops, ptid_t ptid)
1057 {
1058   static char buf[100];
1059
1060   if (ptid_tid_p (ptid))
1061     {
1062       ptid_t lwp;
1063
1064       lwp = thread_to_lwp (ptid, -2);
1065
1066       if (ptid_get_pid (lwp) == -1)
1067         xsnprintf (buf, sizeof (buf), "Thread %ld (defunct)",
1068                    ptid_get_tid (ptid));
1069       else if (ptid_get_pid (lwp) != -2)
1070         xsnprintf (buf, sizeof (buf), "Thread %ld (LWP %ld)",
1071                  ptid_get_tid (ptid), ptid_get_lwp (lwp));
1072       else
1073         xsnprintf (buf, sizeof (buf), "Thread %ld        ",
1074                    ptid_get_tid (ptid));
1075     }
1076   else if (ptid_get_lwp (ptid) != 0)
1077     xsnprintf (buf, sizeof (buf), "LWP    %ld        ", ptid_get_lwp (ptid));
1078   else
1079     xsnprintf (buf, sizeof (buf), "process %d    ", ptid_get_pid (ptid));
1080
1081   return buf;
1082 }
1083 \f
1084
1085 /* Worker bee for update_thread_list.  Callback function that gets
1086    called once per user-level thread (i.e. not for LWP's).  */
1087
1088 static int
1089 sol_update_thread_list_callback (const td_thrhandle_t *th, void *ignored)
1090 {
1091   td_err_e retval;
1092   td_thrinfo_t ti;
1093   ptid_t ptid;
1094
1095   retval = p_td_thr_get_info (th, &ti);
1096   if (retval != TD_OK)
1097     return -1;
1098
1099   ptid = ptid_build (ptid_get_pid (inferior_ptid), 0, ti.ti_tid);
1100   if (!in_thread_list (ptid) || is_exited (ptid))
1101     add_thread (ptid);
1102
1103   return 0;
1104 }
1105
1106 static void
1107 sol_update_thread_list (struct target_ops *ops)
1108 {
1109   struct target_ops *beneath = find_target_beneath (ops);
1110
1111   /* Delete dead threads.  */
1112   prune_threads ();
1113
1114   /* Find any new LWP's.  */
1115   beneath->to_update_thread_list (beneath);
1116
1117   /* Then find any new user-level threads.  */
1118   p_td_ta_thr_iter (main_ta, sol_update_thread_list_callback, (void *) 0,
1119                     TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
1120                     TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
1121 }
1122
1123 /* Worker bee for the "info sol-thread" command.  This is a callback
1124    function that gets called once for each Solaris user-level thread
1125    (i.e. not for LWPs) in the inferior.  Print anything interesting
1126    that we can think of.  */
1127
1128 static int
1129 info_cb (const td_thrhandle_t *th, void *s)
1130 {
1131   td_err_e ret;
1132   td_thrinfo_t ti;
1133
1134   ret = p_td_thr_get_info (th, &ti);
1135   if (ret == TD_OK)
1136     {
1137       printf_filtered ("%s thread #%d, lwp %d, ",
1138                        ti.ti_type == TD_THR_SYSTEM ? "system" : "user  ",
1139                        ti.ti_tid, ti.ti_lid);
1140       switch (ti.ti_state)
1141         {
1142         default:
1143         case TD_THR_UNKNOWN:
1144           printf_filtered ("<unknown state>");
1145           break;
1146         case TD_THR_STOPPED:
1147           printf_filtered ("(stopped)");
1148           break;
1149         case TD_THR_RUN:
1150           printf_filtered ("(run)    ");
1151           break;
1152         case TD_THR_ACTIVE:
1153           printf_filtered ("(active) ");
1154           break;
1155         case TD_THR_ZOMBIE:
1156           printf_filtered ("(zombie) ");
1157           break;
1158         case TD_THR_SLEEP:
1159           printf_filtered ("(asleep) ");
1160           break;
1161         case TD_THR_STOPPED_ASLEEP:
1162           printf_filtered ("(stopped asleep)");
1163           break;
1164         }
1165       /* Print thr_create start function.  */
1166       if (ti.ti_startfunc != 0)
1167         {
1168           const struct bound_minimal_symbol msym
1169             = lookup_minimal_symbol_by_pc (ti.ti_startfunc);
1170
1171           printf_filtered ("   startfunc=%s",
1172                            msym.minsym
1173                            ? MSYMBOL_PRINT_NAME (msym.minsym)
1174                            : paddress (target_gdbarch (), ti.ti_startfunc));
1175         }
1176
1177       /* If thread is asleep, print function that went to sleep.  */
1178       if (ti.ti_state == TD_THR_SLEEP)
1179         {
1180           const struct bound_minimal_symbol msym
1181             = lookup_minimal_symbol_by_pc (ti.ti_pc);
1182
1183           printf_filtered ("   sleepfunc=%s",
1184                            msym.minsym
1185                            ? MSYMBOL_PRINT_NAME (msym.minsym)
1186                            : paddress (target_gdbarch (), ti.ti_pc));
1187         }
1188
1189       printf_filtered ("\n");
1190     }
1191   else
1192     warning (_("info sol-thread: failed to get info for thread."));
1193
1194   return 0;
1195 }
1196
1197 /* List some state about each Solaris user-level thread in the
1198    inferior.  */
1199
1200 static void
1201 info_solthreads (char *args, int from_tty)
1202 {
1203   p_td_ta_thr_iter (main_ta, info_cb, args,
1204                     TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
1205                     TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
1206 }
1207
1208 /* Callback routine used to find a thread based on the TID part of
1209    its PTID.  */
1210
1211 static int
1212 thread_db_find_thread_from_tid (struct thread_info *thread, void *data)
1213 {
1214   long *tid = (long *) data;
1215
1216   if (ptid_get_tid (thread->ptid) == *tid)
1217     return 1;
1218
1219   return 0;
1220 }
1221
1222 static ptid_t
1223 sol_get_ada_task_ptid (struct target_ops *self, long lwp, long thread)
1224 {
1225   struct thread_info *thread_info =
1226     iterate_over_threads (thread_db_find_thread_from_tid, &thread);
1227
1228   if (thread_info == NULL)
1229     {
1230       /* The list of threads is probably not up to date.  Find any
1231          thread that is missing from the list, and try again.  */
1232       sol_update_thread_list (&current_target);
1233       thread_info = iterate_over_threads (thread_db_find_thread_from_tid,
1234                                           &thread);
1235     }
1236
1237   gdb_assert (thread_info != NULL);
1238
1239   return (thread_info->ptid);
1240 }
1241
1242 static void
1243 init_sol_thread_ops (void)
1244 {
1245   sol_thread_ops.to_shortname = "solaris-threads";
1246   sol_thread_ops.to_longname = "Solaris threads and pthread.";
1247   sol_thread_ops.to_doc = "Solaris threads and pthread support.";
1248   sol_thread_ops.to_detach = sol_thread_detach;
1249   sol_thread_ops.to_resume = sol_thread_resume;
1250   sol_thread_ops.to_wait = sol_thread_wait;
1251   sol_thread_ops.to_fetch_registers = sol_thread_fetch_registers;
1252   sol_thread_ops.to_store_registers = sol_thread_store_registers;
1253   sol_thread_ops.to_xfer_partial = sol_thread_xfer_partial;
1254   sol_thread_ops.to_mourn_inferior = sol_thread_mourn_inferior;
1255   sol_thread_ops.to_thread_alive = sol_thread_alive;
1256   sol_thread_ops.to_pid_to_str = solaris_pid_to_str;
1257   sol_thread_ops.to_update_thread_list = sol_update_thread_list;
1258   sol_thread_ops.to_stratum = thread_stratum;
1259   sol_thread_ops.to_get_ada_task_ptid = sol_get_ada_task_ptid;
1260   sol_thread_ops.to_magic = OPS_MAGIC;
1261 }
1262
1263 /* Silence -Wmissing-prototypes.  */
1264 extern void _initialize_sol_thread (void);
1265
1266 void
1267 _initialize_sol_thread (void)
1268 {
1269   void *dlhandle;
1270
1271   init_sol_thread_ops ();
1272
1273   dlhandle = dlopen ("libthread_db.so.1", RTLD_NOW);
1274   if (!dlhandle)
1275     goto die;
1276
1277 #define resolve(X) \
1278   if (!(p_##X = (X ## _ftype *) dlsym (dlhandle, #X)))  \
1279     goto die;
1280
1281   resolve (td_log);
1282   resolve (td_ta_new);
1283   resolve (td_ta_delete);
1284   resolve (td_init);
1285   resolve (td_ta_get_ph);
1286   resolve (td_ta_get_nthreads);
1287   resolve (td_ta_tsd_iter);
1288   resolve (td_ta_thr_iter);
1289   resolve (td_thr_validate);
1290   resolve (td_thr_tsd);
1291   resolve (td_thr_get_info);
1292   resolve (td_thr_getfpregs);
1293   resolve (td_thr_getxregsize);
1294   resolve (td_thr_getxregs);
1295   resolve (td_thr_sigsetmask);
1296   resolve (td_thr_setprio);
1297   resolve (td_thr_setsigpending);
1298   resolve (td_thr_setfpregs);
1299   resolve (td_thr_setxregs);
1300   resolve (td_ta_map_id2thr);
1301   resolve (td_ta_map_lwp2thr);
1302   resolve (td_thr_getgregs);
1303   resolve (td_thr_setgregs);
1304
1305   complete_target_initialization (&sol_thread_ops);
1306
1307   add_cmd ("sol-threads", class_maintenance, info_solthreads,
1308            _("Show info on Solaris user threads."), &maintenanceinfolist);
1309
1310   /* Hook into new_objfile notification.  */
1311   observer_attach_new_objfile (sol_thread_new_objfile);
1312   return;
1313
1314  die:
1315   fprintf_unfiltered (gdb_stderr, "\
1316 [GDB will not be able to debug user-mode threads: %s]\n", dlerror ());
1317
1318   if (dlhandle)
1319     dlclose (dlhandle);
1320
1321   return;
1322 }