xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/sol-thread.c (revision 99e23f81b2b10aef1a10b03588663e472627bb76)
1 /* Solaris threads debugging interface.
2 
3    Copyright (C) 1996-2017 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   const 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 
178 
179 /* Return the libthread_db error string associated with ERRCODE.  If
180    ERRCODE is unknown, return an appropriate message.  */
181 
182 static const 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 const 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 
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 
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   ptid_t ptid = regcache_get_ptid (regcache);
466 
467   if (!ptid_tid_p (ptid))
468     {
469       /* It's an LWP; pass the request on to the layer beneath.  */
470       beneath->to_fetch_registers (beneath, regcache, regnum);
471       return;
472     }
473 
474   /* Solaris thread: convert PTID into a td_thrhandle_t.  */
475   thread = ptid_get_tid (ptid);
476   if (thread == 0)
477     error (_("sol_thread_fetch_registers: thread == 0"));
478 
479   val = p_td_ta_map_id2thr (main_ta, thread, &thandle);
480   if (val != TD_OK)
481     error (_("sol_thread_fetch_registers: td_ta_map_id2thr: %s"),
482 	   td_err_string (val));
483 
484   /* Get the general-purpose registers.  */
485 
486   val = p_td_thr_getgregs (&thandle, gregset);
487   if (val != TD_OK && val != TD_PARTIALREG)
488     error (_("sol_thread_fetch_registers: td_thr_getgregs %s"),
489 	   td_err_string (val));
490 
491   /* For SPARC, TD_PARTIALREG means that only %i0...%i7, %l0..%l7, %pc
492      and %sp are saved (by a thread context switch).  */
493 
494   /* And, now the floating-point registers.  */
495 
496   val = p_td_thr_getfpregs (&thandle, &fpregset);
497   if (val != TD_OK && val != TD_NOFPREGS)
498     error (_("sol_thread_fetch_registers: td_thr_getfpregs %s"),
499 	   td_err_string (val));
500 
501   /* Note that we must call supply_gregset and supply_fpregset *after*
502      calling the td routines because the td routines call ps_lget*
503      which affect the values stored in the registers array.  */
504 
505   supply_gregset (regcache, (const gdb_gregset_t *) gregset_p);
506   supply_fpregset (regcache, (const gdb_fpregset_t *) fpregset_p);
507 }
508 
509 static void
510 sol_thread_store_registers (struct target_ops *ops,
511 			    struct regcache *regcache, int regnum)
512 {
513   thread_t thread;
514   td_thrhandle_t thandle;
515   td_err_e val;
516   prgregset_t gregset;
517   prfpregset_t fpregset;
518   ptid_t ptid = regcache_get_ptid (regcache);
519 
520   if (!ptid_tid_p (ptid))
521     {
522       struct target_ops *beneath = find_target_beneath (ops);
523 
524       /* It's an LWP; pass the request on to the layer beneath.  */
525       beneath->to_store_registers (beneath, regcache, regnum);
526       return;
527     }
528 
529   /* Solaris thread: convert PTID into a td_thrhandle_t.  */
530   thread = ptid_get_tid (ptid);
531 
532   val = p_td_ta_map_id2thr (main_ta, thread, &thandle);
533   if (val != TD_OK)
534     error (_("sol_thread_store_registers: td_ta_map_id2thr %s"),
535 	   td_err_string (val));
536 
537   if (regnum != -1)
538     {
539       val = p_td_thr_getgregs (&thandle, gregset);
540       if (val != TD_OK)
541 	error (_("sol_thread_store_registers: td_thr_getgregs %s"),
542 	       td_err_string (val));
543       val = p_td_thr_getfpregs (&thandle, &fpregset);
544       if (val != TD_OK)
545 	error (_("sol_thread_store_registers: td_thr_getfpregs %s"),
546 	       td_err_string (val));
547     }
548 
549   fill_gregset (regcache, (gdb_gregset_t *) &gregset, regnum);
550   fill_fpregset (regcache, (gdb_fpregset_t *) &fpregset, regnum);
551 
552   val = p_td_thr_setgregs (&thandle, gregset);
553   if (val != TD_OK)
554     error (_("sol_thread_store_registers: td_thr_setgregs %s"),
555 	   td_err_string (val));
556   val = p_td_thr_setfpregs (&thandle, &fpregset);
557   if (val != TD_OK)
558     error (_("sol_thread_store_registers: td_thr_setfpregs %s"),
559 	   td_err_string (val));
560 }
561 
562 /* Perform partial transfers on OBJECT.  See target_read_partial and
563    target_write_partial for details of each variant.  One, and only
564    one, of readbuf or writebuf must be non-NULL.  */
565 
566 static enum target_xfer_status
567 sol_thread_xfer_partial (struct target_ops *ops, enum target_object object,
568 			  const char *annex, gdb_byte *readbuf,
569 			  const gdb_byte *writebuf,
570 			 ULONGEST offset, ULONGEST len, ULONGEST *xfered_len)
571 {
572   enum target_xfer_status retval;
573   struct cleanup *old_chain;
574   struct target_ops *beneath = find_target_beneath (ops);
575 
576   old_chain = save_inferior_ptid ();
577 
578   if (ptid_tid_p (inferior_ptid) || !target_thread_alive (inferior_ptid))
579     {
580       /* It's either a thread or an LWP that isn't alive.  Any live
581          LWP will do so use the first available.
582 
583 	 NOTE: We don't need to call switch_to_thread; we're just
584 	 reading memory.  */
585       inferior_ptid = procfs_first_available ();
586     }
587 
588   retval = beneath->to_xfer_partial (beneath, object, annex, readbuf,
589 				     writebuf, offset, len, xfered_len);
590 
591   do_cleanups (old_chain);
592 
593   return retval;
594 }
595 
596 static void
597 check_for_thread_db (void)
598 {
599   td_err_e err;
600   ptid_t ptid;
601 
602   /* Don't attempt to use thread_db for remote targets.  */
603   if (!(target_can_run (&current_target) || core_bfd))
604     return;
605 
606   /* Do nothing if we couldn't load libthread_db.so.1.  */
607   if (p_td_ta_new == NULL)
608     return;
609 
610   if (sol_thread_active)
611     /* Nothing to do.  The thread library was already detected and the
612        target vector was already activated.  */
613     return;
614 
615   /* Now, initialize libthread_db.  This needs to be done after the
616      shared libraries are located because it needs information from
617      the user's thread library.  */
618 
619   err = p_td_init ();
620   if (err != TD_OK)
621     {
622       warning (_("sol_thread_new_objfile: td_init: %s"), td_err_string (err));
623       return;
624     }
625 
626   /* Now attempt to open a connection to the thread library.  */
627   err = p_td_ta_new (&main_ph, &main_ta);
628   switch (err)
629     {
630     case TD_NOLIBTHREAD:
631       /* No thread library was detected.  */
632       break;
633 
634     case TD_OK:
635       printf_unfiltered (_("[Thread debugging using libthread_db enabled]\n"));
636 
637       /* The thread library was detected.  Activate the sol_thread target.  */
638       push_target (&sol_thread_ops);
639       sol_thread_active = 1;
640 
641       main_ph.ptid = inferior_ptid; /* Save for xfer_memory.  */
642       ptid = lwp_to_thread (inferior_ptid);
643       if (ptid_get_pid (ptid) != -1)
644 	inferior_ptid = ptid;
645 
646       target_update_thread_list ();
647       break;
648 
649     default:
650       warning (_("Cannot initialize thread debugging library: %s"),
651 	       td_err_string (err));
652       break;
653     }
654 }
655 
656 /* This routine is called whenever a new symbol table is read in, or
657    when all symbol tables are removed.  libthread_db can only be
658    initialized when it finds the right variables in libthread.so.
659    Since it's a shared library, those variables don't show up until
660    the library gets mapped and the symbol table is read in.  */
661 
662 static void
663 sol_thread_new_objfile (struct objfile *objfile)
664 {
665   if (objfile != NULL)
666     check_for_thread_db ();
667 }
668 
669 /* Clean up after the inferior dies.  */
670 
671 static void
672 sol_thread_mourn_inferior (struct target_ops *ops)
673 {
674   struct target_ops *beneath = find_target_beneath (ops);
675 
676   sol_thread_active = 0;
677 
678   unpush_target (ops);
679 
680   beneath->to_mourn_inferior (beneath);
681 }
682 
683 /* Return true if PTID is still active in the inferior.  */
684 
685 static int
686 sol_thread_alive (struct target_ops *ops, ptid_t ptid)
687 {
688   if (ptid_tid_p (ptid))
689     {
690       /* It's a (user-level) thread.  */
691       td_err_e val;
692       td_thrhandle_t th;
693       int pid;
694 
695       pid = ptid_get_tid (ptid);
696       if ((val = p_td_ta_map_id2thr (main_ta, pid, &th)) != TD_OK)
697 	return 0;		/* Thread not found.  */
698       if ((val = p_td_thr_validate (&th)) != TD_OK)
699 	return 0;		/* Thread not valid.  */
700       return 1;			/* Known thread.  */
701     }
702   else
703     {
704       struct target_ops *beneath = find_target_beneath (ops);
705 
706       /* It's an LPW; pass the request on to the layer below.  */
707       return beneath->to_thread_alive (beneath, ptid);
708     }
709 }
710 
711 
712 /* These routines implement the lower half of the thread_db interface,
713    i.e. the ps_* routines.  */
714 
715 /* Various versions of <proc_service.h> have slightly different
716    function prototypes.  In particular, we have
717 
718    NEWER                        OLDER
719    struct ps_prochandle *       const struct ps_prochandle *
720    void*                        char*
721    const void*          	char*
722    int                  	size_t
723 
724    Which one you have depends on the Solaris version and what patches
725    you've applied.  On the theory that there are only two major
726    variants, we have configure check the prototype of ps_pdwrite (),
727    and use that info to make appropriate typedefs here.  */
728 
729 #ifdef PROC_SERVICE_IS_OLD
730 typedef const struct ps_prochandle *gdb_ps_prochandle_t;
731 typedef char *gdb_ps_read_buf_t;
732 typedef char *gdb_ps_write_buf_t;
733 typedef int gdb_ps_size_t;
734 typedef psaddr_t gdb_ps_addr_t;
735 #else
736 typedef struct ps_prochandle *gdb_ps_prochandle_t;
737 typedef void *gdb_ps_read_buf_t;
738 typedef const void *gdb_ps_write_buf_t;
739 typedef size_t gdb_ps_size_t;
740 typedef psaddr_t gdb_ps_addr_t;
741 #endif
742 
743 /* The next four routines are called by libthread_db to tell us to
744    stop and stop a particular process or lwp.  Since GDB ensures that
745    these are all stopped by the time we call anything in thread_db,
746    these routines need to do nothing.  */
747 
748 /* Process stop.  */
749 
750 ps_err_e
751 ps_pstop (gdb_ps_prochandle_t ph)
752 {
753   return PS_OK;
754 }
755 
756 /* Process continue.  */
757 
758 ps_err_e
759 ps_pcontinue (gdb_ps_prochandle_t ph)
760 {
761   return PS_OK;
762 }
763 
764 /* LWP stop.  */
765 
766 ps_err_e
767 ps_lstop (gdb_ps_prochandle_t ph, lwpid_t lwpid)
768 {
769   return PS_OK;
770 }
771 
772 /* LWP continue.  */
773 
774 ps_err_e
775 ps_lcontinue (gdb_ps_prochandle_t ph, lwpid_t lwpid)
776 {
777   return PS_OK;
778 }
779 
780 /* Looks up the symbol LD_SYMBOL_NAME in the debugger's symbol table.  */
781 
782 ps_err_e
783 ps_pglobal_lookup (gdb_ps_prochandle_t ph, const char *ld_object_name,
784 		   const char *ld_symbol_name, gdb_ps_addr_t *ld_symbol_addr)
785 {
786   struct bound_minimal_symbol ms;
787 
788   ms = lookup_minimal_symbol (ld_symbol_name, NULL, NULL);
789   if (!ms.minsym)
790     return PS_NOSYM;
791 
792   *ld_symbol_addr = BMSYMBOL_VALUE_ADDRESS (ms);
793   return PS_OK;
794 }
795 
796 /* Common routine for reading and writing memory.  */
797 
798 static ps_err_e
799 rw_common (int dowrite, const struct ps_prochandle *ph, gdb_ps_addr_t addr,
800 	   gdb_byte *buf, int size)
801 {
802   int ret;
803   struct cleanup *old_chain;
804 
805   old_chain = save_inferior_ptid ();
806 
807   if (ptid_tid_p (inferior_ptid) || !target_thread_alive (inferior_ptid))
808     {
809       /* It's either a thread or an LWP that isn't alive.  Any live
810          LWP will do so use the first available.
811 
812 	 NOTE: We don't need to call switch_to_thread; we're just
813 	 reading memory.  */
814       inferior_ptid = procfs_first_available ();
815     }
816 
817 #if defined (__sparcv9)
818   /* For Sparc64 cross Sparc32, make sure the address has not been
819      accidentally sign-extended (or whatever) to beyond 32 bits.  */
820   if (bfd_get_arch_size (exec_bfd) == 32)
821     addr &= 0xffffffff;
822 #endif
823 
824   if (dowrite)
825     ret = target_write_memory (addr, (gdb_byte *) buf, size);
826   else
827     ret = target_read_memory (addr, (gdb_byte *) buf, size);
828 
829   do_cleanups (old_chain);
830 
831   return (ret == 0 ? PS_OK : PS_ERR);
832 }
833 
834 /* Copies SIZE bytes from target process .data segment to debugger memory.  */
835 
836 ps_err_e
837 ps_pdread (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
838 	   gdb_ps_read_buf_t buf, gdb_ps_size_t size)
839 {
840   return rw_common (0, ph, addr, (gdb_byte *) buf, size);
841 }
842 
843 /* Copies SIZE bytes from debugger memory .data segment to target process.  */
844 
845 ps_err_e
846 ps_pdwrite (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
847 	    gdb_ps_write_buf_t buf, gdb_ps_size_t size)
848 {
849   return rw_common (1, ph, addr, (gdb_byte *) buf, size);
850 }
851 
852 /* Copies SIZE bytes from target process .text segment to debugger memory.  */
853 
854 ps_err_e
855 ps_ptread (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
856 	   gdb_ps_read_buf_t buf, gdb_ps_size_t size)
857 {
858   return rw_common (0, ph, addr, (gdb_byte *) buf, size);
859 }
860 
861 /* Copies SIZE bytes from debugger memory .text segment to target process.  */
862 
863 ps_err_e
864 ps_ptwrite (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
865 	    gdb_ps_write_buf_t buf, gdb_ps_size_t size)
866 {
867   return rw_common (1, ph, addr, (gdb_byte *) buf, size);
868 }
869 
870 /* Get general-purpose registers for LWP.  */
871 
872 ps_err_e
873 ps_lgetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, prgregset_t gregset)
874 {
875   ptid_t ptid = ptid_build (ptid_get_pid (inferior_ptid), lwpid, 0);
876   struct regcache *regcache
877     = get_thread_arch_regcache (ptid, target_gdbarch ());
878 
879   target_fetch_registers (regcache, -1);
880   fill_gregset (regcache, (gdb_gregset_t *) gregset, -1);
881 
882   return PS_OK;
883 }
884 
885 /* Set general-purpose registers for LWP.  */
886 
887 ps_err_e
888 ps_lsetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
889 	     const prgregset_t gregset)
890 {
891   ptid_t ptid = ptid_build (ptid_get_pid (inferior_ptid), lwpid, 0);
892   struct regcache *regcache
893     = get_thread_arch_regcache (ptid, target_gdbarch ());
894 
895   supply_gregset (regcache, (const gdb_gregset_t *) gregset);
896   target_store_registers (regcache, -1);
897 
898   return PS_OK;
899 }
900 
901 /* Log a message (sends to gdb_stderr).  */
902 
903 void
904 ps_plog (const char *fmt, ...)
905 {
906   va_list args;
907 
908   va_start (args, fmt);
909 
910   vfprintf_filtered (gdb_stderr, fmt, args);
911 }
912 
913 /* Get size of extra register set.  Currently a noop.  */
914 
915 ps_err_e
916 ps_lgetxregsize (gdb_ps_prochandle_t ph, lwpid_t lwpid, int *xregsize)
917 {
918   return PS_OK;
919 }
920 
921 /* Get extra register set.  Currently a noop.  */
922 
923 ps_err_e
924 ps_lgetxregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, caddr_t xregset)
925 {
926   return PS_OK;
927 }
928 
929 /* Set extra register set.  Currently a noop.  */
930 
931 ps_err_e
932 ps_lsetxregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, caddr_t xregset)
933 {
934   return PS_OK;
935 }
936 
937 /* Get floating-point registers for LWP.  */
938 
939 ps_err_e
940 ps_lgetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
941 	       prfpregset_t *fpregset)
942 {
943   ptid_t ptid = ptid_build (ptid_get_pid (inferior_ptid), lwpid, 0);
944   struct regcache *regcache
945     = get_thread_arch_regcache (ptid, target_gdbarch ());
946 
947   target_fetch_registers (regcache, -1);
948   fill_fpregset (regcache, (gdb_fpregset_t *) fpregset, -1);
949 
950   return PS_OK;
951 }
952 
953 /* Set floating-point regs for LWP.  */
954 
955 ps_err_e
956 ps_lsetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
957 	       const prfpregset_t * fpregset)
958 {
959   ptid_t ptid = ptid_build (ptid_get_pid (inferior_ptid), lwpid, 0);
960   struct regcache *regcache
961     = get_thread_arch_regcache (ptid, target_gdbarch ());
962 
963   supply_fpregset (regcache, (const gdb_fpregset_t *) fpregset);
964   target_store_registers (regcache, -1);
965 
966   return PS_OK;
967 }
968 
969 #ifdef PR_MODEL_LP64
970 /* Identify process as 32-bit or 64-bit.  At the moment we're using
971    BFD to do this.  There might be a more Solaris-specific
972    (e.g. procfs) method, but this ought to work.  */
973 
974 ps_err_e
975 ps_pdmodel (gdb_ps_prochandle_t ph, int *data_model)
976 {
977   if (exec_bfd == 0)
978     *data_model = PR_MODEL_UNKNOWN;
979   else if (bfd_get_arch_size (exec_bfd) == 32)
980     *data_model = PR_MODEL_ILP32;
981   else
982     *data_model = PR_MODEL_LP64;
983 
984   return PS_OK;
985 }
986 #endif /* PR_MODEL_LP64 */
987 
988 #if (defined(__i386__) || defined(__x86_64__)) && defined (sun)
989 
990 /* Reads the local descriptor table of a LWP.
991 
992    This function is necessary on x86-solaris only.  Without it, the loading
993    of libthread_db would fail because of ps_lgetLDT being undefined.  */
994 
995 ps_err_e
996 ps_lgetLDT (gdb_ps_prochandle_t ph, lwpid_t lwpid,
997 	    struct ssd *pldt)
998 {
999   /* NOTE: only used on Solaris, therefore OK to refer to procfs.c.  */
1000   struct ssd *ret;
1001 
1002   /* FIXME: can't I get the process ID from the prochandle or
1003      something?  */
1004 
1005   if (ptid_get_pid (inferior_ptid) <= 0 || lwpid <= 0)
1006     return PS_BADLID;
1007 
1008   ret = procfs_find_LDT_entry (ptid_build (ptid_get_pid (inferior_ptid),
1009 			       lwpid, 0));
1010   if (ret)
1011     {
1012       memcpy (pldt, ret, sizeof (struct ssd));
1013       return PS_OK;
1014     }
1015   else
1016     /* LDT not found.  */
1017     return PS_ERR;
1018 }
1019 #endif
1020 
1021 
1022 /* Convert PTID to printable form.  */
1023 
1024 static const char *
1025 solaris_pid_to_str (struct target_ops *ops, ptid_t ptid)
1026 {
1027   static char buf[100];
1028 
1029   if (ptid_tid_p (ptid))
1030     {
1031       ptid_t lwp;
1032 
1033       lwp = thread_to_lwp (ptid, -2);
1034 
1035       if (ptid_get_pid (lwp) == -1)
1036 	xsnprintf (buf, sizeof (buf), "Thread %ld (defunct)",
1037 		   ptid_get_tid (ptid));
1038       else if (ptid_get_pid (lwp) != -2)
1039 	xsnprintf (buf, sizeof (buf), "Thread %ld (LWP %ld)",
1040 		 ptid_get_tid (ptid), ptid_get_lwp (lwp));
1041       else
1042 	xsnprintf (buf, sizeof (buf), "Thread %ld        ",
1043 		   ptid_get_tid (ptid));
1044     }
1045   else if (ptid_get_lwp (ptid) != 0)
1046     xsnprintf (buf, sizeof (buf), "LWP    %ld        ", ptid_get_lwp (ptid));
1047   else
1048     xsnprintf (buf, sizeof (buf), "process %d    ", ptid_get_pid (ptid));
1049 
1050   return buf;
1051 }
1052 
1053 
1054 /* Worker bee for update_thread_list.  Callback function that gets
1055    called once per user-level thread (i.e. not for LWP's).  */
1056 
1057 static int
1058 sol_update_thread_list_callback (const td_thrhandle_t *th, void *ignored)
1059 {
1060   td_err_e retval;
1061   td_thrinfo_t ti;
1062   ptid_t ptid;
1063 
1064   retval = p_td_thr_get_info (th, &ti);
1065   if (retval != TD_OK)
1066     return -1;
1067 
1068   ptid = ptid_build (ptid_get_pid (inferior_ptid), 0, ti.ti_tid);
1069   if (!in_thread_list (ptid) || is_exited (ptid))
1070     add_thread (ptid);
1071 
1072   return 0;
1073 }
1074 
1075 static void
1076 sol_update_thread_list (struct target_ops *ops)
1077 {
1078   struct target_ops *beneath = find_target_beneath (ops);
1079 
1080   /* Delete dead threads.  */
1081   prune_threads ();
1082 
1083   /* Find any new LWP's.  */
1084   beneath->to_update_thread_list (beneath);
1085 
1086   /* Then find any new user-level threads.  */
1087   p_td_ta_thr_iter (main_ta, sol_update_thread_list_callback, (void *) 0,
1088 		    TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
1089 		    TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
1090 }
1091 
1092 /* Worker bee for the "info sol-thread" command.  This is a callback
1093    function that gets called once for each Solaris user-level thread
1094    (i.e. not for LWPs) in the inferior.  Print anything interesting
1095    that we can think of.  */
1096 
1097 static int
1098 info_cb (const td_thrhandle_t *th, void *s)
1099 {
1100   td_err_e ret;
1101   td_thrinfo_t ti;
1102 
1103   ret = p_td_thr_get_info (th, &ti);
1104   if (ret == TD_OK)
1105     {
1106       printf_filtered ("%s thread #%d, lwp %d, ",
1107 		       ti.ti_type == TD_THR_SYSTEM ? "system" : "user  ",
1108 		       ti.ti_tid, ti.ti_lid);
1109       switch (ti.ti_state)
1110 	{
1111 	default:
1112 	case TD_THR_UNKNOWN:
1113 	  printf_filtered ("<unknown state>");
1114 	  break;
1115 	case TD_THR_STOPPED:
1116 	  printf_filtered ("(stopped)");
1117 	  break;
1118 	case TD_THR_RUN:
1119 	  printf_filtered ("(run)    ");
1120 	  break;
1121 	case TD_THR_ACTIVE:
1122 	  printf_filtered ("(active) ");
1123 	  break;
1124 	case TD_THR_ZOMBIE:
1125 	  printf_filtered ("(zombie) ");
1126 	  break;
1127 	case TD_THR_SLEEP:
1128 	  printf_filtered ("(asleep) ");
1129 	  break;
1130 	case TD_THR_STOPPED_ASLEEP:
1131 	  printf_filtered ("(stopped asleep)");
1132 	  break;
1133 	}
1134       /* Print thr_create start function.  */
1135       if (ti.ti_startfunc != 0)
1136 	{
1137 	  const struct bound_minimal_symbol msym
1138 	    = lookup_minimal_symbol_by_pc (ti.ti_startfunc);
1139 
1140 	  printf_filtered ("   startfunc=%s",
1141 			   msym.minsym
1142 			   ? MSYMBOL_PRINT_NAME (msym.minsym)
1143 			   : paddress (target_gdbarch (), ti.ti_startfunc));
1144 	}
1145 
1146       /* If thread is asleep, print function that went to sleep.  */
1147       if (ti.ti_state == TD_THR_SLEEP)
1148 	{
1149 	  const struct bound_minimal_symbol msym
1150 	    = lookup_minimal_symbol_by_pc (ti.ti_pc);
1151 
1152 	  printf_filtered ("   sleepfunc=%s",
1153 			   msym.minsym
1154 			   ? MSYMBOL_PRINT_NAME (msym.minsym)
1155 			   : paddress (target_gdbarch (), ti.ti_pc));
1156 	}
1157 
1158       printf_filtered ("\n");
1159     }
1160   else
1161     warning (_("info sol-thread: failed to get info for thread."));
1162 
1163   return 0;
1164 }
1165 
1166 /* List some state about each Solaris user-level thread in the
1167    inferior.  */
1168 
1169 static void
1170 info_solthreads (char *args, int from_tty)
1171 {
1172   p_td_ta_thr_iter (main_ta, info_cb, args,
1173 		    TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
1174 		    TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
1175 }
1176 
1177 /* Callback routine used to find a thread based on the TID part of
1178    its PTID.  */
1179 
1180 static int
1181 thread_db_find_thread_from_tid (struct thread_info *thread, void *data)
1182 {
1183   long *tid = (long *) data;
1184 
1185   if (ptid_get_tid (thread->ptid) == *tid)
1186     return 1;
1187 
1188   return 0;
1189 }
1190 
1191 static ptid_t
1192 sol_get_ada_task_ptid (struct target_ops *self, long lwp, long thread)
1193 {
1194   struct thread_info *thread_info =
1195     iterate_over_threads (thread_db_find_thread_from_tid, &thread);
1196 
1197   if (thread_info == NULL)
1198     {
1199       /* The list of threads is probably not up to date.  Find any
1200          thread that is missing from the list, and try again.  */
1201       sol_update_thread_list (&current_target);
1202       thread_info = iterate_over_threads (thread_db_find_thread_from_tid,
1203                                           &thread);
1204     }
1205 
1206   gdb_assert (thread_info != NULL);
1207 
1208   return (thread_info->ptid);
1209 }
1210 
1211 static void
1212 init_sol_thread_ops (void)
1213 {
1214   sol_thread_ops.to_shortname = "solaris-threads";
1215   sol_thread_ops.to_longname = "Solaris threads and pthread.";
1216   sol_thread_ops.to_doc = "Solaris threads and pthread support.";
1217   sol_thread_ops.to_detach = sol_thread_detach;
1218   sol_thread_ops.to_resume = sol_thread_resume;
1219   sol_thread_ops.to_wait = sol_thread_wait;
1220   sol_thread_ops.to_fetch_registers = sol_thread_fetch_registers;
1221   sol_thread_ops.to_store_registers = sol_thread_store_registers;
1222   sol_thread_ops.to_xfer_partial = sol_thread_xfer_partial;
1223   sol_thread_ops.to_mourn_inferior = sol_thread_mourn_inferior;
1224   sol_thread_ops.to_thread_alive = sol_thread_alive;
1225   sol_thread_ops.to_pid_to_str = solaris_pid_to_str;
1226   sol_thread_ops.to_update_thread_list = sol_update_thread_list;
1227   sol_thread_ops.to_stratum = thread_stratum;
1228   sol_thread_ops.to_get_ada_task_ptid = sol_get_ada_task_ptid;
1229   sol_thread_ops.to_magic = OPS_MAGIC;
1230 }
1231 
1232 /* Silence -Wmissing-prototypes.  */
1233 extern void _initialize_sol_thread (void);
1234 
1235 void
1236 _initialize_sol_thread (void)
1237 {
1238   void *dlhandle;
1239 
1240   init_sol_thread_ops ();
1241 
1242   dlhandle = dlopen ("libthread_db.so.1", RTLD_NOW);
1243   if (!dlhandle)
1244     goto die;
1245 
1246 #define resolve(X) \
1247   if (!(p_##X = (X ## _ftype *) dlsym (dlhandle, #X)))	\
1248     goto die;
1249 
1250   resolve (td_log);
1251   resolve (td_ta_new);
1252   resolve (td_ta_delete);
1253   resolve (td_init);
1254   resolve (td_ta_get_ph);
1255   resolve (td_ta_get_nthreads);
1256   resolve (td_ta_tsd_iter);
1257   resolve (td_ta_thr_iter);
1258   resolve (td_thr_validate);
1259   resolve (td_thr_tsd);
1260   resolve (td_thr_get_info);
1261   resolve (td_thr_getfpregs);
1262   resolve (td_thr_getxregsize);
1263   resolve (td_thr_getxregs);
1264   resolve (td_thr_sigsetmask);
1265   resolve (td_thr_setprio);
1266   resolve (td_thr_setsigpending);
1267   resolve (td_thr_setfpregs);
1268   resolve (td_thr_setxregs);
1269   resolve (td_ta_map_id2thr);
1270   resolve (td_ta_map_lwp2thr);
1271   resolve (td_thr_getgregs);
1272   resolve (td_thr_setgregs);
1273 
1274   complete_target_initialization (&sol_thread_ops);
1275 
1276   add_cmd ("sol-threads", class_maintenance, info_solthreads,
1277 	   _("Show info on Solaris user threads."), &maintenanceinfolist);
1278 
1279   /* Hook into new_objfile notification.  */
1280   observer_attach_new_objfile (sol_thread_new_objfile);
1281   return;
1282 
1283  die:
1284   fprintf_unfiltered (gdb_stderr, "\
1285 [GDB will not be able to debug user-mode threads: %s]\n", dlerror ());
1286 
1287   if (dlhandle)
1288     dlclose (dlhandle);
1289 
1290   return;
1291 }
1292