820317b167de24c753cbc98fe61482d79fa74e07
[deliverable/binutils-gdb.git] / gdb / sol-thread.c
1 /* Solaris threads debugging interface.
2
3 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
4 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., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, 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 "symfile.h"
68
69 #include "gdb_string.h"
70
71 extern struct target_ops sol_thread_ops; /* Forward declaration */
72 extern struct target_ops sol_core_ops; /* Forward declaration */
73
74 /* place to store core_ops before we overwrite it */
75 static struct target_ops orig_core_ops;
76
77 struct target_ops sol_thread_ops;
78 struct target_ops sol_core_ops;
79
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);
84
85 /* Prototypes for supply_gregset etc. */
86 #include "gregset.h"
87
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. */
91
92 struct ps_prochandle
93 {
94 ptid_t ptid;
95 };
96
97 struct string_map
98 {
99 int num;
100 char *str;
101 };
102
103 static struct ps_prochandle main_ph;
104 static td_thragent_t *main_ta;
105 static int sol_thread_active = 0;
106
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);
110
111 static void init_sol_thread_ops (void);
112 static void init_sol_core_ops (void);
113
114 /* Default definitions: These must be defined in tm.h if they are to
115 be shared with a process module such as procfs. */
116
117 #define GET_PID(ptid) ptid_get_pid (ptid)
118 #define GET_LWP(ptid) ptid_get_lwp (ptid)
119 #define GET_THREAD(ptid) ptid_get_tid (ptid)
120
121 #define is_lwp(ptid) (GET_LWP (ptid) != 0)
122 #define is_thread(ptid) (GET_THREAD (ptid) != 0)
123
124 #define BUILD_LWP(lwp, pid) ptid_build (pid, lwp, 0)
125 #define BUILD_THREAD(tid, pid) ptid_build (pid, 0, tid)
126
127 /* Pointers to routines from libthread_db resolved by dlopen(). */
128
129 static void (*p_td_log)(const int on_off);
130 static td_err_e (*p_td_ta_new)(const struct ps_prochandle *ph_p,
131 td_thragent_t **ta_pp);
132 static td_err_e (*p_td_ta_delete)(td_thragent_t *ta_p);
133 static td_err_e (*p_td_init)(void);
134 static td_err_e (*p_td_ta_get_ph)(const td_thragent_t *ta_p,
135 struct ps_prochandle **ph_pp);
136 static td_err_e (*p_td_ta_get_nthreads)(const td_thragent_t *ta_p,
137 int *nthread_p);
138 static td_err_e (*p_td_ta_tsd_iter)(const td_thragent_t *ta_p,
139 td_key_iter_f *cb, 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);
177 \f
178
179 /* Return the libthread_db error string associated with ERRCODE. If
180 ERRCODE is unknown, return an appropriate message. */
181
182 static char *
183 td_err_string (td_err_e errcode)
184 {
185 static struct string_map td_err_table[] =
186 {
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" }
208 };
209 const int td_err_size = sizeof td_err_table / sizeof (struct string_map);
210 int i;
211 static char buf[50];
212
213 for (i = 0; i < td_err_size; i++)
214 if (td_err_table[i].num == errcode)
215 return td_err_table[i].str;
216
217 sprintf (buf, "Unknown libthread_db error code: %d", errcode);
218
219 return buf;
220 }
221
222 /* Return the the libthread_db state string assicoated with STATECODE.
223 If STATECODE is unknown, return an appropriate message. */
224
225 static char *
226 td_state_string (td_thr_state_e statecode)
227 {
228 static struct string_map td_thr_state_table[] =
229 {
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" }
238 };
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];
243
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;
247
248 sprintf (buf, "Unknown libthread_db state code: %d", statecode);
249
250 return buf;
251 }
252 \f
253
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.
257
258 NOTE: This function probably shouldn't call error(). */
259
260 static ptid_t
261 thread_to_lwp (ptid_t thread_id, int default_lwp)
262 {
263 td_thrinfo_t ti;
264 td_thrhandle_t th;
265 td_err_e val;
266
267 if (is_lwp (thread_id))
268 return thread_id; /* It's already an LWP ID. */
269
270 /* It's a thread. Convert to LWP. */
271
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));
277
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));
283
284 if (ti.ti_state != TD_THR_ACTIVE)
285 {
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));
290 }
291
292 return BUILD_LWP (ti.ti_lid, PIDGET (thread_id));
293 }
294
295 /* Convert an LWP ID into a POSIX or Solaris thread ID. If LWP_ID
296 doesn't exists, that's an error.
297
298 NOTE: This function probably shouldn't call error(). */
299
300 static ptid_t
301 lwp_to_thread (ptid_t lwp)
302 {
303 td_thrinfo_t ti;
304 td_thrhandle_t th;
305 td_err_e val;
306
307 if (is_thread (lwp))
308 return lwp; /* It's already a thread ID. */
309
310 /* It's an LWP. Convert it to a thread ID. */
311
312 if (!sol_thread_alive (lwp))
313 return pid_to_ptid (-1); /* Must be a defunct LPW. */
314
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));
320
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));
326
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));
332
333 return BUILD_THREAD (ti.ti_tid, PIDGET (lwp));
334 }
335 \f
336
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. */
340
341 static void
342 sol_thread_open (char *arg, int from_tty)
343 {
344 procfs_ops.to_open (arg, from_tty);
345 }
346
347 /* Attach to process PID, then initialize for debugging it and wait
348 for the trace-trap that results from attaching. */
349
350 static void
351 sol_thread_attach (char *args, int from_tty)
352 {
353 procfs_ops.to_attach (args, from_tty);
354
355 /* Must get symbols from shared libraries before libthread_db can run! */
356 SOLIB_ADD ((char *) 0, from_tty, (struct target_ops *) 0, auto_solib_add);
357
358 if (sol_thread_active)
359 {
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);
368 }
369
370 /* FIXME: Might want to iterate over all the threads and register
371 them. */
372 }
373
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). */
380
381 static void
382 sol_thread_detach (char *args, int from_tty)
383 {
384 inferior_ptid = pid_to_ptid (PIDGET (main_ph.ptid));
385 unpush_target (&sol_thread_ops);
386 procfs_ops.to_detach (args, from_tty);
387 }
388
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. */
393
394 static void
395 sol_thread_resume (ptid_t ptid, int step, enum target_signal signo)
396 {
397 struct cleanup *old_chain;
398
399 old_chain = save_inferior_ptid ();
400
401 inferior_ptid = thread_to_lwp (inferior_ptid, PIDGET (main_ph.ptid));
402 if (PIDGET (inferior_ptid) == -1)
403 inferior_ptid = procfs_first_available ();
404
405 if (PIDGET (ptid) != -1)
406 {
407 ptid_t save_ptid = ptid;
408
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));
415 }
416
417 procfs_ops.to_resume (ptid, step, signo);
418
419 do_cleanups (old_chain);
420 }
421
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. */
424
425 static ptid_t
426 sol_thread_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
427 {
428 ptid_t rtnval;
429 ptid_t save_ptid;
430 struct cleanup *old_chain;
431
432 save_ptid = inferior_ptid;
433 old_chain = save_inferior_ptid ();
434
435 inferior_ptid = thread_to_lwp (inferior_ptid, PIDGET (main_ph.ptid));
436 if (PIDGET (inferior_ptid) == -1)
437 inferior_ptid = procfs_first_available ();
438
439 if (PIDGET (ptid) != -1)
440 {
441 ptid_t save_ptid = ptid;
442
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));
449 }
450
451 rtnval = procfs_ops.to_wait (ptid, ourstatus);
452
453 if (ourstatus->kind != TARGET_WAITKIND_EXITED)
454 {
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;
459
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 {
465 printf_filtered ("[New %s]\n", target_pid_to_str (rtnval));
466 add_thread (rtnval);
467 }
468 }
469
470 /* During process initialization, we may get here without the thread
471 package being initialized, since that can only happen after we've
472 found the shared libs. */
473
474 do_cleanups (old_chain);
475
476 return rtnval;
477 }
478
479 static void
480 sol_thread_fetch_registers (int regnum)
481 {
482 thread_t thread;
483 td_thrhandle_t thandle;
484 td_err_e val;
485 prgregset_t gregset;
486 prfpregset_t fpregset;
487 #if 0
488 int xregsize;
489 caddr_t xregset;
490 #endif
491
492 if (!is_thread (inferior_ptid))
493 {
494 /* It's an LWP; pass the request on to procfs. */
495 if (target_has_execution)
496 procfs_ops.to_fetch_registers (regnum);
497 else
498 orig_core_ops.to_fetch_registers (regnum);
499 return;
500 }
501
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");
506
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));
511
512 /* Get the general-purpose registers. */
513
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));
518
519 /* For SPARC, TD_PARTIALREG means that only %i0...%i7, %l0..%l7, %pc
520 and %sp are saved (by a thread context switch). */
521
522 /* And, now the floating-point registers. */
523
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));
528
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. */
532
533 supply_gregset ((gdb_gregset_t *) &gregset);
534 supply_fpregset ((gdb_fpregset_t *) &fpregset);
535
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));
542
543 if (val == TD_OK)
544 {
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));
550 }
551 #endif
552 }
553
554 static void
555 sol_thread_store_registers (int regnum)
556 {
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
566
567 if (!is_thread (inferior_ptid))
568 {
569 /* It's an LWP; pass the request on to procfs.c. */
570 procfs_ops.to_store_registers (regnum);
571 return;
572 }
573
574 /* Solaris thread: convert INFERIOR_PTID into a td_thrhandle_t. */
575 thread = GET_THREAD (inferior_ptid);
576
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));
581
582 if (regnum != -1)
583 {
584 /* Not writing all the registers. */
585 char old_value[MAX_REGISTER_SIZE];
586
587 /* Save new register value. */
588 regcache_raw_collect (current_regcache, regnum, old_value);
589
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));
598
599 /* Restore new register value. */
600 regcache_raw_supply (current_regcache, regnum, old_value);
601
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));
608
609 if (val == TD_OK)
610 {
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));
616 }
617 #endif
618 }
619
620 fill_gregset ((gdb_gregset_t *) &gregset, regnum);
621 fill_fpregset ((gdb_fpregset_t *) &fpregset, regnum);
622
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));
631
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));
638
639 /* ??? Should probably do something about writing the xregs here,
640 but what are they? */
641 #endif
642 }
643
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. */
649
650 static void
651 sol_thread_prepare_to_store (void)
652 {
653 procfs_ops.to_prepare_to_store ();
654 }
655
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.
659
660 Returns the number of bytes transferred. */
661
662 static int
663 sol_thread_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int dowrite,
664 struct mem_attrib *attrib,
665 struct target_ops *target)
666 {
667 int retval;
668 struct cleanup *old_chain;
669
670 old_chain = save_inferior_ptid ();
671
672 if (is_thread (inferior_ptid) || !target_thread_alive (inferior_ptid))
673 {
674 /* It's either a thread or an LWP that isn't alive. Any live
675 LWP will do so use the first available.
676
677 NOTE: We don't need to call switch_to_thread; we're just
678 reading memory. */
679 inferior_ptid = procfs_first_available ();
680 }
681
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);
688
689 do_cleanups (old_chain);
690
691 return retval;
692 }
693
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. */
697
698 static LONGEST
699 sol_thread_xfer_partial (struct target_ops *ops, enum target_object object,
700 const char *annex, void *readbuf,
701 const void *writebuf, ULONGEST offset, LONGEST len)
702 {
703 int retval;
704 struct cleanup *old_chain;
705
706 old_chain = save_inferior_ptid ();
707
708 if (is_thread (inferior_ptid) || !target_thread_alive (inferior_ptid))
709 {
710 /* It's either a thread or an LWP that isn't alive. Any live
711 LWP will do so use the first available.
712
713 NOTE: We don't need to call switch_to_thread; we're just
714 reading memory. */
715 inferior_ptid = procfs_first_available ();
716 }
717
718 if (target_has_execution)
719 retval = procfs_ops.to_xfer_partial (ops, object, annex,
720 readbuf, writebuf, offset, len);
721 else
722 retval = orig_core_ops.to_xfer_partial (ops, object, annex,
723 readbuf, writebuf, offset, len);
724
725 do_cleanups (old_chain);
726
727 return retval;
728 }
729
730 /* Print status information about what we're accessing. */
731
732 static void
733 sol_thread_files_info (struct target_ops *ignore)
734 {
735 procfs_ops.to_files_info (ignore);
736 }
737
738 static void
739 sol_thread_kill_inferior (void)
740 {
741 procfs_ops.to_kill ();
742 }
743
744 static void
745 sol_thread_notice_signals (ptid_t ptid)
746 {
747 procfs_ops.to_notice_signals (pid_to_ptid (PIDGET (ptid)));
748 }
749
750 /* Fork an inferior process, and start debugging it with /proc. */
751
752 static void
753 sol_thread_create_inferior (char *exec_file, char *allargs, char **env,
754 int from_tty)
755 {
756 procfs_ops.to_create_inferior (exec_file, allargs, env, from_tty);
757
758 if (sol_thread_active && !ptid_equal (inferior_ptid, null_ptid))
759 {
760 /* Save for xfer_memory. */
761 main_ph.ptid = inferior_ptid;
762
763 push_target (&sol_thread_ops);
764
765 inferior_ptid = lwp_to_thread (inferior_ptid);
766 if (PIDGET (inferior_ptid) == -1)
767 inferior_ptid = main_ph.ptid;
768
769 if (!in_thread_list (inferior_ptid))
770 add_thread (inferior_ptid);
771 }
772 }
773
774 /* This routine is called whenever a new symbol table is read in, or
775 when all symbol tables are removed. libthread_db can only be
776 initialized when it finds the right variables in libthread.so.
777 Since it's a shared library, those variables don't show up until
778 the library gets mapped and the symbol table is read in.
779
780 This new_objfile event is managed by a chained function pointer.
781 It is the callee's responsability to call the next client on the
782 chain. */
783
784 /* Saved pointer to previous owner of the new_objfile event. */
785 static void (*target_new_objfile_chain) (struct objfile *);
786
787 void
788 sol_thread_new_objfile (struct objfile *objfile)
789 {
790 td_err_e val;
791
792 if (!objfile)
793 {
794 sol_thread_active = 0;
795 goto quit;
796 }
797
798 /* Don't do anything if init failed to resolve the libthread_db
799 library. */
800 if (!procfs_suppress_run)
801 goto quit;
802
803 /* Now, initialize libthread_db. This needs to be done after the
804 shared libraries are located because it needs information from
805 the user's thread library. */
806
807 val = p_td_init ();
808 if (val != TD_OK)
809 {
810 warning ("sol_thread_new_objfile: td_init: %s", td_err_string (val));
811 goto quit;
812 }
813
814 val = p_td_ta_new (&main_ph, &main_ta);
815 if (val == TD_NOLIBTHREAD)
816 goto quit;
817 else if (val != TD_OK)
818 {
819 warning ("sol_thread_new_objfile: td_ta_new: %s", td_err_string (val));
820 goto quit;
821 }
822
823 sol_thread_active = 1;
824
825 quit:
826 /* Call predecessor on chain, if any. */
827 if (target_new_objfile_chain)
828 target_new_objfile_chain (objfile);
829 }
830
831 /* Clean up after the inferior dies. */
832
833 static void
834 sol_thread_mourn_inferior (void)
835 {
836 unpush_target (&sol_thread_ops);
837 procfs_ops.to_mourn_inferior ();
838 }
839
840 /* Mark our target-struct as eligible for stray "run" and "attach"
841 commands. */
842
843 static int
844 sol_thread_can_run (void)
845 {
846 return procfs_suppress_run;
847 }
848
849 /*
850
851 LOCAL FUNCTION
852
853 sol_thread_alive - test thread for "aliveness"
854
855 SYNOPSIS
856
857 static bool sol_thread_alive (ptid_t ptid);
858
859 DESCRIPTION
860
861 returns true if thread still active in inferior.
862
863 */
864
865 /* Return true if PTID is still active in the inferior. */
866
867 static int
868 sol_thread_alive (ptid_t ptid)
869 {
870 if (is_thread (ptid))
871 {
872 /* It's a (user-level) thread. */
873 td_err_e val;
874 td_thrhandle_t th;
875 int pid;
876
877 pid = GET_THREAD (ptid);
878 if ((val = p_td_ta_map_id2thr (main_ta, pid, &th)) != TD_OK)
879 return 0; /* Thread not found. */
880 if ((val = p_td_thr_validate (&th)) != TD_OK)
881 return 0; /* Thread not valid. */
882 return 1; /* Known thread. */
883 }
884 else
885 {
886 /* It's an LPW; pass the request on to procfs. */
887 if (target_has_execution)
888 return procfs_ops.to_thread_alive (ptid);
889 else
890 return orig_core_ops.to_thread_alive (ptid);
891 }
892 }
893
894 static void
895 sol_thread_stop (void)
896 {
897 procfs_ops.to_stop ();
898 }
899 \f
900 /* These routines implement the lower half of the thread_db interface,
901 i.e. the ps_* routines. */
902
903 /* Various versions of <proc_service.h> have slightly different
904 function prototypes. In particular, we have
905
906 NEWER OLDER
907 struct ps_prochandle * const struct ps_prochandle *
908 void* char*
909 const void* char*
910 int size_t
911
912 Which one you have depends on the Solaris version and what patches
913 you've applied. On the theory that there are only two major
914 variants, we have configure check the prototype of ps_pdwrite (),
915 and use that info to make appropriate typedefs here. */
916
917 #ifdef PROC_SERVICE_IS_OLD
918 typedef const struct ps_prochandle *gdb_ps_prochandle_t;
919 typedef char *gdb_ps_read_buf_t;
920 typedef char *gdb_ps_write_buf_t;
921 typedef int gdb_ps_size_t;
922 typedef paddr_t gdb_ps_addr_t;
923 #else
924 typedef struct ps_prochandle *gdb_ps_prochandle_t;
925 typedef void *gdb_ps_read_buf_t;
926 typedef const void *gdb_ps_write_buf_t;
927 typedef size_t gdb_ps_size_t;
928 typedef psaddr_t gdb_ps_addr_t;
929 #endif
930
931 /* The next four routines are called by libthread_db to tell us to
932 stop and stop a particular process or lwp. Since GDB ensures that
933 these are all stopped by the time we call anything in thread_db,
934 these routines need to do nothing. */
935
936 /* Process stop. */
937
938 ps_err_e
939 ps_pstop (gdb_ps_prochandle_t ph)
940 {
941 return PS_OK;
942 }
943
944 /* Process continue. */
945
946 ps_err_e
947 ps_pcontinue (gdb_ps_prochandle_t ph)
948 {
949 return PS_OK;
950 }
951
952 /* LWP stop. */
953
954 ps_err_e
955 ps_lstop (gdb_ps_prochandle_t ph, lwpid_t lwpid)
956 {
957 return PS_OK;
958 }
959
960 /* LWP continue. */
961
962 ps_err_e
963 ps_lcontinue (gdb_ps_prochandle_t ph, lwpid_t lwpid)
964 {
965 return PS_OK;
966 }
967
968 /* Looks up the symbol LD_SYMBOL_NAME in the debugger's symbol table. */
969
970 ps_err_e
971 ps_pglobal_lookup (gdb_ps_prochandle_t ph, const char *ld_object_name,
972 const char *ld_symbol_name, gdb_ps_addr_t *ld_symbol_addr)
973 {
974 struct minimal_symbol *ms;
975
976 ms = lookup_minimal_symbol (ld_symbol_name, NULL, NULL);
977 if (!ms)
978 return PS_NOSYM;
979
980 *ld_symbol_addr = SYMBOL_VALUE_ADDRESS (ms);
981 return PS_OK;
982 }
983
984 /* Common routine for reading and writing memory. */
985
986 static ps_err_e
987 rw_common (int dowrite, const struct ps_prochandle *ph, gdb_ps_addr_t addr,
988 char *buf, int size)
989 {
990 struct cleanup *old_chain;
991
992 old_chain = save_inferior_ptid ();
993
994 if (is_thread (inferior_ptid) || !target_thread_alive (inferior_ptid))
995 {
996 /* It's either a thread or an LWP that isn't alive. Any live
997 LWP will do so use the first available.
998
999 NOTE: We don't need to call switch_to_thread; we're just
1000 reading memory. */
1001 inferior_ptid = procfs_first_available ();
1002 }
1003
1004 #if defined (__sparcv9)
1005 /* For Sparc64 cross Sparc32, make sure the address has not been
1006 accidentally sign-extended (or whatever) to beyond 32 bits. */
1007 if (bfd_get_arch_size (exec_bfd) == 32)
1008 addr &= 0xffffffff;
1009 #endif
1010
1011 while (size > 0)
1012 {
1013 int cc;
1014
1015 /* FIXME: passing 0 as attrib argument. */
1016 if (target_has_execution)
1017 cc = procfs_ops.deprecated_xfer_memory (addr, buf, size,
1018 dowrite, 0, &procfs_ops);
1019 else
1020 cc = orig_core_ops.deprecated_xfer_memory (addr, buf, size,
1021 dowrite, 0, &core_ops);
1022
1023 if (cc < 0)
1024 {
1025 if (dowrite == 0)
1026 print_sys_errmsg ("rw_common (): read", errno);
1027 else
1028 print_sys_errmsg ("rw_common (): write", errno);
1029
1030 do_cleanups (old_chain);
1031
1032 return PS_ERR;
1033 }
1034 else if (cc == 0)
1035 {
1036 if (dowrite == 0)
1037 warning ("rw_common (): unable to read at addr 0x%lx",
1038 (long) addr);
1039 else
1040 warning ("rw_common (): unable to write at addr 0x%lx",
1041 (long) addr);
1042
1043 do_cleanups (old_chain);
1044
1045 return PS_ERR;
1046 }
1047
1048 size -= cc;
1049 buf += cc;
1050 }
1051
1052 do_cleanups (old_chain);
1053
1054 return PS_OK;
1055 }
1056
1057 /* Copies SIZE bytes from target process .data segment to debugger memory. */
1058
1059 ps_err_e
1060 ps_pdread (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
1061 gdb_ps_read_buf_t buf, gdb_ps_size_t size)
1062 {
1063 return rw_common (0, ph, addr, buf, size);
1064 }
1065
1066 /* Copies SIZE bytes from debugger memory .data segment to target process. */
1067
1068 ps_err_e
1069 ps_pdwrite (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
1070 gdb_ps_write_buf_t buf, gdb_ps_size_t size)
1071 {
1072 return rw_common (1, ph, addr, (char *) buf, size);
1073 }
1074
1075 /* Copies SIZE bytes from target process .text segment to debugger memory. */
1076
1077 ps_err_e
1078 ps_ptread (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
1079 gdb_ps_read_buf_t buf, gdb_ps_size_t size)
1080 {
1081 return rw_common (0, ph, addr, buf, size);
1082 }
1083
1084 /* Copies SIZE bytes from debugger memory .text segment to target process. */
1085
1086 ps_err_e
1087 ps_ptwrite (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
1088 gdb_ps_write_buf_t buf, gdb_ps_size_t size)
1089 {
1090 return rw_common (1, ph, addr, (char *) buf, size);
1091 }
1092
1093 /* Get general-purpose registers for LWP. */
1094
1095 ps_err_e
1096 ps_lgetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, prgregset_t gregset)
1097 {
1098 struct cleanup *old_chain;
1099
1100 old_chain = save_inferior_ptid ();
1101
1102 inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
1103
1104 if (target_has_execution)
1105 procfs_ops.to_fetch_registers (-1);
1106 else
1107 orig_core_ops.to_fetch_registers (-1);
1108 fill_gregset ((gdb_gregset_t *) gregset, -1);
1109
1110 do_cleanups (old_chain);
1111
1112 return PS_OK;
1113 }
1114
1115 /* Set general-purpose registers for LWP. */
1116
1117 ps_err_e
1118 ps_lsetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
1119 const prgregset_t gregset)
1120 {
1121 struct cleanup *old_chain;
1122
1123 old_chain = save_inferior_ptid ();
1124
1125 inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
1126
1127 supply_gregset ((gdb_gregset_t *) gregset);
1128 if (target_has_execution)
1129 procfs_ops.to_store_registers (-1);
1130 else
1131 orig_core_ops.to_store_registers (-1);
1132
1133 do_cleanups (old_chain);
1134
1135 return PS_OK;
1136 }
1137
1138 /* Log a message (sends to gdb_stderr). */
1139
1140 void
1141 ps_plog (const char *fmt, ...)
1142 {
1143 va_list args;
1144
1145 va_start (args, fmt);
1146
1147 vfprintf_filtered (gdb_stderr, fmt, args);
1148 }
1149
1150 /* Get size of extra register set. Currently a noop. */
1151
1152 ps_err_e
1153 ps_lgetxregsize (gdb_ps_prochandle_t ph, lwpid_t lwpid, int *xregsize)
1154 {
1155 #if 0
1156 int lwp_fd;
1157 int regsize;
1158 ps_err_e val;
1159
1160 val = get_lwp_fd (ph, lwpid, &lwp_fd);
1161 if (val != PS_OK)
1162 return val;
1163
1164 if (ioctl (lwp_fd, PIOCGXREGSIZE, &regsize))
1165 {
1166 if (errno == EINVAL)
1167 return PS_NOFREGS; /* XXX Wrong code, but this is the closest
1168 thing in proc_service.h */
1169
1170 print_sys_errmsg ("ps_lgetxregsize (): PIOCGXREGSIZE", errno);
1171 return PS_ERR;
1172 }
1173 #endif
1174
1175 return PS_OK;
1176 }
1177
1178 /* Get extra register set. Currently a noop. */
1179
1180 ps_err_e
1181 ps_lgetxregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, caddr_t xregset)
1182 {
1183 #if 0
1184 int lwp_fd;
1185 ps_err_e val;
1186
1187 val = get_lwp_fd (ph, lwpid, &lwp_fd);
1188 if (val != PS_OK)
1189 return val;
1190
1191 if (ioctl (lwp_fd, PIOCGXREG, xregset))
1192 {
1193 print_sys_errmsg ("ps_lgetxregs (): PIOCGXREG", errno);
1194 return PS_ERR;
1195 }
1196 #endif
1197
1198 return PS_OK;
1199 }
1200
1201 /* Set extra register set. Currently a noop. */
1202
1203 ps_err_e
1204 ps_lsetxregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, caddr_t xregset)
1205 {
1206 #if 0
1207 int lwp_fd;
1208 ps_err_e val;
1209
1210 val = get_lwp_fd (ph, lwpid, &lwp_fd);
1211 if (val != PS_OK)
1212 return val;
1213
1214 if (ioctl (lwp_fd, PIOCSXREG, xregset))
1215 {
1216 print_sys_errmsg ("ps_lsetxregs (): PIOCSXREG", errno);
1217 return PS_ERR;
1218 }
1219 #endif
1220
1221 return PS_OK;
1222 }
1223
1224 /* Get floating-point registers for LWP. */
1225
1226 ps_err_e
1227 ps_lgetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
1228 prfpregset_t *fpregset)
1229 {
1230 struct cleanup *old_chain;
1231
1232 old_chain = save_inferior_ptid ();
1233
1234 inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
1235
1236 if (target_has_execution)
1237 procfs_ops.to_fetch_registers (-1);
1238 else
1239 orig_core_ops.to_fetch_registers (-1);
1240 fill_fpregset ((gdb_fpregset_t *) fpregset, -1);
1241
1242 do_cleanups (old_chain);
1243
1244 return PS_OK;
1245 }
1246
1247 /* Set floating-point regs for LWP */
1248
1249 ps_err_e
1250 ps_lsetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
1251 const prfpregset_t * fpregset)
1252 {
1253 struct cleanup *old_chain;
1254
1255 old_chain = save_inferior_ptid ();
1256
1257 inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
1258
1259 supply_fpregset ((gdb_fpregset_t *) fpregset);
1260 if (target_has_execution)
1261 procfs_ops.to_store_registers (-1);
1262 else
1263 orig_core_ops.to_store_registers (-1);
1264
1265 do_cleanups (old_chain);
1266
1267 return PS_OK;
1268 }
1269
1270 #ifdef PR_MODEL_LP64
1271 /* Identify process as 32-bit or 64-bit. At the moment we're using
1272 BFD to do this. There might be a more Solaris-specific
1273 (e.g. procfs) method, but this ought to work. */
1274
1275 ps_err_e
1276 ps_pdmodel (gdb_ps_prochandle_t ph, int *data_model)
1277 {
1278 if (exec_bfd == 0)
1279 *data_model = PR_MODEL_UNKNOWN;
1280 else if (bfd_get_arch_size (exec_bfd) == 32)
1281 *data_model = PR_MODEL_ILP32;
1282 else
1283 *data_model = PR_MODEL_LP64;
1284
1285 return PS_OK;
1286 }
1287 #endif /* PR_MODEL_LP64 */
1288
1289 #ifdef TM_I386SOL2_H
1290
1291 /* Reads the local descriptor table of a LWP. */
1292
1293 ps_err_e
1294 ps_lgetLDT (gdb_ps_prochandle_t ph, lwpid_t lwpid,
1295 struct ssd *pldt)
1296 {
1297 /* NOTE: only used on Solaris, therefore OK to refer to procfs.c. */
1298 extern struct ssd *procfs_find_LDT_entry (ptid_t);
1299 struct ssd *ret;
1300
1301 /* FIXME: can't I get the process ID from the prochandle or
1302 something? */
1303
1304 if (PIDGET (inferior_ptid) <= 0 || lwpid <= 0)
1305 return PS_BADLID;
1306
1307 ret = procfs_find_LDT_entry (BUILD_LWP (lwpid, PIDGET (inferior_ptid)));
1308 if (ret)
1309 {
1310 memcpy (pldt, ret, sizeof (struct ssd));
1311 return PS_OK;
1312 }
1313 else
1314 /* LDT not found. */
1315 return PS_ERR;
1316 }
1317 #endif /* TM_I386SOL2_H */
1318 \f
1319
1320 /* Convert PTID to printable form. */
1321
1322 char *
1323 solaris_pid_to_str (ptid_t ptid)
1324 {
1325 static char buf[100];
1326
1327 /* In case init failed to resolve the libthread_db library. */
1328 if (!procfs_suppress_run)
1329 return procfs_pid_to_str (ptid);
1330
1331 if (is_thread (ptid))
1332 {
1333 ptid_t lwp;
1334
1335 lwp = thread_to_lwp (ptid, -2);
1336
1337 if (PIDGET (lwp) == -1)
1338 sprintf (buf, "Thread %ld (defunct)", GET_THREAD (ptid));
1339 else if (PIDGET (lwp) != -2)
1340 sprintf (buf, "Thread %ld (LWP %ld)",
1341 GET_THREAD (ptid), GET_LWP (lwp));
1342 else
1343 sprintf (buf, "Thread %ld ", GET_THREAD (ptid));
1344 }
1345 else if (GET_LWP (ptid) != 0)
1346 sprintf (buf, "LWP %ld ", GET_LWP (ptid));
1347 else
1348 sprintf (buf, "process %d ", PIDGET (ptid));
1349
1350 return buf;
1351 }
1352 \f
1353
1354 /* Worker bee for find_new_threads. Callback function that gets
1355 called once per user-level thread (i.e. not for LWP's). */
1356
1357 static int
1358 sol_find_new_threads_callback (const td_thrhandle_t *th, void *ignored)
1359 {
1360 td_err_e retval;
1361 td_thrinfo_t ti;
1362 ptid_t ptid;
1363
1364 retval = p_td_thr_get_info (th, &ti);
1365 if (retval != TD_OK)
1366 return -1;
1367
1368 ptid = BUILD_THREAD (ti.ti_tid, PIDGET (inferior_ptid));
1369 if (!in_thread_list (ptid))
1370 add_thread (ptid);
1371
1372 return 0;
1373 }
1374
1375 static void
1376 sol_find_new_threads (void)
1377 {
1378 /* Don't do anything if init failed to resolve the libthread_db
1379 library. */
1380 if (!procfs_suppress_run)
1381 return;
1382
1383 if (PIDGET (inferior_ptid) == -1)
1384 {
1385 printf_filtered ("No process.\n");
1386 return;
1387 }
1388
1389 /* First Find any new LWP's. */
1390 procfs_ops.to_find_new_threads ();
1391
1392 /* Then find any new user-level threads. */
1393 p_td_ta_thr_iter (main_ta, sol_find_new_threads_callback, (void *) 0,
1394 TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
1395 TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
1396 }
1397
1398 static void
1399 sol_core_open (char *filename, int from_tty)
1400 {
1401 orig_core_ops.to_open (filename, from_tty);
1402 }
1403
1404 static void
1405 sol_core_close (int quitting)
1406 {
1407 orig_core_ops.to_close (quitting);
1408 }
1409
1410 static void
1411 sol_core_detach (char *args, int from_tty)
1412 {
1413 unpush_target (&core_ops);
1414 orig_core_ops.to_detach (args, from_tty);
1415 }
1416
1417 static void
1418 sol_core_files_info (struct target_ops *t)
1419 {
1420 orig_core_ops.to_files_info (t);
1421 }
1422
1423 /* Worker bee for the "info sol-thread" command. This is a callback
1424 function that gets called once for each Solaris user-level thread
1425 (i.e. not for LWPs) in the inferior. Print anything interesting
1426 that we can think of. */
1427
1428 static int
1429 info_cb (const td_thrhandle_t *th, void *s)
1430 {
1431 td_err_e ret;
1432 td_thrinfo_t ti;
1433
1434 ret = p_td_thr_get_info (th, &ti);
1435 if (ret == TD_OK)
1436 {
1437 printf_filtered ("%s thread #%d, lwp %d, ",
1438 ti.ti_type == TD_THR_SYSTEM ? "system" : "user ",
1439 ti.ti_tid, ti.ti_lid);
1440 switch (ti.ti_state)
1441 {
1442 default:
1443 case TD_THR_UNKNOWN:
1444 printf_filtered ("<unknown state>");
1445 break;
1446 case TD_THR_STOPPED:
1447 printf_filtered ("(stopped)");
1448 break;
1449 case TD_THR_RUN:
1450 printf_filtered ("(run) ");
1451 break;
1452 case TD_THR_ACTIVE:
1453 printf_filtered ("(active) ");
1454 break;
1455 case TD_THR_ZOMBIE:
1456 printf_filtered ("(zombie) ");
1457 break;
1458 case TD_THR_SLEEP:
1459 printf_filtered ("(asleep) ");
1460 break;
1461 case TD_THR_STOPPED_ASLEEP:
1462 printf_filtered ("(stopped asleep)");
1463 break;
1464 }
1465 /* Print thr_create start function. */
1466 if (ti.ti_startfunc != 0)
1467 {
1468 struct minimal_symbol *msym;
1469 msym = lookup_minimal_symbol_by_pc (ti.ti_startfunc);
1470 if (msym)
1471 printf_filtered (" startfunc: %s\n",
1472 DEPRECATED_SYMBOL_NAME (msym));
1473 else
1474 printf_filtered (" startfunc: 0x%s\n", paddr (ti.ti_startfunc));
1475 }
1476
1477 /* If thread is asleep, print function that went to sleep. */
1478 if (ti.ti_state == TD_THR_SLEEP)
1479 {
1480 struct minimal_symbol *msym;
1481 msym = lookup_minimal_symbol_by_pc (ti.ti_pc);
1482 if (msym)
1483 printf_filtered (" - Sleep func: %s\n",
1484 DEPRECATED_SYMBOL_NAME (msym));
1485 else
1486 printf_filtered (" - Sleep func: 0x%s\n", paddr (ti.ti_startfunc));
1487 }
1488
1489 /* Wrap up line, if necessary. */
1490 if (ti.ti_state != TD_THR_SLEEP && ti.ti_startfunc == 0)
1491 printf_filtered ("\n"); /* don't you hate counting newlines? */
1492 }
1493 else
1494 warning ("info sol-thread: failed to get info for thread.");
1495
1496 return 0;
1497 }
1498
1499 /* List some state about each Solaris user-level thread in the
1500 inferior. */
1501
1502 static void
1503 info_solthreads (char *args, int from_tty)
1504 {
1505 p_td_ta_thr_iter (main_ta, info_cb, args,
1506 TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
1507 TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
1508 }
1509
1510 static int
1511 sol_find_memory_regions (int (*func) (CORE_ADDR, unsigned long,
1512 int, int, int, void *),
1513 void *data)
1514 {
1515 return procfs_ops.to_find_memory_regions (func, data);
1516 }
1517
1518 static char *
1519 sol_make_note_section (bfd *obfd, int *note_size)
1520 {
1521 return procfs_ops.to_make_corefile_notes (obfd, note_size);
1522 }
1523
1524 static int
1525 ignore (CORE_ADDR addr, char *contents)
1526 {
1527 return 0;
1528 }
1529
1530 static void
1531 init_sol_thread_ops (void)
1532 {
1533 sol_thread_ops.to_shortname = "solaris-threads";
1534 sol_thread_ops.to_longname = "Solaris threads and pthread.";
1535 sol_thread_ops.to_doc = "Solaris threads and pthread support.";
1536 sol_thread_ops.to_open = sol_thread_open;
1537 sol_thread_ops.to_attach = sol_thread_attach;
1538 sol_thread_ops.to_detach = sol_thread_detach;
1539 sol_thread_ops.to_resume = sol_thread_resume;
1540 sol_thread_ops.to_wait = sol_thread_wait;
1541 sol_thread_ops.to_fetch_registers = sol_thread_fetch_registers;
1542 sol_thread_ops.to_store_registers = sol_thread_store_registers;
1543 sol_thread_ops.to_prepare_to_store = sol_thread_prepare_to_store;
1544 sol_thread_ops.deprecated_xfer_memory = sol_thread_xfer_memory;
1545 sol_thread_ops.to_xfer_partial = sol_thread_xfer_partial;
1546 sol_thread_ops.to_files_info = sol_thread_files_info;
1547 sol_thread_ops.to_insert_breakpoint = memory_insert_breakpoint;
1548 sol_thread_ops.to_remove_breakpoint = memory_remove_breakpoint;
1549 sol_thread_ops.to_terminal_init = terminal_init_inferior;
1550 sol_thread_ops.to_terminal_inferior = terminal_inferior;
1551 sol_thread_ops.to_terminal_ours_for_output = terminal_ours_for_output;
1552 sol_thread_ops.to_terminal_ours = terminal_ours;
1553 sol_thread_ops.to_terminal_save_ours = terminal_save_ours;
1554 sol_thread_ops.to_terminal_info = child_terminal_info;
1555 sol_thread_ops.to_kill = sol_thread_kill_inferior;
1556 sol_thread_ops.to_create_inferior = sol_thread_create_inferior;
1557 sol_thread_ops.to_mourn_inferior = sol_thread_mourn_inferior;
1558 sol_thread_ops.to_can_run = sol_thread_can_run;
1559 sol_thread_ops.to_notice_signals = sol_thread_notice_signals;
1560 sol_thread_ops.to_thread_alive = sol_thread_alive;
1561 sol_thread_ops.to_pid_to_str = solaris_pid_to_str;
1562 sol_thread_ops.to_find_new_threads = sol_find_new_threads;
1563 sol_thread_ops.to_stop = sol_thread_stop;
1564 sol_thread_ops.to_stratum = process_stratum;
1565 sol_thread_ops.to_has_all_memory = 1;
1566 sol_thread_ops.to_has_memory = 1;
1567 sol_thread_ops.to_has_stack = 1;
1568 sol_thread_ops.to_has_registers = 1;
1569 sol_thread_ops.to_has_execution = 1;
1570 sol_thread_ops.to_has_thread_control = tc_none;
1571 sol_thread_ops.to_find_memory_regions = sol_find_memory_regions;
1572 sol_thread_ops.to_make_corefile_notes = sol_make_note_section;
1573 sol_thread_ops.to_magic = OPS_MAGIC;
1574 }
1575
1576 static void
1577 init_sol_core_ops (void)
1578 {
1579 sol_core_ops.to_shortname = "solaris-core";
1580 sol_core_ops.to_longname = "Solaris core threads and pthread.";
1581 sol_core_ops.to_doc = "Solaris threads and pthread support for core files.";
1582 sol_core_ops.to_open = sol_core_open;
1583 sol_core_ops.to_close = sol_core_close;
1584 sol_core_ops.to_attach = sol_thread_attach;
1585 sol_core_ops.to_detach = sol_core_detach;
1586 sol_core_ops.to_fetch_registers = sol_thread_fetch_registers;
1587 sol_core_ops.deprecated_xfer_memory = sol_thread_xfer_memory;
1588 sol_core_ops.to_xfer_partial = sol_thread_xfer_partial;
1589 sol_core_ops.to_files_info = sol_core_files_info;
1590 sol_core_ops.to_insert_breakpoint = ignore;
1591 sol_core_ops.to_remove_breakpoint = ignore;
1592 sol_core_ops.to_create_inferior = sol_thread_create_inferior;
1593 sol_core_ops.to_stratum = core_stratum;
1594 sol_core_ops.to_has_memory = 1;
1595 sol_core_ops.to_has_stack = 1;
1596 sol_core_ops.to_has_registers = 1;
1597 sol_core_ops.to_has_thread_control = tc_none;
1598 sol_core_ops.to_thread_alive = sol_thread_alive;
1599 sol_core_ops.to_pid_to_str = solaris_pid_to_str;
1600 /* On Solaris/x86, when debugging a threaded core file from process
1601 <n>, the following causes "info threads" to produce "procfs:
1602 couldn't find pid <n> in procinfo list" where <n> is the pid of
1603 the process that produced the core file. Disable it for now. */
1604 #if 0
1605 sol_core_ops.to_find_new_threads = sol_find_new_threads;
1606 #endif
1607 sol_core_ops.to_magic = OPS_MAGIC;
1608 }
1609
1610 /* We suppress the call to add_target of core_ops in corelow because
1611 if there are two targets in the stratum core_stratum,
1612 find_core_target won't know which one to return. See corelow.c for
1613 an additonal comment on coreops_suppress_target. */
1614 int coreops_suppress_target = 1;
1615
1616 void
1617 _initialize_sol_thread (void)
1618 {
1619 void *dlhandle;
1620
1621 init_sol_thread_ops ();
1622 init_sol_core_ops ();
1623
1624 dlhandle = dlopen ("libthread_db.so.1", RTLD_NOW);
1625 if (!dlhandle)
1626 goto die;
1627
1628 #define resolve(X) \
1629 if (!(p_##X = dlsym (dlhandle, #X))) \
1630 goto die;
1631
1632 resolve (td_log);
1633 resolve (td_ta_new);
1634 resolve (td_ta_delete);
1635 resolve (td_init);
1636 resolve (td_ta_get_ph);
1637 resolve (td_ta_get_nthreads);
1638 resolve (td_ta_tsd_iter);
1639 resolve (td_ta_thr_iter);
1640 resolve (td_thr_validate);
1641 resolve (td_thr_tsd);
1642 resolve (td_thr_get_info);
1643 resolve (td_thr_getfpregs);
1644 resolve (td_thr_getxregsize);
1645 resolve (td_thr_getxregs);
1646 resolve (td_thr_sigsetmask);
1647 resolve (td_thr_setprio);
1648 resolve (td_thr_setsigpending);
1649 resolve (td_thr_setfpregs);
1650 resolve (td_thr_setxregs);
1651 resolve (td_ta_map_id2thr);
1652 resolve (td_ta_map_lwp2thr);
1653 resolve (td_thr_getgregs);
1654 resolve (td_thr_setgregs);
1655
1656 add_target (&sol_thread_ops);
1657
1658 procfs_suppress_run = 1;
1659
1660 add_cmd ("sol-threads", class_maintenance, info_solthreads,
1661 "Show info on Solaris user threads.\n", &maintenanceinfolist);
1662
1663 memcpy (&orig_core_ops, &core_ops, sizeof (struct target_ops));
1664 memcpy (&core_ops, &sol_core_ops, sizeof (struct target_ops));
1665 add_target (&core_ops);
1666
1667 /* Hook into new_objfile notification. */
1668 target_new_objfile_chain = deprecated_target_new_objfile_hook;
1669 deprecated_target_new_objfile_hook = sol_thread_new_objfile;
1670 return;
1671
1672 die:
1673 fprintf_unfiltered (gdb_stderr, "\
1674 [GDB will not be able to debug user-mode threads: %s]\n", dlerror ());
1675
1676 if (dlhandle)
1677 dlclose (dlhandle);
1678
1679 /* Allow the user to debug non-threaded core files. */
1680 add_target (&core_ops);
1681
1682 return;
1683 }
This page took 0.064168 seconds and 3 git commands to generate.