1 /* Solaris threads debugging interface.
3 Copyright (C) 1996-2014 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"
73 struct target_ops sol_thread_ops;
75 /* Prototypes for supply_gregset etc. */
78 /* This struct is defined by us, but mainly used for the proc_service
79 interface. We don't have much use for it, except as a handy place
80 to get a real PID for memory accesses. */
93 static struct ps_prochandle main_ph;
94 static td_thragent_t *main_ta;
95 static int sol_thread_active = 0;
97 static void init_sol_thread_ops (void);
99 /* Default definitions: These must be defined in tm.h if they are to
100 be shared with a process module such as procfs. */
102 /* Pointers to routines from libthread_db resolved by dlopen(). */
104 static void (*p_td_log)(const int on_off);
105 static td_err_e (*p_td_ta_new)(const struct ps_prochandle *ph_p,
106 td_thragent_t **ta_pp);
107 static td_err_e (*p_td_ta_delete)(td_thragent_t *ta_p);
108 static td_err_e (*p_td_init)(void);
109 static td_err_e (*p_td_ta_get_ph)(const td_thragent_t *ta_p,
110 struct ps_prochandle **ph_pp);
111 static td_err_e (*p_td_ta_get_nthreads)(const td_thragent_t *ta_p,
113 static td_err_e (*p_td_ta_tsd_iter)(const td_thragent_t *ta_p,
114 td_key_iter_f *cb, void *cbdata_p);
115 static td_err_e (*p_td_ta_thr_iter)(const td_thragent_t *ta_p,
116 td_thr_iter_f *cb, void *cbdata_p,
117 td_thr_state_e state, int ti_pri,
118 sigset_t *ti_sigmask_p,
119 unsigned ti_user_flags);
120 static td_err_e (*p_td_thr_validate)(const td_thrhandle_t *th_p);
121 static td_err_e (*p_td_thr_tsd)(const td_thrhandle_t * th_p,
122 const thread_key_t key, void **data_pp);
123 static td_err_e (*p_td_thr_get_info)(const td_thrhandle_t *th_p,
125 static td_err_e (*p_td_thr_getfpregs)(const td_thrhandle_t *th_p,
126 prfpregset_t *fpregset);
127 static td_err_e (*p_td_thr_getxregsize)(const td_thrhandle_t *th_p,
129 static td_err_e (*p_td_thr_getxregs)(const td_thrhandle_t *th_p,
130 const caddr_t xregset);
131 static td_err_e (*p_td_thr_sigsetmask)(const td_thrhandle_t *th_p,
132 const sigset_t ti_sigmask);
133 static td_err_e (*p_td_thr_setprio)(const td_thrhandle_t *th_p,
135 static td_err_e (*p_td_thr_setsigpending)(const td_thrhandle_t *th_p,
136 const uchar_t ti_pending_flag,
137 const sigset_t ti_pending);
138 static td_err_e (*p_td_thr_setfpregs)(const td_thrhandle_t *th_p,
139 const prfpregset_t *fpregset);
140 static td_err_e (*p_td_thr_setxregs)(const td_thrhandle_t *th_p,
141 const caddr_t xregset);
142 static td_err_e (*p_td_ta_map_id2thr)(const td_thragent_t *ta_p,
144 td_thrhandle_t *th_p);
145 static td_err_e (*p_td_ta_map_lwp2thr)(const td_thragent_t *ta_p,
147 td_thrhandle_t *th_p);
148 static td_err_e (*p_td_thr_getgregs)(const td_thrhandle_t *th_p,
150 static td_err_e (*p_td_thr_setgregs)(const td_thrhandle_t *th_p,
151 const prgregset_t regset);
154 /* Return the libthread_db error string associated with ERRCODE. If
155 ERRCODE is unknown, return an appropriate message. */
158 td_err_string (td_err_e errcode)
160 static struct string_map td_err_table[] =
162 { TD_OK, "generic \"call succeeded\"" },
163 { TD_ERR, "generic error." },
164 { TD_NOTHR, "no thread can be found to satisfy query" },
165 { TD_NOSV, "no synch. variable can be found to satisfy query" },
166 { TD_NOLWP, "no lwp can be found to satisfy query" },
167 { TD_BADPH, "invalid process handle" },
168 { TD_BADTH, "invalid thread handle" },
169 { TD_BADSH, "invalid synchronization handle" },
170 { TD_BADTA, "invalid thread agent" },
171 { TD_BADKEY, "invalid key" },
172 { TD_NOMSG, "td_thr_event_getmsg() called when there was no message" },
173 { TD_NOFPREGS, "FPU register set not available for given thread" },
174 { TD_NOLIBTHREAD, "application not linked with libthread" },
175 { TD_NOEVENT, "requested event is not supported" },
176 { TD_NOCAPAB, "capability not available" },
177 { TD_DBERR, "Debugger service failed" },
178 { TD_NOAPLIC, "Operation not applicable to" },
179 { TD_NOTSD, "No thread specific data for this thread" },
180 { TD_MALLOC, "Malloc failed" },
181 { TD_PARTIALREG, "Only part of register set was written/read" },
182 { TD_NOXREGS, "X register set not available for given thread" }
184 const int td_err_size = sizeof td_err_table / sizeof (struct string_map);
188 for (i = 0; i < td_err_size; i++)
189 if (td_err_table[i].num == errcode)
190 return td_err_table[i].str;
192 xsnprintf (buf, sizeof (buf), "Unknown libthread_db error code: %d",
198 /* Return the libthread_db state string assicoated with STATECODE.
199 If STATECODE is unknown, return an appropriate message. */
202 td_state_string (td_thr_state_e statecode)
204 static struct string_map td_thr_state_table[] =
206 { TD_THR_ANY_STATE, "any state" },
207 { TD_THR_UNKNOWN, "unknown" },
208 { TD_THR_STOPPED, "stopped" },
209 { TD_THR_RUN, "run" },
210 { TD_THR_ACTIVE, "active" },
211 { TD_THR_ZOMBIE, "zombie" },
212 { TD_THR_SLEEP, "sleep" },
213 { TD_THR_STOPPED_ASLEEP, "stopped asleep" }
215 const int td_thr_state_table_size =
216 sizeof td_thr_state_table / sizeof (struct string_map);
220 for (i = 0; i < td_thr_state_table_size; i++)
221 if (td_thr_state_table[i].num == statecode)
222 return td_thr_state_table[i].str;
224 xsnprintf (buf, sizeof (buf), "Unknown libthread_db state code: %d",
231 /* Convert a POSIX or Solaris thread ID into a LWP ID. If THREAD_ID
232 doesn't exist, that's an error. If it's an inactive thread, return
235 NOTE: This function probably shouldn't call error(). */
238 thread_to_lwp (ptid_t thread_id, int default_lwp)
244 if (ptid_lwp_p (thread_id))
245 return thread_id; /* It's already an LWP ID. */
247 /* It's a thread. Convert to LWP. */
249 val = p_td_ta_map_id2thr (main_ta, ptid_get_tid (thread_id), &th);
251 return pid_to_ptid (-1); /* Thread must have terminated. */
252 else if (val != TD_OK)
253 error (_("thread_to_lwp: td_ta_map_id2thr %s"), td_err_string (val));
255 val = p_td_thr_get_info (&th, &ti);
257 return pid_to_ptid (-1); /* Thread must have terminated. */
258 else if (val != TD_OK)
259 error (_("thread_to_lwp: td_thr_get_info: %s"), td_err_string (val));
261 if (ti.ti_state != TD_THR_ACTIVE)
263 if (default_lwp != -1)
264 return pid_to_ptid (default_lwp);
265 error (_("thread_to_lwp: thread state not active: %s"),
266 td_state_string (ti.ti_state));
269 return ptid_build (ptid_get_pid (thread_id), ti.ti_lid, 0);
272 /* Convert an LWP ID into a POSIX or Solaris thread ID. If LWP_ID
273 doesn't exists, that's an error.
275 NOTE: This function probably shouldn't call error(). */
278 lwp_to_thread (ptid_t lwp)
284 if (ptid_tid_p (lwp))
285 return lwp; /* It's already a thread ID. */
287 /* It's an LWP. Convert it to a thread ID. */
289 if (!target_thread_alive (lwp))
290 return pid_to_ptid (-1); /* Must be a defunct LPW. */
292 val = p_td_ta_map_lwp2thr (main_ta, ptid_get_lwp (lwp), &th);
294 return pid_to_ptid (-1); /* Thread must have terminated. */
295 else if (val != TD_OK)
296 error (_("lwp_to_thread: td_ta_map_lwp2thr: %s."), td_err_string (val));
298 val = p_td_thr_validate (&th);
300 return lwp; /* Unknown to libthread; just return LPW, */
301 else if (val != TD_OK)
302 error (_("lwp_to_thread: td_thr_validate: %s."), td_err_string (val));
304 val = p_td_thr_get_info (&th, &ti);
306 return pid_to_ptid (-1); /* Thread must have terminated. */
307 else if (val != TD_OK)
308 error (_("lwp_to_thread: td_thr_get_info: %s."), td_err_string (val));
310 return ptid_build (ptid_get_pid (lwp), 0 , ti.ti_tid);
314 /* Most target vector functions from here on actually just pass
315 through to the layer beneath, as they don't need to do anything
316 specific for threads. */
318 /* Take a program previously attached to and detaches it. The program
319 resumes execution and will no longer stop on signals, etc. We'd
320 better not have left any breakpoints in the program or it'll die
321 when it hits one. For this to work, it may be necessary for the
322 process to have been previously attached. It *might* work if the
323 program was started via the normal ptrace (PTRACE_TRACEME). */
326 sol_thread_detach (struct target_ops *ops, const char *args, int from_tty)
328 struct target_ops *beneath = find_target_beneath (ops);
330 sol_thread_active = 0;
331 inferior_ptid = pid_to_ptid (ptid_get_pid (main_ph.ptid));
333 beneath->to_detach (beneath, args, from_tty);
336 /* Resume execution of process PTID. If STEP is nozero, then just
337 single step it. If SIGNAL is nonzero, restart it with that signal
338 activated. We may have to convert PTID from a thread ID to an LWP
342 sol_thread_resume (struct target_ops *ops,
343 ptid_t ptid, int step, enum gdb_signal signo)
345 struct cleanup *old_chain;
346 struct target_ops *beneath = find_target_beneath (ops);
348 old_chain = save_inferior_ptid ();
350 inferior_ptid = thread_to_lwp (inferior_ptid, ptid_get_pid (main_ph.ptid));
351 if (ptid_get_pid (inferior_ptid) == -1)
352 inferior_ptid = procfs_first_available ();
354 if (ptid_get_pid (ptid) != -1)
356 ptid_t save_ptid = ptid;
358 ptid = thread_to_lwp (ptid, -2);
359 if (ptid_get_pid (ptid) == -2) /* Inactive thread. */
360 error (_("This version of Solaris can't start inactive threads."));
361 if (info_verbose && ptid_get_pid (ptid) == -1)
362 warning (_("Specified thread %ld seems to have terminated"),
363 ptid_get_tid (save_ptid));
366 beneath->to_resume (beneath, ptid, step, signo);
368 do_cleanups (old_chain);
371 /* Wait for any threads to stop. We may have to convert PTID from a
372 thread ID to an LWP ID, and vice versa on the way out. */
375 sol_thread_wait (struct target_ops *ops,
376 ptid_t ptid, struct target_waitstatus *ourstatus, int options)
380 struct target_ops *beneath = find_target_beneath (ops);
381 struct cleanup *old_chain;
383 save_ptid = inferior_ptid;
384 old_chain = save_inferior_ptid ();
386 inferior_ptid = thread_to_lwp (inferior_ptid, ptid_get_pid (main_ph.ptid));
387 if (ptid_get_pid (inferior_ptid) == -1)
388 inferior_ptid = procfs_first_available ();
390 if (ptid_get_pid (ptid) != -1)
392 ptid_t save_ptid = ptid;
394 ptid = thread_to_lwp (ptid, -2);
395 if (ptid_get_pid (ptid) == -2) /* Inactive thread. */
396 error (_("This version of Solaris can't start inactive threads."));
397 if (info_verbose && ptid_get_pid (ptid) == -1)
398 warning (_("Specified thread %ld seems to have terminated"),
399 ptid_get_tid (save_ptid));
402 rtnval = beneath->to_wait (beneath, ptid, ourstatus, options);
404 if (ourstatus->kind != TARGET_WAITKIND_EXITED)
406 /* Map the LWP of interest back to the appropriate thread ID. */
407 rtnval = lwp_to_thread (rtnval);
408 if (ptid_get_pid (rtnval) == -1)
411 /* See if we have a new thread. */
412 if (ptid_tid_p (rtnval)
413 && !ptid_equal (rtnval, save_ptid)
414 && (!in_thread_list (rtnval)
415 || is_exited (rtnval)))
419 /* During process initialization, we may get here without the thread
420 package being initialized, since that can only happen after we've
421 found the shared libs. */
423 do_cleanups (old_chain);
429 sol_thread_fetch_registers (struct target_ops *ops,
430 struct regcache *regcache, int regnum)
433 td_thrhandle_t thandle;
436 prfpregset_t fpregset;
437 gdb_gregset_t *gregset_p = &gregset;
438 gdb_fpregset_t *fpregset_p = &fpregset;
439 struct target_ops *beneath = find_target_beneath (ops);
441 if (!ptid_tid_p (inferior_ptid))
443 /* It's an LWP; pass the request on to the layer beneath. */
444 beneath->to_fetch_registers (beneath, regcache, regnum);
448 /* Solaris thread: convert INFERIOR_PTID into a td_thrhandle_t. */
449 thread = ptid_get_tid (inferior_ptid);
451 error (_("sol_thread_fetch_registers: thread == 0"));
453 val = p_td_ta_map_id2thr (main_ta, thread, &thandle);
455 error (_("sol_thread_fetch_registers: td_ta_map_id2thr: %s"),
456 td_err_string (val));
458 /* Get the general-purpose registers. */
460 val = p_td_thr_getgregs (&thandle, gregset);
461 if (val != TD_OK && val != TD_PARTIALREG)
462 error (_("sol_thread_fetch_registers: td_thr_getgregs %s"),
463 td_err_string (val));
465 /* For SPARC, TD_PARTIALREG means that only %i0...%i7, %l0..%l7, %pc
466 and %sp are saved (by a thread context switch). */
468 /* And, now the floating-point registers. */
470 val = p_td_thr_getfpregs (&thandle, &fpregset);
471 if (val != TD_OK && val != TD_NOFPREGS)
472 error (_("sol_thread_fetch_registers: td_thr_getfpregs %s"),
473 td_err_string (val));
475 /* Note that we must call supply_gregset and supply_fpregset *after*
476 calling the td routines because the td routines call ps_lget*
477 which affect the values stored in the registers array. */
479 supply_gregset (regcache, (const gdb_gregset_t *) gregset_p);
480 supply_fpregset (regcache, (const gdb_fpregset_t *) fpregset_p);
484 sol_thread_store_registers (struct target_ops *ops,
485 struct regcache *regcache, int regnum)
488 td_thrhandle_t thandle;
491 prfpregset_t fpregset;
493 if (!ptid_tid_p (inferior_ptid))
495 struct target_ops *beneath = find_target_beneath (ops);
497 /* It's an LWP; pass the request on to the layer beneath. */
498 beneath->to_store_registers (beneath, regcache, regnum);
502 /* Solaris thread: convert INFERIOR_PTID into a td_thrhandle_t. */
503 thread = ptid_get_tid (inferior_ptid);
505 val = p_td_ta_map_id2thr (main_ta, thread, &thandle);
507 error (_("sol_thread_store_registers: td_ta_map_id2thr %s"),
508 td_err_string (val));
512 /* Not writing all the registers. */
513 char old_value[MAX_REGISTER_SIZE];
515 /* Save new register value. */
516 regcache_raw_collect (regcache, regnum, old_value);
518 val = p_td_thr_getgregs (&thandle, gregset);
520 error (_("sol_thread_store_registers: td_thr_getgregs %s"),
521 td_err_string (val));
522 val = p_td_thr_getfpregs (&thandle, &fpregset);
524 error (_("sol_thread_store_registers: td_thr_getfpregs %s"),
525 td_err_string (val));
527 /* Restore new register value. */
528 regcache_raw_supply (regcache, regnum, old_value);
531 fill_gregset (regcache, (gdb_gregset_t *) &gregset, regnum);
532 fill_fpregset (regcache, (gdb_fpregset_t *) &fpregset, regnum);
534 val = p_td_thr_setgregs (&thandle, gregset);
536 error (_("sol_thread_store_registers: td_thr_setgregs %s"),
537 td_err_string (val));
538 val = p_td_thr_setfpregs (&thandle, &fpregset);
540 error (_("sol_thread_store_registers: td_thr_setfpregs %s"),
541 td_err_string (val));
544 /* Perform partial transfers on OBJECT. See target_read_partial and
545 target_write_partial for details of each variant. One, and only
546 one, of readbuf or writebuf must be non-NULL. */
548 static enum target_xfer_status
549 sol_thread_xfer_partial (struct target_ops *ops, enum target_object object,
550 const char *annex, gdb_byte *readbuf,
551 const gdb_byte *writebuf,
552 ULONGEST offset, ULONGEST len, ULONGEST *xfered_len)
554 enum target_xfer_status retval;
555 struct cleanup *old_chain;
556 struct target_ops *beneath = find_target_beneath (ops);
558 old_chain = save_inferior_ptid ();
560 if (ptid_tid_p (inferior_ptid) || !target_thread_alive (inferior_ptid))
562 /* It's either a thread or an LWP that isn't alive. Any live
563 LWP will do so use the first available.
565 NOTE: We don't need to call switch_to_thread; we're just
567 inferior_ptid = procfs_first_available ();
570 retval = beneath->to_xfer_partial (beneath, object, annex, readbuf,
571 writebuf, offset, len, xfered_len);
573 do_cleanups (old_chain);
579 check_for_thread_db (void)
584 /* Don't attempt to use thread_db for remote targets. */
585 if (!(target_can_run (¤t_target) || core_bfd))
588 /* Do nothing if we couldn't load libthread_db.so.1. */
589 if (p_td_ta_new == NULL)
592 if (sol_thread_active)
593 /* Nothing to do. The thread library was already detected and the
594 target vector was already activated. */
597 /* Now, initialize libthread_db. This needs to be done after the
598 shared libraries are located because it needs information from
599 the user's thread library. */
604 warning (_("sol_thread_new_objfile: td_init: %s"), td_err_string (err));
608 /* Now attempt to open a connection to the thread library. */
609 err = p_td_ta_new (&main_ph, &main_ta);
613 /* No thread library was detected. */
617 printf_unfiltered (_("[Thread debugging using libthread_db enabled]\n"));
619 /* The thread library was detected. Activate the sol_thread target. */
620 push_target (&sol_thread_ops);
621 sol_thread_active = 1;
623 main_ph.ptid = inferior_ptid; /* Save for xfer_memory. */
624 ptid = lwp_to_thread (inferior_ptid);
625 if (ptid_get_pid (ptid) != -1)
626 inferior_ptid = ptid;
628 target_find_new_threads ();
632 warning (_("Cannot initialize thread debugging library: %s"),
633 td_err_string (err));
638 /* This routine is called whenever a new symbol table is read in, or
639 when all symbol tables are removed. libthread_db can only be
640 initialized when it finds the right variables in libthread.so.
641 Since it's a shared library, those variables don't show up until
642 the library gets mapped and the symbol table is read in. */
645 sol_thread_new_objfile (struct objfile *objfile)
648 check_for_thread_db ();
651 /* Clean up after the inferior dies. */
654 sol_thread_mourn_inferior (struct target_ops *ops)
656 struct target_ops *beneath = find_target_beneath (ops);
658 sol_thread_active = 0;
662 beneath->to_mourn_inferior (beneath);
665 /* Return true if PTID is still active in the inferior. */
668 sol_thread_alive (struct target_ops *ops, ptid_t ptid)
670 if (ptid_tid_p (ptid))
672 /* It's a (user-level) thread. */
677 pid = ptid_get_tid (ptid);
678 if ((val = p_td_ta_map_id2thr (main_ta, pid, &th)) != TD_OK)
679 return 0; /* Thread not found. */
680 if ((val = p_td_thr_validate (&th)) != TD_OK)
681 return 0; /* Thread not valid. */
682 return 1; /* Known thread. */
686 struct target_ops *beneath = find_target_beneath (ops);
688 /* It's an LPW; pass the request on to the layer below. */
689 return beneath->to_thread_alive (beneath, ptid);
694 /* These routines implement the lower half of the thread_db interface,
695 i.e. the ps_* routines. */
697 /* Various versions of <proc_service.h> have slightly different
698 function prototypes. In particular, we have
701 struct ps_prochandle * const struct ps_prochandle *
706 Which one you have depends on the Solaris version and what patches
707 you've applied. On the theory that there are only two major
708 variants, we have configure check the prototype of ps_pdwrite (),
709 and use that info to make appropriate typedefs here. */
711 #ifdef PROC_SERVICE_IS_OLD
712 typedef const struct ps_prochandle *gdb_ps_prochandle_t;
713 typedef char *gdb_ps_read_buf_t;
714 typedef char *gdb_ps_write_buf_t;
715 typedef int gdb_ps_size_t;
716 typedef psaddr_t gdb_ps_addr_t;
718 typedef struct ps_prochandle *gdb_ps_prochandle_t;
719 typedef void *gdb_ps_read_buf_t;
720 typedef const void *gdb_ps_write_buf_t;
721 typedef size_t gdb_ps_size_t;
722 typedef psaddr_t gdb_ps_addr_t;
725 /* The next four routines are called by libthread_db to tell us to
726 stop and stop a particular process or lwp. Since GDB ensures that
727 these are all stopped by the time we call anything in thread_db,
728 these routines need to do nothing. */
733 ps_pstop (gdb_ps_prochandle_t ph)
738 /* Process continue. */
741 ps_pcontinue (gdb_ps_prochandle_t ph)
749 ps_lstop (gdb_ps_prochandle_t ph, lwpid_t lwpid)
757 ps_lcontinue (gdb_ps_prochandle_t ph, lwpid_t lwpid)
762 /* Looks up the symbol LD_SYMBOL_NAME in the debugger's symbol table. */
765 ps_pglobal_lookup (gdb_ps_prochandle_t ph, const char *ld_object_name,
766 const char *ld_symbol_name, gdb_ps_addr_t *ld_symbol_addr)
768 struct bound_minimal_symbol ms;
770 ms = lookup_minimal_symbol (ld_symbol_name, NULL, NULL);
774 *ld_symbol_addr = BMSYMBOL_VALUE_ADDRESS (ms);
778 /* Common routine for reading and writing memory. */
781 rw_common (int dowrite, const struct ps_prochandle *ph, gdb_ps_addr_t addr,
782 gdb_byte *buf, int size)
785 struct cleanup *old_chain;
787 old_chain = save_inferior_ptid ();
789 if (ptid_tid_p (inferior_ptid) || !target_thread_alive (inferior_ptid))
791 /* It's either a thread or an LWP that isn't alive. Any live
792 LWP will do so use the first available.
794 NOTE: We don't need to call switch_to_thread; we're just
796 inferior_ptid = procfs_first_available ();
799 #if defined (__sparcv9)
800 /* For Sparc64 cross Sparc32, make sure the address has not been
801 accidentally sign-extended (or whatever) to beyond 32 bits. */
802 if (bfd_get_arch_size (exec_bfd) == 32)
807 ret = target_write_memory (addr, (gdb_byte *) buf, size);
809 ret = target_read_memory (addr, (gdb_byte *) buf, size);
811 do_cleanups (old_chain);
813 return (ret == 0 ? PS_OK : PS_ERR);
816 /* Copies SIZE bytes from target process .data segment to debugger memory. */
819 ps_pdread (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
820 gdb_ps_read_buf_t buf, gdb_ps_size_t size)
822 return rw_common (0, ph, addr, buf, size);
825 /* Copies SIZE bytes from debugger memory .data segment to target process. */
828 ps_pdwrite (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
829 gdb_ps_write_buf_t buf, gdb_ps_size_t size)
831 return rw_common (1, ph, addr, (gdb_byte *) buf, size);
834 /* Copies SIZE bytes from target process .text segment to debugger memory. */
837 ps_ptread (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
838 gdb_ps_read_buf_t buf, gdb_ps_size_t size)
840 return rw_common (0, ph, addr, buf, size);
843 /* Copies SIZE bytes from debugger memory .text segment to target process. */
846 ps_ptwrite (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
847 gdb_ps_write_buf_t buf, gdb_ps_size_t size)
849 return rw_common (1, ph, addr, (gdb_byte *) buf, size);
852 /* Get general-purpose registers for LWP. */
855 ps_lgetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, prgregset_t gregset)
857 struct cleanup *old_chain;
858 struct regcache *regcache;
860 old_chain = save_inferior_ptid ();
862 inferior_ptid = ptid_build (ptid_get_pid (inferior_ptid), lwpid, 0);
863 regcache = get_thread_arch_regcache (inferior_ptid, target_gdbarch ());
865 target_fetch_registers (regcache, -1);
866 fill_gregset (regcache, (gdb_gregset_t *) gregset, -1);
868 do_cleanups (old_chain);
873 /* Set general-purpose registers for LWP. */
876 ps_lsetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
877 const prgregset_t gregset)
879 struct cleanup *old_chain;
880 struct regcache *regcache;
882 old_chain = save_inferior_ptid ();
884 inferior_ptid = ptid_build (ptid_get_pid (inferior_ptid), lwpid, 0);
885 regcache = get_thread_arch_regcache (inferior_ptid, target_gdbarch ());
887 supply_gregset (regcache, (const gdb_gregset_t *) gregset);
888 target_store_registers (regcache, -1);
890 do_cleanups (old_chain);
895 /* Log a message (sends to gdb_stderr). */
898 ps_plog (const char *fmt, ...)
902 va_start (args, fmt);
904 vfprintf_filtered (gdb_stderr, fmt, args);
907 /* Get size of extra register set. Currently a noop. */
910 ps_lgetxregsize (gdb_ps_prochandle_t ph, lwpid_t lwpid, int *xregsize)
915 /* Get extra register set. Currently a noop. */
918 ps_lgetxregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, caddr_t xregset)
923 /* Set extra register set. Currently a noop. */
926 ps_lsetxregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, caddr_t xregset)
931 /* Get floating-point registers for LWP. */
934 ps_lgetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
935 prfpregset_t *fpregset)
937 struct cleanup *old_chain;
938 struct regcache *regcache;
940 old_chain = save_inferior_ptid ();
942 inferior_ptid = ptid_build (ptid_get_pid (inferior_ptid), lwpid, 0);
943 regcache = get_thread_arch_regcache (inferior_ptid, target_gdbarch ());
945 target_fetch_registers (regcache, -1);
946 fill_fpregset (regcache, (gdb_fpregset_t *) fpregset, -1);
948 do_cleanups (old_chain);
953 /* Set floating-point regs for LWP. */
956 ps_lsetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
957 const prfpregset_t * fpregset)
959 struct cleanup *old_chain;
960 struct regcache *regcache;
962 old_chain = save_inferior_ptid ();
964 inferior_ptid = ptid_build (ptid_get_pid (inferior_ptid), lwpid, 0);
965 regcache = get_thread_arch_regcache (inferior_ptid, target_gdbarch ());
967 supply_fpregset (regcache, (const gdb_fpregset_t *) fpregset);
968 target_store_registers (regcache, -1);
970 do_cleanups (old_chain);
976 /* Identify process as 32-bit or 64-bit. At the moment we're using
977 BFD to do this. There might be a more Solaris-specific
978 (e.g. procfs) method, but this ought to work. */
981 ps_pdmodel (gdb_ps_prochandle_t ph, int *data_model)
984 *data_model = PR_MODEL_UNKNOWN;
985 else if (bfd_get_arch_size (exec_bfd) == 32)
986 *data_model = PR_MODEL_ILP32;
988 *data_model = PR_MODEL_LP64;
992 #endif /* PR_MODEL_LP64 */
994 #if (defined(__i386__) || defined(__x86_64__)) && defined (sun)
996 /* Reads the local descriptor table of a LWP.
998 This function is necessary on x86-solaris only. Without it, the loading
999 of libthread_db would fail because of ps_lgetLDT being undefined. */
1002 ps_lgetLDT (gdb_ps_prochandle_t ph, lwpid_t lwpid,
1005 /* NOTE: only used on Solaris, therefore OK to refer to procfs.c. */
1008 /* FIXME: can't I get the process ID from the prochandle or
1011 if (ptid_get_pid (inferior_ptid) <= 0 || lwpid <= 0)
1014 ret = procfs_find_LDT_entry (ptid_build (ptid_get_pid (inferior_ptid),
1018 memcpy (pldt, ret, sizeof (struct ssd));
1022 /* LDT not found. */
1028 /* Convert PTID to printable form. */
1031 solaris_pid_to_str (struct target_ops *ops, ptid_t ptid)
1033 static char buf[100];
1035 if (ptid_tid_p (ptid))
1039 lwp = thread_to_lwp (ptid, -2);
1041 if (ptid_get_pid (lwp) == -1)
1042 xsnprintf (buf, sizeof (buf), "Thread %ld (defunct)",
1043 ptid_get_tid (ptid));
1044 else if (ptid_get_pid (lwp) != -2)
1045 xsnprintf (buf, sizeof (buf), "Thread %ld (LWP %ld)",
1046 ptid_get_tid (ptid), ptid_get_lwp (lwp));
1048 xsnprintf (buf, sizeof (buf), "Thread %ld ",
1049 ptid_get_tid (ptid));
1051 else if (ptid_get_lwp (ptid) != 0)
1052 xsnprintf (buf, sizeof (buf), "LWP %ld ", ptid_get_lwp (ptid));
1054 xsnprintf (buf, sizeof (buf), "process %d ", ptid_get_pid (ptid));
1060 /* Worker bee for find_new_threads. Callback function that gets
1061 called once per user-level thread (i.e. not for LWP's). */
1064 sol_find_new_threads_callback (const td_thrhandle_t *th, void *ignored)
1070 retval = p_td_thr_get_info (th, &ti);
1071 if (retval != TD_OK)
1074 ptid = ptid_build (ptid_get_pid (inferior_ptid), 0, ti.ti_tid);
1075 if (!in_thread_list (ptid) || is_exited (ptid))
1082 sol_find_new_threads (struct target_ops *ops)
1084 struct target_ops *beneath = find_target_beneath (ops);
1086 /* First Find any new LWP's. */
1087 if (beneath->to_find_new_threads != NULL)
1088 beneath->to_find_new_threads (beneath);
1090 /* Then find any new user-level threads. */
1091 p_td_ta_thr_iter (main_ta, sol_find_new_threads_callback, (void *) 0,
1092 TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
1093 TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
1096 /* Worker bee for the "info sol-thread" command. This is a callback
1097 function that gets called once for each Solaris user-level thread
1098 (i.e. not for LWPs) in the inferior. Print anything interesting
1099 that we can think of. */
1102 info_cb (const td_thrhandle_t *th, void *s)
1107 ret = p_td_thr_get_info (th, &ti);
1110 printf_filtered ("%s thread #%d, lwp %d, ",
1111 ti.ti_type == TD_THR_SYSTEM ? "system" : "user ",
1112 ti.ti_tid, ti.ti_lid);
1113 switch (ti.ti_state)
1116 case TD_THR_UNKNOWN:
1117 printf_filtered ("<unknown state>");
1119 case TD_THR_STOPPED:
1120 printf_filtered ("(stopped)");
1123 printf_filtered ("(run) ");
1126 printf_filtered ("(active) ");
1129 printf_filtered ("(zombie) ");
1132 printf_filtered ("(asleep) ");
1134 case TD_THR_STOPPED_ASLEEP:
1135 printf_filtered ("(stopped asleep)");
1138 /* Print thr_create start function. */
1139 if (ti.ti_startfunc != 0)
1141 const struct bound_minimal_symbol msym
1142 = lookup_minimal_symbol_by_pc (ti.ti_startfunc);
1144 printf_filtered (" startfunc=%s",
1146 ? MSYMBOL_PRINT_NAME (msym.minsym)
1147 : paddress (target_gdbarch (), ti.ti_startfunc));
1150 /* If thread is asleep, print function that went to sleep. */
1151 if (ti.ti_state == TD_THR_SLEEP)
1153 const struct bound_minimal_symbol msym
1154 = lookup_minimal_symbol_by_pc (ti.ti_pc);
1156 printf_filtered (" sleepfunc=%s",
1158 ? MSYMBOL_PRINT_NAME (msym.minsym)
1159 : paddress (target_gdbarch (), ti.ti_pc));
1162 printf_filtered ("\n");
1165 warning (_("info sol-thread: failed to get info for thread."));
1170 /* List some state about each Solaris user-level thread in the
1174 info_solthreads (char *args, int from_tty)
1176 p_td_ta_thr_iter (main_ta, info_cb, args,
1177 TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
1178 TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
1181 /* Callback routine used to find a thread based on the TID part of
1185 thread_db_find_thread_from_tid (struct thread_info *thread, void *data)
1187 long *tid = (long *) data;
1189 if (ptid_get_tid (thread->ptid) == *tid)
1196 sol_get_ada_task_ptid (struct target_ops *self, long lwp, long thread)
1198 struct thread_info *thread_info =
1199 iterate_over_threads (thread_db_find_thread_from_tid, &thread);
1201 if (thread_info == NULL)
1203 /* The list of threads is probably not up to date. Find any
1204 thread that is missing from the list, and try again. */
1205 sol_find_new_threads (¤t_target);
1206 thread_info = iterate_over_threads (thread_db_find_thread_from_tid,
1210 gdb_assert (thread_info != NULL);
1212 return (thread_info->ptid);
1216 init_sol_thread_ops (void)
1218 sol_thread_ops.to_shortname = "solaris-threads";
1219 sol_thread_ops.to_longname = "Solaris threads and pthread.";
1220 sol_thread_ops.to_doc = "Solaris threads and pthread support.";
1221 sol_thread_ops.to_detach = sol_thread_detach;
1222 sol_thread_ops.to_resume = sol_thread_resume;
1223 sol_thread_ops.to_wait = sol_thread_wait;
1224 sol_thread_ops.to_fetch_registers = sol_thread_fetch_registers;
1225 sol_thread_ops.to_store_registers = sol_thread_store_registers;
1226 sol_thread_ops.to_xfer_partial = sol_thread_xfer_partial;
1227 sol_thread_ops.to_mourn_inferior = sol_thread_mourn_inferior;
1228 sol_thread_ops.to_thread_alive = sol_thread_alive;
1229 sol_thread_ops.to_pid_to_str = solaris_pid_to_str;
1230 sol_thread_ops.to_find_new_threads = sol_find_new_threads;
1231 sol_thread_ops.to_stratum = thread_stratum;
1232 sol_thread_ops.to_get_ada_task_ptid = sol_get_ada_task_ptid;
1233 sol_thread_ops.to_magic = OPS_MAGIC;
1236 /* Silence -Wmissing-prototypes. */
1237 extern void _initialize_sol_thread (void);
1240 _initialize_sol_thread (void)
1244 init_sol_thread_ops ();
1246 dlhandle = dlopen ("libthread_db.so.1", RTLD_NOW);
1250 #define resolve(X) \
1251 if (!(p_##X = dlsym (dlhandle, #X))) \
1255 resolve (td_ta_new);
1256 resolve (td_ta_delete);
1258 resolve (td_ta_get_ph);
1259 resolve (td_ta_get_nthreads);
1260 resolve (td_ta_tsd_iter);
1261 resolve (td_ta_thr_iter);
1262 resolve (td_thr_validate);
1263 resolve (td_thr_tsd);
1264 resolve (td_thr_get_info);
1265 resolve (td_thr_getfpregs);
1266 resolve (td_thr_getxregsize);
1267 resolve (td_thr_getxregs);
1268 resolve (td_thr_sigsetmask);
1269 resolve (td_thr_setprio);
1270 resolve (td_thr_setsigpending);
1271 resolve (td_thr_setfpregs);
1272 resolve (td_thr_setxregs);
1273 resolve (td_ta_map_id2thr);
1274 resolve (td_ta_map_lwp2thr);
1275 resolve (td_thr_getgregs);
1276 resolve (td_thr_setgregs);
1278 complete_target_initialization (&sol_thread_ops);
1280 add_cmd ("sol-threads", class_maintenance, info_solthreads,
1281 _("Show info on Solaris user threads."), &maintenanceinfolist);
1283 /* Hook into new_objfile notification. */
1284 observer_attach_new_objfile (sol_thread_new_objfile);
1288 fprintf_unfiltered (gdb_stderr, "\
1289 [GDB will not be able to debug user-mode threads: %s]\n", dlerror ());