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