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