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