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