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