* regcache.c (struct regcache): Add ptid_t member.
[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 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 2 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, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor,
21    Boston, MA 02110-1301, USA.  */
22
23 /* This module implements a sort of half target that sits between the
24    machine-independent parts of GDB and the /proc interface (procfs.c)
25    to provide access to the Solaris user-mode thread implementation.
26
27    Solaris threads are true user-mode threads, which are invoked via
28    the thr_* and pthread_* (native and POSIX respectivly) interfaces.
29    These are mostly implemented in user-space, with all thread context
30    kept in various structures that live in the user's heap.  These
31    should not be confused with lightweight processes (LWPs), which are
32    implemented by the kernel, and scheduled without explicit
33    intervention by the process.
34
35    Just to confuse things a little, Solaris threads (both native and
36    POSIX) are actually implemented using LWPs.  In general, there are
37    going to be more threads than LWPs.  There is no fixed
38    correspondence between a thread and an LWP.  When a thread wants to
39    run, it gets scheduled onto the first available LWP and can
40    therefore migrate from one LWP to another as time goes on.  A
41    sleeping thread may not be associated with an LWP at all!
42
43    To make it possible to mess with threads, Sun provides a library
44    called libthread_db.so.1 (not to be confused with
45    libthread_db.so.0, which doesn't have a published interface).  This
46    interface has an upper part, which it provides, and a lower part
47    which we provide.  The upper part consists of the td_* routines,
48    which allow us to find all the threads, query their state, etc...
49    The lower part consists of all of the ps_*, which are used by the
50    td_* routines to read/write memory, manipulate LWPs, lookup
51    symbols, etc...  The ps_* routines actually do most of their work
52    by calling functions in procfs.c.  */
53
54 #include "defs.h"
55 #include <thread.h>
56 #include <proc_service.h>
57 #include <thread_db.h>
58 #include "gdbthread.h"
59 #include "target.h"
60 #include "inferior.h"
61 #include <fcntl.h>
62 #include "gdb_stat.h"
63 #include <dlfcn.h>
64 #include "gdbcmd.h"
65 #include "gdbcore.h"
66 #include "regcache.h"
67 #include "solib.h"
68 #include "symfile.h"
69 #include "observer.h"
70
71 #include "gdb_string.h"
72
73 extern struct target_ops sol_thread_ops;        /* Forward declaration */
74 extern struct target_ops sol_core_ops;  /* Forward declaration */
75
76 /* place to store core_ops before we overwrite it */
77 static struct target_ops orig_core_ops;
78
79 struct target_ops sol_thread_ops;
80 struct target_ops sol_core_ops;
81
82 extern int procfs_suppress_run;
83 extern struct target_ops procfs_ops;    /* target vector for procfs.c */
84 extern struct target_ops core_ops;      /* target vector for corelow.c */
85 extern char *procfs_pid_to_str (ptid_t ptid);
86
87 /* Prototypes for supply_gregset etc. */
88 #include "gregset.h"
89
90 /* This struct is defined by us, but mainly used for the proc_service
91    interface.  We don't have much use for it, except as a handy place
92    to get a real PID for memory accesses.  */
93
94 struct ps_prochandle
95 {
96   ptid_t ptid;
97 };
98
99 struct string_map
100 {
101   int num;
102   char *str;
103 };
104
105 static struct ps_prochandle main_ph;
106 static td_thragent_t *main_ta;
107 static int sol_thread_active = 0;
108
109 static void sol_thread_resume (ptid_t ptid, int step, enum target_signal signo);
110 static int sol_thread_alive (ptid_t ptid);
111 static void sol_core_close (int quitting);
112
113 static void init_sol_thread_ops (void);
114 static void init_sol_core_ops (void);
115
116 /* Default definitions: These must be defined in tm.h if they are to
117    be shared with a process module such as procfs.  */
118
119 #define GET_PID(ptid)           ptid_get_pid (ptid)
120 #define GET_LWP(ptid)           ptid_get_lwp (ptid)
121 #define GET_THREAD(ptid)        ptid_get_tid (ptid)
122
123 #define is_lwp(ptid)            (GET_LWP (ptid) != 0)
124 #define is_thread(ptid)         (GET_THREAD (ptid) != 0)
125
126 #define BUILD_LWP(lwp, pid)     ptid_build (pid, lwp, 0)
127 #define BUILD_THREAD(tid, pid)  ptid_build (pid, 0, tid)
128
129 /* Pointers to routines from libthread_db resolved by dlopen().  */
130
131 static void (*p_td_log)(const int on_off);
132 static td_err_e (*p_td_ta_new)(const struct ps_prochandle *ph_p,
133                                td_thragent_t **ta_pp);
134 static td_err_e (*p_td_ta_delete)(td_thragent_t *ta_p);
135 static td_err_e (*p_td_init)(void);
136 static td_err_e (*p_td_ta_get_ph)(const td_thragent_t *ta_p,
137                                   struct ps_prochandle **ph_pp);
138 static td_err_e (*p_td_ta_get_nthreads)(const td_thragent_t *ta_p,
139                                         int *nthread_p);
140 static td_err_e (*p_td_ta_tsd_iter)(const td_thragent_t *ta_p,
141                                     td_key_iter_f *cb, void *cbdata_p);
142 static td_err_e (*p_td_ta_thr_iter)(const td_thragent_t *ta_p,
143                                     td_thr_iter_f *cb, void *cbdata_p,
144                                     td_thr_state_e state, int ti_pri,
145                                     sigset_t *ti_sigmask_p,
146                                     unsigned ti_user_flags);
147 static td_err_e (*p_td_thr_validate)(const td_thrhandle_t *th_p);
148 static td_err_e (*p_td_thr_tsd)(const td_thrhandle_t * th_p,
149                                 const thread_key_t key, void **data_pp);
150 static td_err_e (*p_td_thr_get_info)(const td_thrhandle_t *th_p,
151                                      td_thrinfo_t *ti_p);
152 static td_err_e (*p_td_thr_getfpregs)(const td_thrhandle_t *th_p,
153                                       prfpregset_t *fpregset);
154 static td_err_e (*p_td_thr_getxregsize)(const td_thrhandle_t *th_p,
155                                         int *xregsize);
156 static td_err_e (*p_td_thr_getxregs)(const td_thrhandle_t *th_p,
157                                      const caddr_t xregset);
158 static td_err_e (*p_td_thr_sigsetmask)(const td_thrhandle_t *th_p,
159                                        const sigset_t ti_sigmask);
160 static td_err_e (*p_td_thr_setprio)(const td_thrhandle_t *th_p,
161                                     const int ti_pri);
162 static td_err_e (*p_td_thr_setsigpending)(const td_thrhandle_t *th_p,
163                                           const uchar_t ti_pending_flag,
164                                           const sigset_t ti_pending);
165 static td_err_e (*p_td_thr_setfpregs)(const td_thrhandle_t *th_p,
166                                       const prfpregset_t *fpregset);
167 static td_err_e (*p_td_thr_setxregs)(const td_thrhandle_t *th_p,
168                                      const caddr_t xregset);
169 static td_err_e (*p_td_ta_map_id2thr)(const td_thragent_t *ta_p,
170                                       thread_t tid,
171                                       td_thrhandle_t *th_p);
172 static td_err_e (*p_td_ta_map_lwp2thr)(const td_thragent_t *ta_p,
173                                        lwpid_t lwpid,
174                                        td_thrhandle_t *th_p);
175 static td_err_e (*p_td_thr_getgregs)(const td_thrhandle_t *th_p,
176                                      prgregset_t regset);
177 static td_err_e (*p_td_thr_setgregs)(const td_thrhandle_t *th_p,
178                                      const prgregset_t regset);
179 \f
180
181 /* Return the libthread_db error string associated with ERRCODE.  If
182    ERRCODE is unknown, return an appropriate message.  */
183
184 static char *
185 td_err_string (td_err_e errcode)
186 {
187   static struct string_map td_err_table[] =
188   {
189     { TD_OK, "generic \"call succeeded\"" },
190     { TD_ERR, "generic error." },
191     { TD_NOTHR, "no thread can be found to satisfy query" },
192     { TD_NOSV, "no synch. variable can be found to satisfy query" },
193     { TD_NOLWP, "no lwp can be found to satisfy query" },
194     { TD_BADPH, "invalid process handle" },
195     { TD_BADTH, "invalid thread handle" },
196     { TD_BADSH, "invalid synchronization handle" },
197     { TD_BADTA, "invalid thread agent" },
198     { TD_BADKEY, "invalid key" },
199     { TD_NOMSG, "td_thr_event_getmsg() called when there was no message" },
200     { TD_NOFPREGS, "FPU register set not available for given thread" },
201     { TD_NOLIBTHREAD, "application not linked with libthread" },
202     { TD_NOEVENT, "requested event is not supported" },
203     { TD_NOCAPAB, "capability not available" },
204     { TD_DBERR, "Debugger service failed" },
205     { TD_NOAPLIC, "Operation not applicable to" },
206     { TD_NOTSD, "No thread specific data for this thread" },
207     { TD_MALLOC, "Malloc failed" },
208     { TD_PARTIALREG, "Only part of register set was written/read" },
209     { TD_NOXREGS, "X register set not available for given thread" }
210   };
211   const int td_err_size = sizeof td_err_table / sizeof (struct string_map);
212   int i;
213   static char buf[50];
214
215   for (i = 0; i < td_err_size; i++)
216     if (td_err_table[i].num == errcode)
217       return td_err_table[i].str;
218
219   sprintf (buf, "Unknown libthread_db error code: %d", errcode);
220
221   return buf;
222 }
223
224 /* Return the the libthread_db state string assicoated with STATECODE.
225    If STATECODE is unknown, return an appropriate message.  */
226
227 static char *
228 td_state_string (td_thr_state_e statecode)
229 {
230   static struct string_map td_thr_state_table[] =
231   {
232     { TD_THR_ANY_STATE, "any state" },
233     { TD_THR_UNKNOWN, "unknown" },
234     { TD_THR_STOPPED, "stopped" },
235     { TD_THR_RUN, "run" },
236     { TD_THR_ACTIVE, "active" },
237     { TD_THR_ZOMBIE, "zombie" },
238     { TD_THR_SLEEP, "sleep" },
239     { TD_THR_STOPPED_ASLEEP, "stopped asleep" }
240   };
241   const int td_thr_state_table_size =
242     sizeof td_thr_state_table / sizeof (struct string_map);
243   int i;
244   static char buf[50];
245
246   for (i = 0; i < td_thr_state_table_size; i++)
247     if (td_thr_state_table[i].num == statecode)
248       return td_thr_state_table[i].str;
249
250   sprintf (buf, "Unknown libthread_db state code: %d", statecode);
251
252   return buf;
253 }
254 \f
255
256 /* Convert a POSIX or Solaris thread ID into a LWP ID.  If THREAD_ID
257    doesn't exist, that's an error.  If it's an inactive thread, return
258    DEFAULT_LPW.
259
260    NOTE: This function probably shouldn't call error().  */
261
262 static ptid_t
263 thread_to_lwp (ptid_t thread_id, int default_lwp)
264 {
265   td_thrinfo_t ti;
266   td_thrhandle_t th;
267   td_err_e val;
268
269   if (is_lwp (thread_id))
270     return thread_id;           /* It's already an LWP ID.  */
271
272   /* It's a thread.  Convert to LWP.  */
273
274   val = p_td_ta_map_id2thr (main_ta, GET_THREAD (thread_id), &th);
275   if (val == TD_NOTHR)
276     return pid_to_ptid (-1);    /* Thread must have terminated.  */
277   else if (val != TD_OK)
278     error (_("thread_to_lwp: td_ta_map_id2thr %s"), td_err_string (val));
279
280   val = p_td_thr_get_info (&th, &ti);
281   if (val == TD_NOTHR)
282     return pid_to_ptid (-1);    /* Thread must have terminated.  */
283   else if (val != TD_OK)
284     error (_("thread_to_lwp: td_thr_get_info: %s"), td_err_string (val));
285
286   if (ti.ti_state != TD_THR_ACTIVE)
287     {
288       if (default_lwp != -1)
289         return pid_to_ptid (default_lwp);
290       error (_("thread_to_lwp: thread state not active: %s"),
291              td_state_string (ti.ti_state));
292     }
293
294   return BUILD_LWP (ti.ti_lid, PIDGET (thread_id));
295 }
296
297 /* Convert an LWP ID into a POSIX or Solaris thread ID.  If LWP_ID
298    doesn't exists, that's an error.
299
300    NOTE: This function probably shouldn't call error().  */
301
302 static ptid_t
303 lwp_to_thread (ptid_t lwp)
304 {
305   td_thrinfo_t ti;
306   td_thrhandle_t th;
307   td_err_e val;
308
309   if (is_thread (lwp))
310     return lwp;                 /* It's already a thread ID.  */
311
312   /* It's an LWP.  Convert it to a thread ID.  */
313
314   if (!sol_thread_alive (lwp))
315     return pid_to_ptid (-1);    /* Must be a defunct LPW.  */
316
317   val = p_td_ta_map_lwp2thr (main_ta, GET_LWP (lwp), &th);
318   if (val == TD_NOTHR)
319     return pid_to_ptid (-1);    /* Thread must have terminated.  */
320   else if (val != TD_OK)
321     error (_("lwp_to_thread: td_ta_map_lwp2thr: %s."), td_err_string (val));
322
323   val = p_td_thr_validate (&th);
324   if (val == TD_NOTHR)
325     return lwp;                 /* Unknown to libthread; just return LPW,  */
326   else if (val != TD_OK)
327     error (_("lwp_to_thread: td_thr_validate: %s."), td_err_string (val));
328
329   val = p_td_thr_get_info (&th, &ti);
330   if (val == TD_NOTHR)
331     return pid_to_ptid (-1);    /* Thread must have terminated.  */
332   else if (val != TD_OK)
333     error (_("lwp_to_thread: td_thr_get_info: %s."), td_err_string (val));
334
335   return BUILD_THREAD (ti.ti_tid, PIDGET (lwp));
336 }
337 \f
338
339 /* Most target vector functions from here on actually just pass
340    through to procfs.c, as they don't need to do anything specific for
341    threads.  */
342
343 static void
344 sol_thread_open (char *arg, int from_tty)
345 {
346   procfs_ops.to_open (arg, from_tty);
347 }
348
349 /* Attach to process PID, then initialize for debugging it and wait
350    for the trace-trap that results from attaching.  */
351
352 static void
353 sol_thread_attach (char *args, int from_tty)
354 {
355   procfs_ops.to_attach (args, from_tty);
356
357   /* Must get symbols from shared libraries before libthread_db can run!  */
358   solib_add (NULL, from_tty, (struct target_ops *) 0, auto_solib_add);
359
360   if (sol_thread_active)
361     {
362       printf_filtered ("sol-thread active.\n");
363       main_ph.ptid = inferior_ptid; /* Save for xfer_memory.  */
364       push_target (&sol_thread_ops);
365       inferior_ptid = lwp_to_thread (inferior_ptid);
366       if (PIDGET (inferior_ptid) == -1)
367         inferior_ptid = main_ph.ptid;
368       else
369         add_thread (inferior_ptid);
370     }
371
372   /* FIXME: Might want to iterate over all the threads and register
373      them.  */
374 }
375
376 /* Take a program previously attached to and detaches it.  The program
377    resumes execution and will no longer stop on signals, etc.  We'd
378    better not have left any breakpoints in the program or it'll die
379    when it hits one.  For this to work, it may be necessary for the
380    process to have been previously attached.  It *might* work if the
381    program was started via the normal ptrace (PTRACE_TRACEME).  */
382
383 static void
384 sol_thread_detach (char *args, int from_tty)
385 {
386   inferior_ptid = pid_to_ptid (PIDGET (main_ph.ptid));
387   unpush_target (&sol_thread_ops);
388   procfs_ops.to_detach (args, from_tty);
389 }
390
391 /* Resume execution of process PTID.  If STEP is nozero, then just
392    single step it.  If SIGNAL is nonzero, restart it with that signal
393    activated.  We may have to convert PTID from a thread ID to an LWP
394    ID for procfs.  */
395
396 static void
397 sol_thread_resume (ptid_t ptid, int step, enum target_signal signo)
398 {
399   struct cleanup *old_chain;
400
401   old_chain = save_inferior_ptid ();
402
403   inferior_ptid = thread_to_lwp (inferior_ptid, PIDGET (main_ph.ptid));
404   if (PIDGET (inferior_ptid) == -1)
405     inferior_ptid = procfs_first_available ();
406
407   if (PIDGET (ptid) != -1)
408     {
409       ptid_t save_ptid = ptid;
410
411       ptid = thread_to_lwp (ptid, -2);
412       if (PIDGET (ptid) == -2)          /* Inactive thread.  */
413         error (_("This version of Solaris can't start inactive threads."));
414       if (info_verbose && PIDGET (ptid) == -1)
415         warning (_("Specified thread %ld seems to have terminated"),
416                  GET_THREAD (save_ptid));
417     }
418
419   procfs_ops.to_resume (ptid, step, signo);
420
421   do_cleanups (old_chain);
422 }
423
424 /* Wait for any threads to stop.  We may have to convert PIID from a
425    thread ID to an LWP ID, and vice versa on the way out.  */
426
427 static ptid_t
428 sol_thread_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
429 {
430   ptid_t rtnval;
431   ptid_t save_ptid;
432   struct cleanup *old_chain;
433
434   save_ptid = inferior_ptid;
435   old_chain = save_inferior_ptid ();
436
437   inferior_ptid = thread_to_lwp (inferior_ptid, PIDGET (main_ph.ptid));
438   if (PIDGET (inferior_ptid) == -1)
439     inferior_ptid = procfs_first_available ();
440
441   if (PIDGET (ptid) != -1)
442     {
443       ptid_t save_ptid = ptid;
444
445       ptid = thread_to_lwp (ptid, -2);
446       if (PIDGET (ptid) == -2)          /* Inactive thread.  */
447         error (_("This version of Solaris can't start inactive threads."));
448       if (info_verbose && PIDGET (ptid) == -1)
449         warning (_("Specified thread %ld seems to have terminated"),
450                  GET_THREAD (save_ptid));
451     }
452
453   rtnval = procfs_ops.to_wait (ptid, ourstatus);
454
455   if (ourstatus->kind != TARGET_WAITKIND_EXITED)
456     {
457       /* Map the LWP of interest back to the appropriate thread ID.  */
458       rtnval = lwp_to_thread (rtnval);
459       if (PIDGET (rtnval) == -1)
460         rtnval = save_ptid;
461
462       /* See if we have a new thread.  */
463       if (is_thread (rtnval)
464           && !ptid_equal (rtnval, save_ptid)
465           && !in_thread_list (rtnval))
466         {
467           printf_filtered ("[New %s]\n", target_pid_to_str (rtnval));
468           add_thread (rtnval);
469         }
470     }
471
472   /* During process initialization, we may get here without the thread
473      package being initialized, since that can only happen after we've
474      found the shared libs.  */
475
476   do_cleanups (old_chain);
477
478   return rtnval;
479 }
480
481 static void
482 sol_thread_fetch_registers (struct regcache *regcache, int regnum)
483 {
484   thread_t thread;
485   td_thrhandle_t thandle;
486   td_err_e val;
487   prgregset_t gregset;
488   prfpregset_t fpregset;
489 #if 0
490   int xregsize;
491   caddr_t xregset;
492 #endif
493
494   if (!is_thread (inferior_ptid))
495     {
496       /* It's an LWP; pass the request on to procfs.  */
497       if (target_has_execution)
498         procfs_ops.to_fetch_registers (regcache, regnum);
499       else
500         orig_core_ops.to_fetch_registers (regcache, regnum);
501       return;
502     }
503
504   /* Solaris thread: convert INFERIOR_PTID into a td_thrhandle_t.  */
505   thread = GET_THREAD (inferior_ptid);
506   if (thread == 0)
507     error (_("sol_thread_fetch_registers: thread == 0"));
508
509   val = p_td_ta_map_id2thr (main_ta, thread, &thandle);
510   if (val != TD_OK)
511     error (_("sol_thread_fetch_registers: td_ta_map_id2thr: %s"),
512            td_err_string (val));
513
514   /* Get the general-purpose registers.  */
515
516   val = p_td_thr_getgregs (&thandle, gregset);
517   if (val != TD_OK && val != TD_PARTIALREG)
518     error (_("sol_thread_fetch_registers: td_thr_getgregs %s"),
519            td_err_string (val));
520
521   /* For SPARC, TD_PARTIALREG means that only %i0...%i7, %l0..%l7, %pc
522      and %sp are saved (by a thread context switch).  */
523
524   /* And, now the floating-point registers.  */
525
526   val = p_td_thr_getfpregs (&thandle, &fpregset);
527   if (val != TD_OK && val != TD_NOFPREGS)
528     error (_("sol_thread_fetch_registers: td_thr_getfpregs %s"),
529            td_err_string (val));
530
531   /* Note that we must call supply_gregset and supply_fpregset *after*
532      calling the td routines because the td routines call ps_lget*
533      which affect the values stored in the registers array.  */
534
535   supply_gregset (regcache, (const gdb_gregset_t *) &gregset);
536   supply_fpregset (regcache, (const gdb_fpregset_t *) &fpregset);
537
538 #if 0
539   /* FIXME: libthread_db doesn't seem to handle this right.  */
540   val = td_thr_getxregsize (&thandle, &xregsize);
541   if (val != TD_OK && val != TD_NOXREGS)
542     error (_("sol_thread_fetch_registers: td_thr_getxregsize %s"),
543            td_err_string (val));
544
545   if (val == TD_OK)
546     {
547       xregset = alloca (xregsize);
548       val = td_thr_getxregs (&thandle, xregset);
549       if (val != TD_OK)
550         error (_("sol_thread_fetch_registers: td_thr_getxregs %s"),
551                td_err_string (val));
552     }
553 #endif
554 }
555
556 static void
557 sol_thread_store_registers (struct regcache *regcache, int regnum)
558 {
559   thread_t thread;
560   td_thrhandle_t thandle;
561   td_err_e val;
562   prgregset_t gregset;
563   prfpregset_t fpregset;
564 #if 0
565   int xregsize;
566   caddr_t xregset;
567 #endif
568
569   if (!is_thread (inferior_ptid))
570     {
571       /* It's an LWP; pass the request on to procfs.c.  */
572       procfs_ops.to_store_registers (regcache, regnum);
573       return;
574     }
575
576   /* Solaris thread: convert INFERIOR_PTID into a td_thrhandle_t.  */
577   thread = GET_THREAD (inferior_ptid);
578
579   val = p_td_ta_map_id2thr (main_ta, thread, &thandle);
580   if (val != TD_OK)
581     error (_("sol_thread_store_registers: td_ta_map_id2thr %s"),
582            td_err_string (val));
583
584   if (regnum != -1)
585     {
586       /* Not writing all the registers.  */
587       char old_value[MAX_REGISTER_SIZE];
588
589       /* Save new register value.  */
590       regcache_raw_collect (regcache, regnum, old_value);
591
592       val = p_td_thr_getgregs (&thandle, gregset);
593       if (val != TD_OK)
594         error (_("sol_thread_store_registers: td_thr_getgregs %s"),
595                td_err_string (val));
596       val = p_td_thr_getfpregs (&thandle, &fpregset);
597       if (val != TD_OK)
598         error (_("sol_thread_store_registers: td_thr_getfpregs %s"),
599                td_err_string (val));
600
601       /* Restore new register value.  */
602       regcache_raw_supply (regcache, regnum, old_value);
603
604 #if 0
605       /* FIXME: libthread_db doesn't seem to handle this right.  */
606       val = td_thr_getxregsize (&thandle, &xregsize);
607       if (val != TD_OK && val != TD_NOXREGS)
608         error (_("sol_thread_store_registers: td_thr_getxregsize %s"),
609                td_err_string (val));
610
611       if (val == TD_OK)
612         {
613           xregset = alloca (xregsize);
614           val = td_thr_getxregs (&thandle, xregset);
615           if (val != TD_OK)
616             error (_("sol_thread_store_registers: td_thr_getxregs %s"),
617                    td_err_string (val));
618         }
619 #endif
620     }
621
622   fill_gregset (regcache, (gdb_gregset_t *) &gregset, regnum);
623   fill_fpregset (regcache, (gdb_fpregset_t *) &fpregset, regnum);
624
625   val = p_td_thr_setgregs (&thandle, gregset);
626   if (val != TD_OK)
627     error (_("sol_thread_store_registers: td_thr_setgregs %s"),
628            td_err_string (val));
629   val = p_td_thr_setfpregs (&thandle, &fpregset);
630   if (val != TD_OK)
631     error (_("sol_thread_store_registers: td_thr_setfpregs %s"),
632            td_err_string (val));
633
634 #if 0
635   /* FIXME: libthread_db doesn't seem to handle this right.  */
636   val = td_thr_getxregsize (&thandle, &xregsize);
637   if (val != TD_OK && val != TD_NOXREGS)
638     error (_("sol_thread_store_registers: td_thr_getxregsize %s"),
639            td_err_string (val));
640
641   /* ??? Should probably do something about writing the xregs here,
642      but what are they?  */
643 #endif
644 }
645
646 /* Get ready to modify the registers array.  On machines which store
647    individual registers, this doesn't need to do anything.  On
648    machines which store all the registers in one fell swoop, this
649    makes sure that registers contains all the registers from the
650    program being debugged.  */
651
652 static void
653 sol_thread_prepare_to_store (struct regcache *regcache)
654 {
655   procfs_ops.to_prepare_to_store (regcache);
656 }
657
658 /* Transfer LEN bytes between GDB address MYADDR and target address
659    MEMADDR.  If DOWRITE is non-zero, transfer them to the target,
660    otherwise transfer them from the target.  TARGET is unused.
661
662    Returns the number of bytes transferred.  */
663
664 static int
665 sol_thread_xfer_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len,
666                         int dowrite, struct mem_attrib *attrib,
667                         struct target_ops *target)
668 {
669   int retval;
670   struct cleanup *old_chain;
671
672   old_chain = save_inferior_ptid ();
673
674   if (is_thread (inferior_ptid) || !target_thread_alive (inferior_ptid))
675     {
676       /* It's either a thread or an LWP that isn't alive.  Any live
677          LWP will do so use the first available.
678
679          NOTE: We don't need to call switch_to_thread; we're just
680          reading memory.  */
681       inferior_ptid = procfs_first_available ();
682     }
683
684   if (target_has_execution)
685     retval = procfs_ops.deprecated_xfer_memory (memaddr, myaddr, len,
686                                                 dowrite, attrib, target);
687   else
688     retval = orig_core_ops.deprecated_xfer_memory (memaddr, myaddr, len,
689                                                    dowrite, attrib, target);
690
691   do_cleanups (old_chain);
692
693   return retval;
694 }
695
696 /* Perform partial transfers on OBJECT.  See target_read_partial and
697    target_write_partial for details of each variant.  One, and only
698    one, of readbuf or writebuf must be non-NULL.  */
699
700 static LONGEST
701 sol_thread_xfer_partial (struct target_ops *ops, enum target_object object,
702                           const char *annex, gdb_byte *readbuf,
703                           const gdb_byte *writebuf,
704                          ULONGEST offset, LONGEST len)
705 {
706   int retval;
707   struct cleanup *old_chain;
708
709   old_chain = save_inferior_ptid ();
710
711   if (is_thread (inferior_ptid) || !target_thread_alive (inferior_ptid))
712     {
713       /* It's either a thread or an LWP that isn't alive.  Any live
714          LWP will do so use the first available.
715
716          NOTE: We don't need to call switch_to_thread; we're just
717          reading memory.  */
718       inferior_ptid = procfs_first_available ();
719     }
720
721   if (target_has_execution)
722     retval = procfs_ops.to_xfer_partial (ops, object, annex,
723                                          readbuf, writebuf, offset, len);
724   else
725     retval = orig_core_ops.to_xfer_partial (ops, object, annex,
726                                             readbuf, writebuf, offset, len);
727
728   do_cleanups (old_chain);
729
730   return retval;
731 }
732
733 /* Print status information about what we're accessing.  */
734
735 static void
736 sol_thread_files_info (struct target_ops *ignore)
737 {
738   procfs_ops.to_files_info (ignore);
739 }
740
741 static void
742 sol_thread_kill_inferior (void)
743 {
744   procfs_ops.to_kill ();
745 }
746
747 static void
748 sol_thread_notice_signals (ptid_t ptid)
749 {
750   procfs_ops.to_notice_signals (pid_to_ptid (PIDGET (ptid)));
751 }
752
753 /* Fork an inferior process, and start debugging it with /proc.  */
754
755 static void
756 sol_thread_create_inferior (char *exec_file, char *allargs, char **env,
757                             int from_tty)
758 {
759   procfs_ops.to_create_inferior (exec_file, allargs, env, from_tty);
760
761   if (sol_thread_active && !ptid_equal (inferior_ptid, null_ptid))
762     {
763       /* Save for xfer_memory.  */
764       main_ph.ptid = inferior_ptid;
765
766       push_target (&sol_thread_ops);
767
768       inferior_ptid = lwp_to_thread (inferior_ptid);
769       if (PIDGET (inferior_ptid) == -1)
770         inferior_ptid = main_ph.ptid;
771
772       if (!in_thread_list (inferior_ptid))
773         add_thread (inferior_ptid);
774     }
775 }
776
777 /* This routine is called whenever a new symbol table is read in, or
778    when all symbol tables are removed.  libthread_db can only be
779    initialized when it finds the right variables in libthread.so.
780    Since it's a shared library, those variables don't show up until
781    the library gets mapped and the symbol table is read in.  */
782
783 static void
784 sol_thread_new_objfile (struct objfile *objfile)
785 {
786   td_err_e val;
787
788   if (!objfile)
789     {
790       sol_thread_active = 0;
791       return;
792     }
793
794   /* Don't do anything if init failed to resolve the libthread_db
795      library.  */
796   if (!procfs_suppress_run)
797     return;
798
799   /* Now, initialize libthread_db.  This needs to be done after the
800      shared libraries are located because it needs information from
801      the user's thread library.  */
802
803   val = p_td_init ();
804   if (val != TD_OK)
805     {
806       warning (_("sol_thread_new_objfile: td_init: %s"), td_err_string (val));
807       return;
808     }
809
810   val = p_td_ta_new (&main_ph, &main_ta);
811   if (val == TD_NOLIBTHREAD)
812     return;
813   else if (val != TD_OK)
814     {
815       warning (_("sol_thread_new_objfile: td_ta_new: %s"), td_err_string (val));
816       return;
817     }
818
819   sol_thread_active = 1;
820 }
821
822 /* Clean up after the inferior dies.  */
823
824 static void
825 sol_thread_mourn_inferior (void)
826 {
827   unpush_target (&sol_thread_ops);
828   procfs_ops.to_mourn_inferior ();
829 }
830
831 /* Mark our target-struct as eligible for stray "run" and "attach"
832    commands.  */
833
834 static int
835 sol_thread_can_run (void)
836 {
837   return procfs_suppress_run;
838 }
839
840 /*
841
842    LOCAL FUNCTION
843
844    sol_thread_alive     - test thread for "aliveness"
845
846    SYNOPSIS
847
848    static bool sol_thread_alive (ptid_t ptid);
849
850    DESCRIPTION
851
852    returns true if thread still active in inferior.
853
854  */
855
856 /* Return true if PTID is still active in the inferior.  */
857
858 static int
859 sol_thread_alive (ptid_t ptid)
860 {
861   if (is_thread (ptid))
862     {
863       /* It's a (user-level) thread.  */
864       td_err_e val;
865       td_thrhandle_t th;
866       int pid;
867
868       pid = GET_THREAD (ptid);
869       if ((val = p_td_ta_map_id2thr (main_ta, pid, &th)) != TD_OK)
870         return 0;               /* Thread not found.  */
871       if ((val = p_td_thr_validate (&th)) != TD_OK)
872         return 0;               /* Thread not valid.  */
873       return 1;                 /* Known thread.  */
874     }
875   else
876     {
877       /* It's an LPW; pass the request on to procfs.  */
878       if (target_has_execution)
879         return procfs_ops.to_thread_alive (ptid);
880       else
881         return orig_core_ops.to_thread_alive (ptid);
882     }
883 }
884
885 static void
886 sol_thread_stop (void)
887 {
888   procfs_ops.to_stop ();
889 }
890 \f
891 /* These routines implement the lower half of the thread_db interface,
892    i.e. the ps_* routines.  */
893
894 /* Various versions of <proc_service.h> have slightly different
895    function prototypes.  In particular, we have
896
897    NEWER                        OLDER
898    struct ps_prochandle *       const struct ps_prochandle *
899    void*                        char*
900    const void*                  char*
901    int                          size_t
902
903    Which one you have depends on the Solaris version and what patches
904    you've applied.  On the theory that there are only two major
905    variants, we have configure check the prototype of ps_pdwrite (),
906    and use that info to make appropriate typedefs here. */
907
908 #ifdef PROC_SERVICE_IS_OLD
909 typedef const struct ps_prochandle *gdb_ps_prochandle_t;
910 typedef char *gdb_ps_read_buf_t;
911 typedef char *gdb_ps_write_buf_t;
912 typedef int gdb_ps_size_t;
913 typedef psaddr_t gdb_ps_addr_t;
914 #else
915 typedef struct ps_prochandle *gdb_ps_prochandle_t;
916 typedef void *gdb_ps_read_buf_t;
917 typedef const void *gdb_ps_write_buf_t;
918 typedef size_t gdb_ps_size_t;
919 typedef psaddr_t gdb_ps_addr_t;
920 #endif
921
922 /* The next four routines are called by libthread_db to tell us to
923    stop and stop a particular process or lwp.  Since GDB ensures that
924    these are all stopped by the time we call anything in thread_db,
925    these routines need to do nothing.  */
926
927 /* Process stop.  */
928
929 ps_err_e
930 ps_pstop (gdb_ps_prochandle_t ph)
931 {
932   return PS_OK;
933 }
934
935 /* Process continue.  */
936
937 ps_err_e
938 ps_pcontinue (gdb_ps_prochandle_t ph)
939 {
940   return PS_OK;
941 }
942
943 /* LWP stop.  */
944
945 ps_err_e
946 ps_lstop (gdb_ps_prochandle_t ph, lwpid_t lwpid)
947 {
948   return PS_OK;
949 }
950
951 /* LWP continue.  */
952
953 ps_err_e
954 ps_lcontinue (gdb_ps_prochandle_t ph, lwpid_t lwpid)
955 {
956   return PS_OK;
957 }
958
959 /* Looks up the symbol LD_SYMBOL_NAME in the debugger's symbol table.  */
960
961 ps_err_e
962 ps_pglobal_lookup (gdb_ps_prochandle_t ph, const char *ld_object_name,
963                    const char *ld_symbol_name, gdb_ps_addr_t *ld_symbol_addr)
964 {
965   struct minimal_symbol *ms;
966
967   ms = lookup_minimal_symbol (ld_symbol_name, NULL, NULL);
968   if (!ms)
969     return PS_NOSYM;
970
971   *ld_symbol_addr = SYMBOL_VALUE_ADDRESS (ms);
972   return PS_OK;
973 }
974
975 /* Common routine for reading and writing memory.  */
976
977 static ps_err_e
978 rw_common (int dowrite, const struct ps_prochandle *ph, gdb_ps_addr_t addr,
979            char *buf, int size)
980 {
981   struct cleanup *old_chain;
982
983   old_chain = save_inferior_ptid ();
984
985   if (is_thread (inferior_ptid) || !target_thread_alive (inferior_ptid))
986     {
987       /* It's either a thread or an LWP that isn't alive.  Any live
988          LWP will do so use the first available.
989
990          NOTE: We don't need to call switch_to_thread; we're just
991          reading memory.  */
992       inferior_ptid = procfs_first_available ();
993     }
994
995 #if defined (__sparcv9)
996   /* For Sparc64 cross Sparc32, make sure the address has not been
997      accidentally sign-extended (or whatever) to beyond 32 bits.  */
998   if (bfd_get_arch_size (exec_bfd) == 32)
999     addr &= 0xffffffff;
1000 #endif
1001
1002   while (size > 0)
1003     {
1004       int cc;
1005
1006       /* FIXME: passing 0 as attrib argument.  */
1007       if (target_has_execution)
1008         cc = procfs_ops.deprecated_xfer_memory (addr, buf, size,
1009                                                 dowrite, 0, &procfs_ops);
1010       else
1011         cc = orig_core_ops.deprecated_xfer_memory (addr, buf, size,
1012                                                    dowrite, 0, &core_ops);
1013
1014       if (cc < 0)
1015         {
1016           if (dowrite == 0)
1017             print_sys_errmsg ("rw_common (): read", errno);
1018           else
1019             print_sys_errmsg ("rw_common (): write", errno);
1020
1021           do_cleanups (old_chain);
1022
1023           return PS_ERR;
1024         }
1025       else if (cc == 0)
1026         {
1027           if (dowrite == 0)
1028             warning (_("rw_common (): unable to read at addr 0x%lx"),
1029                      (long) addr);
1030           else
1031             warning (_("rw_common (): unable to write at addr 0x%lx"),
1032                      (long) addr);
1033
1034           do_cleanups (old_chain);
1035
1036           return PS_ERR;
1037         }
1038
1039       size -= cc;
1040       buf += cc;
1041     }
1042
1043   do_cleanups (old_chain);
1044
1045   return PS_OK;
1046 }
1047
1048 /* Copies SIZE bytes from target process .data segment to debugger memory.  */
1049
1050 ps_err_e
1051 ps_pdread (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
1052            gdb_ps_read_buf_t buf, gdb_ps_size_t size)
1053 {
1054   return rw_common (0, ph, addr, buf, size);
1055 }
1056
1057 /* Copies SIZE bytes from debugger memory .data segment to target process.  */
1058
1059 ps_err_e
1060 ps_pdwrite (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
1061             gdb_ps_write_buf_t buf, gdb_ps_size_t size)
1062 {
1063   return rw_common (1, ph, addr, (char *) buf, size);
1064 }
1065
1066 /* Copies SIZE bytes from target process .text segment to debugger memory.  */
1067
1068 ps_err_e
1069 ps_ptread (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
1070            gdb_ps_read_buf_t buf, gdb_ps_size_t size)
1071 {
1072   return rw_common (0, ph, addr, buf, size);
1073 }
1074
1075 /* Copies SIZE bytes from debugger memory .text segment to target process.  */
1076
1077 ps_err_e
1078 ps_ptwrite (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
1079             gdb_ps_write_buf_t buf, gdb_ps_size_t size)
1080 {
1081   return rw_common (1, ph, addr, (char *) buf, size);
1082 }
1083
1084 /* Get general-purpose registers for LWP.  */
1085
1086 ps_err_e
1087 ps_lgetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, prgregset_t gregset)
1088 {
1089   struct cleanup *old_chain;
1090   struct regcache *regcache;
1091
1092   old_chain = save_inferior_ptid ();
1093
1094   inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
1095   regcache = get_thread_regcache (inferior_ptid);
1096
1097   if (target_has_execution)
1098     procfs_ops.to_fetch_registers (regcache, -1);
1099   else
1100     orig_core_ops.to_fetch_registers (regcache, -1);
1101   fill_gregset (regcache, (gdb_gregset_t *) gregset, -1);
1102
1103   do_cleanups (old_chain);
1104
1105   return PS_OK;
1106 }
1107
1108 /* Set general-purpose registers for LWP.  */
1109
1110 ps_err_e
1111 ps_lsetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
1112              const prgregset_t gregset)
1113 {
1114   struct cleanup *old_chain;
1115   struct regcache *regcache;
1116
1117   old_chain = save_inferior_ptid ();
1118
1119   inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
1120   regcache = get_thread_regcache (inferior_ptid);
1121
1122   supply_gregset (regcache, (const gdb_gregset_t *) gregset);
1123   if (target_has_execution)
1124     procfs_ops.to_store_registers (regcache, -1);
1125   else
1126     orig_core_ops.to_store_registers (regcache, -1);
1127
1128   do_cleanups (old_chain);
1129
1130   return PS_OK;
1131 }
1132
1133 /* Log a message (sends to gdb_stderr).  */
1134
1135 void
1136 ps_plog (const char *fmt, ...)
1137 {
1138   va_list args;
1139
1140   va_start (args, fmt);
1141
1142   vfprintf_filtered (gdb_stderr, fmt, args);
1143 }
1144
1145 /* Get size of extra register set.  Currently a noop.  */
1146
1147 ps_err_e
1148 ps_lgetxregsize (gdb_ps_prochandle_t ph, lwpid_t lwpid, int *xregsize)
1149 {
1150 #if 0
1151   int lwp_fd;
1152   int regsize;
1153   ps_err_e val;
1154
1155   val = get_lwp_fd (ph, lwpid, &lwp_fd);
1156   if (val != PS_OK)
1157     return val;
1158
1159   if (ioctl (lwp_fd, PIOCGXREGSIZE, &regsize))
1160     {
1161       if (errno == EINVAL)
1162         return PS_NOFREGS;      /* XXX Wrong code, but this is the closest
1163                                    thing in proc_service.h  */
1164
1165       print_sys_errmsg ("ps_lgetxregsize (): PIOCGXREGSIZE", errno);
1166       return PS_ERR;
1167     }
1168 #endif
1169
1170   return PS_OK;
1171 }
1172
1173 /* Get extra register set.  Currently a noop.  */
1174
1175 ps_err_e
1176 ps_lgetxregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, caddr_t xregset)
1177 {
1178 #if 0
1179   int lwp_fd;
1180   ps_err_e val;
1181
1182   val = get_lwp_fd (ph, lwpid, &lwp_fd);
1183   if (val != PS_OK)
1184     return val;
1185
1186   if (ioctl (lwp_fd, PIOCGXREG, xregset))
1187     {
1188       print_sys_errmsg ("ps_lgetxregs (): PIOCGXREG", errno);
1189       return PS_ERR;
1190     }
1191 #endif
1192
1193   return PS_OK;
1194 }
1195
1196 /* Set extra register set.  Currently a noop.  */
1197
1198 ps_err_e
1199 ps_lsetxregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, caddr_t xregset)
1200 {
1201 #if 0
1202   int lwp_fd;
1203   ps_err_e val;
1204
1205   val = get_lwp_fd (ph, lwpid, &lwp_fd);
1206   if (val != PS_OK)
1207     return val;
1208
1209   if (ioctl (lwp_fd, PIOCSXREG, xregset))
1210     {
1211       print_sys_errmsg ("ps_lsetxregs (): PIOCSXREG", errno);
1212       return PS_ERR;
1213     }
1214 #endif
1215
1216   return PS_OK;
1217 }
1218
1219 /* Get floating-point registers for LWP.  */
1220
1221 ps_err_e
1222 ps_lgetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
1223                prfpregset_t *fpregset)
1224 {
1225   struct cleanup *old_chain;
1226   struct regcache *regcache;
1227
1228   old_chain = save_inferior_ptid ();
1229
1230   inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
1231   regcache = get_thread_regcache (inferior_ptid);
1232
1233   if (target_has_execution)
1234     procfs_ops.to_fetch_registers (regcache, -1);
1235   else
1236     orig_core_ops.to_fetch_registers (regcache, -1);
1237   fill_fpregset (regcache, (gdb_fpregset_t *) fpregset, -1);
1238
1239   do_cleanups (old_chain);
1240
1241   return PS_OK;
1242 }
1243
1244 /* Set floating-point regs for LWP */
1245
1246 ps_err_e
1247 ps_lsetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
1248                const prfpregset_t * fpregset)
1249 {
1250   struct cleanup *old_chain;
1251   struct regcache *regcache;
1252
1253   old_chain = save_inferior_ptid ();
1254
1255   inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
1256   regcache = get_thread_regcache (inferior_ptid);
1257
1258   supply_fpregset (regcache, (const gdb_fpregset_t *) fpregset);
1259   if (target_has_execution)
1260     procfs_ops.to_store_registers (regcache, -1);
1261   else
1262     orig_core_ops.to_store_registers (regcache, -1);
1263
1264   do_cleanups (old_chain);
1265
1266   return PS_OK;
1267 }
1268
1269 #ifdef PR_MODEL_LP64
1270 /* Identify process as 32-bit or 64-bit.  At the moment we're using
1271    BFD to do this.  There might be a more Solaris-specific
1272    (e.g. procfs) method, but this ought to work.  */
1273
1274 ps_err_e
1275 ps_pdmodel (gdb_ps_prochandle_t ph, int *data_model)
1276 {
1277   if (exec_bfd == 0)
1278     *data_model = PR_MODEL_UNKNOWN;
1279   else if (bfd_get_arch_size (exec_bfd) == 32)
1280     *data_model = PR_MODEL_ILP32;
1281   else
1282     *data_model = PR_MODEL_LP64;
1283
1284   return PS_OK;
1285 }
1286 #endif /* PR_MODEL_LP64 */
1287
1288 #ifdef TM_I386SOL2_H
1289
1290 /* Reads the local descriptor table of a LWP.  */
1291
1292 ps_err_e
1293 ps_lgetLDT (gdb_ps_prochandle_t ph, lwpid_t lwpid,
1294             struct ssd *pldt)
1295 {
1296   /* NOTE: only used on Solaris, therefore OK to refer to procfs.c.  */
1297   extern struct ssd *procfs_find_LDT_entry (ptid_t);
1298   struct ssd *ret;
1299
1300   /* FIXME: can't I get the process ID from the prochandle or
1301      something?  */
1302
1303   if (PIDGET (inferior_ptid) <= 0 || lwpid <= 0)
1304     return PS_BADLID;
1305
1306   ret = procfs_find_LDT_entry (BUILD_LWP (lwpid, PIDGET (inferior_ptid)));
1307   if (ret)
1308     {
1309       memcpy (pldt, ret, sizeof (struct ssd));
1310       return PS_OK;
1311     }
1312   else
1313     /* LDT not found.  */
1314     return PS_ERR;
1315 }
1316 #endif /* TM_I386SOL2_H */
1317 \f
1318
1319 /* Convert PTID to printable form.  */
1320
1321 char *
1322 solaris_pid_to_str (ptid_t ptid)
1323 {
1324   static char buf[100];
1325
1326   /* In case init failed to resolve the libthread_db library.  */
1327   if (!procfs_suppress_run)
1328     return procfs_pid_to_str (ptid);
1329
1330   if (is_thread (ptid))
1331     {
1332       ptid_t lwp;
1333
1334       lwp = thread_to_lwp (ptid, -2);
1335
1336       if (PIDGET (lwp) == -1)
1337         sprintf (buf, "Thread %ld (defunct)", GET_THREAD (ptid));
1338       else if (PIDGET (lwp) != -2)
1339         sprintf (buf, "Thread %ld (LWP %ld)",
1340                  GET_THREAD (ptid), GET_LWP (lwp));
1341       else
1342         sprintf (buf, "Thread %ld        ", GET_THREAD (ptid));
1343     }
1344   else if (GET_LWP (ptid) != 0)
1345     sprintf (buf, "LWP    %ld        ", GET_LWP (ptid));
1346   else
1347     sprintf (buf, "process %d    ", PIDGET (ptid));
1348
1349   return buf;
1350 }
1351 \f
1352
1353 /* Worker bee for find_new_threads.  Callback function that gets
1354    called once per user-level thread (i.e. not for LWP's).  */
1355
1356 static int
1357 sol_find_new_threads_callback (const td_thrhandle_t *th, void *ignored)
1358 {
1359   td_err_e retval;
1360   td_thrinfo_t ti;
1361   ptid_t ptid;
1362
1363   retval = p_td_thr_get_info (th, &ti);
1364   if (retval != TD_OK)
1365     return -1;
1366
1367   ptid = BUILD_THREAD (ti.ti_tid, PIDGET (inferior_ptid));
1368   if (!in_thread_list (ptid))
1369     add_thread (ptid);
1370
1371   return 0;
1372 }
1373
1374 static void
1375 sol_find_new_threads (void)
1376 {
1377   /* Don't do anything if init failed to resolve the libthread_db
1378      library.  */
1379   if (!procfs_suppress_run)
1380     return;
1381
1382   if (PIDGET (inferior_ptid) == -1)
1383     {
1384       printf_filtered ("No process.\n");
1385       return;
1386     }
1387
1388   /* First Find any new LWP's.  */
1389   procfs_ops.to_find_new_threads ();
1390
1391   /* Then find any new user-level threads.  */
1392   p_td_ta_thr_iter (main_ta, sol_find_new_threads_callback, (void *) 0,
1393                     TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
1394                     TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
1395 }
1396
1397 static void
1398 sol_core_open (char *filename, int from_tty)
1399 {
1400   orig_core_ops.to_open (filename, from_tty);
1401 }
1402
1403 static void
1404 sol_core_close (int quitting)
1405 {
1406   orig_core_ops.to_close (quitting);
1407 }
1408
1409 static void
1410 sol_core_detach (char *args, int from_tty)
1411 {
1412   unpush_target (&core_ops);
1413   orig_core_ops.to_detach (args, from_tty);
1414 }
1415
1416 static void
1417 sol_core_files_info (struct target_ops *t)
1418 {
1419   orig_core_ops.to_files_info (t);
1420 }
1421
1422 /* Worker bee for the "info sol-thread" command.  This is a callback
1423    function that gets called once for each Solaris user-level thread
1424    (i.e. not for LWPs) in the inferior.  Print anything interesting
1425    that we can think of.  */
1426
1427 static int
1428 info_cb (const td_thrhandle_t *th, void *s)
1429 {
1430   td_err_e ret;
1431   td_thrinfo_t ti;
1432
1433   ret = p_td_thr_get_info (th, &ti);
1434   if (ret == TD_OK)
1435     {
1436       printf_filtered ("%s thread #%d, lwp %d, ",
1437                        ti.ti_type == TD_THR_SYSTEM ? "system" : "user  ",
1438                        ti.ti_tid, ti.ti_lid);
1439       switch (ti.ti_state)
1440         {
1441         default:
1442         case TD_THR_UNKNOWN:
1443           printf_filtered ("<unknown state>");
1444           break;
1445         case TD_THR_STOPPED:
1446           printf_filtered ("(stopped)");
1447           break;
1448         case TD_THR_RUN:
1449           printf_filtered ("(run)    ");
1450           break;
1451         case TD_THR_ACTIVE:
1452           printf_filtered ("(active) ");
1453           break;
1454         case TD_THR_ZOMBIE:
1455           printf_filtered ("(zombie) ");
1456           break;
1457         case TD_THR_SLEEP:
1458           printf_filtered ("(asleep) ");
1459           break;
1460         case TD_THR_STOPPED_ASLEEP:
1461           printf_filtered ("(stopped asleep)");
1462           break;
1463         }
1464       /* Print thr_create start function.  */
1465       if (ti.ti_startfunc != 0)
1466         {
1467           struct minimal_symbol *msym;
1468           msym = lookup_minimal_symbol_by_pc (ti.ti_startfunc);
1469           if (msym)
1470             printf_filtered ("   startfunc: %s\n",
1471                              DEPRECATED_SYMBOL_NAME (msym));
1472           else
1473             printf_filtered ("   startfunc: 0x%s\n", paddr (ti.ti_startfunc));
1474         }
1475
1476       /* If thread is asleep, print function that went to sleep.  */
1477       if (ti.ti_state == TD_THR_SLEEP)
1478         {
1479           struct minimal_symbol *msym;
1480           msym = lookup_minimal_symbol_by_pc (ti.ti_pc);
1481           if (msym)
1482             printf_filtered (" - Sleep func: %s\n",
1483                              DEPRECATED_SYMBOL_NAME (msym));
1484           else
1485             printf_filtered (" - Sleep func: 0x%s\n", paddr (ti.ti_startfunc));
1486         }
1487
1488       /* Wrap up line, if necessary.  */
1489       if (ti.ti_state != TD_THR_SLEEP && ti.ti_startfunc == 0)
1490         printf_filtered ("\n"); /* don't you hate counting newlines? */
1491     }
1492   else
1493     warning (_("info sol-thread: failed to get info for thread."));
1494
1495   return 0;
1496 }
1497
1498 /* List some state about each Solaris user-level thread in the
1499    inferior.  */
1500
1501 static void
1502 info_solthreads (char *args, int from_tty)
1503 {
1504   p_td_ta_thr_iter (main_ta, info_cb, args,
1505                     TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
1506                     TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
1507 }
1508
1509 static int
1510 sol_find_memory_regions (int (*func) (CORE_ADDR, unsigned long,
1511                                       int, int, int, void *),
1512                          void *data)
1513 {
1514   return procfs_ops.to_find_memory_regions (func, data);
1515 }
1516
1517 static char *
1518 sol_make_note_section (bfd *obfd, int *note_size)
1519 {
1520   return procfs_ops.to_make_corefile_notes (obfd, note_size);
1521 }
1522
1523 static int
1524 ignore (struct bp_target_info *bp_tgt)
1525 {
1526   return 0;
1527 }
1528
1529 static void
1530 init_sol_thread_ops (void)
1531 {
1532   sol_thread_ops.to_shortname = "solaris-threads";
1533   sol_thread_ops.to_longname = "Solaris threads and pthread.";
1534   sol_thread_ops.to_doc = "Solaris threads and pthread support.";
1535   sol_thread_ops.to_open = sol_thread_open;
1536   sol_thread_ops.to_attach = sol_thread_attach;
1537   sol_thread_ops.to_detach = sol_thread_detach;
1538   sol_thread_ops.to_resume = sol_thread_resume;
1539   sol_thread_ops.to_wait = sol_thread_wait;
1540   sol_thread_ops.to_fetch_registers = sol_thread_fetch_registers;
1541   sol_thread_ops.to_store_registers = sol_thread_store_registers;
1542   sol_thread_ops.to_prepare_to_store = sol_thread_prepare_to_store;
1543   sol_thread_ops.deprecated_xfer_memory = sol_thread_xfer_memory;
1544   sol_thread_ops.to_xfer_partial = sol_thread_xfer_partial;
1545   sol_thread_ops.to_files_info = sol_thread_files_info;
1546   sol_thread_ops.to_insert_breakpoint = memory_insert_breakpoint;
1547   sol_thread_ops.to_remove_breakpoint = memory_remove_breakpoint;
1548   sol_thread_ops.to_terminal_init = terminal_init_inferior;
1549   sol_thread_ops.to_terminal_inferior = terminal_inferior;
1550   sol_thread_ops.to_terminal_ours_for_output = terminal_ours_for_output;
1551   sol_thread_ops.to_terminal_ours = terminal_ours;
1552   sol_thread_ops.to_terminal_save_ours = terminal_save_ours;
1553   sol_thread_ops.to_terminal_info = child_terminal_info;
1554   sol_thread_ops.to_kill = sol_thread_kill_inferior;
1555   sol_thread_ops.to_create_inferior = sol_thread_create_inferior;
1556   sol_thread_ops.to_mourn_inferior = sol_thread_mourn_inferior;
1557   sol_thread_ops.to_can_run = sol_thread_can_run;
1558   sol_thread_ops.to_notice_signals = sol_thread_notice_signals;
1559   sol_thread_ops.to_thread_alive = sol_thread_alive;
1560   sol_thread_ops.to_pid_to_str = solaris_pid_to_str;
1561   sol_thread_ops.to_find_new_threads = sol_find_new_threads;
1562   sol_thread_ops.to_stop = sol_thread_stop;
1563   sol_thread_ops.to_stratum = process_stratum;
1564   sol_thread_ops.to_has_all_memory = 1;
1565   sol_thread_ops.to_has_memory = 1;
1566   sol_thread_ops.to_has_stack = 1;
1567   sol_thread_ops.to_has_registers = 1;
1568   sol_thread_ops.to_has_execution = 1;
1569   sol_thread_ops.to_has_thread_control = tc_none;
1570   sol_thread_ops.to_find_memory_regions = sol_find_memory_regions;
1571   sol_thread_ops.to_make_corefile_notes = sol_make_note_section;
1572   sol_thread_ops.to_magic = OPS_MAGIC;
1573 }
1574
1575 static void
1576 init_sol_core_ops (void)
1577 {
1578   sol_core_ops.to_shortname = "solaris-core";
1579   sol_core_ops.to_longname = "Solaris core threads and pthread.";
1580   sol_core_ops.to_doc = "Solaris threads and pthread support for core files.";
1581   sol_core_ops.to_open = sol_core_open;
1582   sol_core_ops.to_close = sol_core_close;
1583   sol_core_ops.to_attach = sol_thread_attach;
1584   sol_core_ops.to_detach = sol_core_detach;
1585   sol_core_ops.to_fetch_registers = sol_thread_fetch_registers;
1586   sol_core_ops.deprecated_xfer_memory = sol_thread_xfer_memory;
1587   sol_core_ops.to_xfer_partial = sol_thread_xfer_partial;
1588   sol_core_ops.to_files_info = sol_core_files_info;
1589   sol_core_ops.to_insert_breakpoint = ignore;
1590   sol_core_ops.to_remove_breakpoint = ignore;
1591   sol_core_ops.to_create_inferior = sol_thread_create_inferior;
1592   sol_core_ops.to_stratum = core_stratum;
1593   sol_core_ops.to_has_memory = 1;
1594   sol_core_ops.to_has_stack = 1;
1595   sol_core_ops.to_has_registers = 1;
1596   sol_core_ops.to_has_thread_control = tc_none;
1597   sol_core_ops.to_thread_alive = sol_thread_alive;
1598   sol_core_ops.to_pid_to_str = solaris_pid_to_str;
1599   /* On Solaris/x86, when debugging a threaded core file from process
1600      <n>, the following causes "info threads" to produce "procfs:
1601      couldn't find pid <n> in procinfo list" where <n> is the pid of
1602      the process that produced the core file.  Disable it for now. */
1603 #if 0
1604   sol_core_ops.to_find_new_threads = sol_find_new_threads;
1605 #endif
1606   sol_core_ops.to_magic = OPS_MAGIC;
1607 }
1608
1609 /* We suppress the call to add_target of core_ops in corelow because
1610    if there are two targets in the stratum core_stratum,
1611    find_core_target won't know which one to return.  See corelow.c for
1612    an additonal comment on coreops_suppress_target.  */
1613 int coreops_suppress_target = 1;
1614
1615 void
1616 _initialize_sol_thread (void)
1617 {
1618   void *dlhandle;
1619
1620   init_sol_thread_ops ();
1621   init_sol_core_ops ();
1622
1623   dlhandle = dlopen ("libthread_db.so.1", RTLD_NOW);
1624   if (!dlhandle)
1625     goto die;
1626
1627 #define resolve(X) \
1628   if (!(p_##X = dlsym (dlhandle, #X))) \
1629     goto die;
1630
1631   resolve (td_log);
1632   resolve (td_ta_new);
1633   resolve (td_ta_delete);
1634   resolve (td_init);
1635   resolve (td_ta_get_ph);
1636   resolve (td_ta_get_nthreads);
1637   resolve (td_ta_tsd_iter);
1638   resolve (td_ta_thr_iter);
1639   resolve (td_thr_validate);
1640   resolve (td_thr_tsd);
1641   resolve (td_thr_get_info);
1642   resolve (td_thr_getfpregs);
1643   resolve (td_thr_getxregsize);
1644   resolve (td_thr_getxregs);
1645   resolve (td_thr_sigsetmask);
1646   resolve (td_thr_setprio);
1647   resolve (td_thr_setsigpending);
1648   resolve (td_thr_setfpregs);
1649   resolve (td_thr_setxregs);
1650   resolve (td_ta_map_id2thr);
1651   resolve (td_ta_map_lwp2thr);
1652   resolve (td_thr_getgregs);
1653   resolve (td_thr_setgregs);
1654
1655   add_target (&sol_thread_ops);
1656
1657   procfs_suppress_run = 1;
1658
1659   add_cmd ("sol-threads", class_maintenance, info_solthreads,
1660            _("Show info on Solaris user threads."), &maintenanceinfolist);
1661
1662   memcpy (&orig_core_ops, &core_ops, sizeof (struct target_ops));
1663   memcpy (&core_ops, &sol_core_ops, sizeof (struct target_ops));
1664   add_target (&core_ops);
1665
1666   /* Hook into new_objfile notification.  */
1667   observer_attach_new_objfile (sol_thread_new_objfile);
1668   return;
1669
1670  die:
1671   fprintf_unfiltered (gdb_stderr, "\
1672 [GDB will not be able to debug user-mode threads: %s]\n", dlerror ());
1673
1674   if (dlhandle)
1675     dlclose (dlhandle);
1676
1677   /* Allow the user to debug non-threaded core files.  */
1678   add_target (&core_ops);
1679
1680   return;
1681 }