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