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