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