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