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