1 /* Solaris threads debugging interface.
3 Copyright (C) 1996-2015 Free Software Foundation, Inc.
5 This file is part of GDB.
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 3 of the License, or
10 (at your option) any later version.
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.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
20 /* This module implements a sort of half target that sits between the
21 machine-independent parts of GDB and the /proc interface (procfs.c)
22 to provide access to the Solaris user-mode thread implementation.
24 Solaris threads are true user-mode threads, which are invoked via
25 the thr_* and pthread_* (native and POSIX respectivly) interfaces.
26 These are mostly implemented in user-space, with all thread context
27 kept in various structures that live in the user's heap. These
28 should not be confused with lightweight processes (LWPs), which are
29 implemented by the kernel, and scheduled without explicit
30 intervention by the process.
32 Just to confuse things a little, Solaris threads (both native and
33 POSIX) are actually implemented using LWPs. In general, there are
34 going to be more threads than LWPs. There is no fixed
35 correspondence between a thread and an LWP. When a thread wants to
36 run, it gets scheduled onto the first available LWP and can
37 therefore migrate from one LWP to another as time goes on. A
38 sleeping thread may not be associated with an LWP at all!
40 To make it possible to mess with threads, Sun provides a library
41 called libthread_db.so.1 (not to be confused with
42 libthread_db.so.0, which doesn't have a published interface). This
43 interface has an upper part, which it provides, and a lower part
44 which we provide. The upper part consists of the td_* routines,
45 which allow us to find all the threads, query their state, etc...
46 The lower part consists of all of the ps_*, which are used by the
47 td_* routines to read/write memory, manipulate LWPs, lookup
48 symbols, etc... The ps_* routines actually do most of their work
49 by calling functions in procfs.c. */
53 #include <proc_service.h>
54 #include <thread_db.h>
55 #include "gdbthread.h"
72 struct target_ops sol_thread_ops;
74 /* Prototypes for supply_gregset etc. */
77 /* This struct is defined by us, but mainly used for the proc_service
78 interface. We don't have much use for it, except as a handy place
79 to get a real PID for memory accesses. */
92 static struct ps_prochandle main_ph;
93 static td_thragent_t *main_ta;
94 static int sol_thread_active = 0;
96 static void init_sol_thread_ops (void);
98 /* Default definitions: These must be defined in tm.h if they are to
99 be shared with a process module such as procfs. */
101 /* Pointers to routines from libthread_db resolved by dlopen(). */
103 static void (*p_td_log)(const int on_off);
104 static td_err_e (*p_td_ta_new)(const struct ps_prochandle *ph_p,
105 td_thragent_t **ta_pp);
106 static td_err_e (*p_td_ta_delete)(td_thragent_t *ta_p);
107 static td_err_e (*p_td_init)(void);
108 static td_err_e (*p_td_ta_get_ph)(const td_thragent_t *ta_p,
109 struct ps_prochandle **ph_pp);
110 static td_err_e (*p_td_ta_get_nthreads)(const td_thragent_t *ta_p,
112 static td_err_e (*p_td_ta_tsd_iter)(const td_thragent_t *ta_p,
113 td_key_iter_f *cb, void *cbdata_p);
114 static td_err_e (*p_td_ta_thr_iter)(const td_thragent_t *ta_p,
115 td_thr_iter_f *cb, void *cbdata_p,
116 td_thr_state_e state, int ti_pri,
117 sigset_t *ti_sigmask_p,
118 unsigned ti_user_flags);
119 static td_err_e (*p_td_thr_validate)(const td_thrhandle_t *th_p);
120 static td_err_e (*p_td_thr_tsd)(const td_thrhandle_t * th_p,
121 const thread_key_t key, void **data_pp);
122 static td_err_e (*p_td_thr_get_info)(const td_thrhandle_t *th_p,
124 static td_err_e (*p_td_thr_getfpregs)(const td_thrhandle_t *th_p,
125 prfpregset_t *fpregset);
126 static td_err_e (*p_td_thr_getxregsize)(const td_thrhandle_t *th_p,
128 static td_err_e (*p_td_thr_getxregs)(const td_thrhandle_t *th_p,
129 const caddr_t xregset);
130 static td_err_e (*p_td_thr_sigsetmask)(const td_thrhandle_t *th_p,
131 const sigset_t ti_sigmask);
132 static td_err_e (*p_td_thr_setprio)(const td_thrhandle_t *th_p,
134 static td_err_e (*p_td_thr_setsigpending)(const td_thrhandle_t *th_p,
135 const uchar_t ti_pending_flag,
136 const sigset_t ti_pending);
137 static td_err_e (*p_td_thr_setfpregs)(const td_thrhandle_t *th_p,
138 const prfpregset_t *fpregset);
139 static td_err_e (*p_td_thr_setxregs)(const td_thrhandle_t *th_p,
140 const caddr_t xregset);
141 static td_err_e (*p_td_ta_map_id2thr)(const td_thragent_t *ta_p,
143 td_thrhandle_t *th_p);
144 static td_err_e (*p_td_ta_map_lwp2thr)(const td_thragent_t *ta_p,
146 td_thrhandle_t *th_p);
147 static td_err_e (*p_td_thr_getgregs)(const td_thrhandle_t *th_p,
149 static td_err_e (*p_td_thr_setgregs)(const td_thrhandle_t *th_p,
150 const prgregset_t regset);
153 /* Return the libthread_db error string associated with ERRCODE. If
154 ERRCODE is unknown, return an appropriate message. */
157 td_err_string (td_err_e errcode)
159 static struct string_map td_err_table[] =
161 { TD_OK, "generic \"call succeeded\"" },
162 { TD_ERR, "generic error." },
163 { TD_NOTHR, "no thread can be found to satisfy query" },
164 { TD_NOSV, "no synch. variable can be found to satisfy query" },
165 { TD_NOLWP, "no lwp can be found to satisfy query" },
166 { TD_BADPH, "invalid process handle" },
167 { TD_BADTH, "invalid thread handle" },
168 { TD_BADSH, "invalid synchronization handle" },
169 { TD_BADTA, "invalid thread agent" },
170 { TD_BADKEY, "invalid key" },
171 { TD_NOMSG, "td_thr_event_getmsg() called when there was no message" },
172 { TD_NOFPREGS, "FPU register set not available for given thread" },
173 { TD_NOLIBTHREAD, "application not linked with libthread" },
174 { TD_NOEVENT, "requested event is not supported" },
175 { TD_NOCAPAB, "capability not available" },
176 { TD_DBERR, "Debugger service failed" },
177 { TD_NOAPLIC, "Operation not applicable to" },
178 { TD_NOTSD, "No thread specific data for this thread" },
179 { TD_MALLOC, "Malloc failed" },
180 { TD_PARTIALREG, "Only part of register set was written/read" },
181 { TD_NOXREGS, "X register set not available for given thread" }
183 const int td_err_size = sizeof td_err_table / sizeof (struct string_map);
187 for (i = 0; i < td_err_size; i++)
188 if (td_err_table[i].num == errcode)
189 return td_err_table[i].str;
191 xsnprintf (buf, sizeof (buf), "Unknown libthread_db error code: %d",
197 /* Return the libthread_db state string assicoated with STATECODE.
198 If STATECODE is unknown, return an appropriate message. */
201 td_state_string (td_thr_state_e statecode)
203 static struct string_map td_thr_state_table[] =
205 { TD_THR_ANY_STATE, "any state" },
206 { TD_THR_UNKNOWN, "unknown" },
207 { TD_THR_STOPPED, "stopped" },
208 { TD_THR_RUN, "run" },
209 { TD_THR_ACTIVE, "active" },
210 { TD_THR_ZOMBIE, "zombie" },
211 { TD_THR_SLEEP, "sleep" },
212 { TD_THR_STOPPED_ASLEEP, "stopped asleep" }
214 const int td_thr_state_table_size =
215 sizeof td_thr_state_table / sizeof (struct string_map);
219 for (i = 0; i < td_thr_state_table_size; i++)
220 if (td_thr_state_table[i].num == statecode)
221 return td_thr_state_table[i].str;
223 xsnprintf (buf, sizeof (buf), "Unknown libthread_db state code: %d",
230 /* Convert a POSIX or Solaris thread ID into a LWP ID. If THREAD_ID
231 doesn't exist, that's an error. If it's an inactive thread, return
234 NOTE: This function probably shouldn't call error(). */
237 thread_to_lwp (ptid_t thread_id, int default_lwp)
243 if (ptid_lwp_p (thread_id))
244 return thread_id; /* It's already an LWP ID. */
246 /* It's a thread. Convert to LWP. */
248 val = p_td_ta_map_id2thr (main_ta, ptid_get_tid (thread_id), &th);
250 return pid_to_ptid (-1); /* Thread must have terminated. */
251 else if (val != TD_OK)
252 error (_("thread_to_lwp: td_ta_map_id2thr %s"), td_err_string (val));
254 val = p_td_thr_get_info (&th, &ti);
256 return pid_to_ptid (-1); /* Thread must have terminated. */
257 else if (val != TD_OK)
258 error (_("thread_to_lwp: td_thr_get_info: %s"), td_err_string (val));
260 if (ti.ti_state != TD_THR_ACTIVE)
262 if (default_lwp != -1)
263 return pid_to_ptid (default_lwp);
264 error (_("thread_to_lwp: thread state not active: %s"),
265 td_state_string (ti.ti_state));
268 return ptid_build (ptid_get_pid (thread_id), ti.ti_lid, 0);
271 /* Convert an LWP ID into a POSIX or Solaris thread ID. If LWP_ID
272 doesn't exists, that's an error.
274 NOTE: This function probably shouldn't call error(). */
277 lwp_to_thread (ptid_t lwp)
283 if (ptid_tid_p (lwp))
284 return lwp; /* It's already a thread ID. */
286 /* It's an LWP. Convert it to a thread ID. */
288 if (!target_thread_alive (lwp))
289 return pid_to_ptid (-1); /* Must be a defunct LPW. */
291 val = p_td_ta_map_lwp2thr (main_ta, ptid_get_lwp (lwp), &th);
293 return pid_to_ptid (-1); /* Thread must have terminated. */
294 else if (val != TD_OK)
295 error (_("lwp_to_thread: td_ta_map_lwp2thr: %s."), td_err_string (val));
297 val = p_td_thr_validate (&th);
299 return lwp; /* Unknown to libthread; just return LPW, */
300 else if (val != TD_OK)
301 error (_("lwp_to_thread: td_thr_validate: %s."), td_err_string (val));
303 val = p_td_thr_get_info (&th, &ti);
305 return pid_to_ptid (-1); /* Thread must have terminated. */
306 else if (val != TD_OK)
307 error (_("lwp_to_thread: td_thr_get_info: %s."), td_err_string (val));
309 return ptid_build (ptid_get_pid (lwp), 0 , ti.ti_tid);
313 /* Most target vector functions from here on actually just pass
314 through to the layer beneath, as they don't need to do anything
315 specific for threads. */
317 /* Take a program previously attached to and detaches it. The program
318 resumes execution and will no longer stop on signals, etc. We'd
319 better not have left any breakpoints in the program or it'll die
320 when it hits one. For this to work, it may be necessary for the
321 process to have been previously attached. It *might* work if the
322 program was started via the normal ptrace (PTRACE_TRACEME). */
325 sol_thread_detach (struct target_ops *ops, const char *args, int from_tty)
327 struct target_ops *beneath = find_target_beneath (ops);
329 sol_thread_active = 0;
330 inferior_ptid = pid_to_ptid (ptid_get_pid (main_ph.ptid));
332 beneath->to_detach (beneath, args, from_tty);
335 /* Resume execution of process PTID. If STEP is nozero, then just
336 single step it. If SIGNAL is nonzero, restart it with that signal
337 activated. We may have to convert PTID from a thread ID to an LWP
341 sol_thread_resume (struct target_ops *ops,
342 ptid_t ptid, int step, enum gdb_signal signo)
344 struct cleanup *old_chain;
345 struct target_ops *beneath = find_target_beneath (ops);
347 old_chain = save_inferior_ptid ();
349 inferior_ptid = thread_to_lwp (inferior_ptid, ptid_get_pid (main_ph.ptid));
350 if (ptid_get_pid (inferior_ptid) == -1)
351 inferior_ptid = procfs_first_available ();
353 if (ptid_get_pid (ptid) != -1)
355 ptid_t save_ptid = ptid;
357 ptid = thread_to_lwp (ptid, -2);
358 if (ptid_get_pid (ptid) == -2) /* Inactive thread. */
359 error (_("This version of Solaris can't start inactive threads."));
360 if (info_verbose && ptid_get_pid (ptid) == -1)
361 warning (_("Specified thread %ld seems to have terminated"),
362 ptid_get_tid (save_ptid));
365 beneath->to_resume (beneath, ptid, step, signo);
367 do_cleanups (old_chain);
370 /* Wait for any threads to stop. We may have to convert PTID from a
371 thread ID to an LWP ID, and vice versa on the way out. */
374 sol_thread_wait (struct target_ops *ops,
375 ptid_t ptid, struct target_waitstatus *ourstatus, int options)
379 struct target_ops *beneath = find_target_beneath (ops);
380 struct cleanup *old_chain;
382 save_ptid = inferior_ptid;
383 old_chain = save_inferior_ptid ();
385 inferior_ptid = thread_to_lwp (inferior_ptid, ptid_get_pid (main_ph.ptid));
386 if (ptid_get_pid (inferior_ptid) == -1)
387 inferior_ptid = procfs_first_available ();
389 if (ptid_get_pid (ptid) != -1)
391 ptid_t save_ptid = ptid;
393 ptid = thread_to_lwp (ptid, -2);
394 if (ptid_get_pid (ptid) == -2) /* Inactive thread. */
395 error (_("This version of Solaris can't start inactive threads."));
396 if (info_verbose && ptid_get_pid (ptid) == -1)
397 warning (_("Specified thread %ld seems to have terminated"),
398 ptid_get_tid (save_ptid));
401 rtnval = beneath->to_wait (beneath, ptid, ourstatus, options);
403 if (ourstatus->kind != TARGET_WAITKIND_EXITED)
405 /* Map the LWP of interest back to the appropriate thread ID. */
406 rtnval = lwp_to_thread (rtnval);
407 if (ptid_get_pid (rtnval) == -1)
410 /* See if we have a new thread. */
411 if (ptid_tid_p (rtnval)
412 && !ptid_equal (rtnval, save_ptid)
413 && (!in_thread_list (rtnval)
414 || is_exited (rtnval)))
418 /* During process initialization, we may get here without the thread
419 package being initialized, since that can only happen after we've
420 found the shared libs. */
422 do_cleanups (old_chain);
428 sol_thread_fetch_registers (struct target_ops *ops,
429 struct regcache *regcache, int regnum)
432 td_thrhandle_t thandle;
435 prfpregset_t fpregset;
436 gdb_gregset_t *gregset_p = &gregset;
437 gdb_fpregset_t *fpregset_p = &fpregset;
438 struct target_ops *beneath = find_target_beneath (ops);
440 if (!ptid_tid_p (inferior_ptid))
442 /* It's an LWP; pass the request on to the layer beneath. */
443 beneath->to_fetch_registers (beneath, regcache, regnum);
447 /* Solaris thread: convert INFERIOR_PTID into a td_thrhandle_t. */
448 thread = ptid_get_tid (inferior_ptid);
450 error (_("sol_thread_fetch_registers: thread == 0"));
452 val = p_td_ta_map_id2thr (main_ta, thread, &thandle);
454 error (_("sol_thread_fetch_registers: td_ta_map_id2thr: %s"),
455 td_err_string (val));
457 /* Get the general-purpose registers. */
459 val = p_td_thr_getgregs (&thandle, gregset);
460 if (val != TD_OK && val != TD_PARTIALREG)
461 error (_("sol_thread_fetch_registers: td_thr_getgregs %s"),
462 td_err_string (val));
464 /* For SPARC, TD_PARTIALREG means that only %i0...%i7, %l0..%l7, %pc
465 and %sp are saved (by a thread context switch). */
467 /* And, now the floating-point registers. */
469 val = p_td_thr_getfpregs (&thandle, &fpregset);
470 if (val != TD_OK && val != TD_NOFPREGS)
471 error (_("sol_thread_fetch_registers: td_thr_getfpregs %s"),
472 td_err_string (val));
474 /* Note that we must call supply_gregset and supply_fpregset *after*
475 calling the td routines because the td routines call ps_lget*
476 which affect the values stored in the registers array. */
478 supply_gregset (regcache, (const gdb_gregset_t *) gregset_p);
479 supply_fpregset (regcache, (const gdb_fpregset_t *) fpregset_p);
483 sol_thread_store_registers (struct target_ops *ops,
484 struct regcache *regcache, int regnum)
487 td_thrhandle_t thandle;
490 prfpregset_t fpregset;
492 if (!ptid_tid_p (inferior_ptid))
494 struct target_ops *beneath = find_target_beneath (ops);
496 /* It's an LWP; pass the request on to the layer beneath. */
497 beneath->to_store_registers (beneath, regcache, regnum);
501 /* Solaris thread: convert INFERIOR_PTID into a td_thrhandle_t. */
502 thread = ptid_get_tid (inferior_ptid);
504 val = p_td_ta_map_id2thr (main_ta, thread, &thandle);
506 error (_("sol_thread_store_registers: td_ta_map_id2thr %s"),
507 td_err_string (val));
511 /* Not writing all the registers. */
512 char old_value[MAX_REGISTER_SIZE];
514 /* Save new register value. */
515 regcache_raw_collect (regcache, regnum, old_value);
517 val = p_td_thr_getgregs (&thandle, gregset);
519 error (_("sol_thread_store_registers: td_thr_getgregs %s"),
520 td_err_string (val));
521 val = p_td_thr_getfpregs (&thandle, &fpregset);
523 error (_("sol_thread_store_registers: td_thr_getfpregs %s"),
524 td_err_string (val));
526 /* Restore new register value. */
527 regcache_raw_supply (regcache, regnum, old_value);
530 fill_gregset (regcache, (gdb_gregset_t *) &gregset, regnum);
531 fill_fpregset (regcache, (gdb_fpregset_t *) &fpregset, regnum);
533 val = p_td_thr_setgregs (&thandle, gregset);
535 error (_("sol_thread_store_registers: td_thr_setgregs %s"),
536 td_err_string (val));
537 val = p_td_thr_setfpregs (&thandle, &fpregset);
539 error (_("sol_thread_store_registers: td_thr_setfpregs %s"),
540 td_err_string (val));
543 /* Perform partial transfers on OBJECT. See target_read_partial and
544 target_write_partial for details of each variant. One, and only
545 one, of readbuf or writebuf must be non-NULL. */
547 static enum target_xfer_status
548 sol_thread_xfer_partial (struct target_ops *ops, enum target_object object,
549 const char *annex, gdb_byte *readbuf,
550 const gdb_byte *writebuf,
551 ULONGEST offset, ULONGEST len, ULONGEST *xfered_len)
553 enum target_xfer_status retval;
554 struct cleanup *old_chain;
555 struct target_ops *beneath = find_target_beneath (ops);
557 old_chain = save_inferior_ptid ();
559 if (ptid_tid_p (inferior_ptid) || !target_thread_alive (inferior_ptid))
561 /* It's either a thread or an LWP that isn't alive. Any live
562 LWP will do so use the first available.
564 NOTE: We don't need to call switch_to_thread; we're just
566 inferior_ptid = procfs_first_available ();
569 retval = beneath->to_xfer_partial (beneath, object, annex, readbuf,
570 writebuf, offset, len, xfered_len);
572 do_cleanups (old_chain);
578 check_for_thread_db (void)
583 /* Don't attempt to use thread_db for remote targets. */
584 if (!(target_can_run (¤t_target) || core_bfd))
587 /* Do nothing if we couldn't load libthread_db.so.1. */
588 if (p_td_ta_new == NULL)
591 if (sol_thread_active)
592 /* Nothing to do. The thread library was already detected and the
593 target vector was already activated. */
596 /* Now, initialize libthread_db. This needs to be done after the
597 shared libraries are located because it needs information from
598 the user's thread library. */
603 warning (_("sol_thread_new_objfile: td_init: %s"), td_err_string (err));
607 /* Now attempt to open a connection to the thread library. */
608 err = p_td_ta_new (&main_ph, &main_ta);
612 /* No thread library was detected. */
616 printf_unfiltered (_("[Thread debugging using libthread_db enabled]\n"));
618 /* The thread library was detected. Activate the sol_thread target. */
619 push_target (&sol_thread_ops);
620 sol_thread_active = 1;
622 main_ph.ptid = inferior_ptid; /* Save for xfer_memory. */
623 ptid = lwp_to_thread (inferior_ptid);
624 if (ptid_get_pid (ptid) != -1)
625 inferior_ptid = ptid;
627 target_update_thread_list ();
631 warning (_("Cannot initialize thread debugging library: %s"),
632 td_err_string (err));
637 /* This routine is called whenever a new symbol table is read in, or
638 when all symbol tables are removed. libthread_db can only be
639 initialized when it finds the right variables in libthread.so.
640 Since it's a shared library, those variables don't show up until
641 the library gets mapped and the symbol table is read in. */
644 sol_thread_new_objfile (struct objfile *objfile)
647 check_for_thread_db ();
650 /* Clean up after the inferior dies. */
653 sol_thread_mourn_inferior (struct target_ops *ops)
655 struct target_ops *beneath = find_target_beneath (ops);
657 sol_thread_active = 0;
661 beneath->to_mourn_inferior (beneath);
664 /* Return true if PTID is still active in the inferior. */
667 sol_thread_alive (struct target_ops *ops, ptid_t ptid)
669 if (ptid_tid_p (ptid))
671 /* It's a (user-level) thread. */
676 pid = ptid_get_tid (ptid);
677 if ((val = p_td_ta_map_id2thr (main_ta, pid, &th)) != TD_OK)
678 return 0; /* Thread not found. */
679 if ((val = p_td_thr_validate (&th)) != TD_OK)
680 return 0; /* Thread not valid. */
681 return 1; /* Known thread. */
685 struct target_ops *beneath = find_target_beneath (ops);
687 /* It's an LPW; pass the request on to the layer below. */
688 return beneath->to_thread_alive (beneath, ptid);
693 /* These routines implement the lower half of the thread_db interface,
694 i.e. the ps_* routines. */
696 /* Various versions of <proc_service.h> have slightly different
697 function prototypes. In particular, we have
700 struct ps_prochandle * const struct ps_prochandle *
705 Which one you have depends on the Solaris version and what patches
706 you've applied. On the theory that there are only two major
707 variants, we have configure check the prototype of ps_pdwrite (),
708 and use that info to make appropriate typedefs here. */
710 #ifdef PROC_SERVICE_IS_OLD
711 typedef const struct ps_prochandle *gdb_ps_prochandle_t;
712 typedef char *gdb_ps_read_buf_t;
713 typedef char *gdb_ps_write_buf_t;
714 typedef int gdb_ps_size_t;
715 typedef psaddr_t gdb_ps_addr_t;
717 typedef struct ps_prochandle *gdb_ps_prochandle_t;
718 typedef void *gdb_ps_read_buf_t;
719 typedef const void *gdb_ps_write_buf_t;
720 typedef size_t gdb_ps_size_t;
721 typedef psaddr_t gdb_ps_addr_t;
724 /* The next four routines are called by libthread_db to tell us to
725 stop and stop a particular process or lwp. Since GDB ensures that
726 these are all stopped by the time we call anything in thread_db,
727 these routines need to do nothing. */
732 ps_pstop (gdb_ps_prochandle_t ph)
737 /* Process continue. */
740 ps_pcontinue (gdb_ps_prochandle_t ph)
748 ps_lstop (gdb_ps_prochandle_t ph, lwpid_t lwpid)
756 ps_lcontinue (gdb_ps_prochandle_t ph, lwpid_t lwpid)
761 /* Looks up the symbol LD_SYMBOL_NAME in the debugger's symbol table. */
764 ps_pglobal_lookup (gdb_ps_prochandle_t ph, const char *ld_object_name,
765 const char *ld_symbol_name, gdb_ps_addr_t *ld_symbol_addr)
767 struct bound_minimal_symbol ms;
769 ms = lookup_minimal_symbol (ld_symbol_name, NULL, NULL);
773 *ld_symbol_addr = BMSYMBOL_VALUE_ADDRESS (ms);
777 /* Common routine for reading and writing memory. */
780 rw_common (int dowrite, const struct ps_prochandle *ph, gdb_ps_addr_t addr,
781 gdb_byte *buf, int size)
784 struct cleanup *old_chain;
786 old_chain = save_inferior_ptid ();
788 if (ptid_tid_p (inferior_ptid) || !target_thread_alive (inferior_ptid))
790 /* It's either a thread or an LWP that isn't alive. Any live
791 LWP will do so use the first available.
793 NOTE: We don't need to call switch_to_thread; we're just
795 inferior_ptid = procfs_first_available ();
798 #if defined (__sparcv9)
799 /* For Sparc64 cross Sparc32, make sure the address has not been
800 accidentally sign-extended (or whatever) to beyond 32 bits. */
801 if (bfd_get_arch_size (exec_bfd) == 32)
806 ret = target_write_memory (addr, (gdb_byte *) buf, size);
808 ret = target_read_memory (addr, (gdb_byte *) buf, size);
810 do_cleanups (old_chain);
812 return (ret == 0 ? PS_OK : PS_ERR);
815 /* Copies SIZE bytes from target process .data segment to debugger memory. */
818 ps_pdread (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
819 gdb_ps_read_buf_t buf, gdb_ps_size_t size)
821 return rw_common (0, ph, addr, buf, size);
824 /* Copies SIZE bytes from debugger memory .data segment to target process. */
827 ps_pdwrite (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
828 gdb_ps_write_buf_t buf, gdb_ps_size_t size)
830 return rw_common (1, ph, addr, (gdb_byte *) buf, size);
833 /* Copies SIZE bytes from target process .text segment to debugger memory. */
836 ps_ptread (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
837 gdb_ps_read_buf_t buf, gdb_ps_size_t size)
839 return rw_common (0, ph, addr, buf, size);
842 /* Copies SIZE bytes from debugger memory .text segment to target process. */
845 ps_ptwrite (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
846 gdb_ps_write_buf_t buf, gdb_ps_size_t size)
848 return rw_common (1, ph, addr, (gdb_byte *) buf, size);
851 /* Get general-purpose registers for LWP. */
854 ps_lgetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, prgregset_t gregset)
856 struct cleanup *old_chain;
857 struct regcache *regcache;
859 old_chain = save_inferior_ptid ();
861 inferior_ptid = ptid_build (ptid_get_pid (inferior_ptid), lwpid, 0);
862 regcache = get_thread_arch_regcache (inferior_ptid, target_gdbarch ());
864 target_fetch_registers (regcache, -1);
865 fill_gregset (regcache, (gdb_gregset_t *) gregset, -1);
867 do_cleanups (old_chain);
872 /* Set general-purpose registers for LWP. */
875 ps_lsetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
876 const prgregset_t gregset)
878 struct cleanup *old_chain;
879 struct regcache *regcache;
881 old_chain = save_inferior_ptid ();
883 inferior_ptid = ptid_build (ptid_get_pid (inferior_ptid), lwpid, 0);
884 regcache = get_thread_arch_regcache (inferior_ptid, target_gdbarch ());
886 supply_gregset (regcache, (const gdb_gregset_t *) gregset);
887 target_store_registers (regcache, -1);
889 do_cleanups (old_chain);
894 /* Log a message (sends to gdb_stderr). */
897 ps_plog (const char *fmt, ...)
901 va_start (args, fmt);
903 vfprintf_filtered (gdb_stderr, fmt, args);
906 /* Get size of extra register set. Currently a noop. */
909 ps_lgetxregsize (gdb_ps_prochandle_t ph, lwpid_t lwpid, int *xregsize)
914 /* Get extra register set. Currently a noop. */
917 ps_lgetxregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, caddr_t xregset)
922 /* Set extra register set. Currently a noop. */
925 ps_lsetxregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, caddr_t xregset)
930 /* Get floating-point registers for LWP. */
933 ps_lgetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
934 prfpregset_t *fpregset)
936 struct cleanup *old_chain;
937 struct regcache *regcache;
939 old_chain = save_inferior_ptid ();
941 inferior_ptid = ptid_build (ptid_get_pid (inferior_ptid), lwpid, 0);
942 regcache = get_thread_arch_regcache (inferior_ptid, target_gdbarch ());
944 target_fetch_registers (regcache, -1);
945 fill_fpregset (regcache, (gdb_fpregset_t *) fpregset, -1);
947 do_cleanups (old_chain);
952 /* Set floating-point regs for LWP. */
955 ps_lsetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
956 const prfpregset_t * fpregset)
958 struct cleanup *old_chain;
959 struct regcache *regcache;
961 old_chain = save_inferior_ptid ();
963 inferior_ptid = ptid_build (ptid_get_pid (inferior_ptid), lwpid, 0);
964 regcache = get_thread_arch_regcache (inferior_ptid, target_gdbarch ());
966 supply_fpregset (regcache, (const gdb_fpregset_t *) fpregset);
967 target_store_registers (regcache, -1);
969 do_cleanups (old_chain);
975 /* Identify process as 32-bit or 64-bit. At the moment we're using
976 BFD to do this. There might be a more Solaris-specific
977 (e.g. procfs) method, but this ought to work. */
980 ps_pdmodel (gdb_ps_prochandle_t ph, int *data_model)
983 *data_model = PR_MODEL_UNKNOWN;
984 else if (bfd_get_arch_size (exec_bfd) == 32)
985 *data_model = PR_MODEL_ILP32;
987 *data_model = PR_MODEL_LP64;
991 #endif /* PR_MODEL_LP64 */
993 #if (defined(__i386__) || defined(__x86_64__)) && defined (sun)
995 /* Reads the local descriptor table of a LWP.
997 This function is necessary on x86-solaris only. Without it, the loading
998 of libthread_db would fail because of ps_lgetLDT being undefined. */
1001 ps_lgetLDT (gdb_ps_prochandle_t ph, lwpid_t lwpid,
1004 /* NOTE: only used on Solaris, therefore OK to refer to procfs.c. */
1007 /* FIXME: can't I get the process ID from the prochandle or
1010 if (ptid_get_pid (inferior_ptid) <= 0 || lwpid <= 0)
1013 ret = procfs_find_LDT_entry (ptid_build (ptid_get_pid (inferior_ptid),
1017 memcpy (pldt, ret, sizeof (struct ssd));
1021 /* LDT not found. */
1027 /* Convert PTID to printable form. */
1030 solaris_pid_to_str (struct target_ops *ops, ptid_t ptid)
1032 static char buf[100];
1034 if (ptid_tid_p (ptid))
1038 lwp = thread_to_lwp (ptid, -2);
1040 if (ptid_get_pid (lwp) == -1)
1041 xsnprintf (buf, sizeof (buf), "Thread %ld (defunct)",
1042 ptid_get_tid (ptid));
1043 else if (ptid_get_pid (lwp) != -2)
1044 xsnprintf (buf, sizeof (buf), "Thread %ld (LWP %ld)",
1045 ptid_get_tid (ptid), ptid_get_lwp (lwp));
1047 xsnprintf (buf, sizeof (buf), "Thread %ld ",
1048 ptid_get_tid (ptid));
1050 else if (ptid_get_lwp (ptid) != 0)
1051 xsnprintf (buf, sizeof (buf), "LWP %ld ", ptid_get_lwp (ptid));
1053 xsnprintf (buf, sizeof (buf), "process %d ", ptid_get_pid (ptid));
1059 /* Worker bee for update_thread_list. Callback function that gets
1060 called once per user-level thread (i.e. not for LWP's). */
1063 sol_update_thread_list_callback (const td_thrhandle_t *th, void *ignored)
1069 retval = p_td_thr_get_info (th, &ti);
1070 if (retval != TD_OK)
1073 ptid = ptid_build (ptid_get_pid (inferior_ptid), 0, ti.ti_tid);
1074 if (!in_thread_list (ptid) || is_exited (ptid))
1081 sol_update_thread_list (struct target_ops *ops)
1083 struct target_ops *beneath = find_target_beneath (ops);
1085 /* Delete dead threads. */
1088 /* Find any new LWP's. */
1089 beneath->to_update_thread_list (beneath);
1091 /* Then find any new user-level threads. */
1092 p_td_ta_thr_iter (main_ta, sol_update_thread_list_callback, (void *) 0,
1093 TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
1094 TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
1097 /* Worker bee for the "info sol-thread" command. This is a callback
1098 function that gets called once for each Solaris user-level thread
1099 (i.e. not for LWPs) in the inferior. Print anything interesting
1100 that we can think of. */
1103 info_cb (const td_thrhandle_t *th, void *s)
1108 ret = p_td_thr_get_info (th, &ti);
1111 printf_filtered ("%s thread #%d, lwp %d, ",
1112 ti.ti_type == TD_THR_SYSTEM ? "system" : "user ",
1113 ti.ti_tid, ti.ti_lid);
1114 switch (ti.ti_state)
1117 case TD_THR_UNKNOWN:
1118 printf_filtered ("<unknown state>");
1120 case TD_THR_STOPPED:
1121 printf_filtered ("(stopped)");
1124 printf_filtered ("(run) ");
1127 printf_filtered ("(active) ");
1130 printf_filtered ("(zombie) ");
1133 printf_filtered ("(asleep) ");
1135 case TD_THR_STOPPED_ASLEEP:
1136 printf_filtered ("(stopped asleep)");
1139 /* Print thr_create start function. */
1140 if (ti.ti_startfunc != 0)
1142 const struct bound_minimal_symbol msym
1143 = lookup_minimal_symbol_by_pc (ti.ti_startfunc);
1145 printf_filtered (" startfunc=%s",
1147 ? MSYMBOL_PRINT_NAME (msym.minsym)
1148 : paddress (target_gdbarch (), ti.ti_startfunc));
1151 /* If thread is asleep, print function that went to sleep. */
1152 if (ti.ti_state == TD_THR_SLEEP)
1154 const struct bound_minimal_symbol msym
1155 = lookup_minimal_symbol_by_pc (ti.ti_pc);
1157 printf_filtered (" sleepfunc=%s",
1159 ? MSYMBOL_PRINT_NAME (msym.minsym)
1160 : paddress (target_gdbarch (), ti.ti_pc));
1163 printf_filtered ("\n");
1166 warning (_("info sol-thread: failed to get info for thread."));
1171 /* List some state about each Solaris user-level thread in the
1175 info_solthreads (char *args, int from_tty)
1177 p_td_ta_thr_iter (main_ta, info_cb, args,
1178 TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
1179 TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
1182 /* Callback routine used to find a thread based on the TID part of
1186 thread_db_find_thread_from_tid (struct thread_info *thread, void *data)
1188 long *tid = (long *) data;
1190 if (ptid_get_tid (thread->ptid) == *tid)
1197 sol_get_ada_task_ptid (struct target_ops *self, long lwp, long thread)
1199 struct thread_info *thread_info =
1200 iterate_over_threads (thread_db_find_thread_from_tid, &thread);
1202 if (thread_info == NULL)
1204 /* The list of threads is probably not up to date. Find any
1205 thread that is missing from the list, and try again. */
1206 sol_update_thread_list (¤t_target);
1207 thread_info = iterate_over_threads (thread_db_find_thread_from_tid,
1211 gdb_assert (thread_info != NULL);
1213 return (thread_info->ptid);
1217 init_sol_thread_ops (void)
1219 sol_thread_ops.to_shortname = "solaris-threads";
1220 sol_thread_ops.to_longname = "Solaris threads and pthread.";
1221 sol_thread_ops.to_doc = "Solaris threads and pthread support.";
1222 sol_thread_ops.to_detach = sol_thread_detach;
1223 sol_thread_ops.to_resume = sol_thread_resume;
1224 sol_thread_ops.to_wait = sol_thread_wait;
1225 sol_thread_ops.to_fetch_registers = sol_thread_fetch_registers;
1226 sol_thread_ops.to_store_registers = sol_thread_store_registers;
1227 sol_thread_ops.to_xfer_partial = sol_thread_xfer_partial;
1228 sol_thread_ops.to_mourn_inferior = sol_thread_mourn_inferior;
1229 sol_thread_ops.to_thread_alive = sol_thread_alive;
1230 sol_thread_ops.to_pid_to_str = solaris_pid_to_str;
1231 sol_thread_ops.to_update_thread_list = sol_update_thread_list;
1232 sol_thread_ops.to_stratum = thread_stratum;
1233 sol_thread_ops.to_get_ada_task_ptid = sol_get_ada_task_ptid;
1234 sol_thread_ops.to_magic = OPS_MAGIC;
1237 /* Silence -Wmissing-prototypes. */
1238 extern void _initialize_sol_thread (void);
1241 _initialize_sol_thread (void)
1245 init_sol_thread_ops ();
1247 dlhandle = dlopen ("libthread_db.so.1", RTLD_NOW);
1251 #define resolve(X) \
1252 if (!(p_##X = dlsym (dlhandle, #X))) \
1256 resolve (td_ta_new);
1257 resolve (td_ta_delete);
1259 resolve (td_ta_get_ph);
1260 resolve (td_ta_get_nthreads);
1261 resolve (td_ta_tsd_iter);
1262 resolve (td_ta_thr_iter);
1263 resolve (td_thr_validate);
1264 resolve (td_thr_tsd);
1265 resolve (td_thr_get_info);
1266 resolve (td_thr_getfpregs);
1267 resolve (td_thr_getxregsize);
1268 resolve (td_thr_getxregs);
1269 resolve (td_thr_sigsetmask);
1270 resolve (td_thr_setprio);
1271 resolve (td_thr_setsigpending);
1272 resolve (td_thr_setfpregs);
1273 resolve (td_thr_setxregs);
1274 resolve (td_ta_map_id2thr);
1275 resolve (td_ta_map_lwp2thr);
1276 resolve (td_thr_getgregs);
1277 resolve (td_thr_setgregs);
1279 complete_target_initialization (&sol_thread_ops);
1281 add_cmd ("sol-threads", class_maintenance, info_solthreads,
1282 _("Show info on Solaris user threads."), &maintenanceinfolist);
1284 /* Hook into new_objfile notification. */
1285 observer_attach_new_objfile (sol_thread_new_objfile);
1289 fprintf_unfiltered (gdb_stderr, "\
1290 [GDB will not be able to debug user-mode threads: %s]\n", dlerror ());