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