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 
179 
180 /* Return the libthread_db error string associated with ERRCODE.  If
181    ERRCODE is unknown, return an appropriate message.  */
182 
183 static char *
td_err_string(td_err_e errcode)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 *
td_state_string(td_thr_state_e statecode)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 
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
thread_to_lwp(ptid_t thread_id,int default_lwp)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
lwp_to_thread(ptid_t lwp)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 
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
sol_thread_open(char * arg,int from_tty)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
sol_thread_attach(char * args,int from_tty)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
sol_thread_detach(char * args,int from_tty)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
sol_thread_resume(ptid_t ptid,int step,enum target_signal signo)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
sol_thread_wait(ptid_t ptid,struct target_waitstatus * ourstatus)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
sol_thread_fetch_registers(int regnum)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
sol_thread_store_registers(int regnum)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
sol_thread_prepare_to_store(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
sol_thread_xfer_memory(CORE_ADDR memaddr,gdb_byte * myaddr,int len,int dowrite,struct mem_attrib * attrib,struct target_ops * target)664 sol_thread_xfer_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len,
665 			int dowrite, 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
sol_thread_xfer_partial(struct target_ops * ops,enum target_object object,const char * annex,gdb_byte * readbuf,const gdb_byte * writebuf,ULONGEST offset,LONGEST len)700 sol_thread_xfer_partial (struct target_ops *ops, enum target_object object,
701 			  const char *annex, gdb_byte *readbuf,
702 			  const gdb_byte *writebuf,
703 			 ULONGEST offset, LONGEST len)
704 {
705   int retval;
706   struct cleanup *old_chain;
707 
708   old_chain = save_inferior_ptid ();
709 
710   if (is_thread (inferior_ptid) || !target_thread_alive (inferior_ptid))
711     {
712       /* It's either a thread or an LWP that isn't alive.  Any live
713          LWP will do so use the first available.
714 
715 	 NOTE: We don't need to call switch_to_thread; we're just
716 	 reading memory.  */
717       inferior_ptid = procfs_first_available ();
718     }
719 
720   if (target_has_execution)
721     retval = procfs_ops.to_xfer_partial (ops, object, annex,
722 					 readbuf, writebuf, offset, len);
723   else
724     retval = orig_core_ops.to_xfer_partial (ops, object, annex,
725 					    readbuf, writebuf, offset, len);
726 
727   do_cleanups (old_chain);
728 
729   return retval;
730 }
731 
732 /* Print status information about what we're accessing.  */
733 
734 static void
sol_thread_files_info(struct target_ops * ignore)735 sol_thread_files_info (struct target_ops *ignore)
736 {
737   procfs_ops.to_files_info (ignore);
738 }
739 
740 static void
sol_thread_kill_inferior(void)741 sol_thread_kill_inferior (void)
742 {
743   procfs_ops.to_kill ();
744 }
745 
746 static void
sol_thread_notice_signals(ptid_t ptid)747 sol_thread_notice_signals (ptid_t ptid)
748 {
749   procfs_ops.to_notice_signals (pid_to_ptid (PIDGET (ptid)));
750 }
751 
752 /* Fork an inferior process, and start debugging it with /proc.  */
753 
754 static void
sol_thread_create_inferior(char * exec_file,char * allargs,char ** env,int from_tty)755 sol_thread_create_inferior (char *exec_file, char *allargs, char **env,
756 			    int from_tty)
757 {
758   procfs_ops.to_create_inferior (exec_file, allargs, env, from_tty);
759 
760   if (sol_thread_active && !ptid_equal (inferior_ptid, null_ptid))
761     {
762       /* Save for xfer_memory.  */
763       main_ph.ptid = inferior_ptid;
764 
765       push_target (&sol_thread_ops);
766 
767       inferior_ptid = lwp_to_thread (inferior_ptid);
768       if (PIDGET (inferior_ptid) == -1)
769 	inferior_ptid = main_ph.ptid;
770 
771       if (!in_thread_list (inferior_ptid))
772 	add_thread (inferior_ptid);
773     }
774 }
775 
776 /* This routine is called whenever a new symbol table is read in, or
777    when all symbol tables are removed.  libthread_db can only be
778    initialized when it finds the right variables in libthread.so.
779    Since it's a shared library, those variables don't show up until
780    the library gets mapped and the symbol table is read in.
781 
782    This new_objfile event is managed by a chained function pointer.
783    It is the callee's responsability to call the next client on the
784    chain.  */
785 
786 /* Saved pointer to previous owner of the new_objfile event. */
787 static void (*target_new_objfile_chain) (struct objfile *);
788 
789 void
sol_thread_new_objfile(struct objfile * objfile)790 sol_thread_new_objfile (struct objfile *objfile)
791 {
792   td_err_e val;
793 
794   if (!objfile)
795     {
796       sol_thread_active = 0;
797       goto quit;
798     }
799 
800   /* Don't do anything if init failed to resolve the libthread_db
801      library.  */
802   if (!procfs_suppress_run)
803     goto quit;
804 
805   /* Now, initialize libthread_db.  This needs to be done after the
806      shared libraries are located because it needs information from
807      the user's thread library.  */
808 
809   val = p_td_init ();
810   if (val != TD_OK)
811     {
812       warning (_("sol_thread_new_objfile: td_init: %s"), td_err_string (val));
813       goto quit;
814     }
815 
816   val = p_td_ta_new (&main_ph, &main_ta);
817   if (val == TD_NOLIBTHREAD)
818     goto quit;
819   else if (val != TD_OK)
820     {
821       warning (_("sol_thread_new_objfile: td_ta_new: %s"), td_err_string (val));
822       goto quit;
823     }
824 
825   sol_thread_active = 1;
826 
827 quit:
828   /* Call predecessor on chain, if any.  */
829   if (target_new_objfile_chain)
830     target_new_objfile_chain (objfile);
831 }
832 
833 /* Clean up after the inferior dies.  */
834 
835 static void
sol_thread_mourn_inferior(void)836 sol_thread_mourn_inferior (void)
837 {
838   unpush_target (&sol_thread_ops);
839   procfs_ops.to_mourn_inferior ();
840 }
841 
842 /* Mark our target-struct as eligible for stray "run" and "attach"
843    commands.  */
844 
845 static int
sol_thread_can_run(void)846 sol_thread_can_run (void)
847 {
848   return procfs_suppress_run;
849 }
850 
851 /*
852 
853    LOCAL FUNCTION
854 
855    sol_thread_alive     - test thread for "aliveness"
856 
857    SYNOPSIS
858 
859    static bool sol_thread_alive (ptid_t ptid);
860 
861    DESCRIPTION
862 
863    returns true if thread still active in inferior.
864 
865  */
866 
867 /* Return true if PTID is still active in the inferior.  */
868 
869 static int
sol_thread_alive(ptid_t ptid)870 sol_thread_alive (ptid_t ptid)
871 {
872   if (is_thread (ptid))
873     {
874       /* It's a (user-level) thread.  */
875       td_err_e val;
876       td_thrhandle_t th;
877       int pid;
878 
879       pid = GET_THREAD (ptid);
880       if ((val = p_td_ta_map_id2thr (main_ta, pid, &th)) != TD_OK)
881 	return 0;		/* Thread not found.  */
882       if ((val = p_td_thr_validate (&th)) != TD_OK)
883 	return 0;		/* Thread not valid.  */
884       return 1;			/* Known thread.  */
885     }
886   else
887     {
888       /* It's an LPW; pass the request on to procfs.  */
889       if (target_has_execution)
890 	return procfs_ops.to_thread_alive (ptid);
891       else
892 	return orig_core_ops.to_thread_alive (ptid);
893     }
894 }
895 
896 static void
sol_thread_stop(void)897 sol_thread_stop (void)
898 {
899   procfs_ops.to_stop ();
900 }
901 
902 /* These routines implement the lower half of the thread_db interface,
903    i.e. the ps_* routines.  */
904 
905 /* Various versions of <proc_service.h> have slightly different
906    function prototypes.  In particular, we have
907 
908    NEWER                        OLDER
909    struct ps_prochandle *       const struct ps_prochandle *
910    void*                        char*
911    const void*          	char*
912    int                  	size_t
913 
914    Which one you have depends on the Solaris version and what patches
915    you've applied.  On the theory that there are only two major
916    variants, we have configure check the prototype of ps_pdwrite (),
917    and use that info to make appropriate typedefs here. */
918 
919 #ifdef PROC_SERVICE_IS_OLD
920 typedef const struct ps_prochandle *gdb_ps_prochandle_t;
921 typedef char *gdb_ps_read_buf_t;
922 typedef char *gdb_ps_write_buf_t;
923 typedef int gdb_ps_size_t;
924 typedef paddr_t gdb_ps_addr_t;
925 #else
926 typedef struct ps_prochandle *gdb_ps_prochandle_t;
927 typedef void *gdb_ps_read_buf_t;
928 typedef const void *gdb_ps_write_buf_t;
929 typedef size_t gdb_ps_size_t;
930 typedef psaddr_t gdb_ps_addr_t;
931 #endif
932 
933 /* The next four routines are called by libthread_db to tell us to
934    stop and stop a particular process or lwp.  Since GDB ensures that
935    these are all stopped by the time we call anything in thread_db,
936    these routines need to do nothing.  */
937 
938 /* Process stop.  */
939 
940 ps_err_e
ps_pstop(gdb_ps_prochandle_t ph)941 ps_pstop (gdb_ps_prochandle_t ph)
942 {
943   return PS_OK;
944 }
945 
946 /* Process continue.  */
947 
948 ps_err_e
ps_pcontinue(gdb_ps_prochandle_t ph)949 ps_pcontinue (gdb_ps_prochandle_t ph)
950 {
951   return PS_OK;
952 }
953 
954 /* LWP stop.  */
955 
956 ps_err_e
ps_lstop(gdb_ps_prochandle_t ph,lwpid_t lwpid)957 ps_lstop (gdb_ps_prochandle_t ph, lwpid_t lwpid)
958 {
959   return PS_OK;
960 }
961 
962 /* LWP continue.  */
963 
964 ps_err_e
ps_lcontinue(gdb_ps_prochandle_t ph,lwpid_t lwpid)965 ps_lcontinue (gdb_ps_prochandle_t ph, lwpid_t lwpid)
966 {
967   return PS_OK;
968 }
969 
970 /* Looks up the symbol LD_SYMBOL_NAME in the debugger's symbol table.  */
971 
972 ps_err_e
ps_pglobal_lookup(gdb_ps_prochandle_t ph,const char * ld_object_name,const char * ld_symbol_name,gdb_ps_addr_t * ld_symbol_addr)973 ps_pglobal_lookup (gdb_ps_prochandle_t ph, const char *ld_object_name,
974 		   const char *ld_symbol_name, gdb_ps_addr_t *ld_symbol_addr)
975 {
976   struct minimal_symbol *ms;
977 
978   ms = lookup_minimal_symbol (ld_symbol_name, NULL, NULL);
979   if (!ms)
980     return PS_NOSYM;
981 
982   *ld_symbol_addr = SYMBOL_VALUE_ADDRESS (ms);
983   return PS_OK;
984 }
985 
986 /* Common routine for reading and writing memory.  */
987 
988 static ps_err_e
rw_common(int dowrite,const struct ps_prochandle * ph,gdb_ps_addr_t addr,char * buf,int size)989 rw_common (int dowrite, const struct ps_prochandle *ph, gdb_ps_addr_t addr,
990 	   char *buf, int size)
991 {
992   struct cleanup *old_chain;
993 
994   old_chain = save_inferior_ptid ();
995 
996   if (is_thread (inferior_ptid) || !target_thread_alive (inferior_ptid))
997     {
998       /* It's either a thread or an LWP that isn't alive.  Any live
999          LWP will do so use the first available.
1000 
1001 	 NOTE: We don't need to call switch_to_thread; we're just
1002 	 reading memory.  */
1003       inferior_ptid = procfs_first_available ();
1004     }
1005 
1006 #if defined (__sparcv9)
1007   /* For Sparc64 cross Sparc32, make sure the address has not been
1008      accidentally sign-extended (or whatever) to beyond 32 bits.  */
1009   if (bfd_get_arch_size (exec_bfd) == 32)
1010     addr &= 0xffffffff;
1011 #endif
1012 
1013   while (size > 0)
1014     {
1015       int cc;
1016 
1017       /* FIXME: passing 0 as attrib argument.  */
1018       if (target_has_execution)
1019 	cc = procfs_ops.deprecated_xfer_memory (addr, buf, size,
1020 						dowrite, 0, &procfs_ops);
1021       else
1022 	cc = orig_core_ops.deprecated_xfer_memory (addr, buf, size,
1023 						   dowrite, 0, &core_ops);
1024 
1025       if (cc < 0)
1026 	{
1027 	  if (dowrite == 0)
1028 	    print_sys_errmsg ("rw_common (): read", errno);
1029 	  else
1030 	    print_sys_errmsg ("rw_common (): write", errno);
1031 
1032 	  do_cleanups (old_chain);
1033 
1034 	  return PS_ERR;
1035 	}
1036       else if (cc == 0)
1037 	{
1038 	  if (dowrite == 0)
1039 	    warning (_("rw_common (): unable to read at addr 0x%lx"),
1040 		     (long) addr);
1041 	  else
1042 	    warning (_("rw_common (): unable to write at addr 0x%lx"),
1043 		     (long) addr);
1044 
1045 	  do_cleanups (old_chain);
1046 
1047 	  return PS_ERR;
1048 	}
1049 
1050       size -= cc;
1051       buf += cc;
1052     }
1053 
1054   do_cleanups (old_chain);
1055 
1056   return PS_OK;
1057 }
1058 
1059 /* Copies SIZE bytes from target process .data segment to debugger memory.  */
1060 
1061 ps_err_e
ps_pdread(gdb_ps_prochandle_t ph,gdb_ps_addr_t addr,gdb_ps_read_buf_t buf,gdb_ps_size_t size)1062 ps_pdread (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
1063 	   gdb_ps_read_buf_t buf, gdb_ps_size_t size)
1064 {
1065   return rw_common (0, ph, addr, buf, size);
1066 }
1067 
1068 /* Copies SIZE bytes from debugger memory .data segment to target process.  */
1069 
1070 ps_err_e
ps_pdwrite(gdb_ps_prochandle_t ph,gdb_ps_addr_t addr,gdb_ps_write_buf_t buf,gdb_ps_size_t size)1071 ps_pdwrite (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
1072 	    gdb_ps_write_buf_t buf, gdb_ps_size_t size)
1073 {
1074   return rw_common (1, ph, addr, (char *) buf, size);
1075 }
1076 
1077 /* Copies SIZE bytes from target process .text segment to debugger memory.  */
1078 
1079 ps_err_e
ps_ptread(gdb_ps_prochandle_t ph,gdb_ps_addr_t addr,gdb_ps_read_buf_t buf,gdb_ps_size_t size)1080 ps_ptread (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
1081 	   gdb_ps_read_buf_t buf, gdb_ps_size_t size)
1082 {
1083   return rw_common (0, ph, addr, buf, size);
1084 }
1085 
1086 /* Copies SIZE bytes from debugger memory .text segment to target process.  */
1087 
1088 ps_err_e
ps_ptwrite(gdb_ps_prochandle_t ph,gdb_ps_addr_t addr,gdb_ps_write_buf_t buf,gdb_ps_size_t size)1089 ps_ptwrite (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
1090 	    gdb_ps_write_buf_t buf, gdb_ps_size_t size)
1091 {
1092   return rw_common (1, ph, addr, (char *) buf, size);
1093 }
1094 
1095 /* Get general-purpose registers for LWP.  */
1096 
1097 ps_err_e
ps_lgetregs(gdb_ps_prochandle_t ph,lwpid_t lwpid,prgregset_t gregset)1098 ps_lgetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, prgregset_t gregset)
1099 {
1100   struct cleanup *old_chain;
1101 
1102   old_chain = save_inferior_ptid ();
1103 
1104   inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
1105 
1106   if (target_has_execution)
1107     procfs_ops.to_fetch_registers (-1);
1108   else
1109     orig_core_ops.to_fetch_registers (-1);
1110   fill_gregset ((gdb_gregset_t *) gregset, -1);
1111 
1112   do_cleanups (old_chain);
1113 
1114   return PS_OK;
1115 }
1116 
1117 /* Set general-purpose registers for LWP.  */
1118 
1119 ps_err_e
ps_lsetregs(gdb_ps_prochandle_t ph,lwpid_t lwpid,const prgregset_t gregset)1120 ps_lsetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
1121 	     const prgregset_t gregset)
1122 {
1123   struct cleanup *old_chain;
1124 
1125   old_chain = save_inferior_ptid ();
1126 
1127   inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
1128 
1129   supply_gregset ((gdb_gregset_t *) gregset);
1130   if (target_has_execution)
1131     procfs_ops.to_store_registers (-1);
1132   else
1133     orig_core_ops.to_store_registers (-1);
1134 
1135   do_cleanups (old_chain);
1136 
1137   return PS_OK;
1138 }
1139 
1140 /* Log a message (sends to gdb_stderr).  */
1141 
1142 void
ps_plog(const char * fmt,...)1143 ps_plog (const char *fmt, ...)
1144 {
1145   va_list args;
1146 
1147   va_start (args, fmt);
1148 
1149   vfprintf_filtered (gdb_stderr, fmt, args);
1150 }
1151 
1152 /* Get size of extra register set.  Currently a noop.  */
1153 
1154 ps_err_e
ps_lgetxregsize(gdb_ps_prochandle_t ph,lwpid_t lwpid,int * xregsize)1155 ps_lgetxregsize (gdb_ps_prochandle_t ph, lwpid_t lwpid, int *xregsize)
1156 {
1157 #if 0
1158   int lwp_fd;
1159   int regsize;
1160   ps_err_e val;
1161 
1162   val = get_lwp_fd (ph, lwpid, &lwp_fd);
1163   if (val != PS_OK)
1164     return val;
1165 
1166   if (ioctl (lwp_fd, PIOCGXREGSIZE, &regsize))
1167     {
1168       if (errno == EINVAL)
1169 	return PS_NOFREGS;	/* XXX Wrong code, but this is the closest
1170 				   thing in proc_service.h  */
1171 
1172       print_sys_errmsg ("ps_lgetxregsize (): PIOCGXREGSIZE", errno);
1173       return PS_ERR;
1174     }
1175 #endif
1176 
1177   return PS_OK;
1178 }
1179 
1180 /* Get extra register set.  Currently a noop.  */
1181 
1182 ps_err_e
ps_lgetxregs(gdb_ps_prochandle_t ph,lwpid_t lwpid,caddr_t xregset)1183 ps_lgetxregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, caddr_t xregset)
1184 {
1185 #if 0
1186   int lwp_fd;
1187   ps_err_e val;
1188 
1189   val = get_lwp_fd (ph, lwpid, &lwp_fd);
1190   if (val != PS_OK)
1191     return val;
1192 
1193   if (ioctl (lwp_fd, PIOCGXREG, xregset))
1194     {
1195       print_sys_errmsg ("ps_lgetxregs (): PIOCGXREG", errno);
1196       return PS_ERR;
1197     }
1198 #endif
1199 
1200   return PS_OK;
1201 }
1202 
1203 /* Set extra register set.  Currently a noop.  */
1204 
1205 ps_err_e
ps_lsetxregs(gdb_ps_prochandle_t ph,lwpid_t lwpid,caddr_t xregset)1206 ps_lsetxregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, caddr_t xregset)
1207 {
1208 #if 0
1209   int lwp_fd;
1210   ps_err_e val;
1211 
1212   val = get_lwp_fd (ph, lwpid, &lwp_fd);
1213   if (val != PS_OK)
1214     return val;
1215 
1216   if (ioctl (lwp_fd, PIOCSXREG, xregset))
1217     {
1218       print_sys_errmsg ("ps_lsetxregs (): PIOCSXREG", errno);
1219       return PS_ERR;
1220     }
1221 #endif
1222 
1223   return PS_OK;
1224 }
1225 
1226 /* Get floating-point registers for LWP.  */
1227 
1228 ps_err_e
ps_lgetfpregs(gdb_ps_prochandle_t ph,lwpid_t lwpid,prfpregset_t * fpregset)1229 ps_lgetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
1230 	       prfpregset_t *fpregset)
1231 {
1232   struct cleanup *old_chain;
1233 
1234   old_chain = save_inferior_ptid ();
1235 
1236   inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
1237 
1238   if (target_has_execution)
1239     procfs_ops.to_fetch_registers (-1);
1240   else
1241     orig_core_ops.to_fetch_registers (-1);
1242   fill_fpregset ((gdb_fpregset_t *) fpregset, -1);
1243 
1244   do_cleanups (old_chain);
1245 
1246   return PS_OK;
1247 }
1248 
1249 /* Set floating-point regs for LWP */
1250 
1251 ps_err_e
ps_lsetfpregs(gdb_ps_prochandle_t ph,lwpid_t lwpid,const prfpregset_t * fpregset)1252 ps_lsetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
1253 	       const prfpregset_t * fpregset)
1254 {
1255   struct cleanup *old_chain;
1256 
1257   old_chain = save_inferior_ptid ();
1258 
1259   inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
1260 
1261   supply_fpregset ((gdb_fpregset_t *) fpregset);
1262   if (target_has_execution)
1263     procfs_ops.to_store_registers (-1);
1264   else
1265     orig_core_ops.to_store_registers (-1);
1266 
1267   do_cleanups (old_chain);
1268 
1269   return PS_OK;
1270 }
1271 
1272 #ifdef PR_MODEL_LP64
1273 /* Identify process as 32-bit or 64-bit.  At the moment we're using
1274    BFD to do this.  There might be a more Solaris-specific
1275    (e.g. procfs) method, but this ought to work.  */
1276 
1277 ps_err_e
ps_pdmodel(gdb_ps_prochandle_t ph,int * data_model)1278 ps_pdmodel (gdb_ps_prochandle_t ph, int *data_model)
1279 {
1280   if (exec_bfd == 0)
1281     *data_model = PR_MODEL_UNKNOWN;
1282   else if (bfd_get_arch_size (exec_bfd) == 32)
1283     *data_model = PR_MODEL_ILP32;
1284   else
1285     *data_model = PR_MODEL_LP64;
1286 
1287   return PS_OK;
1288 }
1289 #endif /* PR_MODEL_LP64 */
1290 
1291 #ifdef TM_I386SOL2_H
1292 
1293 /* Reads the local descriptor table of a LWP.  */
1294 
1295 ps_err_e
ps_lgetLDT(gdb_ps_prochandle_t ph,lwpid_t lwpid,struct ssd * pldt)1296 ps_lgetLDT (gdb_ps_prochandle_t ph, lwpid_t lwpid,
1297 	    struct ssd *pldt)
1298 {
1299   /* NOTE: only used on Solaris, therefore OK to refer to procfs.c.  */
1300   extern struct ssd *procfs_find_LDT_entry (ptid_t);
1301   struct ssd *ret;
1302 
1303   /* FIXME: can't I get the process ID from the prochandle or
1304      something?  */
1305 
1306   if (PIDGET (inferior_ptid) <= 0 || lwpid <= 0)
1307     return PS_BADLID;
1308 
1309   ret = procfs_find_LDT_entry (BUILD_LWP (lwpid, PIDGET (inferior_ptid)));
1310   if (ret)
1311     {
1312       memcpy (pldt, ret, sizeof (struct ssd));
1313       return PS_OK;
1314     }
1315   else
1316     /* LDT not found.  */
1317     return PS_ERR;
1318 }
1319 #endif /* TM_I386SOL2_H */
1320 
1321 
1322 /* Convert PTID to printable form.  */
1323 
1324 char *
solaris_pid_to_str(ptid_t ptid)1325 solaris_pid_to_str (ptid_t ptid)
1326 {
1327   static char buf[100];
1328 
1329   /* In case init failed to resolve the libthread_db library.  */
1330   if (!procfs_suppress_run)
1331     return procfs_pid_to_str (ptid);
1332 
1333   if (is_thread (ptid))
1334     {
1335       ptid_t lwp;
1336 
1337       lwp = thread_to_lwp (ptid, -2);
1338 
1339       if (PIDGET (lwp) == -1)
1340 	sprintf (buf, "Thread %ld (defunct)", GET_THREAD (ptid));
1341       else if (PIDGET (lwp) != -2)
1342 	sprintf (buf, "Thread %ld (LWP %ld)",
1343 		 GET_THREAD (ptid), GET_LWP (lwp));
1344       else
1345 	sprintf (buf, "Thread %ld        ", GET_THREAD (ptid));
1346     }
1347   else if (GET_LWP (ptid) != 0)
1348     sprintf (buf, "LWP    %ld        ", GET_LWP (ptid));
1349   else
1350     sprintf (buf, "process %d    ", PIDGET (ptid));
1351 
1352   return buf;
1353 }
1354 
1355 
1356 /* Worker bee for find_new_threads.  Callback function that gets
1357    called once per user-level thread (i.e. not for LWP's).  */
1358 
1359 static int
sol_find_new_threads_callback(const td_thrhandle_t * th,void * ignored)1360 sol_find_new_threads_callback (const td_thrhandle_t *th, void *ignored)
1361 {
1362   td_err_e retval;
1363   td_thrinfo_t ti;
1364   ptid_t ptid;
1365 
1366   retval = p_td_thr_get_info (th, &ti);
1367   if (retval != TD_OK)
1368     return -1;
1369 
1370   ptid = BUILD_THREAD (ti.ti_tid, PIDGET (inferior_ptid));
1371   if (!in_thread_list (ptid))
1372     add_thread (ptid);
1373 
1374   return 0;
1375 }
1376 
1377 static void
sol_find_new_threads(void)1378 sol_find_new_threads (void)
1379 {
1380   /* Don't do anything if init failed to resolve the libthread_db
1381      library.  */
1382   if (!procfs_suppress_run)
1383     return;
1384 
1385   if (PIDGET (inferior_ptid) == -1)
1386     {
1387       printf_filtered ("No process.\n");
1388       return;
1389     }
1390 
1391   /* First Find any new LWP's.  */
1392   procfs_ops.to_find_new_threads ();
1393 
1394   /* Then find any new user-level threads.  */
1395   p_td_ta_thr_iter (main_ta, sol_find_new_threads_callback, (void *) 0,
1396 		    TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
1397 		    TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
1398 }
1399 
1400 static void
sol_core_open(char * filename,int from_tty)1401 sol_core_open (char *filename, int from_tty)
1402 {
1403   orig_core_ops.to_open (filename, from_tty);
1404 }
1405 
1406 static void
sol_core_close(int quitting)1407 sol_core_close (int quitting)
1408 {
1409   orig_core_ops.to_close (quitting);
1410 }
1411 
1412 static void
sol_core_detach(char * args,int from_tty)1413 sol_core_detach (char *args, int from_tty)
1414 {
1415   unpush_target (&core_ops);
1416   orig_core_ops.to_detach (args, from_tty);
1417 }
1418 
1419 static void
sol_core_files_info(struct target_ops * t)1420 sol_core_files_info (struct target_ops *t)
1421 {
1422   orig_core_ops.to_files_info (t);
1423 }
1424 
1425 /* Worker bee for the "info sol-thread" command.  This is a callback
1426    function that gets called once for each Solaris user-level thread
1427    (i.e. not for LWPs) in the inferior.  Print anything interesting
1428    that we can think of.  */
1429 
1430 static int
info_cb(const td_thrhandle_t * th,void * s)1431 info_cb (const td_thrhandle_t *th, void *s)
1432 {
1433   td_err_e ret;
1434   td_thrinfo_t ti;
1435 
1436   ret = p_td_thr_get_info (th, &ti);
1437   if (ret == TD_OK)
1438     {
1439       printf_filtered ("%s thread #%d, lwp %d, ",
1440 		       ti.ti_type == TD_THR_SYSTEM ? "system" : "user  ",
1441 		       ti.ti_tid, ti.ti_lid);
1442       switch (ti.ti_state)
1443 	{
1444 	default:
1445 	case TD_THR_UNKNOWN:
1446 	  printf_filtered ("<unknown state>");
1447 	  break;
1448 	case TD_THR_STOPPED:
1449 	  printf_filtered ("(stopped)");
1450 	  break;
1451 	case TD_THR_RUN:
1452 	  printf_filtered ("(run)    ");
1453 	  break;
1454 	case TD_THR_ACTIVE:
1455 	  printf_filtered ("(active) ");
1456 	  break;
1457 	case TD_THR_ZOMBIE:
1458 	  printf_filtered ("(zombie) ");
1459 	  break;
1460 	case TD_THR_SLEEP:
1461 	  printf_filtered ("(asleep) ");
1462 	  break;
1463 	case TD_THR_STOPPED_ASLEEP:
1464 	  printf_filtered ("(stopped asleep)");
1465 	  break;
1466 	}
1467       /* Print thr_create start function.  */
1468       if (ti.ti_startfunc != 0)
1469 	{
1470 	  struct minimal_symbol *msym;
1471 	  msym = lookup_minimal_symbol_by_pc (ti.ti_startfunc);
1472 	  if (msym)
1473 	    printf_filtered ("   startfunc: %s\n",
1474 			     DEPRECATED_SYMBOL_NAME (msym));
1475 	  else
1476 	    printf_filtered ("   startfunc: 0x%s\n", paddr (ti.ti_startfunc));
1477 	}
1478 
1479       /* If thread is asleep, print function that went to sleep.  */
1480       if (ti.ti_state == TD_THR_SLEEP)
1481 	{
1482 	  struct minimal_symbol *msym;
1483 	  msym = lookup_minimal_symbol_by_pc (ti.ti_pc);
1484 	  if (msym)
1485 	    printf_filtered (" - Sleep func: %s\n",
1486 			     DEPRECATED_SYMBOL_NAME (msym));
1487 	  else
1488 	    printf_filtered (" - Sleep func: 0x%s\n", paddr (ti.ti_startfunc));
1489 	}
1490 
1491       /* Wrap up line, if necessary.  */
1492       if (ti.ti_state != TD_THR_SLEEP && ti.ti_startfunc == 0)
1493 	printf_filtered ("\n");	/* don't you hate counting newlines? */
1494     }
1495   else
1496     warning (_("info sol-thread: failed to get info for thread."));
1497 
1498   return 0;
1499 }
1500 
1501 /* List some state about each Solaris user-level thread in the
1502    inferior.  */
1503 
1504 static void
info_solthreads(char * args,int from_tty)1505 info_solthreads (char *args, int from_tty)
1506 {
1507   p_td_ta_thr_iter (main_ta, info_cb, args,
1508 		    TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
1509 		    TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
1510 }
1511 
1512 static int
sol_find_memory_regions(int (* func)(CORE_ADDR,unsigned long,int,int,int,void *),void * data)1513 sol_find_memory_regions (int (*func) (CORE_ADDR, unsigned long,
1514 				      int, int, int, void *),
1515 			 void *data)
1516 {
1517   return procfs_ops.to_find_memory_regions (func, data);
1518 }
1519 
1520 static char *
sol_make_note_section(bfd * obfd,int * note_size)1521 sol_make_note_section (bfd *obfd, int *note_size)
1522 {
1523   return procfs_ops.to_make_corefile_notes (obfd, note_size);
1524 }
1525 
1526 static int
ignore(CORE_ADDR addr,gdb_byte * contents)1527 ignore (CORE_ADDR addr, gdb_byte *contents)
1528 {
1529   return 0;
1530 }
1531 
1532 static void
init_sol_thread_ops(void)1533 init_sol_thread_ops (void)
1534 {
1535   sol_thread_ops.to_shortname = "solaris-threads";
1536   sol_thread_ops.to_longname = "Solaris threads and pthread.";
1537   sol_thread_ops.to_doc = "Solaris threads and pthread support.";
1538   sol_thread_ops.to_open = sol_thread_open;
1539   sol_thread_ops.to_attach = sol_thread_attach;
1540   sol_thread_ops.to_detach = sol_thread_detach;
1541   sol_thread_ops.to_resume = sol_thread_resume;
1542   sol_thread_ops.to_wait = sol_thread_wait;
1543   sol_thread_ops.to_fetch_registers = sol_thread_fetch_registers;
1544   sol_thread_ops.to_store_registers = sol_thread_store_registers;
1545   sol_thread_ops.to_prepare_to_store = sol_thread_prepare_to_store;
1546   sol_thread_ops.deprecated_xfer_memory = sol_thread_xfer_memory;
1547   sol_thread_ops.to_xfer_partial = sol_thread_xfer_partial;
1548   sol_thread_ops.to_files_info = sol_thread_files_info;
1549   sol_thread_ops.to_insert_breakpoint = memory_insert_breakpoint;
1550   sol_thread_ops.to_remove_breakpoint = memory_remove_breakpoint;
1551   sol_thread_ops.to_terminal_init = terminal_init_inferior;
1552   sol_thread_ops.to_terminal_inferior = terminal_inferior;
1553   sol_thread_ops.to_terminal_ours_for_output = terminal_ours_for_output;
1554   sol_thread_ops.to_terminal_ours = terminal_ours;
1555   sol_thread_ops.to_terminal_save_ours = terminal_save_ours;
1556   sol_thread_ops.to_terminal_info = child_terminal_info;
1557   sol_thread_ops.to_kill = sol_thread_kill_inferior;
1558   sol_thread_ops.to_create_inferior = sol_thread_create_inferior;
1559   sol_thread_ops.to_mourn_inferior = sol_thread_mourn_inferior;
1560   sol_thread_ops.to_can_run = sol_thread_can_run;
1561   sol_thread_ops.to_notice_signals = sol_thread_notice_signals;
1562   sol_thread_ops.to_thread_alive = sol_thread_alive;
1563   sol_thread_ops.to_pid_to_str = solaris_pid_to_str;
1564   sol_thread_ops.to_find_new_threads = sol_find_new_threads;
1565   sol_thread_ops.to_stop = sol_thread_stop;
1566   sol_thread_ops.to_stratum = process_stratum;
1567   sol_thread_ops.to_has_all_memory = 1;
1568   sol_thread_ops.to_has_memory = 1;
1569   sol_thread_ops.to_has_stack = 1;
1570   sol_thread_ops.to_has_registers = 1;
1571   sol_thread_ops.to_has_execution = 1;
1572   sol_thread_ops.to_has_thread_control = tc_none;
1573   sol_thread_ops.to_find_memory_regions = sol_find_memory_regions;
1574   sol_thread_ops.to_make_corefile_notes = sol_make_note_section;
1575   sol_thread_ops.to_magic = OPS_MAGIC;
1576 }
1577 
1578 static void
init_sol_core_ops(void)1579 init_sol_core_ops (void)
1580 {
1581   sol_core_ops.to_shortname = "solaris-core";
1582   sol_core_ops.to_longname = "Solaris core threads and pthread.";
1583   sol_core_ops.to_doc = "Solaris threads and pthread support for core files.";
1584   sol_core_ops.to_open = sol_core_open;
1585   sol_core_ops.to_close = sol_core_close;
1586   sol_core_ops.to_attach = sol_thread_attach;
1587   sol_core_ops.to_detach = sol_core_detach;
1588   sol_core_ops.to_fetch_registers = sol_thread_fetch_registers;
1589   sol_core_ops.deprecated_xfer_memory = sol_thread_xfer_memory;
1590   sol_core_ops.to_xfer_partial = sol_thread_xfer_partial;
1591   sol_core_ops.to_files_info = sol_core_files_info;
1592   sol_core_ops.to_insert_breakpoint = ignore;
1593   sol_core_ops.to_remove_breakpoint = ignore;
1594   sol_core_ops.to_create_inferior = sol_thread_create_inferior;
1595   sol_core_ops.to_stratum = core_stratum;
1596   sol_core_ops.to_has_memory = 1;
1597   sol_core_ops.to_has_stack = 1;
1598   sol_core_ops.to_has_registers = 1;
1599   sol_core_ops.to_has_thread_control = tc_none;
1600   sol_core_ops.to_thread_alive = sol_thread_alive;
1601   sol_core_ops.to_pid_to_str = solaris_pid_to_str;
1602   /* On Solaris/x86, when debugging a threaded core file from process
1603      <n>, the following causes "info threads" to produce "procfs:
1604      couldn't find pid <n> in procinfo list" where <n> is the pid of
1605      the process that produced the core file.  Disable it for now. */
1606 #if 0
1607   sol_core_ops.to_find_new_threads = sol_find_new_threads;
1608 #endif
1609   sol_core_ops.to_magic = OPS_MAGIC;
1610 }
1611 
1612 /* We suppress the call to add_target of core_ops in corelow because
1613    if there are two targets in the stratum core_stratum,
1614    find_core_target won't know which one to return.  See corelow.c for
1615    an additonal comment on coreops_suppress_target.  */
1616 int coreops_suppress_target = 1;
1617 
1618 void
_initialize_sol_thread(void)1619 _initialize_sol_thread (void)
1620 {
1621   void *dlhandle;
1622 
1623   init_sol_thread_ops ();
1624   init_sol_core_ops ();
1625 
1626   dlhandle = dlopen ("libthread_db.so.1", RTLD_NOW);
1627   if (!dlhandle)
1628     goto die;
1629 
1630 #define resolve(X) \
1631   if (!(p_##X = dlsym (dlhandle, #X))) \
1632     goto die;
1633 
1634   resolve (td_log);
1635   resolve (td_ta_new);
1636   resolve (td_ta_delete);
1637   resolve (td_init);
1638   resolve (td_ta_get_ph);
1639   resolve (td_ta_get_nthreads);
1640   resolve (td_ta_tsd_iter);
1641   resolve (td_ta_thr_iter);
1642   resolve (td_thr_validate);
1643   resolve (td_thr_tsd);
1644   resolve (td_thr_get_info);
1645   resolve (td_thr_getfpregs);
1646   resolve (td_thr_getxregsize);
1647   resolve (td_thr_getxregs);
1648   resolve (td_thr_sigsetmask);
1649   resolve (td_thr_setprio);
1650   resolve (td_thr_setsigpending);
1651   resolve (td_thr_setfpregs);
1652   resolve (td_thr_setxregs);
1653   resolve (td_ta_map_id2thr);
1654   resolve (td_ta_map_lwp2thr);
1655   resolve (td_thr_getgregs);
1656   resolve (td_thr_setgregs);
1657 
1658   add_target (&sol_thread_ops);
1659 
1660   procfs_suppress_run = 1;
1661 
1662   add_cmd ("sol-threads", class_maintenance, info_solthreads,
1663 	   _("Show info on Solaris user threads."), &maintenanceinfolist);
1664 
1665   memcpy (&orig_core_ops, &core_ops, sizeof (struct target_ops));
1666   memcpy (&core_ops, &sol_core_ops, sizeof (struct target_ops));
1667   add_target (&core_ops);
1668 
1669   /* Hook into new_objfile notification.  */
1670   target_new_objfile_chain = deprecated_target_new_objfile_hook;
1671   deprecated_target_new_objfile_hook  = sol_thread_new_objfile;
1672   return;
1673 
1674  die:
1675   fprintf_unfiltered (gdb_stderr, "\
1676 [GDB will not be able to debug user-mode threads: %s]\n", dlerror ());
1677 
1678   if (dlhandle)
1679     dlclose (dlhandle);
1680 
1681   /* Allow the user to debug non-threaded core files.  */
1682   add_target (&core_ops);
1683 
1684   return;
1685 }
1686