* procfs.c (to_attach): Create a procinfo for the current lwp.
[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, 2008 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 3 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, see <http://www.gnu.org/licenses/>. */
20
21 /* This module implements a sort of half target that sits between the
22 machine-independent parts of GDB and the /proc interface (procfs.c)
23 to provide access to the Solaris user-mode thread implementation.
24
25 Solaris threads are true user-mode threads, which are invoked via
26 the thr_* and pthread_* (native and POSIX respectivly) interfaces.
27 These are mostly implemented in user-space, with all thread context
28 kept in various structures that live in the user's heap. These
29 should not be confused with lightweight processes (LWPs), which are
30 implemented by the kernel, and scheduled without explicit
31 intervention by the process.
32
33 Just to confuse things a little, Solaris threads (both native and
34 POSIX) are actually implemented using LWPs. In general, there are
35 going to be more threads than LWPs. There is no fixed
36 correspondence between a thread and an LWP. When a thread wants to
37 run, it gets scheduled onto the first available LWP and can
38 therefore migrate from one LWP to another as time goes on. A
39 sleeping thread may not be associated with an LWP at all!
40
41 To make it possible to mess with threads, Sun provides a library
42 called libthread_db.so.1 (not to be confused with
43 libthread_db.so.0, which doesn't have a published interface). This
44 interface has an upper part, which it provides, and a lower part
45 which we provide. The upper part consists of the td_* routines,
46 which allow us to find all the threads, query their state, etc...
47 The lower part consists of all of the ps_*, which are used by the
48 td_* routines to read/write memory, manipulate LWPs, lookup
49 symbols, etc... The ps_* routines actually do most of their work
50 by calling functions in procfs.c. */
51
52 #include "defs.h"
53 #include <thread.h>
54 #include <proc_service.h>
55 #include <thread_db.h>
56 #include "gdbthread.h"
57 #include "target.h"
58 #include "inferior.h"
59 #include <fcntl.h>
60 #include "gdb_stat.h"
61 #include <dlfcn.h>
62 #include "gdbcmd.h"
63 #include "gdbcore.h"
64 #include "regcache.h"
65 #include "solib.h"
66 #include "symfile.h"
67 #include "observer.h"
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_LWP.
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 sol_thread_active = 0;
354 procfs_ops.to_attach (args, from_tty);
355
356 /* Must get symbols from shared libraries before libthread_db can run! */
357 solib_add (NULL, from_tty, (struct target_ops *) 0, auto_solib_add);
358
359 if (sol_thread_active)
360 {
361 ptid_t ptid;
362 printf_filtered ("sol-thread active.\n");
363 main_ph.ptid = inferior_ptid; /* Save for xfer_memory. */
364 push_target (&sol_thread_ops);
365 ptid = lwp_to_thread (inferior_ptid);
366 if (PIDGET (ptid) != -1)
367 thread_change_ptid (inferior_ptid, 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 sol_thread_active = 0;
385 inferior_ptid = pid_to_ptid (PIDGET (main_ph.ptid));
386 unpush_target (&sol_thread_ops);
387 procfs_ops.to_detach (args, from_tty);
388 }
389
390 /* Resume execution of process PTID. If STEP is nozero, then just
391 single step it. If SIGNAL is nonzero, restart it with that signal
392 activated. We may have to convert PTID from a thread ID to an LWP
393 ID for procfs. */
394
395 static void
396 sol_thread_resume (ptid_t ptid, int step, enum target_signal signo)
397 {
398 struct cleanup *old_chain;
399
400 old_chain = save_inferior_ptid ();
401
402 inferior_ptid = thread_to_lwp (inferior_ptid, PIDGET (main_ph.ptid));
403 if (PIDGET (inferior_ptid) == -1)
404 inferior_ptid = procfs_first_available ();
405
406 if (PIDGET (ptid) != -1)
407 {
408 ptid_t save_ptid = ptid;
409
410 ptid = thread_to_lwp (ptid, -2);
411 if (PIDGET (ptid) == -2) /* Inactive thread. */
412 error (_("This version of Solaris can't start inactive threads."));
413 if (info_verbose && PIDGET (ptid) == -1)
414 warning (_("Specified thread %ld seems to have terminated"),
415 GET_THREAD (save_ptid));
416 }
417
418 procfs_ops.to_resume (ptid, step, signo);
419
420 do_cleanups (old_chain);
421 }
422
423 /* Wait for any threads to stop. We may have to convert PTID from a
424 thread ID to an LWP ID, and vice versa on the way out. */
425
426 static ptid_t
427 sol_thread_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
428 {
429 ptid_t rtnval;
430 ptid_t save_ptid;
431 struct cleanup *old_chain;
432
433 save_ptid = inferior_ptid;
434 old_chain = save_inferior_ptid ();
435
436 inferior_ptid = thread_to_lwp (inferior_ptid, PIDGET (main_ph.ptid));
437 if (PIDGET (inferior_ptid) == -1)
438 inferior_ptid = procfs_first_available ();
439
440 if (PIDGET (ptid) != -1)
441 {
442 ptid_t save_ptid = ptid;
443
444 ptid = thread_to_lwp (ptid, -2);
445 if (PIDGET (ptid) == -2) /* Inactive thread. */
446 error (_("This version of Solaris can't start inactive threads."));
447 if (info_verbose && PIDGET (ptid) == -1)
448 warning (_("Specified thread %ld seems to have terminated"),
449 GET_THREAD (save_ptid));
450 }
451
452 rtnval = procfs_ops.to_wait (ptid, ourstatus);
453
454 if (ourstatus->kind != TARGET_WAITKIND_EXITED)
455 {
456 /* Map the LWP of interest back to the appropriate thread ID. */
457 rtnval = lwp_to_thread (rtnval);
458 if (PIDGET (rtnval) == -1)
459 rtnval = save_ptid;
460
461 /* See if we have a new thread. */
462 if (is_thread (rtnval)
463 && !ptid_equal (rtnval, save_ptid)
464 && (!in_thread_list (rtnval)
465 || is_exited (rtnval)))
466 add_thread (rtnval);
467 }
468
469 /* During process initialization, we may get here without the thread
470 package being initialized, since that can only happen after we've
471 found the shared libs. */
472
473 do_cleanups (old_chain);
474
475 return rtnval;
476 }
477
478 static void
479 sol_thread_fetch_registers (struct regcache *regcache, int regnum)
480 {
481 thread_t thread;
482 td_thrhandle_t thandle;
483 td_err_e val;
484 prgregset_t gregset;
485 prfpregset_t fpregset;
486 gdb_gregset_t *gregset_p = &gregset;
487 gdb_fpregset_t *fpregset_p = &fpregset;
488
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_p);
536 supply_fpregset (regcache, (const gdb_fpregset_t *) fpregset_p);
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 sol_thread_active = 0;
760 procfs_ops.to_create_inferior (exec_file, allargs, env, from_tty);
761
762 if (sol_thread_active && !ptid_equal (inferior_ptid, null_ptid))
763 {
764 ptid_t ptid;
765
766 /* Save for xfer_memory. */
767 main_ph.ptid = inferior_ptid;
768
769 push_target (&sol_thread_ops);
770
771 ptid = lwp_to_thread (inferior_ptid);
772 if (PIDGET (ptid) != -1)
773 thread_change_ptid (inferior_ptid, 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 sol_thread_active = 0;
828 unpush_target (&sol_thread_ops);
829 procfs_ops.to_mourn_inferior ();
830 }
831
832 /* Mark our target-struct as eligible for stray "run" and "attach"
833 commands. */
834
835 static int
836 sol_thread_can_run (void)
837 {
838 return procfs_suppress_run;
839 }
840
841 /*
842
843 LOCAL FUNCTION
844
845 sol_thread_alive - test thread for "aliveness"
846
847 SYNOPSIS
848
849 static bool sol_thread_alive (ptid_t ptid);
850
851 DESCRIPTION
852
853 returns true if thread still active in inferior.
854
855 */
856
857 /* Return true if PTID is still active in the inferior. */
858
859 static int
860 sol_thread_alive (ptid_t ptid)
861 {
862 if (is_thread (ptid))
863 {
864 /* It's a (user-level) thread. */
865 td_err_e val;
866 td_thrhandle_t th;
867 int pid;
868
869 pid = GET_THREAD (ptid);
870 if ((val = p_td_ta_map_id2thr (main_ta, pid, &th)) != TD_OK)
871 return 0; /* Thread not found. */
872 if ((val = p_td_thr_validate (&th)) != TD_OK)
873 return 0; /* Thread not valid. */
874 return 1; /* Known thread. */
875 }
876 else
877 {
878 /* It's an LPW; pass the request on to procfs. */
879 if (target_has_execution)
880 return procfs_ops.to_thread_alive (ptid);
881 else
882 return orig_core_ops.to_thread_alive (ptid);
883 }
884 }
885
886 static void
887 sol_thread_stop (ptid_t ptid)
888 {
889 procfs_ops.to_stop (ptid);
890 }
891 \f
892 /* These routines implement the lower half of the thread_db interface,
893 i.e. the ps_* routines. */
894
895 /* Various versions of <proc_service.h> have slightly different
896 function prototypes. In particular, we have
897
898 NEWER OLDER
899 struct ps_prochandle * const struct ps_prochandle *
900 void* char*
901 const void* char*
902 int size_t
903
904 Which one you have depends on the Solaris version and what patches
905 you've applied. On the theory that there are only two major
906 variants, we have configure check the prototype of ps_pdwrite (),
907 and use that info to make appropriate typedefs here. */
908
909 #ifdef PROC_SERVICE_IS_OLD
910 typedef const struct ps_prochandle *gdb_ps_prochandle_t;
911 typedef char *gdb_ps_read_buf_t;
912 typedef char *gdb_ps_write_buf_t;
913 typedef int gdb_ps_size_t;
914 typedef psaddr_t gdb_ps_addr_t;
915 #else
916 typedef struct ps_prochandle *gdb_ps_prochandle_t;
917 typedef void *gdb_ps_read_buf_t;
918 typedef const void *gdb_ps_write_buf_t;
919 typedef size_t gdb_ps_size_t;
920 typedef psaddr_t gdb_ps_addr_t;
921 #endif
922
923 /* The next four routines are called by libthread_db to tell us to
924 stop and stop a particular process or lwp. Since GDB ensures that
925 these are all stopped by the time we call anything in thread_db,
926 these routines need to do nothing. */
927
928 /* Process stop. */
929
930 ps_err_e
931 ps_pstop (gdb_ps_prochandle_t ph)
932 {
933 return PS_OK;
934 }
935
936 /* Process continue. */
937
938 ps_err_e
939 ps_pcontinue (gdb_ps_prochandle_t ph)
940 {
941 return PS_OK;
942 }
943
944 /* LWP stop. */
945
946 ps_err_e
947 ps_lstop (gdb_ps_prochandle_t ph, lwpid_t lwpid)
948 {
949 return PS_OK;
950 }
951
952 /* LWP continue. */
953
954 ps_err_e
955 ps_lcontinue (gdb_ps_prochandle_t ph, lwpid_t lwpid)
956 {
957 return PS_OK;
958 }
959
960 /* Looks up the symbol LD_SYMBOL_NAME in the debugger's symbol table. */
961
962 ps_err_e
963 ps_pglobal_lookup (gdb_ps_prochandle_t ph, const char *ld_object_name,
964 const char *ld_symbol_name, gdb_ps_addr_t *ld_symbol_addr)
965 {
966 struct minimal_symbol *ms;
967
968 ms = lookup_minimal_symbol (ld_symbol_name, NULL, NULL);
969 if (!ms)
970 return PS_NOSYM;
971
972 *ld_symbol_addr = SYMBOL_VALUE_ADDRESS (ms);
973 return PS_OK;
974 }
975
976 /* Common routine for reading and writing memory. */
977
978 static ps_err_e
979 rw_common (int dowrite, const struct ps_prochandle *ph, gdb_ps_addr_t addr,
980 char *buf, int size)
981 {
982 struct cleanup *old_chain;
983
984 old_chain = save_inferior_ptid ();
985
986 if (is_thread (inferior_ptid) || !target_thread_alive (inferior_ptid))
987 {
988 /* It's either a thread or an LWP that isn't alive. Any live
989 LWP will do so use the first available.
990
991 NOTE: We don't need to call switch_to_thread; we're just
992 reading memory. */
993 inferior_ptid = procfs_first_available ();
994 }
995
996 #if defined (__sparcv9)
997 /* For Sparc64 cross Sparc32, make sure the address has not been
998 accidentally sign-extended (or whatever) to beyond 32 bits. */
999 if (bfd_get_arch_size (exec_bfd) == 32)
1000 addr &= 0xffffffff;
1001 #endif
1002
1003 while (size > 0)
1004 {
1005 int cc;
1006
1007 /* FIXME: passing 0 as attrib argument. */
1008 if (target_has_execution)
1009 cc = procfs_ops.deprecated_xfer_memory (addr, buf, size,
1010 dowrite, 0, &procfs_ops);
1011 else
1012 cc = orig_core_ops.deprecated_xfer_memory (addr, buf, size,
1013 dowrite, 0, &core_ops);
1014
1015 if (cc < 0)
1016 {
1017 if (dowrite == 0)
1018 print_sys_errmsg ("rw_common (): read", errno);
1019 else
1020 print_sys_errmsg ("rw_common (): write", errno);
1021
1022 do_cleanups (old_chain);
1023
1024 return PS_ERR;
1025 }
1026 else if (cc == 0)
1027 {
1028 if (dowrite == 0)
1029 warning (_("rw_common (): unable to read at addr 0x%lx"),
1030 (long) addr);
1031 else
1032 warning (_("rw_common (): unable to write at addr 0x%lx"),
1033 (long) addr);
1034
1035 do_cleanups (old_chain);
1036
1037 return PS_ERR;
1038 }
1039
1040 size -= cc;
1041 buf += cc;
1042 }
1043
1044 do_cleanups (old_chain);
1045
1046 return PS_OK;
1047 }
1048
1049 /* Copies SIZE bytes from target process .data segment to debugger memory. */
1050
1051 ps_err_e
1052 ps_pdread (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
1053 gdb_ps_read_buf_t buf, gdb_ps_size_t size)
1054 {
1055 return rw_common (0, ph, addr, buf, size);
1056 }
1057
1058 /* Copies SIZE bytes from debugger memory .data segment to target process. */
1059
1060 ps_err_e
1061 ps_pdwrite (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
1062 gdb_ps_write_buf_t buf, gdb_ps_size_t size)
1063 {
1064 return rw_common (1, ph, addr, (char *) buf, size);
1065 }
1066
1067 /* Copies SIZE bytes from target process .text segment to debugger memory. */
1068
1069 ps_err_e
1070 ps_ptread (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
1071 gdb_ps_read_buf_t buf, gdb_ps_size_t size)
1072 {
1073 return rw_common (0, ph, addr, buf, size);
1074 }
1075
1076 /* Copies SIZE bytes from debugger memory .text segment to target process. */
1077
1078 ps_err_e
1079 ps_ptwrite (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
1080 gdb_ps_write_buf_t buf, gdb_ps_size_t size)
1081 {
1082 return rw_common (1, ph, addr, (char *) buf, size);
1083 }
1084
1085 /* Get general-purpose registers for LWP. */
1086
1087 ps_err_e
1088 ps_lgetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, prgregset_t gregset)
1089 {
1090 struct cleanup *old_chain;
1091 struct regcache *regcache;
1092
1093 old_chain = save_inferior_ptid ();
1094
1095 inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
1096 regcache = get_thread_regcache (inferior_ptid);
1097
1098 if (target_has_execution)
1099 procfs_ops.to_fetch_registers (regcache, -1);
1100 else
1101 orig_core_ops.to_fetch_registers (regcache, -1);
1102 fill_gregset (regcache, (gdb_gregset_t *) gregset, -1);
1103
1104 do_cleanups (old_chain);
1105
1106 return PS_OK;
1107 }
1108
1109 /* Set general-purpose registers for LWP. */
1110
1111 ps_err_e
1112 ps_lsetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
1113 const prgregset_t gregset)
1114 {
1115 struct cleanup *old_chain;
1116 struct regcache *regcache;
1117
1118 old_chain = save_inferior_ptid ();
1119
1120 inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
1121 regcache = get_thread_regcache (inferior_ptid);
1122
1123 supply_gregset (regcache, (const gdb_gregset_t *) gregset);
1124 if (target_has_execution)
1125 procfs_ops.to_store_registers (regcache, -1);
1126 else
1127 orig_core_ops.to_store_registers (regcache, -1);
1128
1129 do_cleanups (old_chain);
1130
1131 return PS_OK;
1132 }
1133
1134 /* Log a message (sends to gdb_stderr). */
1135
1136 void
1137 ps_plog (const char *fmt, ...)
1138 {
1139 va_list args;
1140
1141 va_start (args, fmt);
1142
1143 vfprintf_filtered (gdb_stderr, fmt, args);
1144 }
1145
1146 /* Get size of extra register set. Currently a noop. */
1147
1148 ps_err_e
1149 ps_lgetxregsize (gdb_ps_prochandle_t ph, lwpid_t lwpid, int *xregsize)
1150 {
1151 #if 0
1152 int lwp_fd;
1153 int regsize;
1154 ps_err_e val;
1155
1156 val = get_lwp_fd (ph, lwpid, &lwp_fd);
1157 if (val != PS_OK)
1158 return val;
1159
1160 if (ioctl (lwp_fd, PIOCGXREGSIZE, &regsize))
1161 {
1162 if (errno == EINVAL)
1163 return PS_NOFREGS; /* XXX Wrong code, but this is the closest
1164 thing in proc_service.h */
1165
1166 print_sys_errmsg ("ps_lgetxregsize (): PIOCGXREGSIZE", errno);
1167 return PS_ERR;
1168 }
1169 #endif
1170
1171 return PS_OK;
1172 }
1173
1174 /* Get extra register set. Currently a noop. */
1175
1176 ps_err_e
1177 ps_lgetxregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, caddr_t xregset)
1178 {
1179 #if 0
1180 int lwp_fd;
1181 ps_err_e val;
1182
1183 val = get_lwp_fd (ph, lwpid, &lwp_fd);
1184 if (val != PS_OK)
1185 return val;
1186
1187 if (ioctl (lwp_fd, PIOCGXREG, xregset))
1188 {
1189 print_sys_errmsg ("ps_lgetxregs (): PIOCGXREG", errno);
1190 return PS_ERR;
1191 }
1192 #endif
1193
1194 return PS_OK;
1195 }
1196
1197 /* Set extra register set. Currently a noop. */
1198
1199 ps_err_e
1200 ps_lsetxregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, caddr_t xregset)
1201 {
1202 #if 0
1203 int lwp_fd;
1204 ps_err_e val;
1205
1206 val = get_lwp_fd (ph, lwpid, &lwp_fd);
1207 if (val != PS_OK)
1208 return val;
1209
1210 if (ioctl (lwp_fd, PIOCSXREG, xregset))
1211 {
1212 print_sys_errmsg ("ps_lsetxregs (): PIOCSXREG", errno);
1213 return PS_ERR;
1214 }
1215 #endif
1216
1217 return PS_OK;
1218 }
1219
1220 /* Get floating-point registers for LWP. */
1221
1222 ps_err_e
1223 ps_lgetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
1224 prfpregset_t *fpregset)
1225 {
1226 struct cleanup *old_chain;
1227 struct regcache *regcache;
1228
1229 old_chain = save_inferior_ptid ();
1230
1231 inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
1232 regcache = get_thread_regcache (inferior_ptid);
1233
1234 if (target_has_execution)
1235 procfs_ops.to_fetch_registers (regcache, -1);
1236 else
1237 orig_core_ops.to_fetch_registers (regcache, -1);
1238 fill_fpregset (regcache, (gdb_fpregset_t *) fpregset, -1);
1239
1240 do_cleanups (old_chain);
1241
1242 return PS_OK;
1243 }
1244
1245 /* Set floating-point regs for LWP */
1246
1247 ps_err_e
1248 ps_lsetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
1249 const prfpregset_t * fpregset)
1250 {
1251 struct cleanup *old_chain;
1252 struct regcache *regcache;
1253
1254 old_chain = save_inferior_ptid ();
1255
1256 inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
1257 regcache = get_thread_regcache (inferior_ptid);
1258
1259 supply_fpregset (regcache, (const gdb_fpregset_t *) fpregset);
1260 if (target_has_execution)
1261 procfs_ops.to_store_registers (regcache, -1);
1262 else
1263 orig_core_ops.to_store_registers (regcache, -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 #if (defined(__i386__) || defined(__x86_64__)) && defined (sun)
1290
1291 /* Reads the local descriptor table of a LWP.
1292
1293 This function is necessary on x86-solaris only. Without it, the loading
1294 of libthread_db would fail because of ps_lgetLDT being undefined. */
1295
1296 ps_err_e
1297 ps_lgetLDT (gdb_ps_prochandle_t ph, lwpid_t lwpid,
1298 struct ssd *pldt)
1299 {
1300 /* NOTE: only used on Solaris, therefore OK to refer to procfs.c. */
1301 extern struct ssd *procfs_find_LDT_entry (ptid_t);
1302 struct ssd *ret;
1303
1304 /* FIXME: can't I get the process ID from the prochandle or
1305 something? */
1306
1307 if (PIDGET (inferior_ptid) <= 0 || lwpid <= 0)
1308 return PS_BADLID;
1309
1310 ret = procfs_find_LDT_entry (BUILD_LWP (lwpid, PIDGET (inferior_ptid)));
1311 if (ret)
1312 {
1313 memcpy (pldt, ret, sizeof (struct ssd));
1314 return PS_OK;
1315 }
1316 else
1317 /* LDT not found. */
1318 return PS_ERR;
1319 }
1320 #endif
1321 \f
1322
1323 /* Convert PTID to printable form. */
1324
1325 char *
1326 solaris_pid_to_str (ptid_t ptid)
1327 {
1328 static char buf[100];
1329
1330 /* In case init failed to resolve the libthread_db library. */
1331 if (!procfs_suppress_run)
1332 return procfs_pid_to_str (ptid);
1333
1334 if (is_thread (ptid))
1335 {
1336 ptid_t lwp;
1337
1338 lwp = thread_to_lwp (ptid, -2);
1339
1340 if (PIDGET (lwp) == -1)
1341 sprintf (buf, "Thread %ld (defunct)", GET_THREAD (ptid));
1342 else if (PIDGET (lwp) != -2)
1343 sprintf (buf, "Thread %ld (LWP %ld)",
1344 GET_THREAD (ptid), GET_LWP (lwp));
1345 else
1346 sprintf (buf, "Thread %ld ", GET_THREAD (ptid));
1347 }
1348 else if (GET_LWP (ptid) != 0)
1349 sprintf (buf, "LWP %ld ", GET_LWP (ptid));
1350 else
1351 sprintf (buf, "process %d ", PIDGET (ptid));
1352
1353 return buf;
1354 }
1355 \f
1356
1357 /* Worker bee for find_new_threads. Callback function that gets
1358 called once per user-level thread (i.e. not for LWP's). */
1359
1360 static int
1361 sol_find_new_threads_callback (const td_thrhandle_t *th, void *ignored)
1362 {
1363 td_err_e retval;
1364 td_thrinfo_t ti;
1365 ptid_t ptid;
1366
1367 retval = p_td_thr_get_info (th, &ti);
1368 if (retval != TD_OK)
1369 return -1;
1370
1371 ptid = BUILD_THREAD (ti.ti_tid, PIDGET (inferior_ptid));
1372 if (!in_thread_list (ptid) || is_exited (ptid))
1373 add_thread (ptid);
1374
1375 return 0;
1376 }
1377
1378 static void
1379 sol_find_new_threads (void)
1380 {
1381 /* Don't do anything if init failed to resolve the libthread_db
1382 library. */
1383 if (!procfs_suppress_run)
1384 return;
1385
1386 if (PIDGET (inferior_ptid) == -1)
1387 {
1388 printf_filtered ("No process.\n");
1389 return;
1390 }
1391
1392 /* First Find any new LWP's. */
1393 procfs_ops.to_find_new_threads ();
1394
1395 /* Then find any new user-level threads. */
1396 p_td_ta_thr_iter (main_ta, sol_find_new_threads_callback, (void *) 0,
1397 TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
1398 TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
1399 }
1400
1401 static void
1402 sol_core_open (char *filename, int from_tty)
1403 {
1404 orig_core_ops.to_open (filename, from_tty);
1405 }
1406
1407 static void
1408 sol_core_close (int quitting)
1409 {
1410 orig_core_ops.to_close (quitting);
1411 }
1412
1413 static void
1414 sol_core_detach (char *args, int from_tty)
1415 {
1416 unpush_target (&core_ops);
1417 orig_core_ops.to_detach (args, from_tty);
1418 }
1419
1420 static void
1421 sol_core_files_info (struct target_ops *t)
1422 {
1423 orig_core_ops.to_files_info (t);
1424 }
1425
1426 /* Worker bee for the "info sol-thread" command. This is a callback
1427 function that gets called once for each Solaris user-level thread
1428 (i.e. not for LWPs) in the inferior. Print anything interesting
1429 that we can think of. */
1430
1431 static int
1432 info_cb (const td_thrhandle_t *th, void *s)
1433 {
1434 td_err_e ret;
1435 td_thrinfo_t ti;
1436
1437 ret = p_td_thr_get_info (th, &ti);
1438 if (ret == TD_OK)
1439 {
1440 printf_filtered ("%s thread #%d, lwp %d, ",
1441 ti.ti_type == TD_THR_SYSTEM ? "system" : "user ",
1442 ti.ti_tid, ti.ti_lid);
1443 switch (ti.ti_state)
1444 {
1445 default:
1446 case TD_THR_UNKNOWN:
1447 printf_filtered ("<unknown state>");
1448 break;
1449 case TD_THR_STOPPED:
1450 printf_filtered ("(stopped)");
1451 break;
1452 case TD_THR_RUN:
1453 printf_filtered ("(run) ");
1454 break;
1455 case TD_THR_ACTIVE:
1456 printf_filtered ("(active) ");
1457 break;
1458 case TD_THR_ZOMBIE:
1459 printf_filtered ("(zombie) ");
1460 break;
1461 case TD_THR_SLEEP:
1462 printf_filtered ("(asleep) ");
1463 break;
1464 case TD_THR_STOPPED_ASLEEP:
1465 printf_filtered ("(stopped asleep)");
1466 break;
1467 }
1468 /* Print thr_create start function. */
1469 if (ti.ti_startfunc != 0)
1470 {
1471 struct minimal_symbol *msym;
1472 msym = lookup_minimal_symbol_by_pc (ti.ti_startfunc);
1473 if (msym)
1474 printf_filtered (" startfunc: %s\n",
1475 SYMBOL_PRINT_NAME (msym));
1476 else
1477 printf_filtered (" startfunc: 0x%s\n", paddr (ti.ti_startfunc));
1478 }
1479
1480 /* If thread is asleep, print function that went to sleep. */
1481 if (ti.ti_state == TD_THR_SLEEP)
1482 {
1483 struct minimal_symbol *msym;
1484 msym = lookup_minimal_symbol_by_pc (ti.ti_pc);
1485 if (msym)
1486 printf_filtered (" - Sleep func: %s\n",
1487 SYMBOL_PRINT_NAME (msym));
1488 else
1489 printf_filtered (" - Sleep func: 0x%s\n", paddr (ti.ti_startfunc));
1490 }
1491
1492 /* Wrap up line, if necessary. */
1493 if (ti.ti_state != TD_THR_SLEEP && ti.ti_startfunc == 0)
1494 printf_filtered ("\n"); /* don't you hate counting newlines? */
1495 }
1496 else
1497 warning (_("info sol-thread: failed to get info for thread."));
1498
1499 return 0;
1500 }
1501
1502 /* List some state about each Solaris user-level thread in the
1503 inferior. */
1504
1505 static void
1506 info_solthreads (char *args, int from_tty)
1507 {
1508 p_td_ta_thr_iter (main_ta, info_cb, args,
1509 TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
1510 TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
1511 }
1512
1513 static int
1514 sol_find_memory_regions (int (*func) (CORE_ADDR, unsigned long,
1515 int, int, int, void *),
1516 void *data)
1517 {
1518 return procfs_ops.to_find_memory_regions (func, data);
1519 }
1520
1521 static char *
1522 sol_make_note_section (bfd *obfd, int *note_size)
1523 {
1524 return procfs_ops.to_make_corefile_notes (obfd, note_size);
1525 }
1526
1527 static int
1528 ignore (struct bp_target_info *bp_tgt)
1529 {
1530 return 0;
1531 }
1532
1533 static void
1534 init_sol_thread_ops (void)
1535 {
1536 sol_thread_ops.to_shortname = "solaris-threads";
1537 sol_thread_ops.to_longname = "Solaris threads and pthread.";
1538 sol_thread_ops.to_doc = "Solaris threads and pthread support.";
1539 sol_thread_ops.to_open = sol_thread_open;
1540 sol_thread_ops.to_attach = sol_thread_attach;
1541 sol_thread_ops.to_detach = sol_thread_detach;
1542 sol_thread_ops.to_resume = sol_thread_resume;
1543 sol_thread_ops.to_wait = sol_thread_wait;
1544 sol_thread_ops.to_fetch_registers = sol_thread_fetch_registers;
1545 sol_thread_ops.to_store_registers = sol_thread_store_registers;
1546 sol_thread_ops.to_prepare_to_store = sol_thread_prepare_to_store;
1547 sol_thread_ops.deprecated_xfer_memory = sol_thread_xfer_memory;
1548 sol_thread_ops.to_xfer_partial = sol_thread_xfer_partial;
1549 sol_thread_ops.to_files_info = sol_thread_files_info;
1550 sol_thread_ops.to_insert_breakpoint = memory_insert_breakpoint;
1551 sol_thread_ops.to_remove_breakpoint = memory_remove_breakpoint;
1552 sol_thread_ops.to_terminal_init = terminal_init_inferior;
1553 sol_thread_ops.to_terminal_inferior = terminal_inferior;
1554 sol_thread_ops.to_terminal_ours_for_output = terminal_ours_for_output;
1555 sol_thread_ops.to_terminal_ours = terminal_ours;
1556 sol_thread_ops.to_terminal_save_ours = terminal_save_ours;
1557 sol_thread_ops.to_terminal_info = child_terminal_info;
1558 sol_thread_ops.to_kill = sol_thread_kill_inferior;
1559 sol_thread_ops.to_create_inferior = sol_thread_create_inferior;
1560 sol_thread_ops.to_mourn_inferior = sol_thread_mourn_inferior;
1561 sol_thread_ops.to_can_run = sol_thread_can_run;
1562 sol_thread_ops.to_notice_signals = sol_thread_notice_signals;
1563 sol_thread_ops.to_thread_alive = sol_thread_alive;
1564 sol_thread_ops.to_pid_to_str = solaris_pid_to_str;
1565 sol_thread_ops.to_find_new_threads = sol_find_new_threads;
1566 sol_thread_ops.to_stop = sol_thread_stop;
1567 sol_thread_ops.to_stratum = process_stratum;
1568 sol_thread_ops.to_has_all_memory = 1;
1569 sol_thread_ops.to_has_memory = 1;
1570 sol_thread_ops.to_has_stack = 1;
1571 sol_thread_ops.to_has_registers = 1;
1572 sol_thread_ops.to_has_execution = 1;
1573 sol_thread_ops.to_has_thread_control = tc_none;
1574 sol_thread_ops.to_find_memory_regions = sol_find_memory_regions;
1575 sol_thread_ops.to_make_corefile_notes = sol_make_note_section;
1576 sol_thread_ops.to_magic = OPS_MAGIC;
1577 }
1578
1579 static void
1580 init_sol_core_ops (void)
1581 {
1582 sol_core_ops.to_shortname = "solaris-core";
1583 sol_core_ops.to_longname = "Solaris core threads and pthread.";
1584 sol_core_ops.to_doc = "Solaris threads and pthread support for core files.";
1585 sol_core_ops.to_open = sol_core_open;
1586 sol_core_ops.to_close = sol_core_close;
1587 sol_core_ops.to_attach = sol_thread_attach;
1588 sol_core_ops.to_detach = sol_core_detach;
1589 sol_core_ops.to_fetch_registers = sol_thread_fetch_registers;
1590 sol_core_ops.deprecated_xfer_memory = sol_thread_xfer_memory;
1591 sol_core_ops.to_xfer_partial = sol_thread_xfer_partial;
1592 sol_core_ops.to_files_info = sol_core_files_info;
1593 sol_core_ops.to_insert_breakpoint = ignore;
1594 sol_core_ops.to_remove_breakpoint = ignore;
1595 sol_core_ops.to_create_inferior = sol_thread_create_inferior;
1596 sol_core_ops.to_stratum = core_stratum;
1597 sol_core_ops.to_has_memory = 1;
1598 sol_core_ops.to_has_stack = 1;
1599 sol_core_ops.to_has_registers = 1;
1600 sol_core_ops.to_has_thread_control = tc_none;
1601 sol_core_ops.to_thread_alive = sol_thread_alive;
1602 sol_core_ops.to_pid_to_str = solaris_pid_to_str;
1603 /* On Solaris/x86, when debugging a threaded core file from process
1604 <n>, the following causes "info threads" to produce "procfs:
1605 couldn't find pid <n> in procinfo list" where <n> is the pid of
1606 the process that produced the core file. Disable it for now. */
1607 #if 0
1608 sol_core_ops.to_find_new_threads = sol_find_new_threads;
1609 #endif
1610 sol_core_ops.to_magic = OPS_MAGIC;
1611 }
1612
1613 /* We suppress the call to add_target of core_ops in corelow because
1614 if there are two targets in the stratum core_stratum,
1615 find_core_target won't know which one to return. See corelow.c for
1616 an additonal comment on coreops_suppress_target. */
1617 int coreops_suppress_target = 1;
1618
1619 void
1620 _initialize_sol_thread (void)
1621 {
1622 void *dlhandle;
1623
1624 init_sol_thread_ops ();
1625 init_sol_core_ops ();
1626
1627 dlhandle = dlopen ("libthread_db.so.1", RTLD_NOW);
1628 if (!dlhandle)
1629 goto die;
1630
1631 #define resolve(X) \
1632 if (!(p_##X = dlsym (dlhandle, #X))) \
1633 goto die;
1634
1635 resolve (td_log);
1636 resolve (td_ta_new);
1637 resolve (td_ta_delete);
1638 resolve (td_init);
1639 resolve (td_ta_get_ph);
1640 resolve (td_ta_get_nthreads);
1641 resolve (td_ta_tsd_iter);
1642 resolve (td_ta_thr_iter);
1643 resolve (td_thr_validate);
1644 resolve (td_thr_tsd);
1645 resolve (td_thr_get_info);
1646 resolve (td_thr_getfpregs);
1647 resolve (td_thr_getxregsize);
1648 resolve (td_thr_getxregs);
1649 resolve (td_thr_sigsetmask);
1650 resolve (td_thr_setprio);
1651 resolve (td_thr_setsigpending);
1652 resolve (td_thr_setfpregs);
1653 resolve (td_thr_setxregs);
1654 resolve (td_ta_map_id2thr);
1655 resolve (td_ta_map_lwp2thr);
1656 resolve (td_thr_getgregs);
1657 resolve (td_thr_setgregs);
1658
1659 add_target (&sol_thread_ops);
1660
1661 procfs_suppress_run = 1;
1662
1663 add_cmd ("sol-threads", class_maintenance, info_solthreads,
1664 _("Show info on Solaris user threads."), &maintenanceinfolist);
1665
1666 memcpy (&orig_core_ops, &core_ops, sizeof (struct target_ops));
1667 memcpy (&core_ops, &sol_core_ops, sizeof (struct target_ops));
1668 add_target (&core_ops);
1669
1670 /* Hook into new_objfile notification. */
1671 observer_attach_new_objfile (sol_thread_new_objfile);
1672 return;
1673
1674 die:
1675 fprintf_unfiltered (gdb_stderr, "\
1676 [GDB will not be able to debug user-mode threads: %s]\n", dlerror ());
1677
1678 if (dlhandle)
1679 dlclose (dlhandle);
1680
1681 /* Allow the user to debug non-threaded core files. */
1682 add_target (&core_ops);
1683
1684 return;
1685 }
This page took 0.123683 seconds and 5 git commands to generate.