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