Update
[gdb.git] / gdb / sol-thread.c
blob796065d382add0d03ba73604a833c3c855843f4d
1 /* Solaris threads debugging interface.
3 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
4 2007, 2008 Free Software Foundation, Inc.
6 This file is part of GDB.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
21 /* This module implements a sort of half target that sits between the
22 machine-independent parts of GDB and the /proc interface (procfs.c)
23 to provide access to the Solaris user-mode thread implementation.
25 Solaris threads are true user-mode threads, which are invoked via
26 the thr_* and pthread_* (native and POSIX respectivly) interfaces.
27 These are mostly implemented in user-space, with all thread context
28 kept in various structures that live in the user's heap. These
29 should not be confused with lightweight processes (LWPs), which are
30 implemented by the kernel, and scheduled without explicit
31 intervention by the process.
33 Just to confuse things a little, Solaris threads (both native and
34 POSIX) are actually implemented using LWPs. In general, there are
35 going to be more threads than LWPs. There is no fixed
36 correspondence between a thread and an LWP. When a thread wants to
37 run, it gets scheduled onto the first available LWP and can
38 therefore migrate from one LWP to another as time goes on. A
39 sleeping thread may not be associated with an LWP at all!
41 To make it possible to mess with threads, Sun provides a library
42 called libthread_db.so.1 (not to be confused with
43 libthread_db.so.0, which doesn't have a published interface). This
44 interface has an upper part, which it provides, and a lower part
45 which we provide. The upper part consists of the td_* routines,
46 which allow us to find all the threads, query their state, etc...
47 The lower part consists of all of the ps_*, which are used by the
48 td_* routines to read/write memory, manipulate LWPs, lookup
49 symbols, etc... The ps_* routines actually do most of their work
50 by calling functions in procfs.c. */
52 #include "defs.h"
53 #include <thread.h>
54 #include <proc_service.h>
55 #include <thread_db.h>
56 #include "gdbthread.h"
57 #include "target.h"
58 #include "inferior.h"
59 #include <fcntl.h>
60 #include "gdb_stat.h"
61 #include <dlfcn.h>
62 #include "gdbcmd.h"
63 #include "gdbcore.h"
64 #include "regcache.h"
65 #include "solib.h"
66 #include "symfile.h"
67 #include "observer.h"
69 #include "gdb_string.h"
71 extern struct target_ops sol_thread_ops; /* Forward declaration */
72 extern struct target_ops sol_core_ops; /* Forward declaration */
74 /* place to store core_ops before we overwrite it */
75 static struct target_ops orig_core_ops;
77 struct target_ops sol_thread_ops;
78 struct target_ops sol_core_ops;
80 extern int procfs_suppress_run;
81 extern struct target_ops procfs_ops; /* target vector for procfs.c */
82 extern struct target_ops core_ops; /* target vector for corelow.c */
83 extern char *procfs_pid_to_str (ptid_t ptid);
85 /* Prototypes for supply_gregset etc. */
86 #include "gregset.h"
88 /* This struct is defined by us, but mainly used for the proc_service
89 interface. We don't have much use for it, except as a handy place
90 to get a real PID for memory accesses. */
92 struct ps_prochandle
94 ptid_t ptid;
97 struct string_map
99 int num;
100 char *str;
103 static struct ps_prochandle main_ph;
104 static td_thragent_t *main_ta;
105 static int sol_thread_active = 0;
107 static void sol_thread_resume (ptid_t ptid, int step, enum target_signal signo);
108 static int sol_thread_alive (ptid_t ptid);
109 static void sol_core_close (int quitting);
111 static void init_sol_thread_ops (void);
112 static void init_sol_core_ops (void);
114 /* Default definitions: These must be defined in tm.h if they are to
115 be shared with a process module such as procfs. */
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)
121 #define is_lwp(ptid) (GET_LWP (ptid) != 0)
122 #define is_thread(ptid) (GET_THREAD (ptid) != 0)
124 #define BUILD_LWP(lwp, pid) ptid_build (pid, lwp, 0)
125 #define BUILD_THREAD(tid, pid) ptid_build (pid, 0, tid)
127 /* Pointers to routines from libthread_db resolved by dlopen(). */
129 static void (*p_td_log)(const int on_off);
130 static td_err_e (*p_td_ta_new)(const struct ps_prochandle *ph_p,
131 td_thragent_t **ta_pp);
132 static td_err_e (*p_td_ta_delete)(td_thragent_t *ta_p);
133 static td_err_e (*p_td_init)(void);
134 static td_err_e (*p_td_ta_get_ph)(const td_thragent_t *ta_p,
135 struct ps_prochandle **ph_pp);
136 static td_err_e (*p_td_ta_get_nthreads)(const td_thragent_t *ta_p,
137 int *nthread_p);
138 static td_err_e (*p_td_ta_tsd_iter)(const td_thragent_t *ta_p,
139 td_key_iter_f *cb, void *cbdata_p);
140 static td_err_e (*p_td_ta_thr_iter)(const td_thragent_t *ta_p,
141 td_thr_iter_f *cb, void *cbdata_p,
142 td_thr_state_e state, int ti_pri,
143 sigset_t *ti_sigmask_p,
144 unsigned ti_user_flags);
145 static td_err_e (*p_td_thr_validate)(const td_thrhandle_t *th_p);
146 static td_err_e (*p_td_thr_tsd)(const td_thrhandle_t * th_p,
147 const thread_key_t key, void **data_pp);
148 static td_err_e (*p_td_thr_get_info)(const td_thrhandle_t *th_p,
149 td_thrinfo_t *ti_p);
150 static td_err_e (*p_td_thr_getfpregs)(const td_thrhandle_t *th_p,
151 prfpregset_t *fpregset);
152 static td_err_e (*p_td_thr_getxregsize)(const td_thrhandle_t *th_p,
153 int *xregsize);
154 static td_err_e (*p_td_thr_getxregs)(const td_thrhandle_t *th_p,
155 const caddr_t xregset);
156 static td_err_e (*p_td_thr_sigsetmask)(const td_thrhandle_t *th_p,
157 const sigset_t ti_sigmask);
158 static td_err_e (*p_td_thr_setprio)(const td_thrhandle_t *th_p,
159 const int ti_pri);
160 static td_err_e (*p_td_thr_setsigpending)(const td_thrhandle_t *th_p,
161 const uchar_t ti_pending_flag,
162 const sigset_t ti_pending);
163 static td_err_e (*p_td_thr_setfpregs)(const td_thrhandle_t *th_p,
164 const prfpregset_t *fpregset);
165 static td_err_e (*p_td_thr_setxregs)(const td_thrhandle_t *th_p,
166 const caddr_t xregset);
167 static td_err_e (*p_td_ta_map_id2thr)(const td_thragent_t *ta_p,
168 thread_t tid,
169 td_thrhandle_t *th_p);
170 static td_err_e (*p_td_ta_map_lwp2thr)(const td_thragent_t *ta_p,
171 lwpid_t lwpid,
172 td_thrhandle_t *th_p);
173 static td_err_e (*p_td_thr_getgregs)(const td_thrhandle_t *th_p,
174 prgregset_t regset);
175 static td_err_e (*p_td_thr_setgregs)(const td_thrhandle_t *th_p,
176 const prgregset_t regset);
179 /* Return the libthread_db error string associated with ERRCODE. If
180 ERRCODE is unknown, return an appropriate message. */
182 static char *
183 td_err_string (td_err_e errcode)
185 static struct string_map td_err_table[] =
187 { TD_OK, "generic \"call succeeded\"" },
188 { TD_ERR, "generic error." },
189 { TD_NOTHR, "no thread can be found to satisfy query" },
190 { TD_NOSV, "no synch. variable can be found to satisfy query" },
191 { TD_NOLWP, "no lwp can be found to satisfy query" },
192 { TD_BADPH, "invalid process handle" },
193 { TD_BADTH, "invalid thread handle" },
194 { TD_BADSH, "invalid synchronization handle" },
195 { TD_BADTA, "invalid thread agent" },
196 { TD_BADKEY, "invalid key" },
197 { TD_NOMSG, "td_thr_event_getmsg() called when there was no message" },
198 { TD_NOFPREGS, "FPU register set not available for given thread" },
199 { TD_NOLIBTHREAD, "application not linked with libthread" },
200 { TD_NOEVENT, "requested event is not supported" },
201 { TD_NOCAPAB, "capability not available" },
202 { TD_DBERR, "Debugger service failed" },
203 { TD_NOAPLIC, "Operation not applicable to" },
204 { TD_NOTSD, "No thread specific data for this thread" },
205 { TD_MALLOC, "Malloc failed" },
206 { TD_PARTIALREG, "Only part of register set was written/read" },
207 { TD_NOXREGS, "X register set not available for given thread" }
209 const int td_err_size = sizeof td_err_table / sizeof (struct string_map);
210 int i;
211 static char buf[50];
213 for (i = 0; i < td_err_size; i++)
214 if (td_err_table[i].num == errcode)
215 return td_err_table[i].str;
217 sprintf (buf, "Unknown libthread_db error code: %d", errcode);
219 return buf;
222 /* Return the the libthread_db state string assicoated with STATECODE.
223 If STATECODE is unknown, return an appropriate message. */
225 static char *
226 td_state_string (td_thr_state_e statecode)
228 static struct string_map td_thr_state_table[] =
230 { TD_THR_ANY_STATE, "any state" },
231 { TD_THR_UNKNOWN, "unknown" },
232 { TD_THR_STOPPED, "stopped" },
233 { TD_THR_RUN, "run" },
234 { TD_THR_ACTIVE, "active" },
235 { TD_THR_ZOMBIE, "zombie" },
236 { TD_THR_SLEEP, "sleep" },
237 { TD_THR_STOPPED_ASLEEP, "stopped asleep" }
239 const int td_thr_state_table_size =
240 sizeof td_thr_state_table / sizeof (struct string_map);
241 int i;
242 static char buf[50];
244 for (i = 0; i < td_thr_state_table_size; i++)
245 if (td_thr_state_table[i].num == statecode)
246 return td_thr_state_table[i].str;
248 sprintf (buf, "Unknown libthread_db state code: %d", statecode);
250 return buf;
254 /* Convert a POSIX or Solaris thread ID into a LWP ID. If THREAD_ID
255 doesn't exist, that's an error. If it's an inactive thread, return
256 DEFAULT_LPW.
258 NOTE: This function probably shouldn't call error(). */
260 static ptid_t
261 thread_to_lwp (ptid_t thread_id, int default_lwp)
263 td_thrinfo_t ti;
264 td_thrhandle_t th;
265 td_err_e val;
267 if (is_lwp (thread_id))
268 return thread_id; /* It's already an LWP ID. */
270 /* It's a thread. Convert to LWP. */
272 val = p_td_ta_map_id2thr (main_ta, GET_THREAD (thread_id), &th);
273 if (val == TD_NOTHR)
274 return pid_to_ptid (-1); /* Thread must have terminated. */
275 else if (val != TD_OK)
276 error (_("thread_to_lwp: td_ta_map_id2thr %s"), td_err_string (val));
278 val = p_td_thr_get_info (&th, &ti);
279 if (val == TD_NOTHR)
280 return pid_to_ptid (-1); /* Thread must have terminated. */
281 else if (val != TD_OK)
282 error (_("thread_to_lwp: td_thr_get_info: %s"), td_err_string (val));
284 if (ti.ti_state != TD_THR_ACTIVE)
286 if (default_lwp != -1)
287 return pid_to_ptid (default_lwp);
288 error (_("thread_to_lwp: thread state not active: %s"),
289 td_state_string (ti.ti_state));
292 return BUILD_LWP (ti.ti_lid, PIDGET (thread_id));
295 /* Convert an LWP ID into a POSIX or Solaris thread ID. If LWP_ID
296 doesn't exists, that's an error.
298 NOTE: This function probably shouldn't call error(). */
300 static ptid_t
301 lwp_to_thread (ptid_t lwp)
303 td_thrinfo_t ti;
304 td_thrhandle_t th;
305 td_err_e val;
307 if (is_thread (lwp))
308 return lwp; /* It's already a thread ID. */
310 /* It's an LWP. Convert it to a thread ID. */
312 if (!sol_thread_alive (lwp))
313 return pid_to_ptid (-1); /* Must be a defunct LPW. */
315 val = p_td_ta_map_lwp2thr (main_ta, GET_LWP (lwp), &th);
316 if (val == TD_NOTHR)
317 return pid_to_ptid (-1); /* Thread must have terminated. */
318 else if (val != TD_OK)
319 error (_("lwp_to_thread: td_ta_map_lwp2thr: %s."), td_err_string (val));
321 val = p_td_thr_validate (&th);
322 if (val == TD_NOTHR)
323 return lwp; /* Unknown to libthread; just return LPW, */
324 else if (val != TD_OK)
325 error (_("lwp_to_thread: td_thr_validate: %s."), td_err_string (val));
327 val = p_td_thr_get_info (&th, &ti);
328 if (val == TD_NOTHR)
329 return pid_to_ptid (-1); /* Thread must have terminated. */
330 else if (val != TD_OK)
331 error (_("lwp_to_thread: td_thr_get_info: %s."), td_err_string (val));
333 return BUILD_THREAD (ti.ti_tid, PIDGET (lwp));
337 /* Most target vector functions from here on actually just pass
338 through to procfs.c, as they don't need to do anything specific for
339 threads. */
341 static void
342 sol_thread_open (char *arg, int from_tty)
344 procfs_ops.to_open (arg, from_tty);
347 /* Attach to process PID, then initialize for debugging it and wait
348 for the trace-trap that results from attaching. */
350 static void
351 sol_thread_attach (char *args, int from_tty)
353 procfs_ops.to_attach (args, from_tty);
355 /* Must get symbols from shared libraries before libthread_db can run! */
356 solib_add (NULL, from_tty, (struct target_ops *) 0, auto_solib_add);
358 if (sol_thread_active)
360 printf_filtered ("sol-thread active.\n");
361 main_ph.ptid = inferior_ptid; /* Save for xfer_memory. */
362 push_target (&sol_thread_ops);
363 inferior_ptid = lwp_to_thread (inferior_ptid);
364 if (PIDGET (inferior_ptid) == -1)
365 inferior_ptid = main_ph.ptid;
366 else
367 add_thread (inferior_ptid);
370 /* FIXME: Might want to iterate over all the threads and register
371 them. */
374 /* Take a program previously attached to and detaches it. The program
375 resumes execution and will no longer stop on signals, etc. We'd
376 better not have left any breakpoints in the program or it'll die
377 when it hits one. For this to work, it may be necessary for the
378 process to have been previously attached. It *might* work if the
379 program was started via the normal ptrace (PTRACE_TRACEME). */
381 static void
382 sol_thread_detach (char *args, int from_tty)
384 inferior_ptid = pid_to_ptid (PIDGET (main_ph.ptid));
385 unpush_target (&sol_thread_ops);
386 procfs_ops.to_detach (args, from_tty);
389 /* Resume execution of process PTID. If STEP is nozero, then just
390 single step it. If SIGNAL is nonzero, restart it with that signal
391 activated. We may have to convert PTID from a thread ID to an LWP
392 ID for procfs. */
394 static void
395 sol_thread_resume (ptid_t ptid, int step, enum target_signal signo)
397 struct cleanup *old_chain;
399 old_chain = save_inferior_ptid ();
401 inferior_ptid = thread_to_lwp (inferior_ptid, PIDGET (main_ph.ptid));
402 if (PIDGET (inferior_ptid) == -1)
403 inferior_ptid = procfs_first_available ();
405 if (PIDGET (ptid) != -1)
407 ptid_t save_ptid = ptid;
409 ptid = thread_to_lwp (ptid, -2);
410 if (PIDGET (ptid) == -2) /* Inactive thread. */
411 error (_("This version of Solaris can't start inactive threads."));
412 if (info_verbose && PIDGET (ptid) == -1)
413 warning (_("Specified thread %ld seems to have terminated"),
414 GET_THREAD (save_ptid));
417 procfs_ops.to_resume (ptid, step, signo);
419 do_cleanups (old_chain);
422 /* Wait for any threads to stop. We may have to convert PIID from a
423 thread ID to an LWP ID, and vice versa on the way out. */
425 static ptid_t
426 sol_thread_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
428 ptid_t rtnval;
429 ptid_t save_ptid;
430 struct cleanup *old_chain;
432 save_ptid = inferior_ptid;
433 old_chain = save_inferior_ptid ();
435 inferior_ptid = thread_to_lwp (inferior_ptid, PIDGET (main_ph.ptid));
436 if (PIDGET (inferior_ptid) == -1)
437 inferior_ptid = procfs_first_available ();
439 if (PIDGET (ptid) != -1)
441 ptid_t save_ptid = ptid;
443 ptid = thread_to_lwp (ptid, -2);
444 if (PIDGET (ptid) == -2) /* Inactive thread. */
445 error (_("This version of Solaris can't start inactive threads."));
446 if (info_verbose && PIDGET (ptid) == -1)
447 warning (_("Specified thread %ld seems to have terminated"),
448 GET_THREAD (save_ptid));
451 rtnval = procfs_ops.to_wait (ptid, ourstatus);
453 if (ourstatus->kind != TARGET_WAITKIND_EXITED)
455 /* Map the LWP of interest back to the appropriate thread ID. */
456 rtnval = lwp_to_thread (rtnval);
457 if (PIDGET (rtnval) == -1)
458 rtnval = save_ptid;
460 /* See if we have a new thread. */
461 if (is_thread (rtnval)
462 && !ptid_equal (rtnval, save_ptid)
463 && !in_thread_list (rtnval))
464 add_thread (rtnval);
467 /* During process initialization, we may get here without the thread
468 package being initialized, since that can only happen after we've
469 found the shared libs. */
471 do_cleanups (old_chain);
473 return rtnval;
476 static void
477 sol_thread_fetch_registers (struct regcache *regcache, int regnum)
479 thread_t thread;
480 td_thrhandle_t thandle;
481 td_err_e val;
482 prgregset_t gregset;
483 prfpregset_t fpregset;
484 gdb_gregset_t *gregset_p = &gregset;
485 gdb_fpregset_t *fpregset_p = &fpregset;
487 #if 0
488 int xregsize;
489 caddr_t xregset;
490 #endif
492 if (!is_thread (inferior_ptid))
494 /* It's an LWP; pass the request on to procfs. */
495 if (target_has_execution)
496 procfs_ops.to_fetch_registers (regcache, regnum);
497 else
498 orig_core_ops.to_fetch_registers (regcache, regnum);
499 return;
502 /* Solaris thread: convert INFERIOR_PTID into a td_thrhandle_t. */
503 thread = GET_THREAD (inferior_ptid);
504 if (thread == 0)
505 error (_("sol_thread_fetch_registers: thread == 0"));
507 val = p_td_ta_map_id2thr (main_ta, thread, &thandle);
508 if (val != TD_OK)
509 error (_("sol_thread_fetch_registers: td_ta_map_id2thr: %s"),
510 td_err_string (val));
512 /* Get the general-purpose registers. */
514 val = p_td_thr_getgregs (&thandle, gregset);
515 if (val != TD_OK && val != TD_PARTIALREG)
516 error (_("sol_thread_fetch_registers: td_thr_getgregs %s"),
517 td_err_string (val));
519 /* For SPARC, TD_PARTIALREG means that only %i0...%i7, %l0..%l7, %pc
520 and %sp are saved (by a thread context switch). */
522 /* And, now the floating-point registers. */
524 val = p_td_thr_getfpregs (&thandle, &fpregset);
525 if (val != TD_OK && val != TD_NOFPREGS)
526 error (_("sol_thread_fetch_registers: td_thr_getfpregs %s"),
527 td_err_string (val));
529 /* Note that we must call supply_gregset and supply_fpregset *after*
530 calling the td routines because the td routines call ps_lget*
531 which affect the values stored in the registers array. */
533 supply_gregset (regcache, (const gdb_gregset_t *) gregset_p);
534 supply_fpregset (regcache, (const gdb_fpregset_t *) fpregset_p);
536 #if 0
537 /* FIXME: libthread_db doesn't seem to handle this right. */
538 val = td_thr_getxregsize (&thandle, &xregsize);
539 if (val != TD_OK && val != TD_NOXREGS)
540 error (_("sol_thread_fetch_registers: td_thr_getxregsize %s"),
541 td_err_string (val));
543 if (val == TD_OK)
545 xregset = alloca (xregsize);
546 val = td_thr_getxregs (&thandle, xregset);
547 if (val != TD_OK)
548 error (_("sol_thread_fetch_registers: td_thr_getxregs %s"),
549 td_err_string (val));
551 #endif
554 static void
555 sol_thread_store_registers (struct regcache *regcache, int regnum)
557 thread_t thread;
558 td_thrhandle_t thandle;
559 td_err_e val;
560 prgregset_t gregset;
561 prfpregset_t fpregset;
562 #if 0
563 int xregsize;
564 caddr_t xregset;
565 #endif
567 if (!is_thread (inferior_ptid))
569 /* It's an LWP; pass the request on to procfs.c. */
570 procfs_ops.to_store_registers (regcache, regnum);
571 return;
574 /* Solaris thread: convert INFERIOR_PTID into a td_thrhandle_t. */
575 thread = GET_THREAD (inferior_ptid);
577 val = p_td_ta_map_id2thr (main_ta, thread, &thandle);
578 if (val != TD_OK)
579 error (_("sol_thread_store_registers: td_ta_map_id2thr %s"),
580 td_err_string (val));
582 if (regnum != -1)
584 /* Not writing all the registers. */
585 char old_value[MAX_REGISTER_SIZE];
587 /* Save new register value. */
588 regcache_raw_collect (regcache, regnum, old_value);
590 val = p_td_thr_getgregs (&thandle, gregset);
591 if (val != TD_OK)
592 error (_("sol_thread_store_registers: td_thr_getgregs %s"),
593 td_err_string (val));
594 val = p_td_thr_getfpregs (&thandle, &fpregset);
595 if (val != TD_OK)
596 error (_("sol_thread_store_registers: td_thr_getfpregs %s"),
597 td_err_string (val));
599 /* Restore new register value. */
600 regcache_raw_supply (regcache, regnum, old_value);
602 #if 0
603 /* FIXME: libthread_db doesn't seem to handle this right. */
604 val = td_thr_getxregsize (&thandle, &xregsize);
605 if (val != TD_OK && val != TD_NOXREGS)
606 error (_("sol_thread_store_registers: td_thr_getxregsize %s"),
607 td_err_string (val));
609 if (val == TD_OK)
611 xregset = alloca (xregsize);
612 val = td_thr_getxregs (&thandle, xregset);
613 if (val != TD_OK)
614 error (_("sol_thread_store_registers: td_thr_getxregs %s"),
615 td_err_string (val));
617 #endif
620 fill_gregset (regcache, (gdb_gregset_t *) &gregset, regnum);
621 fill_fpregset (regcache, (gdb_fpregset_t *) &fpregset, regnum);
623 val = p_td_thr_setgregs (&thandle, gregset);
624 if (val != TD_OK)
625 error (_("sol_thread_store_registers: td_thr_setgregs %s"),
626 td_err_string (val));
627 val = p_td_thr_setfpregs (&thandle, &fpregset);
628 if (val != TD_OK)
629 error (_("sol_thread_store_registers: td_thr_setfpregs %s"),
630 td_err_string (val));
632 #if 0
633 /* FIXME: libthread_db doesn't seem to handle this right. */
634 val = td_thr_getxregsize (&thandle, &xregsize);
635 if (val != TD_OK && val != TD_NOXREGS)
636 error (_("sol_thread_store_registers: td_thr_getxregsize %s"),
637 td_err_string (val));
639 /* ??? Should probably do something about writing the xregs here,
640 but what are they? */
641 #endif
644 /* Get ready to modify the registers array. On machines which store
645 individual registers, this doesn't need to do anything. On
646 machines which store all the registers in one fell swoop, this
647 makes sure that registers contains all the registers from the
648 program being debugged. */
650 static void
651 sol_thread_prepare_to_store (struct regcache *regcache)
653 procfs_ops.to_prepare_to_store (regcache);
656 /* Transfer LEN bytes between GDB address MYADDR and target address
657 MEMADDR. If DOWRITE is non-zero, transfer them to the target,
658 otherwise transfer them from the target. TARGET is unused.
660 Returns the number of bytes transferred. */
662 static int
663 sol_thread_xfer_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len,
664 int dowrite, struct mem_attrib *attrib,
665 struct target_ops *target)
667 int retval;
668 struct cleanup *old_chain;
670 old_chain = save_inferior_ptid ();
672 if (is_thread (inferior_ptid) || !target_thread_alive (inferior_ptid))
674 /* It's either a thread or an LWP that isn't alive. Any live
675 LWP will do so use the first available.
677 NOTE: We don't need to call switch_to_thread; we're just
678 reading memory. */
679 inferior_ptid = procfs_first_available ();
682 if (target_has_execution)
683 retval = procfs_ops.deprecated_xfer_memory (memaddr, myaddr, len,
684 dowrite, attrib, target);
685 else
686 retval = orig_core_ops.deprecated_xfer_memory (memaddr, myaddr, len,
687 dowrite, attrib, target);
689 do_cleanups (old_chain);
691 return retval;
694 /* Perform partial transfers on OBJECT. See target_read_partial and
695 target_write_partial for details of each variant. One, and only
696 one, of readbuf or writebuf must be non-NULL. */
698 static LONGEST
699 sol_thread_xfer_partial (struct target_ops *ops, enum target_object object,
700 const char *annex, gdb_byte *readbuf,
701 const gdb_byte *writebuf,
702 ULONGEST offset, LONGEST len)
704 int retval;
705 struct cleanup *old_chain;
707 old_chain = save_inferior_ptid ();
709 if (is_thread (inferior_ptid) || !target_thread_alive (inferior_ptid))
711 /* It's either a thread or an LWP that isn't alive. Any live
712 LWP will do so use the first available.
714 NOTE: We don't need to call switch_to_thread; we're just
715 reading memory. */
716 inferior_ptid = procfs_first_available ();
719 if (target_has_execution)
720 retval = procfs_ops.to_xfer_partial (ops, object, annex,
721 readbuf, writebuf, offset, len);
722 else
723 retval = orig_core_ops.to_xfer_partial (ops, object, annex,
724 readbuf, writebuf, offset, len);
726 do_cleanups (old_chain);
728 return retval;
731 /* Print status information about what we're accessing. */
733 static void
734 sol_thread_files_info (struct target_ops *ignore)
736 procfs_ops.to_files_info (ignore);
739 static void
740 sol_thread_kill_inferior (void)
742 procfs_ops.to_kill ();
745 static void
746 sol_thread_notice_signals (ptid_t ptid)
748 procfs_ops.to_notice_signals (pid_to_ptid (PIDGET (ptid)));
751 /* Fork an inferior process, and start debugging it with /proc. */
753 static void
754 sol_thread_create_inferior (char *exec_file, char *allargs, char **env,
755 int from_tty)
757 procfs_ops.to_create_inferior (exec_file, allargs, env, from_tty);
759 if (sol_thread_active && !ptid_equal (inferior_ptid, null_ptid))
761 /* Save for xfer_memory. */
762 main_ph.ptid = inferior_ptid;
764 push_target (&sol_thread_ops);
766 inferior_ptid = lwp_to_thread (inferior_ptid);
767 if (PIDGET (inferior_ptid) == -1)
768 inferior_ptid = main_ph.ptid;
770 if (!in_thread_list (inferior_ptid))
771 add_thread (inferior_ptid);
775 /* This routine is called whenever a new symbol table is read in, or
776 when all symbol tables are removed. libthread_db can only be
777 initialized when it finds the right variables in libthread.so.
778 Since it's a shared library, those variables don't show up until
779 the library gets mapped and the symbol table is read in. */
781 static void
782 sol_thread_new_objfile (struct objfile *objfile)
784 td_err_e val;
786 if (!objfile)
788 sol_thread_active = 0;
789 return;
792 /* Don't do anything if init failed to resolve the libthread_db
793 library. */
794 if (!procfs_suppress_run)
795 return;
797 /* Now, initialize libthread_db. This needs to be done after the
798 shared libraries are located because it needs information from
799 the user's thread library. */
801 val = p_td_init ();
802 if (val != TD_OK)
804 warning (_("sol_thread_new_objfile: td_init: %s"), td_err_string (val));
805 return;
808 val = p_td_ta_new (&main_ph, &main_ta);
809 if (val == TD_NOLIBTHREAD)
810 return;
811 else if (val != TD_OK)
813 warning (_("sol_thread_new_objfile: td_ta_new: %s"), td_err_string (val));
814 return;
817 sol_thread_active = 1;
820 /* Clean up after the inferior dies. */
822 static void
823 sol_thread_mourn_inferior (void)
825 unpush_target (&sol_thread_ops);
826 procfs_ops.to_mourn_inferior ();
829 /* Mark our target-struct as eligible for stray "run" and "attach"
830 commands. */
832 static int
833 sol_thread_can_run (void)
835 return procfs_suppress_run;
840 LOCAL FUNCTION
842 sol_thread_alive - test thread for "aliveness"
844 SYNOPSIS
846 static bool sol_thread_alive (ptid_t ptid);
848 DESCRIPTION
850 returns true if thread still active in inferior.
854 /* Return true if PTID is still active in the inferior. */
856 static int
857 sol_thread_alive (ptid_t ptid)
859 if (is_thread (ptid))
861 /* It's a (user-level) thread. */
862 td_err_e val;
863 td_thrhandle_t th;
864 int pid;
866 pid = GET_THREAD (ptid);
867 if ((val = p_td_ta_map_id2thr (main_ta, pid, &th)) != TD_OK)
868 return 0; /* Thread not found. */
869 if ((val = p_td_thr_validate (&th)) != TD_OK)
870 return 0; /* Thread not valid. */
871 return 1; /* Known thread. */
873 else
875 /* It's an LPW; pass the request on to procfs. */
876 if (target_has_execution)
877 return procfs_ops.to_thread_alive (ptid);
878 else
879 return orig_core_ops.to_thread_alive (ptid);
883 static void
884 sol_thread_stop (void)
886 procfs_ops.to_stop ();
889 /* These routines implement the lower half of the thread_db interface,
890 i.e. the ps_* routines. */
892 /* Various versions of <proc_service.h> have slightly different
893 function prototypes. In particular, we have
895 NEWER OLDER
896 struct ps_prochandle * const struct ps_prochandle *
897 void* char*
898 const void* char*
899 int size_t
901 Which one you have depends on the Solaris version and what patches
902 you've applied. On the theory that there are only two major
903 variants, we have configure check the prototype of ps_pdwrite (),
904 and use that info to make appropriate typedefs here. */
906 #ifdef PROC_SERVICE_IS_OLD
907 typedef const struct ps_prochandle *gdb_ps_prochandle_t;
908 typedef char *gdb_ps_read_buf_t;
909 typedef char *gdb_ps_write_buf_t;
910 typedef int gdb_ps_size_t;
911 typedef psaddr_t gdb_ps_addr_t;
912 #else
913 typedef struct ps_prochandle *gdb_ps_prochandle_t;
914 typedef void *gdb_ps_read_buf_t;
915 typedef const void *gdb_ps_write_buf_t;
916 typedef size_t gdb_ps_size_t;
917 typedef psaddr_t gdb_ps_addr_t;
918 #endif
920 /* The next four routines are called by libthread_db to tell us to
921 stop and stop a particular process or lwp. Since GDB ensures that
922 these are all stopped by the time we call anything in thread_db,
923 these routines need to do nothing. */
925 /* Process stop. */
927 ps_err_e
928 ps_pstop (gdb_ps_prochandle_t ph)
930 return PS_OK;
933 /* Process continue. */
935 ps_err_e
936 ps_pcontinue (gdb_ps_prochandle_t ph)
938 return PS_OK;
941 /* LWP stop. */
943 ps_err_e
944 ps_lstop (gdb_ps_prochandle_t ph, lwpid_t lwpid)
946 return PS_OK;
949 /* LWP continue. */
951 ps_err_e
952 ps_lcontinue (gdb_ps_prochandle_t ph, lwpid_t lwpid)
954 return PS_OK;
957 /* Looks up the symbol LD_SYMBOL_NAME in the debugger's symbol table. */
959 ps_err_e
960 ps_pglobal_lookup (gdb_ps_prochandle_t ph, const char *ld_object_name,
961 const char *ld_symbol_name, gdb_ps_addr_t *ld_symbol_addr)
963 struct minimal_symbol *ms;
965 ms = lookup_minimal_symbol (ld_symbol_name, NULL, NULL);
966 if (!ms)
967 return PS_NOSYM;
969 *ld_symbol_addr = SYMBOL_VALUE_ADDRESS (ms);
970 return PS_OK;
973 /* Common routine for reading and writing memory. */
975 static ps_err_e
976 rw_common (int dowrite, const struct ps_prochandle *ph, gdb_ps_addr_t addr,
977 char *buf, int size)
979 struct cleanup *old_chain;
981 old_chain = save_inferior_ptid ();
983 if (is_thread (inferior_ptid) || !target_thread_alive (inferior_ptid))
985 /* It's either a thread or an LWP that isn't alive. Any live
986 LWP will do so use the first available.
988 NOTE: We don't need to call switch_to_thread; we're just
989 reading memory. */
990 inferior_ptid = procfs_first_available ();
993 #if defined (__sparcv9)
994 /* For Sparc64 cross Sparc32, make sure the address has not been
995 accidentally sign-extended (or whatever) to beyond 32 bits. */
996 if (bfd_get_arch_size (exec_bfd) == 32)
997 addr &= 0xffffffff;
998 #endif
1000 while (size > 0)
1002 int cc;
1004 /* FIXME: passing 0 as attrib argument. */
1005 if (target_has_execution)
1006 cc = procfs_ops.deprecated_xfer_memory (addr, buf, size,
1007 dowrite, 0, &procfs_ops);
1008 else
1009 cc = orig_core_ops.deprecated_xfer_memory (addr, buf, size,
1010 dowrite, 0, &core_ops);
1012 if (cc < 0)
1014 if (dowrite == 0)
1015 print_sys_errmsg ("rw_common (): read", errno);
1016 else
1017 print_sys_errmsg ("rw_common (): write", errno);
1019 do_cleanups (old_chain);
1021 return PS_ERR;
1023 else if (cc == 0)
1025 if (dowrite == 0)
1026 warning (_("rw_common (): unable to read at addr 0x%lx"),
1027 (long) addr);
1028 else
1029 warning (_("rw_common (): unable to write at addr 0x%lx"),
1030 (long) addr);
1032 do_cleanups (old_chain);
1034 return PS_ERR;
1037 size -= cc;
1038 buf += cc;
1041 do_cleanups (old_chain);
1043 return PS_OK;
1046 /* Copies SIZE bytes from target process .data segment to debugger memory. */
1048 ps_err_e
1049 ps_pdread (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
1050 gdb_ps_read_buf_t buf, gdb_ps_size_t size)
1052 return rw_common (0, ph, addr, buf, size);
1055 /* Copies SIZE bytes from debugger memory .data segment to target process. */
1057 ps_err_e
1058 ps_pdwrite (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
1059 gdb_ps_write_buf_t buf, gdb_ps_size_t size)
1061 return rw_common (1, ph, addr, (char *) buf, size);
1064 /* Copies SIZE bytes from target process .text segment to debugger memory. */
1066 ps_err_e
1067 ps_ptread (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
1068 gdb_ps_read_buf_t buf, gdb_ps_size_t size)
1070 return rw_common (0, ph, addr, buf, size);
1073 /* Copies SIZE bytes from debugger memory .text segment to target process. */
1075 ps_err_e
1076 ps_ptwrite (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
1077 gdb_ps_write_buf_t buf, gdb_ps_size_t size)
1079 return rw_common (1, ph, addr, (char *) buf, size);
1082 /* Get general-purpose registers for LWP. */
1084 ps_err_e
1085 ps_lgetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, prgregset_t gregset)
1087 struct cleanup *old_chain;
1088 struct regcache *regcache;
1090 old_chain = save_inferior_ptid ();
1092 inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
1093 regcache = get_thread_regcache (inferior_ptid);
1095 if (target_has_execution)
1096 procfs_ops.to_fetch_registers (regcache, -1);
1097 else
1098 orig_core_ops.to_fetch_registers (regcache, -1);
1099 fill_gregset (regcache, (gdb_gregset_t *) gregset, -1);
1101 do_cleanups (old_chain);
1103 return PS_OK;
1106 /* Set general-purpose registers for LWP. */
1108 ps_err_e
1109 ps_lsetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
1110 const prgregset_t gregset)
1112 struct cleanup *old_chain;
1113 struct regcache *regcache;
1115 old_chain = save_inferior_ptid ();
1117 inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
1118 regcache = get_thread_regcache (inferior_ptid);
1120 supply_gregset (regcache, (const gdb_gregset_t *) gregset);
1121 if (target_has_execution)
1122 procfs_ops.to_store_registers (regcache, -1);
1123 else
1124 orig_core_ops.to_store_registers (regcache, -1);
1126 do_cleanups (old_chain);
1128 return PS_OK;
1131 /* Log a message (sends to gdb_stderr). */
1133 void
1134 ps_plog (const char *fmt, ...)
1136 va_list args;
1138 va_start (args, fmt);
1140 vfprintf_filtered (gdb_stderr, fmt, args);
1143 /* Get size of extra register set. Currently a noop. */
1145 ps_err_e
1146 ps_lgetxregsize (gdb_ps_prochandle_t ph, lwpid_t lwpid, int *xregsize)
1148 #if 0
1149 int lwp_fd;
1150 int regsize;
1151 ps_err_e val;
1153 val = get_lwp_fd (ph, lwpid, &lwp_fd);
1154 if (val != PS_OK)
1155 return val;
1157 if (ioctl (lwp_fd, PIOCGXREGSIZE, &regsize))
1159 if (errno == EINVAL)
1160 return PS_NOFREGS; /* XXX Wrong code, but this is the closest
1161 thing in proc_service.h */
1163 print_sys_errmsg ("ps_lgetxregsize (): PIOCGXREGSIZE", errno);
1164 return PS_ERR;
1166 #endif
1168 return PS_OK;
1171 /* Get extra register set. Currently a noop. */
1173 ps_err_e
1174 ps_lgetxregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, caddr_t xregset)
1176 #if 0
1177 int lwp_fd;
1178 ps_err_e val;
1180 val = get_lwp_fd (ph, lwpid, &lwp_fd);
1181 if (val != PS_OK)
1182 return val;
1184 if (ioctl (lwp_fd, PIOCGXREG, xregset))
1186 print_sys_errmsg ("ps_lgetxregs (): PIOCGXREG", errno);
1187 return PS_ERR;
1189 #endif
1191 return PS_OK;
1194 /* Set extra register set. Currently a noop. */
1196 ps_err_e
1197 ps_lsetxregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, caddr_t xregset)
1199 #if 0
1200 int lwp_fd;
1201 ps_err_e val;
1203 val = get_lwp_fd (ph, lwpid, &lwp_fd);
1204 if (val != PS_OK)
1205 return val;
1207 if (ioctl (lwp_fd, PIOCSXREG, xregset))
1209 print_sys_errmsg ("ps_lsetxregs (): PIOCSXREG", errno);
1210 return PS_ERR;
1212 #endif
1214 return PS_OK;
1217 /* Get floating-point registers for LWP. */
1219 ps_err_e
1220 ps_lgetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
1221 prfpregset_t *fpregset)
1223 struct cleanup *old_chain;
1224 struct regcache *regcache;
1226 old_chain = save_inferior_ptid ();
1228 inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
1229 regcache = get_thread_regcache (inferior_ptid);
1231 if (target_has_execution)
1232 procfs_ops.to_fetch_registers (regcache, -1);
1233 else
1234 orig_core_ops.to_fetch_registers (regcache, -1);
1235 fill_fpregset (regcache, (gdb_fpregset_t *) fpregset, -1);
1237 do_cleanups (old_chain);
1239 return PS_OK;
1242 /* Set floating-point regs for LWP */
1244 ps_err_e
1245 ps_lsetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
1246 const prfpregset_t * fpregset)
1248 struct cleanup *old_chain;
1249 struct regcache *regcache;
1251 old_chain = save_inferior_ptid ();
1253 inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
1254 regcache = get_thread_regcache (inferior_ptid);
1256 supply_fpregset (regcache, (const gdb_fpregset_t *) fpregset);
1257 if (target_has_execution)
1258 procfs_ops.to_store_registers (regcache, -1);
1259 else
1260 orig_core_ops.to_store_registers (regcache, -1);
1262 do_cleanups (old_chain);
1264 return PS_OK;
1267 #ifdef PR_MODEL_LP64
1268 /* Identify process as 32-bit or 64-bit. At the moment we're using
1269 BFD to do this. There might be a more Solaris-specific
1270 (e.g. procfs) method, but this ought to work. */
1272 ps_err_e
1273 ps_pdmodel (gdb_ps_prochandle_t ph, int *data_model)
1275 if (exec_bfd == 0)
1276 *data_model = PR_MODEL_UNKNOWN;
1277 else if (bfd_get_arch_size (exec_bfd) == 32)
1278 *data_model = PR_MODEL_ILP32;
1279 else
1280 *data_model = PR_MODEL_LP64;
1282 return PS_OK;
1284 #endif /* PR_MODEL_LP64 */
1286 #ifdef TM_I386SOL2_H
1288 /* Reads the local descriptor table of a LWP. */
1290 ps_err_e
1291 ps_lgetLDT (gdb_ps_prochandle_t ph, lwpid_t lwpid,
1292 struct ssd *pldt)
1294 /* NOTE: only used on Solaris, therefore OK to refer to procfs.c. */
1295 extern struct ssd *procfs_find_LDT_entry (ptid_t);
1296 struct ssd *ret;
1298 /* FIXME: can't I get the process ID from the prochandle or
1299 something? */
1301 if (PIDGET (inferior_ptid) <= 0 || lwpid <= 0)
1302 return PS_BADLID;
1304 ret = procfs_find_LDT_entry (BUILD_LWP (lwpid, PIDGET (inferior_ptid)));
1305 if (ret)
1307 memcpy (pldt, ret, sizeof (struct ssd));
1308 return PS_OK;
1310 else
1311 /* LDT not found. */
1312 return PS_ERR;
1314 #endif /* TM_I386SOL2_H */
1317 /* Convert PTID to printable form. */
1319 char *
1320 solaris_pid_to_str (ptid_t ptid)
1322 static char buf[100];
1324 /* In case init failed to resolve the libthread_db library. */
1325 if (!procfs_suppress_run)
1326 return procfs_pid_to_str (ptid);
1328 if (is_thread (ptid))
1330 ptid_t lwp;
1332 lwp = thread_to_lwp (ptid, -2);
1334 if (PIDGET (lwp) == -1)
1335 sprintf (buf, "Thread %ld (defunct)", GET_THREAD (ptid));
1336 else if (PIDGET (lwp) != -2)
1337 sprintf (buf, "Thread %ld (LWP %ld)",
1338 GET_THREAD (ptid), GET_LWP (lwp));
1339 else
1340 sprintf (buf, "Thread %ld ", GET_THREAD (ptid));
1342 else if (GET_LWP (ptid) != 0)
1343 sprintf (buf, "LWP %ld ", GET_LWP (ptid));
1344 else
1345 sprintf (buf, "process %d ", PIDGET (ptid));
1347 return buf;
1351 /* Worker bee for find_new_threads. Callback function that gets
1352 called once per user-level thread (i.e. not for LWP's). */
1354 static int
1355 sol_find_new_threads_callback (const td_thrhandle_t *th, void *ignored)
1357 td_err_e retval;
1358 td_thrinfo_t ti;
1359 ptid_t ptid;
1361 retval = p_td_thr_get_info (th, &ti);
1362 if (retval != TD_OK)
1363 return -1;
1365 ptid = BUILD_THREAD (ti.ti_tid, PIDGET (inferior_ptid));
1366 if (!in_thread_list (ptid))
1367 add_thread (ptid);
1369 return 0;
1372 static void
1373 sol_find_new_threads (void)
1375 /* Don't do anything if init failed to resolve the libthread_db
1376 library. */
1377 if (!procfs_suppress_run)
1378 return;
1380 if (PIDGET (inferior_ptid) == -1)
1382 printf_filtered ("No process.\n");
1383 return;
1386 /* First Find any new LWP's. */
1387 procfs_ops.to_find_new_threads ();
1389 /* Then find any new user-level threads. */
1390 p_td_ta_thr_iter (main_ta, sol_find_new_threads_callback, (void *) 0,
1391 TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
1392 TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
1395 static void
1396 sol_core_open (char *filename, int from_tty)
1398 orig_core_ops.to_open (filename, from_tty);
1401 static void
1402 sol_core_close (int quitting)
1404 orig_core_ops.to_close (quitting);
1407 static void
1408 sol_core_detach (char *args, int from_tty)
1410 unpush_target (&core_ops);
1411 orig_core_ops.to_detach (args, from_tty);
1414 static void
1415 sol_core_files_info (struct target_ops *t)
1417 orig_core_ops.to_files_info (t);
1420 /* Worker bee for the "info sol-thread" command. This is a callback
1421 function that gets called once for each Solaris user-level thread
1422 (i.e. not for LWPs) in the inferior. Print anything interesting
1423 that we can think of. */
1425 static int
1426 info_cb (const td_thrhandle_t *th, void *s)
1428 td_err_e ret;
1429 td_thrinfo_t ti;
1431 ret = p_td_thr_get_info (th, &ti);
1432 if (ret == TD_OK)
1434 printf_filtered ("%s thread #%d, lwp %d, ",
1435 ti.ti_type == TD_THR_SYSTEM ? "system" : "user ",
1436 ti.ti_tid, ti.ti_lid);
1437 switch (ti.ti_state)
1439 default:
1440 case TD_THR_UNKNOWN:
1441 printf_filtered ("<unknown state>");
1442 break;
1443 case TD_THR_STOPPED:
1444 printf_filtered ("(stopped)");
1445 break;
1446 case TD_THR_RUN:
1447 printf_filtered ("(run) ");
1448 break;
1449 case TD_THR_ACTIVE:
1450 printf_filtered ("(active) ");
1451 break;
1452 case TD_THR_ZOMBIE:
1453 printf_filtered ("(zombie) ");
1454 break;
1455 case TD_THR_SLEEP:
1456 printf_filtered ("(asleep) ");
1457 break;
1458 case TD_THR_STOPPED_ASLEEP:
1459 printf_filtered ("(stopped asleep)");
1460 break;
1462 /* Print thr_create start function. */
1463 if (ti.ti_startfunc != 0)
1465 struct minimal_symbol *msym;
1466 msym = lookup_minimal_symbol_by_pc (ti.ti_startfunc);
1467 if (msym)
1468 printf_filtered (" startfunc: %s\n",
1469 DEPRECATED_SYMBOL_NAME (msym));
1470 else
1471 printf_filtered (" startfunc: 0x%s\n", paddr (ti.ti_startfunc));
1474 /* If thread is asleep, print function that went to sleep. */
1475 if (ti.ti_state == TD_THR_SLEEP)
1477 struct minimal_symbol *msym;
1478 msym = lookup_minimal_symbol_by_pc (ti.ti_pc);
1479 if (msym)
1480 printf_filtered (" - Sleep func: %s\n",
1481 DEPRECATED_SYMBOL_NAME (msym));
1482 else
1483 printf_filtered (" - Sleep func: 0x%s\n", paddr (ti.ti_startfunc));
1486 /* Wrap up line, if necessary. */
1487 if (ti.ti_state != TD_THR_SLEEP && ti.ti_startfunc == 0)
1488 printf_filtered ("\n"); /* don't you hate counting newlines? */
1490 else
1491 warning (_("info sol-thread: failed to get info for thread."));
1493 return 0;
1496 /* List some state about each Solaris user-level thread in the
1497 inferior. */
1499 static void
1500 info_solthreads (char *args, int from_tty)
1502 p_td_ta_thr_iter (main_ta, info_cb, args,
1503 TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
1504 TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
1507 static int
1508 sol_find_memory_regions (int (*func) (CORE_ADDR, unsigned long,
1509 int, int, int, void *),
1510 void *data)
1512 return procfs_ops.to_find_memory_regions (func, data);
1515 static char *
1516 sol_make_note_section (bfd *obfd, int *note_size)
1518 return procfs_ops.to_make_corefile_notes (obfd, note_size);
1521 static int
1522 ignore (struct bp_target_info *bp_tgt)
1524 return 0;
1527 static void
1528 init_sol_thread_ops (void)
1530 sol_thread_ops.to_shortname = "solaris-threads";
1531 sol_thread_ops.to_longname = "Solaris threads and pthread.";
1532 sol_thread_ops.to_doc = "Solaris threads and pthread support.";
1533 sol_thread_ops.to_open = sol_thread_open;
1534 sol_thread_ops.to_attach = sol_thread_attach;
1535 sol_thread_ops.to_detach = sol_thread_detach;
1536 sol_thread_ops.to_resume = sol_thread_resume;
1537 sol_thread_ops.to_wait = sol_thread_wait;
1538 sol_thread_ops.to_fetch_registers = sol_thread_fetch_registers;
1539 sol_thread_ops.to_store_registers = sol_thread_store_registers;
1540 sol_thread_ops.to_prepare_to_store = sol_thread_prepare_to_store;
1541 sol_thread_ops.deprecated_xfer_memory = sol_thread_xfer_memory;
1542 sol_thread_ops.to_xfer_partial = sol_thread_xfer_partial;
1543 sol_thread_ops.to_files_info = sol_thread_files_info;
1544 sol_thread_ops.to_insert_breakpoint = memory_insert_breakpoint;
1545 sol_thread_ops.to_remove_breakpoint = memory_remove_breakpoint;
1546 sol_thread_ops.to_terminal_init = terminal_init_inferior;
1547 sol_thread_ops.to_terminal_inferior = terminal_inferior;
1548 sol_thread_ops.to_terminal_ours_for_output = terminal_ours_for_output;
1549 sol_thread_ops.to_terminal_ours = terminal_ours;
1550 sol_thread_ops.to_terminal_save_ours = terminal_save_ours;
1551 sol_thread_ops.to_terminal_info = child_terminal_info;
1552 sol_thread_ops.to_kill = sol_thread_kill_inferior;
1553 sol_thread_ops.to_create_inferior = sol_thread_create_inferior;
1554 sol_thread_ops.to_mourn_inferior = sol_thread_mourn_inferior;
1555 sol_thread_ops.to_can_run = sol_thread_can_run;
1556 sol_thread_ops.to_notice_signals = sol_thread_notice_signals;
1557 sol_thread_ops.to_thread_alive = sol_thread_alive;
1558 sol_thread_ops.to_pid_to_str = solaris_pid_to_str;
1559 sol_thread_ops.to_find_new_threads = sol_find_new_threads;
1560 sol_thread_ops.to_stop = sol_thread_stop;
1561 sol_thread_ops.to_stratum = process_stratum;
1562 sol_thread_ops.to_has_all_memory = 1;
1563 sol_thread_ops.to_has_memory = 1;
1564 sol_thread_ops.to_has_stack = 1;
1565 sol_thread_ops.to_has_registers = 1;
1566 sol_thread_ops.to_has_execution = 1;
1567 sol_thread_ops.to_has_thread_control = tc_none;
1568 sol_thread_ops.to_find_memory_regions = sol_find_memory_regions;
1569 sol_thread_ops.to_make_corefile_notes = sol_make_note_section;
1570 sol_thread_ops.to_magic = OPS_MAGIC;
1573 static void
1574 init_sol_core_ops (void)
1576 sol_core_ops.to_shortname = "solaris-core";
1577 sol_core_ops.to_longname = "Solaris core threads and pthread.";
1578 sol_core_ops.to_doc = "Solaris threads and pthread support for core files.";
1579 sol_core_ops.to_open = sol_core_open;
1580 sol_core_ops.to_close = sol_core_close;
1581 sol_core_ops.to_attach = sol_thread_attach;
1582 sol_core_ops.to_detach = sol_core_detach;
1583 sol_core_ops.to_fetch_registers = sol_thread_fetch_registers;
1584 sol_core_ops.deprecated_xfer_memory = sol_thread_xfer_memory;
1585 sol_core_ops.to_xfer_partial = sol_thread_xfer_partial;
1586 sol_core_ops.to_files_info = sol_core_files_info;
1587 sol_core_ops.to_insert_breakpoint = ignore;
1588 sol_core_ops.to_remove_breakpoint = ignore;
1589 sol_core_ops.to_create_inferior = sol_thread_create_inferior;
1590 sol_core_ops.to_stratum = core_stratum;
1591 sol_core_ops.to_has_memory = 1;
1592 sol_core_ops.to_has_stack = 1;
1593 sol_core_ops.to_has_registers = 1;
1594 sol_core_ops.to_has_thread_control = tc_none;
1595 sol_core_ops.to_thread_alive = sol_thread_alive;
1596 sol_core_ops.to_pid_to_str = solaris_pid_to_str;
1597 /* On Solaris/x86, when debugging a threaded core file from process
1598 <n>, the following causes "info threads" to produce "procfs:
1599 couldn't find pid <n> in procinfo list" where <n> is the pid of
1600 the process that produced the core file. Disable it for now. */
1601 #if 0
1602 sol_core_ops.to_find_new_threads = sol_find_new_threads;
1603 #endif
1604 sol_core_ops.to_magic = OPS_MAGIC;
1607 /* We suppress the call to add_target of core_ops in corelow because
1608 if there are two targets in the stratum core_stratum,
1609 find_core_target won't know which one to return. See corelow.c for
1610 an additonal comment on coreops_suppress_target. */
1611 int coreops_suppress_target = 1;
1613 void
1614 _initialize_sol_thread (void)
1616 void *dlhandle;
1618 init_sol_thread_ops ();
1619 init_sol_core_ops ();
1621 dlhandle = dlopen ("libthread_db.so.1", RTLD_NOW);
1622 if (!dlhandle)
1623 goto die;
1625 #define resolve(X) \
1626 if (!(p_##X = dlsym (dlhandle, #X))) \
1627 goto die;
1629 resolve (td_log);
1630 resolve (td_ta_new);
1631 resolve (td_ta_delete);
1632 resolve (td_init);
1633 resolve (td_ta_get_ph);
1634 resolve (td_ta_get_nthreads);
1635 resolve (td_ta_tsd_iter);
1636 resolve (td_ta_thr_iter);
1637 resolve (td_thr_validate);
1638 resolve (td_thr_tsd);
1639 resolve (td_thr_get_info);
1640 resolve (td_thr_getfpregs);
1641 resolve (td_thr_getxregsize);
1642 resolve (td_thr_getxregs);
1643 resolve (td_thr_sigsetmask);
1644 resolve (td_thr_setprio);
1645 resolve (td_thr_setsigpending);
1646 resolve (td_thr_setfpregs);
1647 resolve (td_thr_setxregs);
1648 resolve (td_ta_map_id2thr);
1649 resolve (td_ta_map_lwp2thr);
1650 resolve (td_thr_getgregs);
1651 resolve (td_thr_setgregs);
1653 add_target (&sol_thread_ops);
1655 procfs_suppress_run = 1;
1657 add_cmd ("sol-threads", class_maintenance, info_solthreads,
1658 _("Show info on Solaris user threads."), &maintenanceinfolist);
1660 memcpy (&orig_core_ops, &core_ops, sizeof (struct target_ops));
1661 memcpy (&core_ops, &sol_core_ops, sizeof (struct target_ops));
1662 add_target (&core_ops);
1664 /* Hook into new_objfile notification. */
1665 observer_attach_new_objfile (sol_thread_new_objfile);
1666 return;
1668 die:
1669 fprintf_unfiltered (gdb_stderr, "\
1670 [GDB will not be able to debug user-mode threads: %s]\n", dlerror ());
1672 if (dlhandle)
1673 dlclose (dlhandle);
1675 /* Allow the user to debug non-threaded core files. */
1676 add_target (&core_ops);
1678 return;