* regset.h (struct regset): Add back `regset' member.
[deliverable/binutils-gdb.git] / gdb / sol-thread.c
CommitLineData
8d027a04
MK
1/* Solaris threads debugging interface.
2
3 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
b6ba6518 4 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
10 the Free Software Foundation; either version 2 of the License, or
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
JM
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
c906108c
SS
22
23/* This module implements a sort of half target that sits between the
8d027a04
MK
24 machine-independent parts of GDB and the /proc interface (procfs.c)
25 to provide access to the Solaris user-mode thread implementation.
26
27 Solaris threads are true user-mode threads, which are invoked via
28 the thr_* and pthread_* (native and POSIX respectivly) interfaces.
29 These are mostly implemented in user-space, with all thread context
30 kept in various structures that live in the user's heap. These
31 should not be confused with lightweight processes (LWPs), which are
32 implemented by the kernel, and scheduled without explicit
33 intervention by the process.
34
35 Just to confuse things a little, Solaris threads (both native and
36 POSIX) are actually implemented using LWPs. In general, there are
37 going to be more threads than LWPs. There is no fixed
38 correspondence between a thread and an LWP. When a thread wants to
39 run, it gets scheduled onto the first available LWP and can
40 therefore migrate from one LWP to another as time goes on. A
c906108c
SS
41 sleeping thread may not be associated with an LWP at all!
42
8d027a04
MK
43 To make it possible to mess with threads, Sun provides a library
44 called libthread_db.so.1 (not to be confused with
45 libthread_db.so.0, which doesn't have a published interface). This
46 interface has an upper part, which it provides, and a lower part
47 which we provide. The upper part consists of the td_* routines,
48 which allow us to find all the threads, query their state, etc...
49 The lower part consists of all of the ps_*, which are used by the
50 td_* routines to read/write memory, manipulate LWPs, lookup
51 symbols, etc... The ps_* routines actually do most of their work
52 by calling functions in procfs.c. */
c906108c
SS
53
54#include "defs.h"
55#include <thread.h>
56#include <proc_service.h>
57#include <thread_db.h>
58#include "gdbthread.h"
59#include "target.h"
60#include "inferior.h"
61#include <fcntl.h>
b8a92b82 62#include "gdb_stat.h"
c906108c
SS
63#include <dlfcn.h>
64#include "gdbcmd.h"
23e04971 65#include "gdbcore.h"
4e052eda 66#include "regcache.h"
990f9fe3 67#include "symfile.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
SS
275 else if (val != TD_OK)
276 error ("thread_to_lwp: td_ta_map_id2thr %s", td_err_string (val));
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
SS
281 else if (val != TD_OK)
282 error ("thread_to_lwp: td_thr_get_info: %s", td_err_string (val));
283
284 if (ti.ti_state != TD_THR_ACTIVE)
285 {
286 if (default_lwp != -1)
39f77062 287 return pid_to_ptid (default_lwp);
c906108c
SS
288 error ("thread_to_lwp: thread state not active: %s",
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
SS
318 else if (val != TD_OK)
319 error ("lwp_to_thread: td_ta_map_lwp2thr: %s.", td_err_string (val));
320
321 val = p_td_thr_validate (&th);
322 if (val == TD_NOTHR)
8d027a04 323 return lwp; /* Unknown to libthread; just return LPW, */
c906108c
SS
324 else if (val != TD_OK)
325 error ("lwp_to_thread: td_thr_validate: %s.", td_err_string (val));
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
SS
330 else if (val != TD_OK)
331 error ("lwp_to_thread: td_thr_get_info: %s.", td_err_string (val));
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! */
990f9fe3 356 SOLIB_ADD ((char *) 0, 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. */
c906108c 411 error ("This version of Solaris can't start inactive threads.");
39f77062
KB
412 if (info_verbose && PIDGET (ptid) == -1)
413 warning ("Specified thread %ld seems to have terminated",
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. */
c906108c 445 error ("This version of Solaris can't start inactive threads.");
39f77062
KB
446 if (info_verbose && PIDGET (ptid) == -1)
447 warning ("Specified thread %ld seems to have terminated",
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
SS
463 && !in_thread_list (rtnval))
464 {
465 printf_filtered ("[New %s]\n", target_pid_to_str (rtnval));
466 add_thread (rtnval);
467 }
468 }
469
8d027a04
MK
470 /* During process initialization, we may get here without the thread
471 package being initialized, since that can only happen after we've
472 found the shared libs. */
c906108c
SS
473
474 do_cleanups (old_chain);
475
476 return rtnval;
477}
478
479static void
8d027a04 480sol_thread_fetch_registers (int regnum)
c906108c
SS
481{
482 thread_t thread;
483 td_thrhandle_t thandle;
484 td_err_e val;
485 prgregset_t gregset;
486 prfpregset_t fpregset;
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)
8d027a04 496 procfs_ops.to_fetch_registers (regnum);
c906108c 497 else
8d027a04 498 orig_core_ops.to_fetch_registers (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)
8d027a04 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)
509 error ("sol_thread_fetch_registers: td_ta_map_id2thr: %s",
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)
c906108c
SS
516 error ("sol_thread_fetch_registers: td_thr_getgregs %s",
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)
c906108c
SS
526 error ("sol_thread_fetch_registers: td_thr_getfpregs %s",
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
8d027a04 533 supply_gregset ((gdb_gregset_t *) &gregset);
c60c0f5f 534 supply_fpregset ((gdb_fpregset_t *) &fpregset);
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)
540 error ("sol_thread_fetch_registers: td_thr_getxregsize %s",
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)
548 error ("sol_thread_fetch_registers: td_thr_getxregs %s",
549 td_err_string (val));
550 }
551#endif
552}
553
554static void
8d027a04 555sol_thread_store_registers (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. */
570 procfs_ops.to_store_registers (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)
579 error ("sol_thread_store_registers: td_ta_map_id2thr %s",
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. */
8d027a04 588 regcache_collect (regnum, old_value);
c906108c 589
c60c0f5f 590 val = p_td_thr_getgregs (&thandle, gregset);
c906108c
SS
591 if (val != TD_OK)
592 error ("sol_thread_store_registers: td_thr_getgregs %s",
593 td_err_string (val));
594 val = p_td_thr_getfpregs (&thandle, &fpregset);
595 if (val != TD_OK)
596 error ("sol_thread_store_registers: td_thr_getfpregs %s",
597 td_err_string (val));
598
87232496 599 /* Restore new register value. */
8d027a04 600 supply_register (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)
606 error ("sol_thread_store_registers: td_thr_getxregsize %s",
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)
614 error ("sol_thread_store_registers: td_thr_getxregs %s",
615 td_err_string (val));
616 }
617#endif
618 }
619
8d027a04
MK
620 fill_gregset ((gdb_gregset_t *) &gregset, regnum);
621 fill_fpregset ((gdb_fpregset_t *) &fpregset, regnum);
c906108c 622
c60c0f5f 623 val = p_td_thr_setgregs (&thandle, gregset);
c906108c
SS
624 if (val != TD_OK)
625 error ("sol_thread_store_registers: td_thr_setgregs %s",
626 td_err_string (val));
627 val = p_td_thr_setfpregs (&thandle, &fpregset);
628 if (val != TD_OK)
629 error ("sol_thread_store_registers: td_thr_setfpregs %s",
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)
636 error ("sol_thread_store_registers: td_thr_getxregsize %s",
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
fba45db2 651sol_thread_prepare_to_store (void)
c906108c
SS
652{
653 procfs_ops.to_prepare_to_store ();
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
c338868a 663sol_thread_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int dowrite,
f4d650ec 664 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)
6034ae49 683 retval = procfs_ops.to_xfer_memory (memaddr, myaddr, len,
f4d650ec 684 dowrite, attrib, target);
c906108c
SS
685 else
686 retval = orig_core_ops.to_xfer_memory (memaddr, myaddr, len,
f4d650ec 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,
700 const char *annex, void *readbuf,
701 const void *writebuf, ULONGEST offset, LONGEST len)
702{
703 int retval;
704 struct cleanup *old_chain;
705
706 old_chain = save_inferior_ptid ();
707
8d027a04
MK
708 if (is_thread (inferior_ptid) || !target_thread_alive (inferior_ptid))
709 {
710 /* It's either a thread or an LWP that isn't alive. Any live
711 LWP will do so use the first available.
712
713 NOTE: We don't need to call switch_to_thread; we're just
714 reading memory. */
715 inferior_ptid = procfs_first_available ();
716 }
6034ae49
RM
717
718 if (target_has_execution)
719 retval = procfs_ops.to_xfer_partial (ops, object, annex,
720 readbuf, writebuf, offset, len);
721 else
722 retval = orig_core_ops.to_xfer_partial (ops, object, annex,
723 readbuf, writebuf, offset, len);
724
725 do_cleanups (old_chain);
726
727 return retval;
728}
729
c906108c
SS
730/* Print status information about what we're accessing. */
731
732static void
fba45db2 733sol_thread_files_info (struct target_ops *ignore)
c906108c
SS
734{
735 procfs_ops.to_files_info (ignore);
736}
737
738static void
fba45db2 739sol_thread_kill_inferior (void)
c906108c
SS
740{
741 procfs_ops.to_kill ();
742}
743
744static void
39f77062 745sol_thread_notice_signals (ptid_t ptid)
c906108c 746{
39f77062 747 procfs_ops.to_notice_signals (pid_to_ptid (PIDGET (ptid)));
c906108c
SS
748}
749
750/* Fork an inferior process, and start debugging it with /proc. */
751
752static void
fba45db2 753sol_thread_create_inferior (char *exec_file, char *allargs, char **env)
c906108c
SS
754{
755 procfs_ops.to_create_inferior (exec_file, allargs, env);
756
39f77062 757 if (sol_thread_active && !ptid_equal (inferior_ptid, null_ptid))
c906108c 758 {
8d027a04
MK
759 /* Save for xfer_memory. */
760 main_ph.ptid = inferior_ptid;
c906108c
SS
761
762 push_target (&sol_thread_ops);
763
39f77062
KB
764 inferior_ptid = lwp_to_thread (inferior_ptid);
765 if (PIDGET (inferior_ptid) == -1)
766 inferior_ptid = main_ph.ptid;
c906108c 767
39f77062
KB
768 if (!in_thread_list (inferior_ptid))
769 add_thread (inferior_ptid);
c906108c
SS
770 }
771}
772
8d027a04
MK
773/* This routine is called whenever a new symbol table is read in, or
774 when all symbol tables are removed. libthread_db can only be
775 initialized when it finds the right variables in libthread.so.
776 Since it's a shared library, those variables don't show up until
777 the library gets mapped and the symbol table is read in.
c906108c 778
8d027a04
MK
779 This new_objfile event is managed by a chained function pointer.
780 It is the callee's responsability to call the next client on the
781 chain. */
11cf8741
JM
782
783/* Saved pointer to previous owner of the new_objfile event. */
507f3c78 784static void (*target_new_objfile_chain) (struct objfile *);
11cf8741 785
c906108c 786void
fba45db2 787sol_thread_new_objfile (struct objfile *objfile)
c906108c
SS
788{
789 td_err_e val;
790
791 if (!objfile)
792 {
793 sol_thread_active = 0;
11cf8741 794 goto quit;
c906108c
SS
795 }
796
8d027a04
MK
797 /* Don't do anything if init failed to resolve the libthread_db
798 library. */
c906108c 799 if (!procfs_suppress_run)
11cf8741 800 goto quit;
c906108c 801
8d027a04
MK
802 /* Now, initialize libthread_db. This needs to be done after the
803 shared libraries are located because it needs information from
804 the user's thread library. */
c906108c
SS
805
806 val = p_td_init ();
807 if (val != TD_OK)
11cf8741
JM
808 {
809 warning ("sol_thread_new_objfile: td_init: %s", td_err_string (val));
810 goto quit;
811 }
c906108c
SS
812
813 val = p_td_ta_new (&main_ph, &main_ta);
814 if (val == TD_NOLIBTHREAD)
11cf8741 815 goto quit;
c906108c 816 else if (val != TD_OK)
11cf8741
JM
817 {
818 warning ("sol_thread_new_objfile: td_ta_new: %s", td_err_string (val));
819 goto quit;
820 }
c906108c
SS
821
822 sol_thread_active = 1;
8d027a04 823
11cf8741 824quit:
8d027a04 825 /* Call predecessor on chain, if any. */
11cf8741
JM
826 if (target_new_objfile_chain)
827 target_new_objfile_chain (objfile);
c906108c
SS
828}
829
830/* Clean up after the inferior dies. */
831
832static void
fba45db2 833sol_thread_mourn_inferior (void)
c906108c
SS
834{
835 unpush_target (&sol_thread_ops);
836 procfs_ops.to_mourn_inferior ();
837}
838
8d027a04
MK
839/* Mark our target-struct as eligible for stray "run" and "attach"
840 commands. */
c906108c
SS
841
842static int
fba45db2 843sol_thread_can_run (void)
c906108c
SS
844{
845 return procfs_suppress_run;
846}
847
6034ae49 848/*
c906108c 849
c5aa993b 850 LOCAL FUNCTION
c906108c 851
c5aa993b 852 sol_thread_alive - test thread for "aliveness"
c906108c 853
c5aa993b 854 SYNOPSIS
c906108c 855
39f77062 856 static bool sol_thread_alive (ptid_t ptid);
c906108c 857
c5aa993b 858 DESCRIPTION
c906108c 859
c5aa993b 860 returns true if thread still active in inferior.
c906108c
SS
861
862 */
863
8d027a04
MK
864/* Return true if PTID is still active in the inferior. */
865
c906108c 866static int
39f77062 867sol_thread_alive (ptid_t ptid)
c906108c 868{
8d027a04 869 if (is_thread (ptid))
c906108c 870 {
8d027a04 871 /* It's a (user-level) thread. */
c906108c
SS
872 td_err_e val;
873 td_thrhandle_t th;
39f77062 874 int pid;
c906108c 875
39f77062 876 pid = GET_THREAD (ptid);
c906108c 877 if ((val = p_td_ta_map_id2thr (main_ta, pid, &th)) != TD_OK)
8d027a04 878 return 0; /* Thread not found. */
c906108c 879 if ((val = p_td_thr_validate (&th)) != TD_OK)
8d027a04
MK
880 return 0; /* Thread not valid. */
881 return 1; /* Known thread. */
c906108c 882 }
c5aa993b 883 else
c906108c 884 {
8d027a04 885 /* It's an LPW; pass the request on to procfs. */
c906108c 886 if (target_has_execution)
39f77062 887 return procfs_ops.to_thread_alive (ptid);
c906108c 888 else
39f77062 889 return orig_core_ops.to_thread_alive (ptid);
c906108c
SS
890 }
891}
892
893static void
fba45db2 894sol_thread_stop (void)
c906108c
SS
895{
896 procfs_ops.to_stop ();
897}
898\f
8d027a04
MK
899/* These routines implement the lower half of the thread_db interface,
900 i.e. the ps_* routines. */
c906108c 901
8d027a04
MK
902/* Various versions of <proc_service.h> have slightly different
903 function prototypes. In particular, we have
c906108c 904
c5aa993b
JM
905 NEWER OLDER
906 struct ps_prochandle * const struct ps_prochandle *
907 void* char*
8d027a04
MK
908 const void* char*
909 int size_t
c906108c 910
8d027a04
MK
911 Which one you have depends on the Solaris version and what patches
912 you've applied. On the theory that there are only two major
913 variants, we have configure check the prototype of ps_pdwrite (),
914 and use that info to make appropriate typedefs here. */
c906108c
SS
915
916#ifdef PROC_SERVICE_IS_OLD
c5aa993b
JM
917typedef const struct ps_prochandle *gdb_ps_prochandle_t;
918typedef char *gdb_ps_read_buf_t;
919typedef char *gdb_ps_write_buf_t;
c906108c 920typedef int gdb_ps_size_t;
291dcb3e 921typedef paddr_t gdb_ps_addr_t;
c906108c 922#else
c5aa993b
JM
923typedef struct ps_prochandle *gdb_ps_prochandle_t;
924typedef void *gdb_ps_read_buf_t;
925typedef const void *gdb_ps_write_buf_t;
c906108c 926typedef size_t gdb_ps_size_t;
291dcb3e 927typedef psaddr_t gdb_ps_addr_t;
c906108c
SS
928#endif
929
8d027a04
MK
930/* The next four routines are called by libthread_db to tell us to
931 stop and stop a particular process or lwp. Since GDB ensures that
932 these are all stopped by the time we call anything in thread_db,
933 these routines need to do nothing. */
c906108c 934
8d027a04 935/* Process stop. */
d4f3574e 936
c906108c
SS
937ps_err_e
938ps_pstop (gdb_ps_prochandle_t ph)
939{
940 return PS_OK;
941}
942
8d027a04 943/* Process continue. */
d4f3574e 944
c906108c
SS
945ps_err_e
946ps_pcontinue (gdb_ps_prochandle_t ph)
947{
948 return PS_OK;
949}
950
8d027a04 951/* LWP stop. */
d4f3574e 952
c906108c
SS
953ps_err_e
954ps_lstop (gdb_ps_prochandle_t ph, lwpid_t lwpid)
955{
956 return PS_OK;
957}
958
8d027a04 959/* LWP continue. */
d4f3574e 960
c906108c
SS
961ps_err_e
962ps_lcontinue (gdb_ps_prochandle_t ph, lwpid_t lwpid)
963{
964 return PS_OK;
965}
966
d4f3574e
SS
967/* Looks up the symbol LD_SYMBOL_NAME in the debugger's symbol table. */
968
c906108c
SS
969ps_err_e
970ps_pglobal_lookup (gdb_ps_prochandle_t ph, const char *ld_object_name,
8d027a04 971 const char *ld_symbol_name, gdb_ps_addr_t *ld_symbol_addr)
c906108c
SS
972{
973 struct minimal_symbol *ms;
974
975 ms = lookup_minimal_symbol (ld_symbol_name, NULL, NULL);
c906108c
SS
976 if (!ms)
977 return PS_NOSYM;
978
979 *ld_symbol_addr = SYMBOL_VALUE_ADDRESS (ms);
c906108c
SS
980 return PS_OK;
981}
982
983/* Common routine for reading and writing memory. */
984
985static ps_err_e
291dcb3e 986rw_common (int dowrite, const struct ps_prochandle *ph, gdb_ps_addr_t addr,
c906108c
SS
987 char *buf, int size)
988{
989 struct cleanup *old_chain;
990
39f77062 991 old_chain = save_inferior_ptid ();
c906108c 992
8d027a04
MK
993 if (is_thread (inferior_ptid) || !target_thread_alive (inferior_ptid))
994 {
995 /* It's either a thread or an LWP that isn't alive. Any live
996 LWP will do so use the first available.
997
998 NOTE: We don't need to call switch_to_thread; we're just
999 reading memory. */
1000 inferior_ptid = procfs_first_available ();
1001 }
c906108c 1002
23e04971
MS
1003#if defined (__sparcv9)
1004 /* For Sparc64 cross Sparc32, make sure the address has not been
1005 accidentally sign-extended (or whatever) to beyond 32 bits. */
359431fb 1006 if (bfd_get_arch_size (exec_bfd) == 32)
23e04971
MS
1007 addr &= 0xffffffff;
1008#endif
1009
c906108c
SS
1010 while (size > 0)
1011 {
1012 int cc;
1013
f4d650ec 1014 /* FIXME: passing 0 as attrib argument. */
c906108c 1015 if (target_has_execution)
6034ae49 1016 cc = procfs_ops.to_xfer_memory (addr, buf, size,
f4d650ec 1017 dowrite, 0, &procfs_ops);
c906108c 1018 else
6034ae49 1019 cc = orig_core_ops.to_xfer_memory (addr, buf, size,
f4d650ec 1020 dowrite, 0, &core_ops);
c906108c
SS
1021
1022 if (cc < 0)
1023 {
1024 if (dowrite == 0)
1025 print_sys_errmsg ("rw_common (): read", errno);
1026 else
1027 print_sys_errmsg ("rw_common (): write", errno);
1028
1029 do_cleanups (old_chain);
1030
1031 return PS_ERR;
1032 }
d5cb3e0e
MS
1033 else if (cc == 0)
1034 {
1035 if (dowrite == 0)
6034ae49 1036 warning ("rw_common (): unable to read at addr 0x%lx",
d5cb3e0e
MS
1037 (long) addr);
1038 else
6034ae49 1039 warning ("rw_common (): unable to write at addr 0x%lx",
d5cb3e0e
MS
1040 (long) addr);
1041
1042 do_cleanups (old_chain);
1043
1044 return PS_ERR;
1045 }
1046
c906108c
SS
1047 size -= cc;
1048 buf += cc;
1049 }
1050
1051 do_cleanups (old_chain);
1052
1053 return PS_OK;
1054}
1055
d4f3574e
SS
1056/* Copies SIZE bytes from target process .data segment to debugger memory. */
1057
c906108c 1058ps_err_e
291dcb3e 1059ps_pdread (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
c906108c
SS
1060 gdb_ps_read_buf_t buf, gdb_ps_size_t size)
1061{
1062 return rw_common (0, ph, addr, buf, size);
1063}
1064
d4f3574e
SS
1065/* Copies SIZE bytes from debugger memory .data segment to target process. */
1066
c906108c 1067ps_err_e
291dcb3e 1068ps_pdwrite (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
c906108c
SS
1069 gdb_ps_write_buf_t buf, gdb_ps_size_t size)
1070{
c5aa993b 1071 return rw_common (1, ph, addr, (char *) buf, size);
c906108c
SS
1072}
1073
d4f3574e
SS
1074/* Copies SIZE bytes from target process .text segment to debugger memory. */
1075
c906108c 1076ps_err_e
291dcb3e 1077ps_ptread (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
c906108c
SS
1078 gdb_ps_read_buf_t buf, gdb_ps_size_t size)
1079{
1080 return rw_common (0, ph, addr, buf, size);
1081}
1082
d4f3574e
SS
1083/* Copies SIZE bytes from debugger memory .text segment to target process. */
1084
c906108c 1085ps_err_e
291dcb3e 1086ps_ptwrite (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
c906108c
SS
1087 gdb_ps_write_buf_t buf, gdb_ps_size_t size)
1088{
c5aa993b 1089 return rw_common (1, ph, addr, (char *) buf, size);
c906108c
SS
1090}
1091
8d027a04 1092/* Get general-purpose registers for LWP. */
c906108c
SS
1093
1094ps_err_e
8d027a04 1095ps_lgetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, prgregset_t gregset)
c906108c
SS
1096{
1097 struct cleanup *old_chain;
1098
39f77062 1099 old_chain = save_inferior_ptid ();
c906108c 1100
39f77062 1101 inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
c5aa993b 1102
c906108c
SS
1103 if (target_has_execution)
1104 procfs_ops.to_fetch_registers (-1);
1105 else
1106 orig_core_ops.to_fetch_registers (-1);
c60c0f5f 1107 fill_gregset ((gdb_gregset_t *) gregset, -1);
c906108c
SS
1108
1109 do_cleanups (old_chain);
1110
1111 return PS_OK;
1112}
1113
8d027a04 1114/* Set general-purpose registers for LWP. */
c906108c
SS
1115
1116ps_err_e
1117ps_lsetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
1118 const prgregset_t gregset)
1119{
1120 struct cleanup *old_chain;
1121
39f77062 1122 old_chain = save_inferior_ptid ();
c906108c 1123
39f77062 1124 inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
c5aa993b 1125
c60c0f5f 1126 supply_gregset ((gdb_gregset_t *) gregset);
c906108c
SS
1127 if (target_has_execution)
1128 procfs_ops.to_store_registers (-1);
1129 else
1130 orig_core_ops.to_store_registers (-1);
1131
1132 do_cleanups (old_chain);
1133
1134 return PS_OK;
1135}
1136
d4f3574e
SS
1137/* Log a message (sends to gdb_stderr). */
1138
c906108c 1139void
8d027a04 1140ps_plog (const char *fmt, ...)
c906108c
SS
1141{
1142 va_list args;
1143
1144 va_start (args, fmt);
1145
1146 vfprintf_filtered (gdb_stderr, fmt, args);
1147}
1148
1149/* Get size of extra register set. Currently a noop. */
1150
1151ps_err_e
1152ps_lgetxregsize (gdb_ps_prochandle_t ph, lwpid_t lwpid, int *xregsize)
1153{
1154#if 0
1155 int lwp_fd;
1156 int regsize;
1157 ps_err_e val;
1158
1159 val = get_lwp_fd (ph, lwpid, &lwp_fd);
1160 if (val != PS_OK)
1161 return val;
1162
1163 if (ioctl (lwp_fd, PIOCGXREGSIZE, &regsize))
1164 {
1165 if (errno == EINVAL)
1166 return PS_NOFREGS; /* XXX Wrong code, but this is the closest
1167 thing in proc_service.h */
1168
1169 print_sys_errmsg ("ps_lgetxregsize (): PIOCGXREGSIZE", errno);
1170 return PS_ERR;
1171 }
1172#endif
1173
1174 return PS_OK;
1175}
1176
1177/* Get extra register set. Currently a noop. */
1178
1179ps_err_e
1180ps_lgetxregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, caddr_t xregset)
1181{
1182#if 0
1183 int lwp_fd;
1184 ps_err_e val;
1185
1186 val = get_lwp_fd (ph, lwpid, &lwp_fd);
1187 if (val != PS_OK)
1188 return val;
1189
1190 if (ioctl (lwp_fd, PIOCGXREG, xregset))
1191 {
1192 print_sys_errmsg ("ps_lgetxregs (): PIOCGXREG", errno);
1193 return PS_ERR;
1194 }
1195#endif
1196
1197 return PS_OK;
1198}
1199
1200/* Set extra register set. Currently a noop. */
1201
1202ps_err_e
1203ps_lsetxregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, caddr_t xregset)
1204{
1205#if 0
1206 int lwp_fd;
1207 ps_err_e val;
1208
1209 val = get_lwp_fd (ph, lwpid, &lwp_fd);
1210 if (val != PS_OK)
1211 return val;
1212
1213 if (ioctl (lwp_fd, PIOCSXREG, xregset))
1214 {
1215 print_sys_errmsg ("ps_lsetxregs (): PIOCSXREG", errno);
1216 return PS_ERR;
1217 }
1218#endif
1219
1220 return PS_OK;
1221}
1222
8d027a04 1223/* Get floating-point registers for LWP. */
c906108c
SS
1224
1225ps_err_e
1226ps_lgetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
8d027a04 1227 prfpregset_t *fpregset)
c906108c
SS
1228{
1229 struct cleanup *old_chain;
1230
39f77062 1231 old_chain = save_inferior_ptid ();
c906108c 1232
39f77062 1233 inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
c906108c
SS
1234
1235 if (target_has_execution)
1236 procfs_ops.to_fetch_registers (-1);
1237 else
1238 orig_core_ops.to_fetch_registers (-1);
c60c0f5f 1239 fill_fpregset ((gdb_fpregset_t *) fpregset, -1);
c906108c
SS
1240
1241 do_cleanups (old_chain);
1242
1243 return PS_OK;
1244}
1245
d4f3574e 1246/* Set floating-point regs for LWP */
c906108c
SS
1247
1248ps_err_e
1249ps_lsetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
c5aa993b 1250 const prfpregset_t * fpregset)
c906108c
SS
1251{
1252 struct cleanup *old_chain;
1253
39f77062 1254 old_chain = save_inferior_ptid ();
c906108c 1255
39f77062 1256 inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
c5aa993b 1257
c60c0f5f 1258 supply_fpregset ((gdb_fpregset_t *) fpregset);
c906108c
SS
1259 if (target_has_execution)
1260 procfs_ops.to_store_registers (-1);
1261 else
1262 orig_core_ops.to_store_registers (-1);
1263
1264 do_cleanups (old_chain);
1265
1266 return PS_OK;
1267}
1268
23715f29 1269#ifdef PR_MODEL_LP64
8d027a04
MK
1270/* Identify process as 32-bit or 64-bit. At the moment we're using
1271 BFD to do this. There might be a more Solaris-specific
1272 (e.g. procfs) method, but this ought to work. */
23e04971
MS
1273
1274ps_err_e
1275ps_pdmodel (gdb_ps_prochandle_t ph, int *data_model)
1276{
1277 if (exec_bfd == 0)
a95ac8b6
PS
1278 *data_model = PR_MODEL_UNKNOWN;
1279 else if (bfd_get_arch_size (exec_bfd) == 32)
23e04971
MS
1280 *data_model = PR_MODEL_ILP32;
1281 else
1282 *data_model = PR_MODEL_LP64;
1283
1284 return PS_OK;
1285}
23715f29 1286#endif /* PR_MODEL_LP64 */
23e04971 1287
c906108c
SS
1288#ifdef TM_I386SOL2_H
1289
d4f3574e
SS
1290/* Reads the local descriptor table of a LWP. */
1291
c906108c
SS
1292ps_err_e
1293ps_lgetLDT (gdb_ps_prochandle_t ph, lwpid_t lwpid,
1294 struct ssd *pldt)
1295{
8d027a04 1296 /* NOTE: only used on Solaris, therefore OK to refer to procfs.c. */
39f77062 1297 extern struct ssd *procfs_find_LDT_entry (ptid_t);
05e28a7b 1298 struct ssd *ret;
c906108c 1299
8d027a04
MK
1300 /* FIXME: can't I get the process ID from the prochandle or
1301 something? */
2f09097b 1302
39f77062 1303 if (PIDGET (inferior_ptid) <= 0 || lwpid <= 0)
2f09097b
ND
1304 return PS_BADLID;
1305
39f77062 1306 ret = procfs_find_LDT_entry (BUILD_LWP (lwpid, PIDGET (inferior_ptid)));
05e28a7b 1307 if (ret)
c906108c 1308 {
05e28a7b
AC
1309 memcpy (pldt, ret, sizeof (struct ssd));
1310 return PS_OK;
c906108c 1311 }
8d027a04
MK
1312 else
1313 /* LDT not found. */
c906108c 1314 return PS_ERR;
c5aa993b 1315}
c906108c
SS
1316#endif /* TM_I386SOL2_H */
1317\f
8d027a04
MK
1318
1319/* Convert PTID to printable form. */
c906108c
SS
1320
1321char *
39f77062 1322solaris_pid_to_str (ptid_t ptid)
c906108c
SS
1323{
1324 static char buf[100];
1325
8d027a04 1326 /* In case init failed to resolve the libthread_db library. */
c906108c 1327 if (!procfs_suppress_run)
39f77062 1328 return procfs_pid_to_str (ptid);
c906108c 1329
39f77062 1330 if (is_thread (ptid))
c906108c 1331 {
39f77062 1332 ptid_t lwp;
c906108c 1333
39f77062 1334 lwp = thread_to_lwp (ptid, -2);
c906108c 1335
39f77062
KB
1336 if (PIDGET (lwp) == -1)
1337 sprintf (buf, "Thread %ld (defunct)", GET_THREAD (ptid));
1338 else if (PIDGET (lwp) != -2)
8d027a04
MK
1339 sprintf (buf, "Thread %ld (LWP %ld)",
1340 GET_THREAD (ptid), GET_LWP (lwp));
c906108c 1341 else
39f77062 1342 sprintf (buf, "Thread %ld ", GET_THREAD (ptid));
c906108c 1343 }
39f77062
KB
1344 else if (GET_LWP (ptid) != 0)
1345 sprintf (buf, "LWP %ld ", GET_LWP (ptid));
c906108c 1346 else
39f77062 1347 sprintf (buf, "process %d ", PIDGET (ptid));
c906108c
SS
1348
1349 return buf;
1350}
1351\f
1352
8d027a04
MK
1353/* Worker bee for find_new_threads. Callback function that gets
1354 called once per user-level thread (i.e. not for LWP's). */
c906108c
SS
1355
1356static int
fba45db2 1357sol_find_new_threads_callback (const td_thrhandle_t *th, void *ignored)
c906108c
SS
1358{
1359 td_err_e retval;
1360 td_thrinfo_t ti;
39f77062 1361 ptid_t ptid;
c906108c 1362
8d027a04
MK
1363 retval = p_td_thr_get_info (th, &ti);
1364 if (retval != TD_OK)
1365 return -1;
1366
39f77062
KB
1367 ptid = BUILD_THREAD (ti.ti_tid, PIDGET (inferior_ptid));
1368 if (!in_thread_list (ptid))
1369 add_thread (ptid);
c906108c
SS
1370
1371 return 0;
1372}
1373
d4f3574e 1374static void
fba45db2 1375sol_find_new_threads (void)
c906108c 1376{
8d027a04
MK
1377 /* Don't do anything if init failed to resolve the libthread_db
1378 library. */
c906108c
SS
1379 if (!procfs_suppress_run)
1380 return;
1381
39f77062 1382 if (PIDGET (inferior_ptid) == -1)
c906108c 1383 {
c5aa993b 1384 printf_filtered ("No process.\n");
c906108c
SS
1385 return;
1386 }
8d027a04
MK
1387
1388 /* First Find any new LWP's. */
1389 procfs_ops.to_find_new_threads ();
1390
1391 /* Then find any new user-level threads. */
c5aa993b 1392 p_td_ta_thr_iter (main_ta, sol_find_new_threads_callback, (void *) 0,
c906108c
SS
1393 TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
1394 TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
1395}
1396
1397static void
fba45db2 1398sol_core_open (char *filename, int from_tty)
c906108c
SS
1399{
1400 orig_core_ops.to_open (filename, from_tty);
1401}
1402
1403static void
fba45db2 1404sol_core_close (int quitting)
c906108c
SS
1405{
1406 orig_core_ops.to_close (quitting);
1407}
1408
1409static void
fba45db2 1410sol_core_detach (char *args, int from_tty)
c906108c
SS
1411{
1412 unpush_target (&core_ops);
1413 orig_core_ops.to_detach (args, from_tty);
1414}
1415
1416static void
fba45db2 1417sol_core_files_info (struct target_ops *t)
c906108c
SS
1418{
1419 orig_core_ops.to_files_info (t);
1420}
1421
8d027a04
MK
1422/* Worker bee for the "info sol-thread" command. This is a callback
1423 function that gets called once for each Solaris user-level thread
1424 (i.e. not for LWPs) in the inferior. Print anything interesting
1425 that we can think of. */
c906108c 1426
c5aa993b 1427static int
fba45db2 1428info_cb (const td_thrhandle_t *th, void *s)
c906108c
SS
1429{
1430 td_err_e ret;
1431 td_thrinfo_t ti;
c906108c 1432
8d027a04
MK
1433 ret = p_td_thr_get_info (th, &ti);
1434 if (ret == TD_OK)
c906108c 1435 {
c5aa993b
JM
1436 printf_filtered ("%s thread #%d, lwp %d, ",
1437 ti.ti_type == TD_THR_SYSTEM ? "system" : "user ",
c906108c 1438 ti.ti_tid, ti.ti_lid);
c5aa993b
JM
1439 switch (ti.ti_state)
1440 {
c906108c 1441 default:
c5aa993b
JM
1442 case TD_THR_UNKNOWN:
1443 printf_filtered ("<unknown state>");
1444 break;
1445 case TD_THR_STOPPED:
1446 printf_filtered ("(stopped)");
1447 break;
1448 case TD_THR_RUN:
1449 printf_filtered ("(run) ");
1450 break;
1451 case TD_THR_ACTIVE:
1452 printf_filtered ("(active) ");
1453 break;
1454 case TD_THR_ZOMBIE:
1455 printf_filtered ("(zombie) ");
1456 break;
1457 case TD_THR_SLEEP:
1458 printf_filtered ("(asleep) ");
1459 break;
1460 case TD_THR_STOPPED_ASLEEP:
1461 printf_filtered ("(stopped asleep)");
1462 break;
1463 }
8d027a04 1464 /* Print thr_create start function. */
c906108c 1465 if (ti.ti_startfunc != 0)
4ce44c66
JM
1466 {
1467 struct minimal_symbol *msym;
1468 msym = lookup_minimal_symbol_by_pc (ti.ti_startfunc);
1469 if (msym)
8d027a04
MK
1470 printf_filtered (" startfunc: %s\n",
1471 DEPRECATED_SYMBOL_NAME (msym));
4ce44c66
JM
1472 else
1473 printf_filtered (" startfunc: 0x%s\n", paddr (ti.ti_startfunc));
1474 }
c906108c 1475
8d027a04 1476 /* If thread is asleep, print function that went to sleep. */
c906108c 1477 if (ti.ti_state == TD_THR_SLEEP)
4ce44c66
JM
1478 {
1479 struct minimal_symbol *msym;
1480 msym = lookup_minimal_symbol_by_pc (ti.ti_pc);
1481 if (msym)
8d027a04
MK
1482 printf_filtered (" - Sleep func: %s\n",
1483 DEPRECATED_SYMBOL_NAME (msym));
4ce44c66
JM
1484 else
1485 printf_filtered (" - Sleep func: 0x%s\n", paddr (ti.ti_startfunc));
1486 }
c906108c 1487
8d027a04 1488 /* Wrap up line, if necessary. */
c906108c
SS
1489 if (ti.ti_state != TD_THR_SLEEP && ti.ti_startfunc == 0)
1490 printf_filtered ("\n"); /* don't you hate counting newlines? */
1491 }
1492 else
1493 warning ("info sol-thread: failed to get info for thread.");
1494
c5aa993b 1495 return 0;
c906108c
SS
1496}
1497
8d027a04
MK
1498/* List some state about each Solaris user-level thread in the
1499 inferior. */
c906108c
SS
1500
1501static void
fba45db2 1502info_solthreads (char *args, int from_tty)
c906108c 1503{
c5aa993b 1504 p_td_ta_thr_iter (main_ta, info_cb, args,
c906108c
SS
1505 TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
1506 TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
1507}
c906108c 1508
be4d1333 1509static int
8d027a04
MK
1510sol_find_memory_regions (int (*func) (CORE_ADDR, unsigned long,
1511 int, int, int, void *),
be4d1333
MS
1512 void *data)
1513{
1514 return procfs_ops.to_find_memory_regions (func, data);
1515}
1516
1517static char *
1518sol_make_note_section (bfd *obfd, int *note_size)
1519{
1520 return procfs_ops.to_make_corefile_notes (obfd, note_size);
1521}
1522
c906108c 1523static int
fba45db2 1524ignore (CORE_ADDR addr, char *contents)
c906108c
SS
1525{
1526 return 0;
1527}
1528
c906108c 1529static void
fba45db2 1530init_sol_thread_ops (void)
c906108c
SS
1531{
1532 sol_thread_ops.to_shortname = "solaris-threads";
1533 sol_thread_ops.to_longname = "Solaris threads and pthread.";
1534 sol_thread_ops.to_doc = "Solaris threads and pthread support.";
1535 sol_thread_ops.to_open = sol_thread_open;
c906108c
SS
1536 sol_thread_ops.to_attach = sol_thread_attach;
1537 sol_thread_ops.to_detach = sol_thread_detach;
1538 sol_thread_ops.to_resume = sol_thread_resume;
1539 sol_thread_ops.to_wait = sol_thread_wait;
1540 sol_thread_ops.to_fetch_registers = sol_thread_fetch_registers;
1541 sol_thread_ops.to_store_registers = sol_thread_store_registers;
1542 sol_thread_ops.to_prepare_to_store = sol_thread_prepare_to_store;
1543 sol_thread_ops.to_xfer_memory = sol_thread_xfer_memory;
6034ae49 1544 sol_thread_ops.to_xfer_partial = sol_thread_xfer_partial;
c906108c
SS
1545 sol_thread_ops.to_files_info = sol_thread_files_info;
1546 sol_thread_ops.to_insert_breakpoint = memory_insert_breakpoint;
1547 sol_thread_ops.to_remove_breakpoint = memory_remove_breakpoint;
1548 sol_thread_ops.to_terminal_init = terminal_init_inferior;
1549 sol_thread_ops.to_terminal_inferior = terminal_inferior;
1550 sol_thread_ops.to_terminal_ours_for_output = terminal_ours_for_output;
1551 sol_thread_ops.to_terminal_ours = terminal_ours;
a790ad35 1552 sol_thread_ops.to_terminal_save_ours = terminal_save_ours;
c906108c
SS
1553 sol_thread_ops.to_terminal_info = child_terminal_info;
1554 sol_thread_ops.to_kill = sol_thread_kill_inferior;
c906108c
SS
1555 sol_thread_ops.to_create_inferior = sol_thread_create_inferior;
1556 sol_thread_ops.to_mourn_inferior = sol_thread_mourn_inferior;
1557 sol_thread_ops.to_can_run = sol_thread_can_run;
1558 sol_thread_ops.to_notice_signals = sol_thread_notice_signals;
1559 sol_thread_ops.to_thread_alive = sol_thread_alive;
ed9a39eb 1560 sol_thread_ops.to_pid_to_str = solaris_pid_to_str;
b83266a0 1561 sol_thread_ops.to_find_new_threads = sol_find_new_threads;
c906108c
SS
1562 sol_thread_ops.to_stop = sol_thread_stop;
1563 sol_thread_ops.to_stratum = process_stratum;
1564 sol_thread_ops.to_has_all_memory = 1;
1565 sol_thread_ops.to_has_memory = 1;
1566 sol_thread_ops.to_has_stack = 1;
1567 sol_thread_ops.to_has_registers = 1;
1568 sol_thread_ops.to_has_execution = 1;
1569 sol_thread_ops.to_has_thread_control = tc_none;
be4d1333
MS
1570 sol_thread_ops.to_find_memory_regions = sol_find_memory_regions;
1571 sol_thread_ops.to_make_corefile_notes = sol_make_note_section;
c906108c
SS
1572 sol_thread_ops.to_magic = OPS_MAGIC;
1573}
1574
c906108c 1575static void
fba45db2 1576init_sol_core_ops (void)
c906108c 1577{
c5aa993b
JM
1578 sol_core_ops.to_shortname = "solaris-core";
1579 sol_core_ops.to_longname = "Solaris core threads and pthread.";
1580 sol_core_ops.to_doc = "Solaris threads and pthread support for core files.";
1581 sol_core_ops.to_open = sol_core_open;
1582 sol_core_ops.to_close = sol_core_close;
1583 sol_core_ops.to_attach = sol_thread_attach;
1584 sol_core_ops.to_detach = sol_core_detach;
c5aa993b 1585 sol_core_ops.to_fetch_registers = sol_thread_fetch_registers;
c5aa993b 1586 sol_core_ops.to_xfer_memory = sol_thread_xfer_memory;
6034ae49 1587 sol_core_ops.to_xfer_partial = sol_thread_xfer_partial;
c5aa993b
JM
1588 sol_core_ops.to_files_info = sol_core_files_info;
1589 sol_core_ops.to_insert_breakpoint = ignore;
1590 sol_core_ops.to_remove_breakpoint = ignore;
c5aa993b
JM
1591 sol_core_ops.to_create_inferior = sol_thread_create_inferior;
1592 sol_core_ops.to_stratum = core_stratum;
c5aa993b
JM
1593 sol_core_ops.to_has_memory = 1;
1594 sol_core_ops.to_has_stack = 1;
1595 sol_core_ops.to_has_registers = 1;
c5aa993b 1596 sol_core_ops.to_has_thread_control = tc_none;
db348f27 1597 sol_core_ops.to_thread_alive = sol_thread_alive;
ed9a39eb 1598 sol_core_ops.to_pid_to_str = solaris_pid_to_str;
8d027a04
MK
1599 /* On Solaris/x86, when debugging a threaded core file from process
1600 <n>, the following causes "info threads" to produce "procfs:
1601 couldn't find pid <n> in procinfo list" where <n> is the pid of
1602 the process that produced the core file. Disable it for now. */
1603#if 0
1604 sol_core_ops.to_find_new_threads = sol_find_new_threads;
1605#endif
c5aa993b 1606 sol_core_ops.to_magic = OPS_MAGIC;
c906108c
SS
1607}
1608
8d027a04
MK
1609/* We suppress the call to add_target of core_ops in corelow because
1610 if there are two targets in the stratum core_stratum,
1611 find_core_target won't know which one to return. See corelow.c for
1612 an additonal comment on coreops_suppress_target. */
c906108c
SS
1613int coreops_suppress_target = 1;
1614
1615void
fba45db2 1616_initialize_sol_thread (void)
c906108c
SS
1617{
1618 void *dlhandle;
1619
1620 init_sol_thread_ops ();
1621 init_sol_core_ops ();
1622
1623 dlhandle = dlopen ("libthread_db.so.1", RTLD_NOW);
1624 if (!dlhandle)
1625 goto die;
1626
1627#define resolve(X) \
1628 if (!(p_##X = dlsym (dlhandle, #X))) \
1629 goto die;
1630
1631 resolve (td_log);
1632 resolve (td_ta_new);
1633 resolve (td_ta_delete);
1634 resolve (td_init);
1635 resolve (td_ta_get_ph);
1636 resolve (td_ta_get_nthreads);
1637 resolve (td_ta_tsd_iter);
1638 resolve (td_ta_thr_iter);
1639 resolve (td_thr_validate);
1640 resolve (td_thr_tsd);
1641 resolve (td_thr_get_info);
1642 resolve (td_thr_getfpregs);
1643 resolve (td_thr_getxregsize);
1644 resolve (td_thr_getxregs);
1645 resolve (td_thr_sigsetmask);
1646 resolve (td_thr_setprio);
1647 resolve (td_thr_setsigpending);
1648 resolve (td_thr_setfpregs);
1649 resolve (td_thr_setxregs);
1650 resolve (td_ta_map_id2thr);
1651 resolve (td_ta_map_lwp2thr);
1652 resolve (td_thr_getgregs);
1653 resolve (td_thr_setgregs);
1654
1655 add_target (&sol_thread_ops);
1656
1657 procfs_suppress_run = 1;
1658
c5aa993b
JM
1659 add_cmd ("sol-threads", class_maintenance, info_solthreads,
1660 "Show info on Solaris user threads.\n", &maintenanceinfolist);
c906108c 1661
c5aa993b
JM
1662 memcpy (&orig_core_ops, &core_ops, sizeof (struct target_ops));
1663 memcpy (&core_ops, &sol_core_ops, sizeof (struct target_ops));
c906108c
SS
1664 add_target (&core_ops);
1665
8d027a04 1666 /* Hook into new_objfile notification. */
9a4105ab
AC
1667 target_new_objfile_chain = deprecated_target_new_objfile_hook;
1668 deprecated_target_new_objfile_hook = 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.539776 seconds and 4 git commands to generate.