Improve MSP430 section placement.
[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;
995816ba 89 const char *str;
8d027a04 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 181
995816ba 182static const 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 225
995816ba 226static const 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 369{
28439f5e 370 struct target_ops *beneath = find_target_beneath (ops);
c906108c 371
2989a365 372 scoped_restore save_inferior_ptid = make_scoped_restore (&inferior_ptid);
c906108c 373
dfd4cc63
LM
374 inferior_ptid = thread_to_lwp (inferior_ptid, ptid_get_pid (main_ph.ptid));
375 if (ptid_get_pid (inferior_ptid) == -1)
39f77062 376 inferior_ptid = procfs_first_available ();
c906108c 377
dfd4cc63 378 if (ptid_get_pid (ptid) != -1)
c906108c 379 {
39f77062 380 ptid_t save_ptid = ptid;
c906108c 381
39f77062 382 ptid = thread_to_lwp (ptid, -2);
dfd4cc63 383 if (ptid_get_pid (ptid) == -2) /* Inactive thread. */
8a3fe4f8 384 error (_("This version of Solaris can't start inactive threads."));
dfd4cc63 385 if (info_verbose && ptid_get_pid (ptid) == -1)
8a3fe4f8 386 warning (_("Specified thread %ld seems to have terminated"),
dfd4cc63 387 ptid_get_tid (save_ptid));
c906108c
SS
388 }
389
28439f5e 390 beneath->to_resume (beneath, ptid, step, signo);
c906108c
SS
391}
392
2689673f 393/* Wait for any threads to stop. We may have to convert PTID from a
8d027a04 394 thread ID to an LWP ID, and vice versa on the way out. */
c906108c 395
39f77062 396static ptid_t
117de6a9 397sol_thread_wait (struct target_ops *ops,
47608cb1 398 ptid_t ptid, struct target_waitstatus *ourstatus, int options)
c906108c 399{
39f77062
KB
400 ptid_t rtnval;
401 ptid_t save_ptid;
28439f5e 402 struct target_ops *beneath = find_target_beneath (ops);
c906108c 403
39f77062 404 save_ptid = inferior_ptid;
2989a365 405 scoped_restore save_inferior_ptid = make_scoped_restore (&inferior_ptid);
c906108c 406
dfd4cc63
LM
407 inferior_ptid = thread_to_lwp (inferior_ptid, ptid_get_pid (main_ph.ptid));
408 if (ptid_get_pid (inferior_ptid) == -1)
39f77062 409 inferior_ptid = procfs_first_available ();
c906108c 410
dfd4cc63 411 if (ptid_get_pid (ptid) != -1)
c906108c 412 {
39f77062 413 ptid_t save_ptid = ptid;
c906108c 414
39f77062 415 ptid = thread_to_lwp (ptid, -2);
dfd4cc63 416 if (ptid_get_pid (ptid) == -2) /* Inactive thread. */
8a3fe4f8 417 error (_("This version of Solaris can't start inactive threads."));
dfd4cc63 418 if (info_verbose && ptid_get_pid (ptid) == -1)
8a3fe4f8 419 warning (_("Specified thread %ld seems to have terminated"),
dfd4cc63 420 ptid_get_tid (save_ptid));
c906108c
SS
421 }
422
47608cb1 423 rtnval = beneath->to_wait (beneath, ptid, ourstatus, options);
c906108c
SS
424
425 if (ourstatus->kind != TARGET_WAITKIND_EXITED)
426 {
8d027a04 427 /* Map the LWP of interest back to the appropriate thread ID. */
c906108c 428 rtnval = lwp_to_thread (rtnval);
dfd4cc63 429 if (ptid_get_pid (rtnval) == -1)
39f77062 430 rtnval = save_ptid;
c906108c 431
8d027a04 432 /* See if we have a new thread. */
dfd4cc63 433 if (ptid_tid_p (rtnval)
39f77062 434 && !ptid_equal (rtnval, save_ptid)
2689673f
PA
435 && (!in_thread_list (rtnval)
436 || is_exited (rtnval)))
93815fbf 437 add_thread (rtnval);
c906108c
SS
438 }
439
8d027a04
MK
440 /* During process initialization, we may get here without the thread
441 package being initialized, since that can only happen after we've
442 found the shared libs. */
c906108c 443
c906108c
SS
444 return rtnval;
445}
446
447static void
28439f5e
PA
448sol_thread_fetch_registers (struct target_ops *ops,
449 struct regcache *regcache, int regnum)
c906108c
SS
450{
451 thread_t thread;
452 td_thrhandle_t thandle;
453 td_err_e val;
454 prgregset_t gregset;
455 prfpregset_t fpregset;
e71c308d
DJ
456 gdb_gregset_t *gregset_p = &gregset;
457 gdb_fpregset_t *fpregset_p = &fpregset;
28439f5e 458 struct target_ops *beneath = find_target_beneath (ops);
bcc0c096 459 ptid_t ptid = regcache_get_ptid (regcache);
e71c308d 460
bcc0c096 461 if (!ptid_tid_p (ptid))
8d027a04 462 {
28439f5e
PA
463 /* It's an LWP; pass the request on to the layer beneath. */
464 beneath->to_fetch_registers (beneath, regcache, regnum);
c906108c
SS
465 return;
466 }
467
bcc0c096
SM
468 /* Solaris thread: convert PTID into a td_thrhandle_t. */
469 thread = ptid_get_tid (ptid);
c906108c 470 if (thread == 0)
8a3fe4f8 471 error (_("sol_thread_fetch_registers: thread == 0"));
c906108c
SS
472
473 val = p_td_ta_map_id2thr (main_ta, thread, &thandle);
474 if (val != TD_OK)
8a3fe4f8 475 error (_("sol_thread_fetch_registers: td_ta_map_id2thr: %s"),
c906108c
SS
476 td_err_string (val));
477
8d027a04 478 /* Get the general-purpose registers. */
c906108c
SS
479
480 val = p_td_thr_getgregs (&thandle, gregset);
8d027a04 481 if (val != TD_OK && val != TD_PARTIALREG)
8a3fe4f8 482 error (_("sol_thread_fetch_registers: td_thr_getgregs %s"),
c906108c
SS
483 td_err_string (val));
484
8d027a04
MK
485 /* For SPARC, TD_PARTIALREG means that only %i0...%i7, %l0..%l7, %pc
486 and %sp are saved (by a thread context switch). */
c906108c 487
8d027a04 488 /* And, now the floating-point registers. */
c906108c
SS
489
490 val = p_td_thr_getfpregs (&thandle, &fpregset);
8d027a04 491 if (val != TD_OK && val != TD_NOFPREGS)
8a3fe4f8 492 error (_("sol_thread_fetch_registers: td_thr_getfpregs %s"),
c906108c
SS
493 td_err_string (val));
494
8d027a04
MK
495 /* Note that we must call supply_gregset and supply_fpregset *after*
496 calling the td routines because the td routines call ps_lget*
497 which affect the values stored in the registers array. */
c906108c 498
e71c308d
DJ
499 supply_gregset (regcache, (const gdb_gregset_t *) gregset_p);
500 supply_fpregset (regcache, (const gdb_fpregset_t *) fpregset_p);
c906108c
SS
501}
502
503static void
28439f5e
PA
504sol_thread_store_registers (struct target_ops *ops,
505 struct regcache *regcache, int regnum)
c906108c
SS
506{
507 thread_t thread;
508 td_thrhandle_t thandle;
509 td_err_e val;
8d027a04 510 prgregset_t gregset;
c906108c 511 prfpregset_t fpregset;
bcc0c096 512 ptid_t ptid = regcache_get_ptid (regcache);
c906108c 513
bcc0c096 514 if (!ptid_tid_p (ptid))
8d027a04 515 {
28439f5e
PA
516 struct target_ops *beneath = find_target_beneath (ops);
517
518 /* It's an LWP; pass the request on to the layer beneath. */
519 beneath->to_store_registers (beneath, regcache, regnum);
c906108c
SS
520 return;
521 }
522
bcc0c096
SM
523 /* Solaris thread: convert PTID into a td_thrhandle_t. */
524 thread = ptid_get_tid (ptid);
c906108c
SS
525
526 val = p_td_ta_map_id2thr (main_ta, thread, &thandle);
527 if (val != TD_OK)
8a3fe4f8 528 error (_("sol_thread_store_registers: td_ta_map_id2thr %s"),
c906108c
SS
529 td_err_string (val));
530
8d027a04
MK
531 if (regnum != -1)
532 {
c60c0f5f 533 val = p_td_thr_getgregs (&thandle, gregset);
c906108c 534 if (val != TD_OK)
8a3fe4f8 535 error (_("sol_thread_store_registers: td_thr_getgregs %s"),
c906108c
SS
536 td_err_string (val));
537 val = p_td_thr_getfpregs (&thandle, &fpregset);
538 if (val != TD_OK)
8a3fe4f8 539 error (_("sol_thread_store_registers: td_thr_getfpregs %s"),
c906108c 540 td_err_string (val));
c906108c
SS
541 }
542
56be3814
UW
543 fill_gregset (regcache, (gdb_gregset_t *) &gregset, regnum);
544 fill_fpregset (regcache, (gdb_fpregset_t *) &fpregset, regnum);
c906108c 545
c60c0f5f 546 val = p_td_thr_setgregs (&thandle, gregset);
c906108c 547 if (val != TD_OK)
8a3fe4f8 548 error (_("sol_thread_store_registers: td_thr_setgregs %s"),
c906108c
SS
549 td_err_string (val));
550 val = p_td_thr_setfpregs (&thandle, &fpregset);
551 if (val != TD_OK)
8a3fe4f8 552 error (_("sol_thread_store_registers: td_thr_setfpregs %s"),
c906108c 553 td_err_string (val));
c906108c
SS
554}
555
8d027a04
MK
556/* Perform partial transfers on OBJECT. See target_read_partial and
557 target_write_partial for details of each variant. One, and only
558 one, of readbuf or writebuf must be non-NULL. */
6034ae49 559
9b409511 560static enum target_xfer_status
6034ae49 561sol_thread_xfer_partial (struct target_ops *ops, enum target_object object,
b6958cfb
MK
562 const char *annex, gdb_byte *readbuf,
563 const gdb_byte *writebuf,
9b409511 564 ULONGEST offset, ULONGEST len, ULONGEST *xfered_len)
6034ae49 565{
28439f5e 566 struct target_ops *beneath = find_target_beneath (ops);
6034ae49 567
2989a365 568 scoped_restore save_inferior_ptid = make_scoped_restore (&inferior_ptid);
6034ae49 569
dfd4cc63 570 if (ptid_tid_p (inferior_ptid) || !target_thread_alive (inferior_ptid))
8d027a04
MK
571 {
572 /* It's either a thread or an LWP that isn't alive. Any live
573 LWP will do so use the first available.
574
575 NOTE: We don't need to call switch_to_thread; we're just
576 reading memory. */
577 inferior_ptid = procfs_first_available ();
578 }
6034ae49 579
2989a365
TT
580 return beneath->to_xfer_partial (beneath, object, annex, readbuf,
581 writebuf, offset, len, xfered_len);
6034ae49
RM
582}
583
c906108c 584static void
28439f5e 585check_for_thread_db (void)
c906108c 586{
28439f5e
PA
587 td_err_e err;
588 ptid_t ptid;
c906108c 589
9a362b9a
PA
590 /* Don't attempt to use thread_db for remote targets. */
591 if (!(target_can_run (&current_target) || core_bfd))
592 return;
593
28439f5e
PA
594 /* Do nothing if we couldn't load libthread_db.so.1. */
595 if (p_td_ta_new == NULL)
596 return;
c906108c 597
28439f5e
PA
598 if (sol_thread_active)
599 /* Nothing to do. The thread library was already detected and the
600 target vector was already activated. */
601 return;
c906108c 602
28439f5e
PA
603 /* Now, initialize libthread_db. This needs to be done after the
604 shared libraries are located because it needs information from
605 the user's thread library. */
c906108c 606
28439f5e
PA
607 err = p_td_init ();
608 if (err != TD_OK)
609 {
610 warning (_("sol_thread_new_objfile: td_init: %s"), td_err_string (err));
611 return;
612 }
c906108c 613
28439f5e
PA
614 /* Now attempt to open a connection to the thread library. */
615 err = p_td_ta_new (&main_ph, &main_ta);
616 switch (err)
c906108c 617 {
28439f5e
PA
618 case TD_NOLIBTHREAD:
619 /* No thread library was detected. */
620 break;
2689673f 621
28439f5e
PA
622 case TD_OK:
623 printf_unfiltered (_("[Thread debugging using libthread_db enabled]\n"));
c906108c 624
28439f5e 625 /* The thread library was detected. Activate the sol_thread target. */
c906108c 626 push_target (&sol_thread_ops);
28439f5e 627 sol_thread_active = 1;
c906108c 628
28439f5e 629 main_ph.ptid = inferior_ptid; /* Save for xfer_memory. */
2689673f 630 ptid = lwp_to_thread (inferior_ptid);
dfd4cc63 631 if (ptid_get_pid (ptid) != -1)
28439f5e
PA
632 inferior_ptid = ptid;
633
e8032dde 634 target_update_thread_list ();
28439f5e
PA
635 break;
636
637 default:
638 warning (_("Cannot initialize thread debugging library: %s"),
639 td_err_string (err));
640 break;
c906108c
SS
641 }
642}
643
8d027a04
MK
644/* This routine is called whenever a new symbol table is read in, or
645 when all symbol tables are removed. libthread_db can only be
646 initialized when it finds the right variables in libthread.so.
647 Since it's a shared library, those variables don't show up until
06d3b283 648 the library gets mapped and the symbol table is read in. */
c906108c 649
06d3b283 650static void
fba45db2 651sol_thread_new_objfile (struct objfile *objfile)
c906108c 652{
28439f5e
PA
653 if (objfile != NULL)
654 check_for_thread_db ();
c906108c
SS
655}
656
657/* Clean up after the inferior dies. */
658
659static void
136d6dae 660sol_thread_mourn_inferior (struct target_ops *ops)
c906108c 661{
28439f5e
PA
662 struct target_ops *beneath = find_target_beneath (ops);
663
2689673f 664 sol_thread_active = 0;
c906108c 665
28439f5e 666 unpush_target (ops);
c906108c 667
28439f5e 668 beneath->to_mourn_inferior (beneath);
c906108c
SS
669}
670
8d027a04
MK
671/* Return true if PTID is still active in the inferior. */
672
c906108c 673static int
28439f5e 674sol_thread_alive (struct target_ops *ops, ptid_t ptid)
c906108c 675{
dfd4cc63 676 if (ptid_tid_p (ptid))
c906108c 677 {
8d027a04 678 /* It's a (user-level) thread. */
c906108c
SS
679 td_err_e val;
680 td_thrhandle_t th;
39f77062 681 int pid;
c906108c 682
dfd4cc63 683 pid = ptid_get_tid (ptid);
c906108c 684 if ((val = p_td_ta_map_id2thr (main_ta, pid, &th)) != TD_OK)
8d027a04 685 return 0; /* Thread not found. */
c906108c 686 if ((val = p_td_thr_validate (&th)) != TD_OK)
8d027a04
MK
687 return 0; /* Thread not valid. */
688 return 1; /* Known thread. */
c906108c 689 }
c5aa993b 690 else
c906108c 691 {
28439f5e
PA
692 struct target_ops *beneath = find_target_beneath (ops);
693
694 /* It's an LPW; pass the request on to the layer below. */
695 return beneath->to_thread_alive (beneath, ptid);
c906108c
SS
696 }
697}
698
c906108c 699\f
8d027a04
MK
700/* These routines implement the lower half of the thread_db interface,
701 i.e. the ps_* routines. */
c906108c 702
8d027a04
MK
703/* Various versions of <proc_service.h> have slightly different
704 function prototypes. In particular, we have
c906108c 705
c5aa993b
JM
706 NEWER OLDER
707 struct ps_prochandle * const struct ps_prochandle *
708 void* char*
8d027a04
MK
709 const void* char*
710 int size_t
c906108c 711
8d027a04
MK
712 Which one you have depends on the Solaris version and what patches
713 you've applied. On the theory that there are only two major
714 variants, we have configure check the prototype of ps_pdwrite (),
c378eb4e 715 and use that info to make appropriate typedefs here. */
c906108c
SS
716
717#ifdef PROC_SERVICE_IS_OLD
c5aa993b
JM
718typedef const struct ps_prochandle *gdb_ps_prochandle_t;
719typedef char *gdb_ps_read_buf_t;
720typedef char *gdb_ps_write_buf_t;
c906108c 721typedef int gdb_ps_size_t;
76e1ee85 722typedef psaddr_t gdb_ps_addr_t;
c906108c 723#else
c5aa993b
JM
724typedef struct ps_prochandle *gdb_ps_prochandle_t;
725typedef void *gdb_ps_read_buf_t;
726typedef const void *gdb_ps_write_buf_t;
c906108c 727typedef size_t gdb_ps_size_t;
291dcb3e 728typedef psaddr_t gdb_ps_addr_t;
c906108c
SS
729#endif
730
8d027a04
MK
731/* The next four routines are called by libthread_db to tell us to
732 stop and stop a particular process or lwp. Since GDB ensures that
733 these are all stopped by the time we call anything in thread_db,
734 these routines need to do nothing. */
c906108c 735
8d027a04 736/* Process stop. */
d4f3574e 737
c906108c
SS
738ps_err_e
739ps_pstop (gdb_ps_prochandle_t ph)
740{
741 return PS_OK;
742}
743
8d027a04 744/* Process continue. */
d4f3574e 745
c906108c
SS
746ps_err_e
747ps_pcontinue (gdb_ps_prochandle_t ph)
748{
749 return PS_OK;
750}
751
8d027a04 752/* LWP stop. */
d4f3574e 753
c906108c
SS
754ps_err_e
755ps_lstop (gdb_ps_prochandle_t ph, lwpid_t lwpid)
756{
757 return PS_OK;
758}
759
8d027a04 760/* LWP continue. */
d4f3574e 761
c906108c
SS
762ps_err_e
763ps_lcontinue (gdb_ps_prochandle_t ph, lwpid_t lwpid)
764{
765 return PS_OK;
766}
767
d4f3574e
SS
768/* Looks up the symbol LD_SYMBOL_NAME in the debugger's symbol table. */
769
c906108c
SS
770ps_err_e
771ps_pglobal_lookup (gdb_ps_prochandle_t ph, const char *ld_object_name,
8d027a04 772 const char *ld_symbol_name, gdb_ps_addr_t *ld_symbol_addr)
c906108c 773{
3b7344d5 774 struct bound_minimal_symbol ms;
c906108c
SS
775
776 ms = lookup_minimal_symbol (ld_symbol_name, NULL, NULL);
3b7344d5 777 if (!ms.minsym)
c906108c
SS
778 return PS_NOSYM;
779
d3c1a85f 780 *ld_symbol_addr = BMSYMBOL_VALUE_ADDRESS (ms);
c906108c
SS
781 return PS_OK;
782}
783
784/* Common routine for reading and writing memory. */
785
786static ps_err_e
291dcb3e 787rw_common (int dowrite, const struct ps_prochandle *ph, gdb_ps_addr_t addr,
019c1128 788 gdb_byte *buf, int size)
c906108c 789{
28439f5e 790 int ret;
c906108c 791
2989a365 792 scoped_restore save_inferior_ptid = make_scoped_restore (&inferior_ptid);
c906108c 793
dfd4cc63 794 if (ptid_tid_p (inferior_ptid) || !target_thread_alive (inferior_ptid))
8d027a04
MK
795 {
796 /* It's either a thread or an LWP that isn't alive. Any live
797 LWP will do so use the first available.
798
799 NOTE: We don't need to call switch_to_thread; we're just
800 reading memory. */
801 inferior_ptid = procfs_first_available ();
802 }
c906108c 803
23e04971
MS
804#if defined (__sparcv9)
805 /* For Sparc64 cross Sparc32, make sure the address has not been
806 accidentally sign-extended (or whatever) to beyond 32 bits. */
359431fb 807 if (bfd_get_arch_size (exec_bfd) == 32)
23e04971
MS
808 addr &= 0xffffffff;
809#endif
810
28439f5e 811 if (dowrite)
0c4f667c 812 ret = target_write_memory (addr, (gdb_byte *) buf, size);
28439f5e 813 else
0c4f667c 814 ret = target_read_memory (addr, (gdb_byte *) buf, size);
c906108c 815
28439f5e 816 return (ret == 0 ? PS_OK : PS_ERR);
c906108c
SS
817}
818
d4f3574e
SS
819/* Copies SIZE bytes from target process .data segment to debugger memory. */
820
c906108c 821ps_err_e
291dcb3e 822ps_pdread (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
c906108c
SS
823 gdb_ps_read_buf_t buf, gdb_ps_size_t size)
824{
b196bc4c 825 return rw_common (0, ph, addr, (gdb_byte *) buf, size);
c906108c
SS
826}
827
d4f3574e
SS
828/* Copies SIZE bytes from debugger memory .data segment to target process. */
829
c906108c 830ps_err_e
291dcb3e 831ps_pdwrite (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
c906108c
SS
832 gdb_ps_write_buf_t buf, gdb_ps_size_t size)
833{
019c1128 834 return rw_common (1, ph, addr, (gdb_byte *) buf, size);
c906108c
SS
835}
836
d4f3574e
SS
837/* Copies SIZE bytes from target process .text segment to debugger memory. */
838
c906108c 839ps_err_e
291dcb3e 840ps_ptread (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
c906108c
SS
841 gdb_ps_read_buf_t buf, gdb_ps_size_t size)
842{
b196bc4c 843 return rw_common (0, ph, addr, (gdb_byte *) buf, size);
c906108c
SS
844}
845
d4f3574e
SS
846/* Copies SIZE bytes from debugger memory .text segment to target process. */
847
c906108c 848ps_err_e
291dcb3e 849ps_ptwrite (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
c906108c
SS
850 gdb_ps_write_buf_t buf, gdb_ps_size_t size)
851{
019c1128 852 return rw_common (1, ph, addr, (gdb_byte *) buf, size);
c906108c
SS
853}
854
8d027a04 855/* Get general-purpose registers for LWP. */
c906108c
SS
856
857ps_err_e
8d027a04 858ps_lgetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, prgregset_t gregset)
c906108c 859{
3e00d44f
SM
860 ptid_t ptid = ptid_build (ptid_get_pid (inferior_ptid), lwpid, 0);
861 struct regcache *regcache
862 = get_thread_arch_regcache (ptid, target_gdbarch ());
c5aa993b 863
28439f5e 864 target_fetch_registers (regcache, -1);
594f7785 865 fill_gregset (regcache, (gdb_gregset_t *) gregset, -1);
c906108c 866
c906108c
SS
867 return PS_OK;
868}
869
8d027a04 870/* Set general-purpose registers for LWP. */
c906108c
SS
871
872ps_err_e
873ps_lsetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
874 const prgregset_t gregset)
875{
3e00d44f
SM
876 ptid_t ptid = ptid_build (ptid_get_pid (inferior_ptid), lwpid, 0);
877 struct regcache *regcache
878 = get_thread_arch_regcache (ptid, target_gdbarch ());
c5aa993b 879
594f7785 880 supply_gregset (regcache, (const gdb_gregset_t *) gregset);
28439f5e 881 target_store_registers (regcache, -1);
c906108c 882
c906108c
SS
883 return PS_OK;
884}
885
d4f3574e
SS
886/* Log a message (sends to gdb_stderr). */
887
c906108c 888void
8d027a04 889ps_plog (const char *fmt, ...)
c906108c
SS
890{
891 va_list args;
892
893 va_start (args, fmt);
894
895 vfprintf_filtered (gdb_stderr, fmt, args);
896}
897
c1357578
JB
898/* Get size of extra register set. Currently a noop. */
899
900ps_err_e
901ps_lgetxregsize (gdb_ps_prochandle_t ph, lwpid_t lwpid, int *xregsize)
902{
903 return PS_OK;
904}
905
906/* Get extra register set. Currently a noop. */
907
908ps_err_e
909ps_lgetxregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, caddr_t xregset)
910{
911 return PS_OK;
912}
913
914/* Set extra register set. Currently a noop. */
915
916ps_err_e
917ps_lsetxregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, caddr_t xregset)
918{
919 return PS_OK;
920}
921
8d027a04 922/* Get floating-point registers for LWP. */
c906108c
SS
923
924ps_err_e
925ps_lgetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
8d027a04 926 prfpregset_t *fpregset)
c906108c 927{
3e00d44f
SM
928 ptid_t ptid = ptid_build (ptid_get_pid (inferior_ptid), lwpid, 0);
929 struct regcache *regcache
930 = get_thread_arch_regcache (ptid, target_gdbarch ());
c906108c 931
28439f5e 932 target_fetch_registers (regcache, -1);
594f7785 933 fill_fpregset (regcache, (gdb_fpregset_t *) fpregset, -1);
c906108c 934
c906108c
SS
935 return PS_OK;
936}
937
c378eb4e 938/* Set floating-point regs for LWP. */
c906108c
SS
939
940ps_err_e
941ps_lsetfpregs (gdb_ps_prochandle_t ph, lwpid_t lwpid,
c5aa993b 942 const prfpregset_t * fpregset)
c906108c 943{
3e00d44f
SM
944 ptid_t ptid = ptid_build (ptid_get_pid (inferior_ptid), lwpid, 0);
945 struct regcache *regcache
946 = get_thread_arch_regcache (ptid, target_gdbarch ());
c5aa993b 947
594f7785 948 supply_fpregset (regcache, (const gdb_fpregset_t *) fpregset);
28439f5e 949 target_store_registers (regcache, -1);
c906108c 950
c906108c
SS
951 return PS_OK;
952}
953
23715f29 954#ifdef PR_MODEL_LP64
8d027a04
MK
955/* Identify process as 32-bit or 64-bit. At the moment we're using
956 BFD to do this. There might be a more Solaris-specific
957 (e.g. procfs) method, but this ought to work. */
23e04971
MS
958
959ps_err_e
960ps_pdmodel (gdb_ps_prochandle_t ph, int *data_model)
961{
962 if (exec_bfd == 0)
a95ac8b6
PS
963 *data_model = PR_MODEL_UNKNOWN;
964 else if (bfd_get_arch_size (exec_bfd) == 32)
23e04971
MS
965 *data_model = PR_MODEL_ILP32;
966 else
967 *data_model = PR_MODEL_LP64;
968
969 return PS_OK;
970}
23715f29 971#endif /* PR_MODEL_LP64 */
23e04971 972
965b60ee 973#if (defined(__i386__) || defined(__x86_64__)) && defined (sun)
c906108c 974
965b60ee
JB
975/* Reads the local descriptor table of a LWP.
976
977 This function is necessary on x86-solaris only. Without it, the loading
978 of libthread_db would fail because of ps_lgetLDT being undefined. */
d4f3574e 979
c906108c
SS
980ps_err_e
981ps_lgetLDT (gdb_ps_prochandle_t ph, lwpid_t lwpid,
982 struct ssd *pldt)
983{
8d027a04 984 /* NOTE: only used on Solaris, therefore OK to refer to procfs.c. */
05e28a7b 985 struct ssd *ret;
c906108c 986
8d027a04
MK
987 /* FIXME: can't I get the process ID from the prochandle or
988 something? */
2f09097b 989
dfd4cc63 990 if (ptid_get_pid (inferior_ptid) <= 0 || lwpid <= 0)
2f09097b
ND
991 return PS_BADLID;
992
dfd4cc63
LM
993 ret = procfs_find_LDT_entry (ptid_build (ptid_get_pid (inferior_ptid),
994 lwpid, 0));
05e28a7b 995 if (ret)
c906108c 996 {
05e28a7b
AC
997 memcpy (pldt, ret, sizeof (struct ssd));
998 return PS_OK;
c906108c 999 }
8d027a04
MK
1000 else
1001 /* LDT not found. */
c906108c 1002 return PS_ERR;
c5aa993b 1003}
965b60ee 1004#endif
c906108c 1005\f
8d027a04
MK
1006
1007/* Convert PTID to printable form. */
c906108c 1008
7a114964 1009static const char *
117de6a9 1010solaris_pid_to_str (struct target_ops *ops, ptid_t ptid)
c906108c
SS
1011{
1012 static char buf[100];
1013
dfd4cc63 1014 if (ptid_tid_p (ptid))
c906108c 1015 {
39f77062 1016 ptid_t lwp;
c906108c 1017
39f77062 1018 lwp = thread_to_lwp (ptid, -2);
c906108c 1019
dfd4cc63 1020 if (ptid_get_pid (lwp) == -1)
8c042590 1021 xsnprintf (buf, sizeof (buf), "Thread %ld (defunct)",
dfd4cc63
LM
1022 ptid_get_tid (ptid));
1023 else if (ptid_get_pid (lwp) != -2)
8c042590 1024 xsnprintf (buf, sizeof (buf), "Thread %ld (LWP %ld)",
dfd4cc63 1025 ptid_get_tid (ptid), ptid_get_lwp (lwp));
c906108c 1026 else
dfd4cc63
LM
1027 xsnprintf (buf, sizeof (buf), "Thread %ld ",
1028 ptid_get_tid (ptid));
c906108c 1029 }
dfd4cc63
LM
1030 else if (ptid_get_lwp (ptid) != 0)
1031 xsnprintf (buf, sizeof (buf), "LWP %ld ", ptid_get_lwp (ptid));
c906108c 1032 else
dfd4cc63 1033 xsnprintf (buf, sizeof (buf), "process %d ", ptid_get_pid (ptid));
c906108c
SS
1034
1035 return buf;
1036}
1037\f
1038
e8032dde 1039/* Worker bee for update_thread_list. Callback function that gets
8d027a04 1040 called once per user-level thread (i.e. not for LWP's). */
c906108c
SS
1041
1042static int
e8032dde 1043sol_update_thread_list_callback (const td_thrhandle_t *th, void *ignored)
c906108c
SS
1044{
1045 td_err_e retval;
1046 td_thrinfo_t ti;
39f77062 1047 ptid_t ptid;
c906108c 1048
8d027a04
MK
1049 retval = p_td_thr_get_info (th, &ti);
1050 if (retval != TD_OK)
1051 return -1;
1052
dfd4cc63 1053 ptid = ptid_build (ptid_get_pid (inferior_ptid), 0, ti.ti_tid);
2689673f 1054 if (!in_thread_list (ptid) || is_exited (ptid))
39f77062 1055 add_thread (ptid);
c906108c
SS
1056
1057 return 0;
1058}
1059
d4f3574e 1060static void
e8032dde 1061sol_update_thread_list (struct target_ops *ops)
c906108c 1062{
28439f5e 1063 struct target_ops *beneath = find_target_beneath (ops);
8d027a04 1064
e8032dde
PA
1065 /* Delete dead threads. */
1066 prune_threads ();
1067
1068 /* Find any new LWP's. */
1069 beneath->to_update_thread_list (beneath);
8d027a04
MK
1070
1071 /* Then find any new user-level threads. */
e8032dde 1072 p_td_ta_thr_iter (main_ta, sol_update_thread_list_callback, (void *) 0,
c906108c
SS
1073 TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
1074 TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
1075}
1076
8d027a04
MK
1077/* Worker bee for the "info sol-thread" command. This is a callback
1078 function that gets called once for each Solaris user-level thread
1079 (i.e. not for LWPs) in the inferior. Print anything interesting
1080 that we can think of. */
c906108c 1081
c5aa993b 1082static int
fba45db2 1083info_cb (const td_thrhandle_t *th, void *s)
c906108c
SS
1084{
1085 td_err_e ret;
1086 td_thrinfo_t ti;
c906108c 1087
8d027a04
MK
1088 ret = p_td_thr_get_info (th, &ti);
1089 if (ret == TD_OK)
c906108c 1090 {
c5aa993b
JM
1091 printf_filtered ("%s thread #%d, lwp %d, ",
1092 ti.ti_type == TD_THR_SYSTEM ? "system" : "user ",
c906108c 1093 ti.ti_tid, ti.ti_lid);
c5aa993b
JM
1094 switch (ti.ti_state)
1095 {
c906108c 1096 default:
c5aa993b
JM
1097 case TD_THR_UNKNOWN:
1098 printf_filtered ("<unknown state>");
1099 break;
1100 case TD_THR_STOPPED:
1101 printf_filtered ("(stopped)");
1102 break;
1103 case TD_THR_RUN:
1104 printf_filtered ("(run) ");
1105 break;
1106 case TD_THR_ACTIVE:
1107 printf_filtered ("(active) ");
1108 break;
1109 case TD_THR_ZOMBIE:
1110 printf_filtered ("(zombie) ");
1111 break;
1112 case TD_THR_SLEEP:
1113 printf_filtered ("(asleep) ");
1114 break;
1115 case TD_THR_STOPPED_ASLEEP:
1116 printf_filtered ("(stopped asleep)");
1117 break;
1118 }
8d027a04 1119 /* Print thr_create start function. */
c906108c 1120 if (ti.ti_startfunc != 0)
4ce44c66 1121 {
5812197c
JB
1122 const struct bound_minimal_symbol msym
1123 = lookup_minimal_symbol_by_pc (ti.ti_startfunc);
1124
17e760ae
JB
1125 printf_filtered (" startfunc=%s",
1126 msym.minsym
d3c1a85f 1127 ? MSYMBOL_PRINT_NAME (msym.minsym)
17e760ae 1128 : paddress (target_gdbarch (), ti.ti_startfunc));
4ce44c66 1129 }
c906108c 1130
8d027a04 1131 /* If thread is asleep, print function that went to sleep. */
c906108c 1132 if (ti.ti_state == TD_THR_SLEEP)
4ce44c66 1133 {
5812197c
JB
1134 const struct bound_minimal_symbol msym
1135 = lookup_minimal_symbol_by_pc (ti.ti_pc);
1136
17e760ae
JB
1137 printf_filtered (" sleepfunc=%s",
1138 msym.minsym
d3c1a85f 1139 ? MSYMBOL_PRINT_NAME (msym.minsym)
17e760ae 1140 : paddress (target_gdbarch (), ti.ti_pc));
4ce44c66 1141 }
c906108c 1142
c0f5f490 1143 printf_filtered ("\n");
c906108c
SS
1144 }
1145 else
8a3fe4f8 1146 warning (_("info sol-thread: failed to get info for thread."));
c906108c 1147
c5aa993b 1148 return 0;
c906108c
SS
1149}
1150
8d027a04
MK
1151/* List some state about each Solaris user-level thread in the
1152 inferior. */
c906108c
SS
1153
1154static void
fba45db2 1155info_solthreads (char *args, int from_tty)
c906108c 1156{
c5aa993b 1157 p_td_ta_thr_iter (main_ta, info_cb, args,
c906108c
SS
1158 TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
1159 TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
1160}
c906108c 1161
3caf13b4
JB
1162/* Callback routine used to find a thread based on the TID part of
1163 its PTID. */
1164
1165static int
1166thread_db_find_thread_from_tid (struct thread_info *thread, void *data)
1167{
1168 long *tid = (long *) data;
1169
1170 if (ptid_get_tid (thread->ptid) == *tid)
1171 return 1;
1172
1173 return 0;
1174}
1175
1176static ptid_t
1e6b91a4 1177sol_get_ada_task_ptid (struct target_ops *self, long lwp, long thread)
3caf13b4
JB
1178{
1179 struct thread_info *thread_info =
1180 iterate_over_threads (thread_db_find_thread_from_tid, &thread);
1181
1182 if (thread_info == NULL)
1183 {
1184 /* The list of threads is probably not up to date. Find any
1185 thread that is missing from the list, and try again. */
e8032dde 1186 sol_update_thread_list (&current_target);
3caf13b4
JB
1187 thread_info = iterate_over_threads (thread_db_find_thread_from_tid,
1188 &thread);
1189 }
1190
1191 gdb_assert (thread_info != NULL);
1192
1193 return (thread_info->ptid);
1194}
1195
c906108c 1196static void
fba45db2 1197init_sol_thread_ops (void)
c906108c
SS
1198{
1199 sol_thread_ops.to_shortname = "solaris-threads";
1200 sol_thread_ops.to_longname = "Solaris threads and pthread.";
1201 sol_thread_ops.to_doc = "Solaris threads and pthread support.";
c906108c
SS
1202 sol_thread_ops.to_detach = sol_thread_detach;
1203 sol_thread_ops.to_resume = sol_thread_resume;
1204 sol_thread_ops.to_wait = sol_thread_wait;
1205 sol_thread_ops.to_fetch_registers = sol_thread_fetch_registers;
1206 sol_thread_ops.to_store_registers = sol_thread_store_registers;
6034ae49 1207 sol_thread_ops.to_xfer_partial = sol_thread_xfer_partial;
c906108c 1208 sol_thread_ops.to_mourn_inferior = sol_thread_mourn_inferior;
c906108c 1209 sol_thread_ops.to_thread_alive = sol_thread_alive;
ed9a39eb 1210 sol_thread_ops.to_pid_to_str = solaris_pid_to_str;
e8032dde 1211 sol_thread_ops.to_update_thread_list = sol_update_thread_list;
28439f5e 1212 sol_thread_ops.to_stratum = thread_stratum;
3caf13b4 1213 sol_thread_ops.to_get_ada_task_ptid = sol_get_ada_task_ptid;
c906108c
SS
1214 sol_thread_ops.to_magic = OPS_MAGIC;
1215}
1216
02f1df11
JB
1217/* Silence -Wmissing-prototypes. */
1218extern void _initialize_sol_thread (void);
1219
c906108c 1220void
fba45db2 1221_initialize_sol_thread (void)
c906108c
SS
1222{
1223 void *dlhandle;
1224
1225 init_sol_thread_ops ();
c906108c
SS
1226
1227 dlhandle = dlopen ("libthread_db.so.1", RTLD_NOW);
1228 if (!dlhandle)
1229 goto die;
1230
1231#define resolve(X) \
b196bc4c 1232 if (!(p_##X = (X ## _ftype *) dlsym (dlhandle, #X))) \
c906108c
SS
1233 goto die;
1234
1235 resolve (td_log);
1236 resolve (td_ta_new);
1237 resolve (td_ta_delete);
1238 resolve (td_init);
1239 resolve (td_ta_get_ph);
1240 resolve (td_ta_get_nthreads);
1241 resolve (td_ta_tsd_iter);
1242 resolve (td_ta_thr_iter);
1243 resolve (td_thr_validate);
1244 resolve (td_thr_tsd);
1245 resolve (td_thr_get_info);
1246 resolve (td_thr_getfpregs);
1247 resolve (td_thr_getxregsize);
1248 resolve (td_thr_getxregs);
1249 resolve (td_thr_sigsetmask);
1250 resolve (td_thr_setprio);
1251 resolve (td_thr_setsigpending);
1252 resolve (td_thr_setfpregs);
1253 resolve (td_thr_setxregs);
1254 resolve (td_ta_map_id2thr);
1255 resolve (td_ta_map_lwp2thr);
1256 resolve (td_thr_getgregs);
1257 resolve (td_thr_setgregs);
1258
12070676 1259 complete_target_initialization (&sol_thread_ops);
c906108c 1260
c5aa993b 1261 add_cmd ("sol-threads", class_maintenance, info_solthreads,
1a966eab 1262 _("Show info on Solaris user threads."), &maintenanceinfolist);
c906108c 1263
8d027a04 1264 /* Hook into new_objfile notification. */
06d3b283 1265 observer_attach_new_objfile (sol_thread_new_objfile);
c906108c
SS
1266 return;
1267
8d027a04
MK
1268 die:
1269 fprintf_unfiltered (gdb_stderr, "\
1270[GDB will not be able to debug user-mode threads: %s]\n", dlerror ());
c906108c
SS
1271
1272 if (dlhandle)
1273 dlclose (dlhandle);
1274
c906108c
SS
1275 return;
1276}
This page took 2.090236 seconds and 4 git commands to generate.