* inferior.h (procfs_first_available): Move declaration to...
[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,
0fb0cc75 4 2007, 2008, 2009 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"
6f4492c8 68#include "gdb_string.h"
cc35222d
PA
69#include <sys/procfs.h>
70#include "proc-utils.h"
6f4492c8 71
c906108c 72struct target_ops sol_thread_ops;
c906108c 73
117de6a9 74extern char *procfs_pid_to_str (struct target_ops *ops, ptid_t ptid);
c906108c 75
c60c0f5f
MS
76/* Prototypes for supply_gregset etc. */
77#include "gregset.h"
c906108c 78
8d027a04
MK
79/* This struct is defined by us, but mainly used for the proc_service
80 interface. We don't have much use for it, except as a handy place
81 to get a real PID for memory accesses. */
c906108c
SS
82
83struct ps_prochandle
8d027a04
MK
84{
85 ptid_t ptid;
86};
c906108c
SS
87
88struct string_map
8d027a04
MK
89{
90 int num;
91 char *str;
92};
c906108c
SS
93
94static struct ps_prochandle main_ph;
95static td_thragent_t *main_ta;
96static int sol_thread_active = 0;
97
a14ed312 98static void init_sol_thread_ops (void);
c906108c 99
8d027a04
MK
100/* Default definitions: These must be defined in tm.h if they are to
101 be shared with a process module such as procfs. */
d4f3574e 102
ca6724c1
KB
103#define GET_PID(ptid) ptid_get_pid (ptid)
104#define GET_LWP(ptid) ptid_get_lwp (ptid)
105#define GET_THREAD(ptid) ptid_get_tid (ptid)
106
107#define is_lwp(ptid) (GET_LWP (ptid) != 0)
108#define is_thread(ptid) (GET_THREAD (ptid) != 0)
109
110#define BUILD_LWP(lwp, pid) ptid_build (pid, lwp, 0)
111#define BUILD_THREAD(tid, pid) ptid_build (pid, 0, tid)
c906108c 112
8d027a04
MK
113/* Pointers to routines from libthread_db resolved by dlopen(). */
114
115static void (*p_td_log)(const int on_off);
116static td_err_e (*p_td_ta_new)(const struct ps_prochandle *ph_p,
117 td_thragent_t **ta_pp);
118static td_err_e (*p_td_ta_delete)(td_thragent_t *ta_p);
119static td_err_e (*p_td_init)(void);
120static td_err_e (*p_td_ta_get_ph)(const td_thragent_t *ta_p,
121 struct ps_prochandle **ph_pp);
122static td_err_e (*p_td_ta_get_nthreads)(const td_thragent_t *ta_p,
123 int *nthread_p);
124static td_err_e (*p_td_ta_tsd_iter)(const td_thragent_t *ta_p,
125 td_key_iter_f *cb, void *cbdata_p);
126static td_err_e (*p_td_ta_thr_iter)(const td_thragent_t *ta_p,
127 td_thr_iter_f *cb, void *cbdata_p,
128 td_thr_state_e state, int ti_pri,
129 sigset_t *ti_sigmask_p,
130 unsigned ti_user_flags);
131static td_err_e (*p_td_thr_validate)(const td_thrhandle_t *th_p);
132static td_err_e (*p_td_thr_tsd)(const td_thrhandle_t * th_p,
133 const thread_key_t key, void **data_pp);
134static td_err_e (*p_td_thr_get_info)(const td_thrhandle_t *th_p,
135 td_thrinfo_t *ti_p);
136static td_err_e (*p_td_thr_getfpregs)(const td_thrhandle_t *th_p,
137 prfpregset_t *fpregset);
138static td_err_e (*p_td_thr_getxregsize)(const td_thrhandle_t *th_p,
139 int *xregsize);
140static td_err_e (*p_td_thr_getxregs)(const td_thrhandle_t *th_p,
141 const caddr_t xregset);
142static td_err_e (*p_td_thr_sigsetmask)(const td_thrhandle_t *th_p,
143 const sigset_t ti_sigmask);
144static td_err_e (*p_td_thr_setprio)(const td_thrhandle_t *th_p,
145 const int ti_pri);
146static td_err_e (*p_td_thr_setsigpending)(const td_thrhandle_t *th_p,
147 const uchar_t ti_pending_flag,
148 const sigset_t ti_pending);
149static td_err_e (*p_td_thr_setfpregs)(const td_thrhandle_t *th_p,
150 const prfpregset_t *fpregset);
151static td_err_e (*p_td_thr_setxregs)(const td_thrhandle_t *th_p,
152 const caddr_t xregset);
153static td_err_e (*p_td_ta_map_id2thr)(const td_thragent_t *ta_p,
154 thread_t tid,
155 td_thrhandle_t *th_p);
156static td_err_e (*p_td_ta_map_lwp2thr)(const td_thragent_t *ta_p,
157 lwpid_t lwpid,
158 td_thrhandle_t *th_p);
159static td_err_e (*p_td_thr_getgregs)(const td_thrhandle_t *th_p,
160 prgregset_t regset);
161static td_err_e (*p_td_thr_setgregs)(const td_thrhandle_t *th_p,
162 const prgregset_t regset);
163\f
c906108c 164
8d027a04
MK
165/* Return the libthread_db error string associated with ERRCODE. If
166 ERRCODE is unknown, return an appropriate message. */
c906108c
SS
167
168static char *
fba45db2 169td_err_string (td_err_e errcode)
c906108c 170{
8d027a04 171 static struct string_map td_err_table[] =
c5aa993b 172 {
8d027a04
MK
173 { TD_OK, "generic \"call succeeded\"" },
174 { TD_ERR, "generic error." },
175 { TD_NOTHR, "no thread can be found to satisfy query" },
176 { TD_NOSV, "no synch. variable can be found to satisfy query" },
177 { TD_NOLWP, "no lwp can be found to satisfy query" },
178 { TD_BADPH, "invalid process handle" },
179 { TD_BADTH, "invalid thread handle" },
180 { TD_BADSH, "invalid synchronization handle" },
181 { TD_BADTA, "invalid thread agent" },
182 { TD_BADKEY, "invalid key" },
183 { TD_NOMSG, "td_thr_event_getmsg() called when there was no message" },
184 { TD_NOFPREGS, "FPU register set not available for given thread" },
185 { TD_NOLIBTHREAD, "application not linked with libthread" },
186 { TD_NOEVENT, "requested event is not supported" },
187 { TD_NOCAPAB, "capability not available" },
188 { TD_DBERR, "Debugger service failed" },
189 { TD_NOAPLIC, "Operation not applicable to" },
190 { TD_NOTSD, "No thread specific data for this thread" },
191 { TD_MALLOC, "Malloc failed" },
192 { TD_PARTIALREG, "Only part of register set was written/read" },
193 { TD_NOXREGS, "X register set not available for given thread" }
c5aa993b 194 };
c906108c
SS
195 const int td_err_size = sizeof td_err_table / sizeof (struct string_map);
196 int i;
197 static char buf[50];
198
199 for (i = 0; i < td_err_size; i++)
200 if (td_err_table[i].num == errcode)
201 return td_err_table[i].str;
c5aa993b 202
8d027a04 203 sprintf (buf, "Unknown libthread_db error code: %d", errcode);
c906108c
SS
204
205 return buf;
206}
c906108c 207
8d027a04
MK
208/* Return the the libthread_db state string assicoated with STATECODE.
209 If STATECODE is unknown, return an appropriate message. */
c906108c
SS
210
211static char *
fba45db2 212td_state_string (td_thr_state_e statecode)
c906108c 213{
8d027a04 214 static struct string_map td_thr_state_table[] =
c5aa993b 215 {
8d027a04
MK
216 { TD_THR_ANY_STATE, "any state" },
217 { TD_THR_UNKNOWN, "unknown" },
218 { TD_THR_STOPPED, "stopped" },
219 { TD_THR_RUN, "run" },
220 { TD_THR_ACTIVE, "active" },
221 { TD_THR_ZOMBIE, "zombie" },
222 { TD_THR_SLEEP, "sleep" },
223 { TD_THR_STOPPED_ASLEEP, "stopped asleep" }
c5aa993b 224 };
8d027a04
MK
225 const int td_thr_state_table_size =
226 sizeof td_thr_state_table / sizeof (struct string_map);
c906108c
SS
227 int i;
228 static char buf[50];
229
230 for (i = 0; i < td_thr_state_table_size; i++)
231 if (td_thr_state_table[i].num == statecode)
232 return td_thr_state_table[i].str;
c5aa993b 233
8d027a04 234 sprintf (buf, "Unknown libthread_db state code: %d", statecode);
c906108c
SS
235
236 return buf;
237}
238\f
c906108c 239
8d027a04
MK
240/* Convert a POSIX or Solaris thread ID into a LWP ID. If THREAD_ID
241 doesn't exist, that's an error. If it's an inactive thread, return
2689673f 242 DEFAULT_LWP.
c906108c 243
8d027a04 244 NOTE: This function probably shouldn't call error(). */
c906108c 245
39f77062
KB
246static ptid_t
247thread_to_lwp (ptid_t thread_id, int default_lwp)
c906108c
SS
248{
249 td_thrinfo_t ti;
250 td_thrhandle_t th;
251 td_err_e val;
252
253 if (is_lwp (thread_id))
8d027a04 254 return thread_id; /* It's already an LWP ID. */
c906108c 255
8d027a04 256 /* It's a thread. Convert to LWP. */
c906108c
SS
257
258 val = p_td_ta_map_id2thr (main_ta, GET_THREAD (thread_id), &th);
259 if (val == TD_NOTHR)
8d027a04 260 return pid_to_ptid (-1); /* Thread must have terminated. */
c906108c 261 else if (val != TD_OK)
8a3fe4f8 262 error (_("thread_to_lwp: td_ta_map_id2thr %s"), td_err_string (val));
c906108c
SS
263
264 val = p_td_thr_get_info (&th, &ti);
265 if (val == TD_NOTHR)
8d027a04 266 return pid_to_ptid (-1); /* Thread must have terminated. */
c906108c 267 else if (val != TD_OK)
8a3fe4f8 268 error (_("thread_to_lwp: td_thr_get_info: %s"), td_err_string (val));
c906108c
SS
269
270 if (ti.ti_state != TD_THR_ACTIVE)
271 {
272 if (default_lwp != -1)
39f77062 273 return pid_to_ptid (default_lwp);
8a3fe4f8 274 error (_("thread_to_lwp: thread state not active: %s"),
c906108c
SS
275 td_state_string (ti.ti_state));
276 }
277
278 return BUILD_LWP (ti.ti_lid, PIDGET (thread_id));
279}
c906108c 280
8d027a04
MK
281/* Convert an LWP ID into a POSIX or Solaris thread ID. If LWP_ID
282 doesn't exists, that's an error.
c906108c 283
8d027a04 284 NOTE: This function probably shouldn't call error(). */
c906108c 285
39f77062
KB
286static ptid_t
287lwp_to_thread (ptid_t lwp)
c906108c
SS
288{
289 td_thrinfo_t ti;
290 td_thrhandle_t th;
291 td_err_e val;
292
293 if (is_thread (lwp))
8d027a04 294 return lwp; /* It's already a thread ID. */
c906108c 295
8d027a04 296 /* It's an LWP. Convert it to a thread ID. */
c906108c 297
28439f5e 298 if (!target_thread_alive (lwp))
8d027a04 299 return pid_to_ptid (-1); /* Must be a defunct LPW. */
c906108c
SS
300
301 val = p_td_ta_map_lwp2thr (main_ta, GET_LWP (lwp), &th);
302 if (val == TD_NOTHR)
8d027a04 303 return pid_to_ptid (-1); /* Thread must have terminated. */
c906108c 304 else if (val != TD_OK)
8a3fe4f8 305 error (_("lwp_to_thread: td_ta_map_lwp2thr: %s."), td_err_string (val));
c906108c
SS
306
307 val = p_td_thr_validate (&th);
308 if (val == TD_NOTHR)
8d027a04 309 return lwp; /* Unknown to libthread; just return LPW, */
c906108c 310 else if (val != TD_OK)
8a3fe4f8 311 error (_("lwp_to_thread: td_thr_validate: %s."), td_err_string (val));
c906108c
SS
312
313 val = p_td_thr_get_info (&th, &ti);
314 if (val == TD_NOTHR)
8d027a04 315 return pid_to_ptid (-1); /* Thread must have terminated. */
c906108c 316 else if (val != TD_OK)
8a3fe4f8 317 error (_("lwp_to_thread: td_thr_get_info: %s."), td_err_string (val));
c906108c
SS
318
319 return BUILD_THREAD (ti.ti_tid, PIDGET (lwp));
320}
321\f
c906108c 322
8d027a04 323/* Most target vector functions from here on actually just pass
28439f5e
PA
324 through to the layer beneath, as they don't need to do anything
325 specific for threads. */
c906108c 326
8d027a04
MK
327/* Take a program previously attached to and detaches it. The program
328 resumes execution and will no longer stop on signals, etc. We'd
329 better not have left any breakpoints in the program or it'll die
330 when it hits one. For this to work, it may be necessary for the
331 process to have been previously attached. It *might* work if the
332 program was started via the normal ptrace (PTRACE_TRACEME). */
c906108c
SS
333
334static void
136d6dae 335sol_thread_detach (struct target_ops *ops, char *args, int from_tty)
c906108c 336{
28439f5e
PA
337 struct target_ops *beneath = find_target_beneath (ops);
338
2689673f 339 sol_thread_active = 0;
39f77062 340 inferior_ptid = pid_to_ptid (PIDGET (main_ph.ptid));
28439f5e
PA
341 unpush_target (ops);
342 beneath->to_detach (beneath, args, from_tty);
c906108c
SS
343}
344
8d027a04
MK
345/* Resume execution of process PTID. If STEP is nozero, then just
346 single step it. If SIGNAL is nonzero, restart it with that signal
347 activated. We may have to convert PTID from a thread ID to an LWP
348 ID for procfs. */
c906108c
SS
349
350static void
28439f5e
PA
351sol_thread_resume (struct target_ops *ops,
352 ptid_t ptid, int step, enum target_signal signo)
c906108c
SS
353{
354 struct cleanup *old_chain;
28439f5e 355 struct target_ops *beneath = find_target_beneath (ops);
c906108c 356
39f77062 357 old_chain = save_inferior_ptid ();
c906108c 358
39f77062
KB
359 inferior_ptid = thread_to_lwp (inferior_ptid, PIDGET (main_ph.ptid));
360 if (PIDGET (inferior_ptid) == -1)
361 inferior_ptid = procfs_first_available ();
c906108c 362
39f77062 363 if (PIDGET (ptid) != -1)
c906108c 364 {
39f77062 365 ptid_t save_ptid = ptid;
c906108c 366
39f77062 367 ptid = thread_to_lwp (ptid, -2);
8d027a04 368 if (PIDGET (ptid) == -2) /* Inactive thread. */
8a3fe4f8 369 error (_("This version of Solaris can't start inactive threads."));
39f77062 370 if (info_verbose && PIDGET (ptid) == -1)
8a3fe4f8 371 warning (_("Specified thread %ld seems to have terminated"),
39f77062 372 GET_THREAD (save_ptid));
c906108c
SS
373 }
374
28439f5e 375 beneath->to_resume (beneath, ptid, step, signo);
c906108c
SS
376
377 do_cleanups (old_chain);
378}
379
2689673f 380/* Wait for any threads to stop. We may have to convert PTID from a
8d027a04 381 thread ID to an LWP ID, and vice versa on the way out. */
c906108c 382
39f77062 383static ptid_t
117de6a9 384sol_thread_wait (struct target_ops *ops,
47608cb1 385 ptid_t ptid, struct target_waitstatus *ourstatus, int options)
c906108c 386{
39f77062
KB
387 ptid_t rtnval;
388 ptid_t save_ptid;
28439f5e 389 struct target_ops *beneath = find_target_beneath (ops);
c906108c
SS
390 struct cleanup *old_chain;
391
39f77062
KB
392 save_ptid = inferior_ptid;
393 old_chain = save_inferior_ptid ();
c906108c 394
39f77062
KB
395 inferior_ptid = thread_to_lwp (inferior_ptid, PIDGET (main_ph.ptid));
396 if (PIDGET (inferior_ptid) == -1)
397 inferior_ptid = procfs_first_available ();
c906108c 398
39f77062 399 if (PIDGET (ptid) != -1)
c906108c 400 {
39f77062 401 ptid_t save_ptid = ptid;
c906108c 402
39f77062 403 ptid = thread_to_lwp (ptid, -2);
8d027a04 404 if (PIDGET (ptid) == -2) /* Inactive thread. */
8a3fe4f8 405 error (_("This version of Solaris can't start inactive threads."));
39f77062 406 if (info_verbose && PIDGET (ptid) == -1)
8a3fe4f8 407 warning (_("Specified thread %ld seems to have terminated"),
39f77062 408 GET_THREAD (save_ptid));
c906108c
SS
409 }
410
47608cb1 411 rtnval = beneath->to_wait (beneath, ptid, ourstatus, options);
c906108c
SS
412
413 if (ourstatus->kind != TARGET_WAITKIND_EXITED)
414 {
8d027a04 415 /* Map the LWP of interest back to the appropriate thread ID. */
c906108c 416 rtnval = lwp_to_thread (rtnval);
39f77062
KB
417 if (PIDGET (rtnval) == -1)
418 rtnval = save_ptid;
c906108c 419
8d027a04 420 /* See if we have a new thread. */
c906108c 421 if (is_thread (rtnval)
39f77062 422 && !ptid_equal (rtnval, save_ptid)
2689673f
PA
423 && (!in_thread_list (rtnval)
424 || is_exited (rtnval)))
93815fbf 425 add_thread (rtnval);
c906108c
SS
426 }
427
8d027a04
MK
428 /* During process initialization, we may get here without the thread
429 package being initialized, since that can only happen after we've
430 found the shared libs. */
c906108c
SS
431
432 do_cleanups (old_chain);
433
434 return rtnval;
435}
436
437static void
28439f5e
PA
438sol_thread_fetch_registers (struct target_ops *ops,
439 struct regcache *regcache, int regnum)
c906108c
SS
440{
441 thread_t thread;
442 td_thrhandle_t thandle;
443 td_err_e val;
444 prgregset_t gregset;
445 prfpregset_t fpregset;
e71c308d
DJ
446 gdb_gregset_t *gregset_p = &gregset;
447 gdb_fpregset_t *fpregset_p = &fpregset;
28439f5e 448 struct target_ops *beneath = find_target_beneath (ops);
e71c308d 449
c906108c
SS
450#if 0
451 int xregsize;
452 caddr_t xregset;
453#endif
454
39f77062 455 if (!is_thread (inferior_ptid))
8d027a04 456 {
28439f5e
PA
457 /* It's an LWP; pass the request on to the layer beneath. */
458 beneath->to_fetch_registers (beneath, regcache, regnum);
c906108c
SS
459 return;
460 }
461
8d027a04 462 /* Solaris thread: convert INFERIOR_PTID into a td_thrhandle_t. */
39f77062 463 thread = GET_THREAD (inferior_ptid);
c906108c 464 if (thread == 0)
8a3fe4f8 465 error (_("sol_thread_fetch_registers: thread == 0"));
c906108c
SS
466
467 val = p_td_ta_map_id2thr (main_ta, thread, &thandle);
468 if (val != TD_OK)
8a3fe4f8 469 error (_("sol_thread_fetch_registers: td_ta_map_id2thr: %s"),
c906108c
SS
470 td_err_string (val));
471
8d027a04 472 /* Get the general-purpose registers. */
c906108c
SS
473
474 val = p_td_thr_getgregs (&thandle, gregset);
8d027a04 475 if (val != TD_OK && val != TD_PARTIALREG)
8a3fe4f8 476 error (_("sol_thread_fetch_registers: td_thr_getgregs %s"),
c906108c
SS
477 td_err_string (val));
478
8d027a04
MK
479 /* For SPARC, TD_PARTIALREG means that only %i0...%i7, %l0..%l7, %pc
480 and %sp are saved (by a thread context switch). */
c906108c 481
8d027a04 482 /* And, now the floating-point registers. */
c906108c
SS
483
484 val = p_td_thr_getfpregs (&thandle, &fpregset);
8d027a04 485 if (val != TD_OK && val != TD_NOFPREGS)
8a3fe4f8 486 error (_("sol_thread_fetch_registers: td_thr_getfpregs %s"),
c906108c
SS
487 td_err_string (val));
488
8d027a04
MK
489 /* Note that we must call supply_gregset and supply_fpregset *after*
490 calling the td routines because the td routines call ps_lget*
491 which affect the values stored in the registers array. */
c906108c 492
e71c308d
DJ
493 supply_gregset (regcache, (const gdb_gregset_t *) gregset_p);
494 supply_fpregset (regcache, (const gdb_fpregset_t *) fpregset_p);
c906108c
SS
495
496#if 0
8d027a04 497 /* FIXME: libthread_db doesn't seem to handle this right. */
c906108c
SS
498 val = td_thr_getxregsize (&thandle, &xregsize);
499 if (val != TD_OK && val != TD_NOXREGS)
8a3fe4f8 500 error (_("sol_thread_fetch_registers: td_thr_getxregsize %s"),
c906108c
SS
501 td_err_string (val));
502
503 if (val == TD_OK)
504 {
505 xregset = alloca (xregsize);
506 val = td_thr_getxregs (&thandle, xregset);
507 if (val != TD_OK)
8a3fe4f8 508 error (_("sol_thread_fetch_registers: td_thr_getxregs %s"),
c906108c
SS
509 td_err_string (val));
510 }
511#endif
512}
513
514static void
28439f5e
PA
515sol_thread_store_registers (struct target_ops *ops,
516 struct regcache *regcache, int regnum)
c906108c
SS
517{
518 thread_t thread;
519 td_thrhandle_t thandle;
520 td_err_e val;
8d027a04 521 prgregset_t gregset;
c906108c
SS
522 prfpregset_t fpregset;
523#if 0
524 int xregsize;
525 caddr_t xregset;
526#endif
527
39f77062 528 if (!is_thread (inferior_ptid))
8d027a04 529 {
28439f5e
PA
530 struct target_ops *beneath = find_target_beneath (ops);
531
532 /* It's an LWP; pass the request on to the layer beneath. */
533 beneath->to_store_registers (beneath, regcache, regnum);
c906108c
SS
534 return;
535 }
536
8d027a04 537 /* Solaris thread: convert INFERIOR_PTID into a td_thrhandle_t. */
39f77062 538 thread = GET_THREAD (inferior_ptid);
c906108c
SS
539
540 val = p_td_ta_map_id2thr (main_ta, thread, &thandle);
541 if (val != TD_OK)
8a3fe4f8 542 error (_("sol_thread_store_registers: td_ta_map_id2thr %s"),
c906108c
SS
543 td_err_string (val));
544
8d027a04
MK
545 if (regnum != -1)
546 {
547 /* Not writing all the registers. */
87232496 548 char old_value[MAX_REGISTER_SIZE];
6034ae49 549
87232496 550 /* Save new register value. */
56be3814 551 regcache_raw_collect (regcache, regnum, old_value);
c906108c 552
c60c0f5f 553 val = p_td_thr_getgregs (&thandle, gregset);
c906108c 554 if (val != TD_OK)
8a3fe4f8 555 error (_("sol_thread_store_registers: td_thr_getgregs %s"),
c906108c
SS
556 td_err_string (val));
557 val = p_td_thr_getfpregs (&thandle, &fpregset);
558 if (val != TD_OK)
8a3fe4f8 559 error (_("sol_thread_store_registers: td_thr_getfpregs %s"),
c906108c
SS
560 td_err_string (val));
561
87232496 562 /* Restore new register value. */
56be3814 563 regcache_raw_supply (regcache, regnum, old_value);
c906108c
SS
564
565#if 0
8d027a04 566 /* FIXME: libthread_db doesn't seem to handle this right. */
c906108c
SS
567 val = td_thr_getxregsize (&thandle, &xregsize);
568 if (val != TD_OK && val != TD_NOXREGS)
8a3fe4f8 569 error (_("sol_thread_store_registers: td_thr_getxregsize %s"),
c906108c
SS
570 td_err_string (val));
571
572 if (val == TD_OK)
573 {
574 xregset = alloca (xregsize);
575 val = td_thr_getxregs (&thandle, xregset);
576 if (val != TD_OK)
8a3fe4f8 577 error (_("sol_thread_store_registers: td_thr_getxregs %s"),
c906108c
SS
578 td_err_string (val));
579 }
580#endif
581 }
582
56be3814
UW
583 fill_gregset (regcache, (gdb_gregset_t *) &gregset, regnum);
584 fill_fpregset (regcache, (gdb_fpregset_t *) &fpregset, regnum);
c906108c 585
c60c0f5f 586 val = p_td_thr_setgregs (&thandle, gregset);
c906108c 587 if (val != TD_OK)
8a3fe4f8 588 error (_("sol_thread_store_registers: td_thr_setgregs %s"),
c906108c
SS
589 td_err_string (val));
590 val = p_td_thr_setfpregs (&thandle, &fpregset);
591 if (val != TD_OK)
8a3fe4f8 592 error (_("sol_thread_store_registers: td_thr_setfpregs %s"),
c906108c
SS
593 td_err_string (val));
594
595#if 0
8d027a04 596 /* FIXME: libthread_db doesn't seem to handle this right. */
c906108c
SS
597 val = td_thr_getxregsize (&thandle, &xregsize);
598 if (val != TD_OK && val != TD_NOXREGS)
8a3fe4f8 599 error (_("sol_thread_store_registers: td_thr_getxregsize %s"),
c906108c
SS
600 td_err_string (val));
601
8d027a04
MK
602 /* ??? Should probably do something about writing the xregs here,
603 but what are they? */
c906108c
SS
604#endif
605}
606
8d027a04
MK
607/* Perform partial transfers on OBJECT. See target_read_partial and
608 target_write_partial for details of each variant. One, and only
609 one, of readbuf or writebuf must be non-NULL. */
6034ae49
RM
610
611static LONGEST
612sol_thread_xfer_partial (struct target_ops *ops, enum target_object object,
b6958cfb
MK
613 const char *annex, gdb_byte *readbuf,
614 const gdb_byte *writebuf,
615 ULONGEST offset, LONGEST len)
6034ae49
RM
616{
617 int retval;
618 struct cleanup *old_chain;
28439f5e 619 struct target_ops *beneath = find_target_beneath (ops);
6034ae49
RM
620
621 old_chain = save_inferior_ptid ();
622
8d027a04
MK
623 if (is_thread (inferior_ptid) || !target_thread_alive (inferior_ptid))
624 {
625 /* It's either a thread or an LWP that isn't alive. Any live
626 LWP will do so use the first available.
627
628 NOTE: We don't need to call switch_to_thread; we're just
629 reading memory. */
630 inferior_ptid = procfs_first_available ();
631 }
6034ae49 632
28439f5e
PA
633 retval = beneath->to_xfer_partial (beneath, object, annex,
634 readbuf, writebuf, offset, len);
6034ae49
RM
635
636 do_cleanups (old_chain);
637
638 return retval;
639}
640
c906108c 641static void
28439f5e 642check_for_thread_db (void)
c906108c 643{
28439f5e
PA
644 td_err_e err;
645 ptid_t ptid;
c906108c 646
28439f5e
PA
647 /* Do nothing if we couldn't load libthread_db.so.1. */
648 if (p_td_ta_new == NULL)
649 return;
c906108c 650
28439f5e
PA
651 if (sol_thread_active)
652 /* Nothing to do. The thread library was already detected and the
653 target vector was already activated. */
654 return;
c906108c 655
28439f5e
PA
656 /* Now, initialize libthread_db. This needs to be done after the
657 shared libraries are located because it needs information from
658 the user's thread library. */
c906108c 659
28439f5e
PA
660 err = p_td_init ();
661 if (err != TD_OK)
662 {
663 warning (_("sol_thread_new_objfile: td_init: %s"), td_err_string (err));
664 return;
665 }
c906108c 666
28439f5e
PA
667 /* Now attempt to open a connection to the thread library. */
668 err = p_td_ta_new (&main_ph, &main_ta);
669 switch (err)
c906108c 670 {
28439f5e
PA
671 case TD_NOLIBTHREAD:
672 /* No thread library was detected. */
673 break;
2689673f 674
28439f5e
PA
675 case TD_OK:
676 printf_unfiltered (_("[Thread debugging using libthread_db enabled]\n"));
c906108c 677
28439f5e 678 /* The thread library was detected. Activate the sol_thread target. */
c906108c 679 push_target (&sol_thread_ops);
28439f5e 680 sol_thread_active = 1;
c906108c 681
28439f5e 682 main_ph.ptid = inferior_ptid; /* Save for xfer_memory. */
2689673f
PA
683 ptid = lwp_to_thread (inferior_ptid);
684 if (PIDGET (ptid) != -1)
28439f5e
PA
685 inferior_ptid = ptid;
686
687 target_find_new_threads ();
688 break;
689
690 default:
691 warning (_("Cannot initialize thread debugging library: %s"),
692 td_err_string (err));
693 break;
c906108c
SS
694 }
695}
696
8d027a04
MK
697/* This routine is called whenever a new symbol table is read in, or
698 when all symbol tables are removed. libthread_db can only be
699 initialized when it finds the right variables in libthread.so.
700 Since it's a shared library, those variables don't show up until
06d3b283 701 the library gets mapped and the symbol table is read in. */
c906108c 702
06d3b283 703static void
fba45db2 704sol_thread_new_objfile (struct objfile *objfile)
c906108c 705{
28439f5e
PA
706 if (objfile != NULL)
707 check_for_thread_db ();
c906108c
SS
708}
709
710/* Clean up after the inferior dies. */
711
712static void
136d6dae 713sol_thread_mourn_inferior (struct target_ops *ops)
c906108c 714{
28439f5e
PA
715 struct target_ops *beneath = find_target_beneath (ops);
716
2689673f 717 sol_thread_active = 0;
c906108c 718
28439f5e 719 unpush_target (ops);
c906108c 720
28439f5e 721 beneath->to_mourn_inferior (beneath);
c906108c
SS
722}
723
8d027a04
MK
724/* Return true if PTID is still active in the inferior. */
725
c906108c 726static int
28439f5e 727sol_thread_alive (struct target_ops *ops, ptid_t ptid)
c906108c 728{
8d027a04 729 if (is_thread (ptid))
c906108c 730 {
8d027a04 731 /* It's a (user-level) thread. */
c906108c
SS
732 td_err_e val;
733 td_thrhandle_t th;
39f77062 734 int pid;
c906108c 735
39f77062 736 pid = GET_THREAD (ptid);
c906108c 737 if ((val = p_td_ta_map_id2thr (main_ta, pid, &th)) != TD_OK)
8d027a04 738 return 0; /* Thread not found. */
c906108c 739 if ((val = p_td_thr_validate (&th)) != TD_OK)
8d027a04
MK
740 return 0; /* Thread not valid. */
741 return 1; /* Known thread. */
c906108c 742 }
c5aa993b 743 else
c906108c 744 {
28439f5e
PA
745 struct target_ops *beneath = find_target_beneath (ops);
746
747 /* It's an LPW; pass the request on to the layer below. */
748 return beneath->to_thread_alive (beneath, ptid);
c906108c
SS
749 }
750}
751
c906108c 752\f
8d027a04
MK
753/* These routines implement the lower half of the thread_db interface,
754 i.e. the ps_* routines. */
c906108c 755
8d027a04
MK
756/* Various versions of <proc_service.h> have slightly different
757 function prototypes. In particular, we have
c906108c 758
c5aa993b
JM
759 NEWER OLDER
760 struct ps_prochandle * const struct ps_prochandle *
761 void* char*
8d027a04
MK
762 const void* char*
763 int size_t
c906108c 764
8d027a04
MK
765 Which one you have depends on the Solaris version and what patches
766 you've applied. On the theory that there are only two major
767 variants, we have configure check the prototype of ps_pdwrite (),
768 and use that info to make appropriate typedefs here. */
c906108c
SS
769
770#ifdef PROC_SERVICE_IS_OLD
c5aa993b
JM
771typedef const struct ps_prochandle *gdb_ps_prochandle_t;
772typedef char *gdb_ps_read_buf_t;
773typedef char *gdb_ps_write_buf_t;
c906108c 774typedef int gdb_ps_size_t;
76e1ee85 775typedef psaddr_t gdb_ps_addr_t;
c906108c 776#else
c5aa993b
JM
777typedef struct ps_prochandle *gdb_ps_prochandle_t;
778typedef void *gdb_ps_read_buf_t;
779typedef const void *gdb_ps_write_buf_t;
c906108c 780typedef size_t gdb_ps_size_t;
291dcb3e 781typedef psaddr_t gdb_ps_addr_t;
c906108c
SS
782#endif
783
8d027a04
MK
784/* The next four routines are called by libthread_db to tell us to
785 stop and stop a particular process or lwp. Since GDB ensures that
786 these are all stopped by the time we call anything in thread_db,
787 these routines need to do nothing. */
c906108c 788
8d027a04 789/* Process stop. */
d4f3574e 790
c906108c
SS
791ps_err_e
792ps_pstop (gdb_ps_prochandle_t ph)
793{
794 return PS_OK;
795}
796
8d027a04 797/* Process continue. */
d4f3574e 798
c906108c
SS
799ps_err_e
800ps_pcontinue (gdb_ps_prochandle_t ph)
801{
802 return PS_OK;
803}
804
8d027a04 805/* LWP stop. */
d4f3574e 806
c906108c
SS
807ps_err_e
808ps_lstop (gdb_ps_prochandle_t ph, lwpid_t lwpid)
809{
810 return PS_OK;
811}
812
8d027a04 813/* LWP continue. */
d4f3574e 814
c906108c
SS
815ps_err_e
816ps_lcontinue (gdb_ps_prochandle_t ph, lwpid_t lwpid)
817{
818 return PS_OK;
819}
820
d4f3574e
SS
821/* Looks up the symbol LD_SYMBOL_NAME in the debugger's symbol table. */
822
c906108c
SS
823ps_err_e
824ps_pglobal_lookup (gdb_ps_prochandle_t ph, const char *ld_object_name,
8d027a04 825 const char *ld_symbol_name, gdb_ps_addr_t *ld_symbol_addr)
c906108c
SS
826{
827 struct minimal_symbol *ms;
828
829 ms = lookup_minimal_symbol (ld_symbol_name, NULL, NULL);
c906108c
SS
830 if (!ms)
831 return PS_NOSYM;
832
833 *ld_symbol_addr = SYMBOL_VALUE_ADDRESS (ms);
c906108c
SS
834 return PS_OK;
835}
836
837/* Common routine for reading and writing memory. */
838
839static ps_err_e
291dcb3e 840rw_common (int dowrite, const struct ps_prochandle *ph, gdb_ps_addr_t addr,
c906108c
SS
841 char *buf, int size)
842{
28439f5e 843 int ret;
c906108c
SS
844 struct cleanup *old_chain;
845
39f77062 846 old_chain = save_inferior_ptid ();
c906108c 847
8d027a04
MK
848 if (is_thread (inferior_ptid) || !target_thread_alive (inferior_ptid))
849 {
850 /* It's either a thread or an LWP that isn't alive. Any live
851 LWP will do so use the first available.
852
853 NOTE: We don't need to call switch_to_thread; we're just
854 reading memory. */
855 inferior_ptid = procfs_first_available ();
856 }
c906108c 857
23e04971
MS
858#if defined (__sparcv9)
859 /* For Sparc64 cross Sparc32, make sure the address has not been
860 accidentally sign-extended (or whatever) to beyond 32 bits. */
359431fb 861 if (bfd_get_arch_size (exec_bfd) == 32)
23e04971
MS
862 addr &= 0xffffffff;
863#endif
864
28439f5e
PA
865 if (dowrite)
866 ret = target_write_memory (addr, buf, size);
867 else
868 ret = target_read_memory (addr, buf, size);
c906108c
SS
869
870 do_cleanups (old_chain);
871
28439f5e 872 return (ret == 0 ? PS_OK : PS_ERR);
c906108c
SS
873}
874
d4f3574e
SS
875/* Copies SIZE bytes from target process .data segment to debugger memory. */
876
c906108c 877ps_err_e
291dcb3e 878ps_pdread (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
c906108c
SS
879 gdb_ps_read_buf_t buf, gdb_ps_size_t size)
880{
881 return rw_common (0, ph, addr, buf, size);
882}
883
d4f3574e
SS
884/* Copies SIZE bytes from debugger memory .data segment to target process. */
885
c906108c 886ps_err_e
291dcb3e 887ps_pdwrite (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
c906108c
SS
888 gdb_ps_write_buf_t buf, gdb_ps_size_t size)
889{
c5aa993b 890 return rw_common (1, ph, addr, (char *) buf, size);
c906108c
SS
891}
892
d4f3574e
SS
893/* Copies SIZE bytes from target process .text segment to debugger memory. */
894
c906108c 895ps_err_e
291dcb3e 896ps_ptread (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
c906108c
SS
897 gdb_ps_read_buf_t buf, gdb_ps_size_t size)
898{
899 return rw_common (0, ph, addr, buf, size);
900}
901
d4f3574e
SS
902/* Copies SIZE bytes from debugger memory .text segment to target process. */
903
c906108c 904ps_err_e
291dcb3e 905ps_ptwrite (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
c906108c
SS
906 gdb_ps_write_buf_t buf, gdb_ps_size_t size)
907{
c5aa993b 908 return rw_common (1, ph, addr, (char *) buf, size);
c906108c
SS
909}
910
8d027a04 911/* Get general-purpose registers for LWP. */
c906108c
SS
912
913ps_err_e
8d027a04 914ps_lgetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, prgregset_t gregset)
c906108c
SS
915{
916 struct cleanup *old_chain;
594f7785 917 struct regcache *regcache;
c906108c 918
39f77062 919 old_chain = save_inferior_ptid ();
c906108c 920
39f77062 921 inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
594f7785 922 regcache = get_thread_regcache (inferior_ptid);
c5aa993b 923
28439f5e 924 target_fetch_registers (regcache, -1);
594f7785 925 fill_gregset (regcache, (gdb_gregset_t *) gregset, -1);
c906108c
SS
926
927 do_cleanups (old_chain);
928
929 return PS_OK;
930}
931
8d027a04 932/* Set general-purpose registers for LWP. */
c906108c
SS
933
934ps_err_e
935ps_lsetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
936 const prgregset_t gregset)
937{
938 struct cleanup *old_chain;
594f7785 939 struct regcache *regcache;
c906108c 940
39f77062 941 old_chain = save_inferior_ptid ();
c906108c 942
39f77062 943 inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
594f7785 944 regcache = get_thread_regcache (inferior_ptid);
c5aa993b 945
594f7785 946 supply_gregset (regcache, (const gdb_gregset_t *) gregset);
28439f5e 947 target_store_registers (regcache, -1);
c906108c
SS
948
949 do_cleanups (old_chain);
950
951 return PS_OK;
952}
953
d4f3574e
SS
954/* Log a message (sends to gdb_stderr). */
955
c906108c 956void
8d027a04 957ps_plog (const char *fmt, ...)
c906108c
SS
958{
959 va_list args;
960
961 va_start (args, fmt);
962
963 vfprintf_filtered (gdb_stderr, fmt, args);
964}
965
966/* Get size of extra register set. Currently a noop. */
967
968ps_err_e
969ps_lgetxregsize (gdb_ps_prochandle_t ph, lwpid_t lwpid, int *xregsize)
970{
971#if 0
972 int lwp_fd;
973 int regsize;
974 ps_err_e val;
975
976 val = get_lwp_fd (ph, lwpid, &lwp_fd);
977 if (val != PS_OK)
978 return val;
979
980 if (ioctl (lwp_fd, PIOCGXREGSIZE, &regsize))
981 {
982 if (errno == EINVAL)
983 return PS_NOFREGS; /* XXX Wrong code, but this is the closest
984 thing in proc_service.h */
985
986 print_sys_errmsg ("ps_lgetxregsize (): PIOCGXREGSIZE", errno);
987 return PS_ERR;
988 }
989#endif
990
991 return PS_OK;
992}
993
994/* Get extra register set. Currently a noop. */
995
996ps_err_e
997ps_lgetxregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, caddr_t xregset)
998{
999#if 0
1000 int lwp_fd;
1001 ps_err_e val;
1002
1003 val = get_lwp_fd (ph, lwpid, &lwp_fd);
1004 if (val != PS_OK)
1005 return val;
1006
1007 if (ioctl (lwp_fd, PIOCGXREG, xregset))
1008 {
1009 print_sys_errmsg ("ps_lgetxregs (): PIOCGXREG", errno);
1010 return PS_ERR;
1011 }
1012#endif
1013
1014 return PS_OK;
1015}
1016
1017/* Set extra register set. Currently a noop. */
1018
1019ps_err_e
1020ps_lsetxregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, caddr_t xregset)
1021{
1022#if 0
1023 int lwp_fd;
1024 ps_err_e val;
1025
1026 val = get_lwp_fd (ph, lwpid, &lwp_fd);
1027 if (val != PS_OK)
1028 return val;
1029
1030 if (ioctl (lwp_fd, PIOCSXREG, xregset))
1031 {
1032 print_sys_errmsg ("ps_lsetxregs (): PIOCSXREG", errno);
1033 return PS_ERR;
1034 }
1035#endif
1036
1037 return PS_OK;
1038}
1039
8d027a04 1040/* Get floating-point registers for LWP. */
c906108c
SS
1041
1042ps_err_e
1043ps_lgetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
8d027a04 1044 prfpregset_t *fpregset)
c906108c
SS
1045{
1046 struct cleanup *old_chain;
594f7785 1047 struct regcache *regcache;
c906108c 1048
39f77062 1049 old_chain = save_inferior_ptid ();
c906108c 1050
39f77062 1051 inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
594f7785 1052 regcache = get_thread_regcache (inferior_ptid);
c906108c 1053
28439f5e 1054 target_fetch_registers (regcache, -1);
594f7785 1055 fill_fpregset (regcache, (gdb_fpregset_t *) fpregset, -1);
c906108c
SS
1056
1057 do_cleanups (old_chain);
1058
1059 return PS_OK;
1060}
1061
d4f3574e 1062/* Set floating-point regs for LWP */
c906108c
SS
1063
1064ps_err_e
1065ps_lsetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
c5aa993b 1066 const prfpregset_t * fpregset)
c906108c
SS
1067{
1068 struct cleanup *old_chain;
594f7785 1069 struct regcache *regcache;
c906108c 1070
39f77062 1071 old_chain = save_inferior_ptid ();
c906108c 1072
39f77062 1073 inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
594f7785 1074 regcache = get_thread_regcache (inferior_ptid);
c5aa993b 1075
594f7785 1076 supply_fpregset (regcache, (const gdb_fpregset_t *) fpregset);
28439f5e 1077 target_store_registers (regcache, -1);
c906108c
SS
1078
1079 do_cleanups (old_chain);
1080
1081 return PS_OK;
1082}
1083
23715f29 1084#ifdef PR_MODEL_LP64
8d027a04
MK
1085/* Identify process as 32-bit or 64-bit. At the moment we're using
1086 BFD to do this. There might be a more Solaris-specific
1087 (e.g. procfs) method, but this ought to work. */
23e04971
MS
1088
1089ps_err_e
1090ps_pdmodel (gdb_ps_prochandle_t ph, int *data_model)
1091{
1092 if (exec_bfd == 0)
a95ac8b6
PS
1093 *data_model = PR_MODEL_UNKNOWN;
1094 else if (bfd_get_arch_size (exec_bfd) == 32)
23e04971
MS
1095 *data_model = PR_MODEL_ILP32;
1096 else
1097 *data_model = PR_MODEL_LP64;
1098
1099 return PS_OK;
1100}
23715f29 1101#endif /* PR_MODEL_LP64 */
23e04971 1102
965b60ee 1103#if (defined(__i386__) || defined(__x86_64__)) && defined (sun)
c906108c 1104
965b60ee
JB
1105/* Reads the local descriptor table of a LWP.
1106
1107 This function is necessary on x86-solaris only. Without it, the loading
1108 of libthread_db would fail because of ps_lgetLDT being undefined. */
d4f3574e 1109
c906108c
SS
1110ps_err_e
1111ps_lgetLDT (gdb_ps_prochandle_t ph, lwpid_t lwpid,
1112 struct ssd *pldt)
1113{
8d027a04 1114 /* NOTE: only used on Solaris, therefore OK to refer to procfs.c. */
39f77062 1115 extern struct ssd *procfs_find_LDT_entry (ptid_t);
05e28a7b 1116 struct ssd *ret;
c906108c 1117
8d027a04
MK
1118 /* FIXME: can't I get the process ID from the prochandle or
1119 something? */
2f09097b 1120
39f77062 1121 if (PIDGET (inferior_ptid) <= 0 || lwpid <= 0)
2f09097b
ND
1122 return PS_BADLID;
1123
39f77062 1124 ret = procfs_find_LDT_entry (BUILD_LWP (lwpid, PIDGET (inferior_ptid)));
05e28a7b 1125 if (ret)
c906108c 1126 {
05e28a7b
AC
1127 memcpy (pldt, ret, sizeof (struct ssd));
1128 return PS_OK;
c906108c 1129 }
8d027a04
MK
1130 else
1131 /* LDT not found. */
c906108c 1132 return PS_ERR;
c5aa993b 1133}
965b60ee 1134#endif
c906108c 1135\f
8d027a04
MK
1136
1137/* Convert PTID to printable form. */
c906108c
SS
1138
1139char *
117de6a9 1140solaris_pid_to_str (struct target_ops *ops, ptid_t ptid)
c906108c
SS
1141{
1142 static char buf[100];
1143
39f77062 1144 if (is_thread (ptid))
c906108c 1145 {
39f77062 1146 ptid_t lwp;
c906108c 1147
39f77062 1148 lwp = thread_to_lwp (ptid, -2);
c906108c 1149
39f77062
KB
1150 if (PIDGET (lwp) == -1)
1151 sprintf (buf, "Thread %ld (defunct)", GET_THREAD (ptid));
1152 else if (PIDGET (lwp) != -2)
8d027a04
MK
1153 sprintf (buf, "Thread %ld (LWP %ld)",
1154 GET_THREAD (ptid), GET_LWP (lwp));
c906108c 1155 else
39f77062 1156 sprintf (buf, "Thread %ld ", GET_THREAD (ptid));
c906108c 1157 }
39f77062
KB
1158 else if (GET_LWP (ptid) != 0)
1159 sprintf (buf, "LWP %ld ", GET_LWP (ptid));
c906108c 1160 else
39f77062 1161 sprintf (buf, "process %d ", PIDGET (ptid));
c906108c
SS
1162
1163 return buf;
1164}
1165\f
1166
8d027a04
MK
1167/* Worker bee for find_new_threads. Callback function that gets
1168 called once per user-level thread (i.e. not for LWP's). */
c906108c
SS
1169
1170static int
fba45db2 1171sol_find_new_threads_callback (const td_thrhandle_t *th, void *ignored)
c906108c
SS
1172{
1173 td_err_e retval;
1174 td_thrinfo_t ti;
39f77062 1175 ptid_t ptid;
c906108c 1176
8d027a04
MK
1177 retval = p_td_thr_get_info (th, &ti);
1178 if (retval != TD_OK)
1179 return -1;
1180
39f77062 1181 ptid = BUILD_THREAD (ti.ti_tid, PIDGET (inferior_ptid));
2689673f 1182 if (!in_thread_list (ptid) || is_exited (ptid))
39f77062 1183 add_thread (ptid);
c906108c
SS
1184
1185 return 0;
1186}
1187
d4f3574e 1188static void
28439f5e 1189sol_find_new_threads (struct target_ops *ops)
c906108c 1190{
28439f5e 1191 struct target_ops *beneath = find_target_beneath (ops);
8d027a04
MK
1192
1193 /* First Find any new LWP's. */
28439f5e
PA
1194 if (beneath->to_find_new_threads != NULL)
1195 beneath->to_find_new_threads (beneath);
8d027a04
MK
1196
1197 /* Then find any new user-level threads. */
c5aa993b 1198 p_td_ta_thr_iter (main_ta, sol_find_new_threads_callback, (void *) 0,
c906108c
SS
1199 TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
1200 TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
1201}
1202
8d027a04
MK
1203/* Worker bee for the "info sol-thread" command. This is a callback
1204 function that gets called once for each Solaris user-level thread
1205 (i.e. not for LWPs) in the inferior. Print anything interesting
1206 that we can think of. */
c906108c 1207
c5aa993b 1208static int
fba45db2 1209info_cb (const td_thrhandle_t *th, void *s)
c906108c
SS
1210{
1211 td_err_e ret;
1212 td_thrinfo_t ti;
c906108c 1213
8d027a04
MK
1214 ret = p_td_thr_get_info (th, &ti);
1215 if (ret == TD_OK)
c906108c 1216 {
c5aa993b
JM
1217 printf_filtered ("%s thread #%d, lwp %d, ",
1218 ti.ti_type == TD_THR_SYSTEM ? "system" : "user ",
c906108c 1219 ti.ti_tid, ti.ti_lid);
c5aa993b
JM
1220 switch (ti.ti_state)
1221 {
c906108c 1222 default:
c5aa993b
JM
1223 case TD_THR_UNKNOWN:
1224 printf_filtered ("<unknown state>");
1225 break;
1226 case TD_THR_STOPPED:
1227 printf_filtered ("(stopped)");
1228 break;
1229 case TD_THR_RUN:
1230 printf_filtered ("(run) ");
1231 break;
1232 case TD_THR_ACTIVE:
1233 printf_filtered ("(active) ");
1234 break;
1235 case TD_THR_ZOMBIE:
1236 printf_filtered ("(zombie) ");
1237 break;
1238 case TD_THR_SLEEP:
1239 printf_filtered ("(asleep) ");
1240 break;
1241 case TD_THR_STOPPED_ASLEEP:
1242 printf_filtered ("(stopped asleep)");
1243 break;
1244 }
8d027a04 1245 /* Print thr_create start function. */
c906108c 1246 if (ti.ti_startfunc != 0)
4ce44c66
JM
1247 {
1248 struct minimal_symbol *msym;
1249 msym = lookup_minimal_symbol_by_pc (ti.ti_startfunc);
1250 if (msym)
8d027a04 1251 printf_filtered (" startfunc: %s\n",
3567439c 1252 SYMBOL_PRINT_NAME (msym));
4ce44c66
JM
1253 else
1254 printf_filtered (" startfunc: 0x%s\n", paddr (ti.ti_startfunc));
1255 }
c906108c 1256
8d027a04 1257 /* If thread is asleep, print function that went to sleep. */
c906108c 1258 if (ti.ti_state == TD_THR_SLEEP)
4ce44c66
JM
1259 {
1260 struct minimal_symbol *msym;
1261 msym = lookup_minimal_symbol_by_pc (ti.ti_pc);
1262 if (msym)
8d027a04 1263 printf_filtered (" - Sleep func: %s\n",
3567439c 1264 SYMBOL_PRINT_NAME (msym));
4ce44c66
JM
1265 else
1266 printf_filtered (" - Sleep func: 0x%s\n", paddr (ti.ti_startfunc));
1267 }
c906108c 1268
8d027a04 1269 /* Wrap up line, if necessary. */
c906108c
SS
1270 if (ti.ti_state != TD_THR_SLEEP && ti.ti_startfunc == 0)
1271 printf_filtered ("\n"); /* don't you hate counting newlines? */
1272 }
1273 else
8a3fe4f8 1274 warning (_("info sol-thread: failed to get info for thread."));
c906108c 1275
c5aa993b 1276 return 0;
c906108c
SS
1277}
1278
8d027a04
MK
1279/* List some state about each Solaris user-level thread in the
1280 inferior. */
c906108c
SS
1281
1282static void
fba45db2 1283info_solthreads (char *args, int from_tty)
c906108c 1284{
c5aa993b 1285 p_td_ta_thr_iter (main_ta, info_cb, args,
c906108c
SS
1286 TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
1287 TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
1288}
c906108c 1289
c906108c 1290static void
fba45db2 1291init_sol_thread_ops (void)
c906108c
SS
1292{
1293 sol_thread_ops.to_shortname = "solaris-threads";
1294 sol_thread_ops.to_longname = "Solaris threads and pthread.";
1295 sol_thread_ops.to_doc = "Solaris threads and pthread support.";
c906108c
SS
1296 sol_thread_ops.to_detach = sol_thread_detach;
1297 sol_thread_ops.to_resume = sol_thread_resume;
1298 sol_thread_ops.to_wait = sol_thread_wait;
1299 sol_thread_ops.to_fetch_registers = sol_thread_fetch_registers;
1300 sol_thread_ops.to_store_registers = sol_thread_store_registers;
6034ae49 1301 sol_thread_ops.to_xfer_partial = sol_thread_xfer_partial;
c906108c 1302 sol_thread_ops.to_mourn_inferior = sol_thread_mourn_inferior;
c906108c 1303 sol_thread_ops.to_thread_alive = sol_thread_alive;
ed9a39eb 1304 sol_thread_ops.to_pid_to_str = solaris_pid_to_str;
b83266a0 1305 sol_thread_ops.to_find_new_threads = sol_find_new_threads;
28439f5e 1306 sol_thread_ops.to_stratum = thread_stratum;
c906108c
SS
1307 sol_thread_ops.to_magic = OPS_MAGIC;
1308}
1309
c906108c 1310void
fba45db2 1311_initialize_sol_thread (void)
c906108c
SS
1312{
1313 void *dlhandle;
1314
1315 init_sol_thread_ops ();
c906108c
SS
1316
1317 dlhandle = dlopen ("libthread_db.so.1", RTLD_NOW);
1318 if (!dlhandle)
1319 goto die;
1320
1321#define resolve(X) \
1322 if (!(p_##X = dlsym (dlhandle, #X))) \
1323 goto die;
1324
1325 resolve (td_log);
1326 resolve (td_ta_new);
1327 resolve (td_ta_delete);
1328 resolve (td_init);
1329 resolve (td_ta_get_ph);
1330 resolve (td_ta_get_nthreads);
1331 resolve (td_ta_tsd_iter);
1332 resolve (td_ta_thr_iter);
1333 resolve (td_thr_validate);
1334 resolve (td_thr_tsd);
1335 resolve (td_thr_get_info);
1336 resolve (td_thr_getfpregs);
1337 resolve (td_thr_getxregsize);
1338 resolve (td_thr_getxregs);
1339 resolve (td_thr_sigsetmask);
1340 resolve (td_thr_setprio);
1341 resolve (td_thr_setsigpending);
1342 resolve (td_thr_setfpregs);
1343 resolve (td_thr_setxregs);
1344 resolve (td_ta_map_id2thr);
1345 resolve (td_ta_map_lwp2thr);
1346 resolve (td_thr_getgregs);
1347 resolve (td_thr_setgregs);
1348
1349 add_target (&sol_thread_ops);
1350
c5aa993b 1351 add_cmd ("sol-threads", class_maintenance, info_solthreads,
1a966eab 1352 _("Show info on Solaris user threads."), &maintenanceinfolist);
c906108c 1353
8d027a04 1354 /* Hook into new_objfile notification. */
06d3b283 1355 observer_attach_new_objfile (sol_thread_new_objfile);
c906108c
SS
1356 return;
1357
8d027a04
MK
1358 die:
1359 fprintf_unfiltered (gdb_stderr, "\
1360[GDB will not be able to debug user-mode threads: %s]\n", dlerror ());
c906108c
SS
1361
1362 if (dlhandle)
1363 dlclose (dlhandle);
1364
c906108c
SS
1365 return;
1366}
This page took 1.042679 seconds and 4 git commands to generate.