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