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