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