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