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