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