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