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