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