]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/sol-thread.c
target factories, target open and multiple instances of targets
[thirdparty/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)
8d027a04 310 return pid_to_ptid (-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)
8d027a04 316 return pid_to_ptid (-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)
39f77062 323 return pid_to_ptid (default_lwp);
8a3fe4f8 324 error (_("thread_to_lwp: thread state not active: %s"),
c906108c
SS
325 td_state_string (ti.ti_state));
326 }
327
dfd4cc63 328 return ptid_build (ptid_get_pid (thread_id), 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))
8d027a04 349 return pid_to_ptid (-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)
8d027a04 353 return pid_to_ptid (-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)
8d027a04 365 return pid_to_ptid (-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
dfd4cc63 369 return ptid_build (ptid_get_pid (lwp), 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{
f6ac5f3d 387 struct target_ops *beneath = find_target_beneath (this);
28439f5e 388
2689673f 389 sol_thread_active = 0;
dfd4cc63 390 inferior_ptid = pid_to_ptid (ptid_get_pid (main_ph.ptid));
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{
f6ac5f3d 403 struct target_ops *beneath = find_target_beneath (this);
c906108c 404
2989a365 405 scoped_restore save_inferior_ptid = make_scoped_restore (&inferior_ptid);
c906108c 406
dfd4cc63
LM
407 inferior_ptid = thread_to_lwp (inferior_ptid, ptid_get_pid (main_ph.ptid));
408 if (ptid_get_pid (inferior_ptid) == -1)
39f77062 409 inferior_ptid = procfs_first_available ();
c906108c 410
dfd4cc63 411 if (ptid_get_pid (ptid) != -1)
c906108c 412 {
39f77062 413 ptid_t save_ptid = ptid;
c906108c 414
39f77062 415 ptid = thread_to_lwp (ptid, -2);
dfd4cc63 416 if (ptid_get_pid (ptid) == -2) /* Inactive thread. */
8a3fe4f8 417 error (_("This version of Solaris can't start inactive threads."));
dfd4cc63 418 if (info_verbose && ptid_get_pid (ptid) == -1)
8a3fe4f8 419 warning (_("Specified thread %ld seems to have terminated"),
dfd4cc63 420 ptid_get_tid (save_ptid));
c906108c
SS
421 }
422
f6ac5f3d 423 beneath->resume (ptid, step, signo);
c906108c
SS
424}
425
2689673f 426/* Wait for any threads to stop. We may have to convert PTID from a
8d027a04 427 thread ID to an LWP ID, and vice versa on the way out. */
c906108c 428
f6ac5f3d
PA
429ptid_t
430sol_thread_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
431 int options)
c906108c 432{
39f77062
KB
433 ptid_t rtnval;
434 ptid_t save_ptid;
f6ac5f3d 435 struct target_ops *beneath = find_target_beneath (this);
c906108c 436
39f77062 437 save_ptid = inferior_ptid;
2989a365 438 scoped_restore save_inferior_ptid = make_scoped_restore (&inferior_ptid);
c906108c 439
dfd4cc63
LM
440 inferior_ptid = thread_to_lwp (inferior_ptid, ptid_get_pid (main_ph.ptid));
441 if (ptid_get_pid (inferior_ptid) == -1)
39f77062 442 inferior_ptid = procfs_first_available ();
c906108c 443
dfd4cc63 444 if (ptid_get_pid (ptid) != -1)
c906108c 445 {
39f77062 446 ptid_t save_ptid = ptid;
c906108c 447
39f77062 448 ptid = thread_to_lwp (ptid, -2);
dfd4cc63 449 if (ptid_get_pid (ptid) == -2) /* Inactive thread. */
8a3fe4f8 450 error (_("This version of Solaris can't start inactive threads."));
dfd4cc63 451 if (info_verbose && ptid_get_pid (ptid) == -1)
8a3fe4f8 452 warning (_("Specified thread %ld seems to have terminated"),
dfd4cc63 453 ptid_get_tid (save_ptid));
c906108c
SS
454 }
455
f6ac5f3d 456 rtnval = beneath->wait (ptid, ourstatus, options);
c906108c
SS
457
458 if (ourstatus->kind != TARGET_WAITKIND_EXITED)
459 {
8d027a04 460 /* Map the LWP of interest back to the appropriate thread ID. */
c906108c 461 rtnval = lwp_to_thread (rtnval);
dfd4cc63 462 if (ptid_get_pid (rtnval) == -1)
39f77062 463 rtnval = save_ptid;
c906108c 464
8d027a04 465 /* See if we have a new thread. */
dfd4cc63 466 if (ptid_tid_p (rtnval)
39f77062 467 && !ptid_equal (rtnval, save_ptid)
2689673f
PA
468 && (!in_thread_list (rtnval)
469 || is_exited (rtnval)))
93815fbf 470 add_thread (rtnval);
c906108c
SS
471 }
472
8d027a04
MK
473 /* During process initialization, we may get here without the thread
474 package being initialized, since that can only happen after we've
475 found the shared libs. */
c906108c 476
c906108c
SS
477 return rtnval;
478}
479
f6ac5f3d
PA
480void
481sol_thread_target::fetch_registers (struct regcache *regcache, int regnum)
c906108c
SS
482{
483 thread_t thread;
484 td_thrhandle_t thandle;
485 td_err_e val;
486 prgregset_t gregset;
487 prfpregset_t fpregset;
e71c308d
DJ
488 gdb_gregset_t *gregset_p = &gregset;
489 gdb_fpregset_t *fpregset_p = &fpregset;
f6ac5f3d 490 struct target_ops *beneath = find_target_beneath (this);
bcc0c096 491 ptid_t ptid = regcache_get_ptid (regcache);
e71c308d 492
bcc0c096 493 if (!ptid_tid_p (ptid))
8d027a04 494 {
28439f5e 495 /* It's an LWP; pass the request on to the layer beneath. */
f6ac5f3d 496 beneath->fetch_registers (regcache, regnum);
c906108c
SS
497 return;
498 }
499
bcc0c096
SM
500 /* Solaris thread: convert PTID into a td_thrhandle_t. */
501 thread = ptid_get_tid (ptid);
c906108c 502 if (thread == 0)
8a3fe4f8 503 error (_("sol_thread_fetch_registers: thread == 0"));
c906108c
SS
504
505 val = p_td_ta_map_id2thr (main_ta, thread, &thandle);
506 if (val != TD_OK)
8a3fe4f8 507 error (_("sol_thread_fetch_registers: td_ta_map_id2thr: %s"),
c906108c
SS
508 td_err_string (val));
509
8d027a04 510 /* Get the general-purpose registers. */
c906108c
SS
511
512 val = p_td_thr_getgregs (&thandle, gregset);
8d027a04 513 if (val != TD_OK && val != TD_PARTIALREG)
8a3fe4f8 514 error (_("sol_thread_fetch_registers: td_thr_getgregs %s"),
c906108c
SS
515 td_err_string (val));
516
8d027a04
MK
517 /* For SPARC, TD_PARTIALREG means that only %i0...%i7, %l0..%l7, %pc
518 and %sp are saved (by a thread context switch). */
c906108c 519
8d027a04 520 /* And, now the floating-point registers. */
c906108c
SS
521
522 val = p_td_thr_getfpregs (&thandle, &fpregset);
8d027a04 523 if (val != TD_OK && val != TD_NOFPREGS)
8a3fe4f8 524 error (_("sol_thread_fetch_registers: td_thr_getfpregs %s"),
c906108c
SS
525 td_err_string (val));
526
8d027a04
MK
527 /* Note that we must call supply_gregset and supply_fpregset *after*
528 calling the td routines because the td routines call ps_lget*
529 which affect the values stored in the registers array. */
c906108c 530
e71c308d
DJ
531 supply_gregset (regcache, (const gdb_gregset_t *) gregset_p);
532 supply_fpregset (regcache, (const gdb_fpregset_t *) fpregset_p);
c906108c
SS
533}
534
f6ac5f3d
PA
535void
536sol_thread_target::store_registers (struct regcache *regcache, int regnum)
c906108c
SS
537{
538 thread_t thread;
539 td_thrhandle_t thandle;
540 td_err_e val;
8d027a04 541 prgregset_t gregset;
c906108c 542 prfpregset_t fpregset;
bcc0c096 543 ptid_t ptid = regcache_get_ptid (regcache);
c906108c 544
bcc0c096 545 if (!ptid_tid_p (ptid))
8d027a04 546 {
f6ac5f3d 547 struct target_ops *beneath = find_target_beneath (this);
28439f5e
PA
548
549 /* It's an LWP; pass the request on to the layer beneath. */
f6ac5f3d 550 beneath->store_registers (regcache, regnum);
c906108c
SS
551 return;
552 }
553
bcc0c096
SM
554 /* Solaris thread: convert PTID into a td_thrhandle_t. */
555 thread = ptid_get_tid (ptid);
c906108c
SS
556
557 val = p_td_ta_map_id2thr (main_ta, thread, &thandle);
558 if (val != TD_OK)
8a3fe4f8 559 error (_("sol_thread_store_registers: td_ta_map_id2thr %s"),
c906108c
SS
560 td_err_string (val));
561
8d027a04
MK
562 if (regnum != -1)
563 {
c60c0f5f 564 val = p_td_thr_getgregs (&thandle, gregset);
c906108c 565 if (val != TD_OK)
8a3fe4f8 566 error (_("sol_thread_store_registers: td_thr_getgregs %s"),
c906108c
SS
567 td_err_string (val));
568 val = p_td_thr_getfpregs (&thandle, &fpregset);
569 if (val != TD_OK)
8a3fe4f8 570 error (_("sol_thread_store_registers: td_thr_getfpregs %s"),
c906108c 571 td_err_string (val));
c906108c
SS
572 }
573
56be3814
UW
574 fill_gregset (regcache, (gdb_gregset_t *) &gregset, regnum);
575 fill_fpregset (regcache, (gdb_fpregset_t *) &fpregset, regnum);
c906108c 576
c60c0f5f 577 val = p_td_thr_setgregs (&thandle, gregset);
c906108c 578 if (val != TD_OK)
8a3fe4f8 579 error (_("sol_thread_store_registers: td_thr_setgregs %s"),
c906108c
SS
580 td_err_string (val));
581 val = p_td_thr_setfpregs (&thandle, &fpregset);
582 if (val != TD_OK)
8a3fe4f8 583 error (_("sol_thread_store_registers: td_thr_setfpregs %s"),
c906108c 584 td_err_string (val));
c906108c
SS
585}
586
8d027a04
MK
587/* Perform partial transfers on OBJECT. See target_read_partial and
588 target_write_partial for details of each variant. One, and only
589 one, of readbuf or writebuf must be non-NULL. */
6034ae49 590
f6ac5f3d
PA
591enum target_xfer_status
592sol_thread_target::xfer_partial (enum target_object object,
593 const char *annex, gdb_byte *readbuf,
594 const gdb_byte *writebuf,
595 ULONGEST offset, ULONGEST len,
596 ULONGEST *xfered_len)
6034ae49 597{
f6ac5f3d 598 struct target_ops *beneath = find_target_beneath (this);
6034ae49 599
2989a365 600 scoped_restore save_inferior_ptid = make_scoped_restore (&inferior_ptid);
6034ae49 601
dfd4cc63 602 if (ptid_tid_p (inferior_ptid) || !target_thread_alive (inferior_ptid))
8d027a04
MK
603 {
604 /* It's either a thread or an LWP that isn't alive. Any live
605 LWP will do so use the first available.
606
607 NOTE: We don't need to call switch_to_thread; we're just
608 reading memory. */
609 inferior_ptid = procfs_first_available ();
610 }
6034ae49 611
f6ac5f3d
PA
612 return beneath->xfer_partial (object, annex, readbuf,
613 writebuf, offset, len, xfered_len);
6034ae49
RM
614}
615
c906108c 616static void
28439f5e 617check_for_thread_db (void)
c906108c 618{
28439f5e
PA
619 td_err_e err;
620 ptid_t ptid;
c906108c 621
9a362b9a 622 /* Don't attempt to use thread_db for remote targets. */
f6ac5f3d 623 if (!(target_can_run () || core_bfd))
9a362b9a
PA
624 return;
625
28439f5e
PA
626 /* Do nothing if we couldn't load libthread_db.so.1. */
627 if (p_td_ta_new == NULL)
628 return;
c906108c 629
28439f5e
PA
630 if (sol_thread_active)
631 /* Nothing to do. The thread library was already detected and the
632 target vector was already activated. */
633 return;
c906108c 634
28439f5e
PA
635 /* Now, initialize libthread_db. This needs to be done after the
636 shared libraries are located because it needs information from
637 the user's thread library. */
c906108c 638
28439f5e
PA
639 err = p_td_init ();
640 if (err != TD_OK)
641 {
642 warning (_("sol_thread_new_objfile: td_init: %s"), td_err_string (err));
643 return;
644 }
c906108c 645
28439f5e
PA
646 /* Now attempt to open a connection to the thread library. */
647 err = p_td_ta_new (&main_ph, &main_ta);
648 switch (err)
c906108c 649 {
28439f5e
PA
650 case TD_NOLIBTHREAD:
651 /* No thread library was detected. */
652 break;
2689673f 653
28439f5e
PA
654 case TD_OK:
655 printf_unfiltered (_("[Thread debugging using libthread_db enabled]\n"));
c906108c 656
28439f5e 657 /* The thread library was detected. Activate the sol_thread target. */
c906108c 658 push_target (&sol_thread_ops);
28439f5e 659 sol_thread_active = 1;
c906108c 660
28439f5e 661 main_ph.ptid = inferior_ptid; /* Save for xfer_memory. */
2689673f 662 ptid = lwp_to_thread (inferior_ptid);
dfd4cc63 663 if (ptid_get_pid (ptid) != -1)
28439f5e
PA
664 inferior_ptid = ptid;
665
e8032dde 666 target_update_thread_list ();
28439f5e
PA
667 break;
668
669 default:
670 warning (_("Cannot initialize thread debugging library: %s"),
671 td_err_string (err));
672 break;
c906108c
SS
673 }
674}
675
8d027a04
MK
676/* This routine is called whenever a new symbol table is read in, or
677 when all symbol tables are removed. libthread_db can only be
678 initialized when it finds the right variables in libthread.so.
679 Since it's a shared library, those variables don't show up until
06d3b283 680 the library gets mapped and the symbol table is read in. */
c906108c 681
06d3b283 682static void
fba45db2 683sol_thread_new_objfile (struct objfile *objfile)
c906108c 684{
28439f5e
PA
685 if (objfile != NULL)
686 check_for_thread_db ();
c906108c
SS
687}
688
689/* Clean up after the inferior dies. */
690
f6ac5f3d
PA
691void
692sol_thread_target::mourn_inferior ()
c906108c 693{
f6ac5f3d 694 struct target_ops *beneath = find_target_beneath (this);
28439f5e 695
2689673f 696 sol_thread_active = 0;
c906108c 697
f6ac5f3d 698 unpush_target (this);
c906108c 699
f6ac5f3d 700 beneath->mourn_inferior ();
c906108c
SS
701}
702
8d027a04
MK
703/* Return true if PTID is still active in the inferior. */
704
57810aa7 705bool
f6ac5f3d 706sol_thread_target::thread_alive (ptid_t ptid)
c906108c 707{
dfd4cc63 708 if (ptid_tid_p (ptid))
c906108c 709 {
8d027a04 710 /* It's a (user-level) thread. */
c906108c
SS
711 td_err_e val;
712 td_thrhandle_t th;
39f77062 713 int pid;
c906108c 714
dfd4cc63 715 pid = ptid_get_tid (ptid);
c906108c 716 if ((val = p_td_ta_map_id2thr (main_ta, pid, &th)) != TD_OK)
57810aa7 717 return false; /* Thread not found. */
c906108c 718 if ((val = p_td_thr_validate (&th)) != TD_OK)
57810aa7
PA
719 return false; /* Thread not valid. */
720 return true; /* Known thread. */
c906108c 721 }
c5aa993b 722 else
c906108c 723 {
f6ac5f3d 724 struct target_ops *beneath = find_target_beneath (this);
28439f5e
PA
725
726 /* It's an LPW; pass the request on to the layer below. */
f6ac5f3d 727 return beneath->thread_alive (ptid);
c906108c
SS
728 }
729}
730
c906108c 731\f
8d027a04
MK
732/* These routines implement the lower half of the thread_db interface,
733 i.e. the ps_* routines. */
c906108c 734
8d027a04
MK
735/* The next four routines are called by libthread_db to tell us to
736 stop and stop a particular process or lwp. Since GDB ensures that
737 these are all stopped by the time we call anything in thread_db,
738 these routines need to do nothing. */
c906108c 739
8d027a04 740/* Process stop. */
d4f3574e 741
c906108c 742ps_err_e
281c4447 743ps_pstop (struct ps_prochandle *ph)
c906108c
SS
744{
745 return PS_OK;
746}
747
8d027a04 748/* Process continue. */
d4f3574e 749
c906108c 750ps_err_e
281c4447 751ps_pcontinue (struct ps_prochandle *ph)
c906108c
SS
752{
753 return PS_OK;
754}
755
8d027a04 756/* LWP stop. */
d4f3574e 757
c906108c 758ps_err_e
281c4447 759ps_lstop (struct ps_prochandle *ph, lwpid_t lwpid)
c906108c
SS
760{
761 return PS_OK;
762}
763
8d027a04 764/* LWP continue. */
d4f3574e 765
c906108c 766ps_err_e
281c4447 767ps_lcontinue (struct ps_prochandle *ph, lwpid_t lwpid)
c906108c
SS
768{
769 return PS_OK;
770}
771
d4f3574e
SS
772/* Looks up the symbol LD_SYMBOL_NAME in the debugger's symbol table. */
773
c906108c 774ps_err_e
281c4447
RO
775ps_pglobal_lookup (struct ps_prochandle *ph, const char *ld_object_name,
776 const char *ld_symbol_name, psaddr_t *ld_symbol_addr)
c906108c 777{
3b7344d5 778 struct bound_minimal_symbol ms;
c906108c
SS
779
780 ms = lookup_minimal_symbol (ld_symbol_name, NULL, NULL);
3b7344d5 781 if (!ms.minsym)
c906108c
SS
782 return PS_NOSYM;
783
d3c1a85f 784 *ld_symbol_addr = BMSYMBOL_VALUE_ADDRESS (ms);
c906108c
SS
785 return PS_OK;
786}
787
788/* Common routine for reading and writing memory. */
789
790static ps_err_e
281c4447 791rw_common (int dowrite, const struct ps_prochandle *ph, psaddr_t addr,
019c1128 792 gdb_byte *buf, int size)
c906108c 793{
28439f5e 794 int ret;
c906108c 795
2989a365 796 scoped_restore save_inferior_ptid = make_scoped_restore (&inferior_ptid);
c906108c 797
dfd4cc63 798 if (ptid_tid_p (inferior_ptid) || !target_thread_alive (inferior_ptid))
8d027a04
MK
799 {
800 /* It's either a thread or an LWP that isn't alive. Any live
801 LWP will do so use the first available.
802
803 NOTE: We don't need to call switch_to_thread; we're just
804 reading memory. */
805 inferior_ptid = procfs_first_available ();
806 }
c906108c 807
23e04971
MS
808#if defined (__sparcv9)
809 /* For Sparc64 cross Sparc32, make sure the address has not been
810 accidentally sign-extended (or whatever) to beyond 32 bits. */
359431fb 811 if (bfd_get_arch_size (exec_bfd) == 32)
23e04971
MS
812 addr &= 0xffffffff;
813#endif
814
28439f5e 815 if (dowrite)
0c4f667c 816 ret = target_write_memory (addr, (gdb_byte *) buf, size);
28439f5e 817 else
0c4f667c 818 ret = target_read_memory (addr, (gdb_byte *) buf, size);
c906108c 819
28439f5e 820 return (ret == 0 ? PS_OK : PS_ERR);
c906108c
SS
821}
822
d4f3574e
SS
823/* Copies SIZE bytes from target process .data segment to debugger memory. */
824
c906108c 825ps_err_e
281c4447 826ps_pdread (struct ps_prochandle *ph, psaddr_t addr, void *buf, size_t size)
c906108c 827{
b196bc4c 828 return rw_common (0, ph, addr, (gdb_byte *) buf, size);
c906108c
SS
829}
830
d4f3574e
SS
831/* Copies SIZE bytes from debugger memory .data segment to target process. */
832
c906108c 833ps_err_e
281c4447
RO
834ps_pdwrite (struct ps_prochandle *ph, psaddr_t addr,
835 const void *buf, size_t size)
c906108c 836{
019c1128 837 return rw_common (1, ph, addr, (gdb_byte *) buf, size);
c906108c
SS
838}
839
d4f3574e
SS
840/* Copies SIZE bytes from target process .text segment to debugger memory. */
841
c906108c 842ps_err_e
281c4447 843ps_ptread (struct ps_prochandle *ph, psaddr_t addr, void *buf, size_t size)
c906108c 844{
b196bc4c 845 return rw_common (0, ph, addr, (gdb_byte *) buf, size);
c906108c
SS
846}
847
d4f3574e
SS
848/* Copies SIZE bytes from debugger memory .text segment to target process. */
849
c906108c 850ps_err_e
281c4447
RO
851ps_ptwrite (struct ps_prochandle *ph, psaddr_t addr,
852 const void *buf, size_t size)
c906108c 853{
019c1128 854 return rw_common (1, ph, addr, (gdb_byte *) buf, size);
c906108c
SS
855}
856
8d027a04 857/* Get general-purpose registers for LWP. */
c906108c
SS
858
859ps_err_e
281c4447 860ps_lgetregs (struct ps_prochandle *ph, lwpid_t lwpid, prgregset_t gregset)
c906108c 861{
3e00d44f
SM
862 ptid_t ptid = ptid_build (ptid_get_pid (inferior_ptid), lwpid, 0);
863 struct regcache *regcache
864 = get_thread_arch_regcache (ptid, target_gdbarch ());
c5aa993b 865
28439f5e 866 target_fetch_registers (regcache, -1);
594f7785 867 fill_gregset (regcache, (gdb_gregset_t *) gregset, -1);
c906108c 868
c906108c
SS
869 return PS_OK;
870}
871
8d027a04 872/* Set general-purpose registers for LWP. */
c906108c
SS
873
874ps_err_e
281c4447 875ps_lsetregs (struct ps_prochandle *ph, lwpid_t lwpid,
c906108c
SS
876 const prgregset_t gregset)
877{
3e00d44f
SM
878 ptid_t ptid = ptid_build (ptid_get_pid (inferior_ptid), lwpid, 0);
879 struct regcache *regcache
880 = get_thread_arch_regcache (ptid, target_gdbarch ());
c5aa993b 881
594f7785 882 supply_gregset (regcache, (const gdb_gregset_t *) gregset);
28439f5e 883 target_store_registers (regcache, -1);
c906108c 884
c906108c
SS
885 return PS_OK;
886}
887
d4f3574e
SS
888/* Log a message (sends to gdb_stderr). */
889
c906108c 890void
8d027a04 891ps_plog (const char *fmt, ...)
c906108c
SS
892{
893 va_list args;
894
895 va_start (args, fmt);
896
897 vfprintf_filtered (gdb_stderr, fmt, args);
898}
899
c1357578
JB
900/* Get size of extra register set. Currently a noop. */
901
902ps_err_e
281c4447 903ps_lgetxregsize (struct ps_prochandle *ph, lwpid_t lwpid, int *xregsize)
c1357578
JB
904{
905 return PS_OK;
906}
907
908/* Get extra register set. Currently a noop. */
909
910ps_err_e
281c4447 911ps_lgetxregs (struct ps_prochandle *ph, lwpid_t lwpid, caddr_t xregset)
c1357578
JB
912{
913 return PS_OK;
914}
915
916/* Set extra register set. Currently a noop. */
917
918ps_err_e
281c4447 919ps_lsetxregs (struct ps_prochandle *ph, lwpid_t lwpid, caddr_t xregset)
c1357578
JB
920{
921 return PS_OK;
922}
923
8d027a04 924/* Get floating-point registers for LWP. */
c906108c
SS
925
926ps_err_e
281c4447 927ps_lgetfpregs (struct ps_prochandle *ph, lwpid_t lwpid,
8d027a04 928 prfpregset_t *fpregset)
c906108c 929{
3e00d44f
SM
930 ptid_t ptid = ptid_build (ptid_get_pid (inferior_ptid), lwpid, 0);
931 struct regcache *regcache
932 = get_thread_arch_regcache (ptid, target_gdbarch ());
c906108c 933
28439f5e 934 target_fetch_registers (regcache, -1);
594f7785 935 fill_fpregset (regcache, (gdb_fpregset_t *) fpregset, -1);
c906108c 936
c906108c
SS
937 return PS_OK;
938}
939
c378eb4e 940/* Set floating-point regs for LWP. */
c906108c
SS
941
942ps_err_e
281c4447 943ps_lsetfpregs (struct ps_prochandle *ph, lwpid_t lwpid,
c5aa993b 944 const prfpregset_t * fpregset)
c906108c 945{
3e00d44f
SM
946 ptid_t ptid = ptid_build (ptid_get_pid (inferior_ptid), lwpid, 0);
947 struct regcache *regcache
948 = get_thread_arch_regcache (ptid, target_gdbarch ());
c5aa993b 949
594f7785 950 supply_fpregset (regcache, (const gdb_fpregset_t *) fpregset);
28439f5e 951 target_store_registers (regcache, -1);
c906108c 952
c906108c
SS
953 return PS_OK;
954}
955
23715f29 956#ifdef PR_MODEL_LP64
8d027a04
MK
957/* Identify process as 32-bit or 64-bit. At the moment we're using
958 BFD to do this. There might be a more Solaris-specific
959 (e.g. procfs) method, but this ought to work. */
23e04971
MS
960
961ps_err_e
281c4447 962ps_pdmodel (struct ps_prochandle *ph, int *data_model)
23e04971
MS
963{
964 if (exec_bfd == 0)
a95ac8b6
PS
965 *data_model = PR_MODEL_UNKNOWN;
966 else if (bfd_get_arch_size (exec_bfd) == 32)
23e04971
MS
967 *data_model = PR_MODEL_ILP32;
968 else
969 *data_model = PR_MODEL_LP64;
970
971 return PS_OK;
972}
23715f29 973#endif /* PR_MODEL_LP64 */
23e04971 974
965b60ee 975#if (defined(__i386__) || defined(__x86_64__)) && defined (sun)
c906108c 976
965b60ee
JB
977/* Reads the local descriptor table of a LWP.
978
979 This function is necessary on x86-solaris only. Without it, the loading
980 of libthread_db would fail because of ps_lgetLDT being undefined. */
d4f3574e 981
c906108c 982ps_err_e
281c4447 983ps_lgetLDT (struct ps_prochandle *ph, lwpid_t lwpid,
c906108c
SS
984 struct ssd *pldt)
985{
8d027a04 986 /* NOTE: only used on Solaris, therefore OK to refer to procfs.c. */
05e28a7b 987 struct ssd *ret;
c906108c 988
8d027a04
MK
989 /* FIXME: can't I get the process ID from the prochandle or
990 something? */
2f09097b 991
dfd4cc63 992 if (ptid_get_pid (inferior_ptid) <= 0 || lwpid <= 0)
2f09097b
ND
993 return PS_BADLID;
994
dfd4cc63
LM
995 ret = procfs_find_LDT_entry (ptid_build (ptid_get_pid (inferior_ptid),
996 lwpid, 0));
05e28a7b 997 if (ret)
c906108c 998 {
05e28a7b
AC
999 memcpy (pldt, ret, sizeof (struct ssd));
1000 return PS_OK;
c906108c 1001 }
8d027a04
MK
1002 else
1003 /* LDT not found. */
c906108c 1004 return PS_ERR;
c5aa993b 1005}
965b60ee 1006#endif
c906108c 1007\f
8d027a04
MK
1008
1009/* Convert PTID to printable form. */
c906108c 1010
f6ac5f3d
PA
1011const char *
1012sol_thread_target::pid_to_str (ptid_t ptid)
c906108c
SS
1013{
1014 static char buf[100];
1015
dfd4cc63 1016 if (ptid_tid_p (ptid))
c906108c 1017 {
39f77062 1018 ptid_t lwp;
c906108c 1019
39f77062 1020 lwp = thread_to_lwp (ptid, -2);
c906108c 1021
dfd4cc63 1022 if (ptid_get_pid (lwp) == -1)
8c042590 1023 xsnprintf (buf, sizeof (buf), "Thread %ld (defunct)",
dfd4cc63
LM
1024 ptid_get_tid (ptid));
1025 else if (ptid_get_pid (lwp) != -2)
8c042590 1026 xsnprintf (buf, sizeof (buf), "Thread %ld (LWP %ld)",
dfd4cc63 1027 ptid_get_tid (ptid), ptid_get_lwp (lwp));
c906108c 1028 else
dfd4cc63
LM
1029 xsnprintf (buf, sizeof (buf), "Thread %ld ",
1030 ptid_get_tid (ptid));
c906108c 1031 }
dfd4cc63
LM
1032 else if (ptid_get_lwp (ptid) != 0)
1033 xsnprintf (buf, sizeof (buf), "LWP %ld ", ptid_get_lwp (ptid));
c906108c 1034 else
dfd4cc63 1035 xsnprintf (buf, sizeof (buf), "process %d ", ptid_get_pid (ptid));
c906108c
SS
1036
1037 return buf;
1038}
1039\f
1040
e8032dde 1041/* Worker bee for update_thread_list. Callback function that gets
8d027a04 1042 called once per user-level thread (i.e. not for LWP's). */
c906108c
SS
1043
1044static int
e8032dde 1045sol_update_thread_list_callback (const td_thrhandle_t *th, void *ignored)
c906108c
SS
1046{
1047 td_err_e retval;
1048 td_thrinfo_t ti;
39f77062 1049 ptid_t ptid;
c906108c 1050
8d027a04
MK
1051 retval = p_td_thr_get_info (th, &ti);
1052 if (retval != TD_OK)
1053 return -1;
1054
dfd4cc63 1055 ptid = ptid_build (ptid_get_pid (inferior_ptid), 0, ti.ti_tid);
2689673f 1056 if (!in_thread_list (ptid) || is_exited (ptid))
39f77062 1057 add_thread (ptid);
c906108c
SS
1058
1059 return 0;
1060}
1061
f6ac5f3d
PA
1062void
1063sol_thread_target::update_thread_list ()
c906108c 1064{
f6ac5f3d 1065 struct target_ops *beneath = find_target_beneath (this);
8d027a04 1066
e8032dde
PA
1067 /* Delete dead threads. */
1068 prune_threads ();
1069
1070 /* Find any new LWP's. */
f6ac5f3d 1071 beneath->update_thread_list ();
8d027a04
MK
1072
1073 /* Then find any new user-level threads. */
e8032dde 1074 p_td_ta_thr_iter (main_ta, sol_update_thread_list_callback, (void *) 0,
c906108c
SS
1075 TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
1076 TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
1077}
1078
8d027a04
MK
1079/* Worker bee for the "info sol-thread" command. This is a callback
1080 function that gets called once for each Solaris user-level thread
1081 (i.e. not for LWPs) in the inferior. Print anything interesting
1082 that we can think of. */
c906108c 1083
c5aa993b 1084static int
fba45db2 1085info_cb (const td_thrhandle_t *th, void *s)
c906108c
SS
1086{
1087 td_err_e ret;
1088 td_thrinfo_t ti;
c906108c 1089
8d027a04
MK
1090 ret = p_td_thr_get_info (th, &ti);
1091 if (ret == TD_OK)
c906108c 1092 {
c5aa993b
JM
1093 printf_filtered ("%s thread #%d, lwp %d, ",
1094 ti.ti_type == TD_THR_SYSTEM ? "system" : "user ",
c906108c 1095 ti.ti_tid, ti.ti_lid);
c5aa993b
JM
1096 switch (ti.ti_state)
1097 {
c906108c 1098 default:
c5aa993b
JM
1099 case TD_THR_UNKNOWN:
1100 printf_filtered ("<unknown state>");
1101 break;
1102 case TD_THR_STOPPED:
1103 printf_filtered ("(stopped)");
1104 break;
1105 case TD_THR_RUN:
1106 printf_filtered ("(run) ");
1107 break;
1108 case TD_THR_ACTIVE:
1109 printf_filtered ("(active) ");
1110 break;
1111 case TD_THR_ZOMBIE:
1112 printf_filtered ("(zombie) ");
1113 break;
1114 case TD_THR_SLEEP:
1115 printf_filtered ("(asleep) ");
1116 break;
1117 case TD_THR_STOPPED_ASLEEP:
1118 printf_filtered ("(stopped asleep)");
1119 break;
1120 }
8d027a04 1121 /* Print thr_create start function. */
c906108c 1122 if (ti.ti_startfunc != 0)
4ce44c66 1123 {
5812197c
JB
1124 const struct bound_minimal_symbol msym
1125 = lookup_minimal_symbol_by_pc (ti.ti_startfunc);
1126
17e760ae
JB
1127 printf_filtered (" startfunc=%s",
1128 msym.minsym
d3c1a85f 1129 ? MSYMBOL_PRINT_NAME (msym.minsym)
17e760ae 1130 : paddress (target_gdbarch (), ti.ti_startfunc));
4ce44c66 1131 }
c906108c 1132
8d027a04 1133 /* If thread is asleep, print function that went to sleep. */
c906108c 1134 if (ti.ti_state == TD_THR_SLEEP)
4ce44c66 1135 {
5812197c
JB
1136 const struct bound_minimal_symbol msym
1137 = lookup_minimal_symbol_by_pc (ti.ti_pc);
1138
17e760ae
JB
1139 printf_filtered (" sleepfunc=%s",
1140 msym.minsym
d3c1a85f 1141 ? MSYMBOL_PRINT_NAME (msym.minsym)
17e760ae 1142 : paddress (target_gdbarch (), ti.ti_pc));
4ce44c66 1143 }
c906108c 1144
c0f5f490 1145 printf_filtered ("\n");
c906108c
SS
1146 }
1147 else
8a3fe4f8 1148 warning (_("info sol-thread: failed to get info for thread."));
c906108c 1149
c5aa993b 1150 return 0;
c906108c
SS
1151}
1152
8d027a04
MK
1153/* List some state about each Solaris user-level thread in the
1154 inferior. */
c906108c
SS
1155
1156static void
e8020e54 1157info_solthreads (const char *args, int from_tty)
c906108c 1158{
e8020e54 1159 p_td_ta_thr_iter (main_ta, info_cb, (void *) args,
c906108c
SS
1160 TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
1161 TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
1162}
c906108c 1163
3caf13b4
JB
1164/* Callback routine used to find a thread based on the TID part of
1165 its PTID. */
1166
1167static int
1168thread_db_find_thread_from_tid (struct thread_info *thread, void *data)
1169{
1170 long *tid = (long *) data;
1171
1172 if (ptid_get_tid (thread->ptid) == *tid)
1173 return 1;
1174
1175 return 0;
1176}
1177
f6ac5f3d
PA
1178ptid_t
1179sol_thread_target::get_ada_task_ptid (long lwp, long thread)
3caf13b4
JB
1180{
1181 struct thread_info *thread_info =
1182 iterate_over_threads (thread_db_find_thread_from_tid, &thread);
1183
1184 if (thread_info == NULL)
1185 {
1186 /* The list of threads is probably not up to date. Find any
1187 thread that is missing from the list, and try again. */
f6ac5f3d 1188 update_thread_list ();
3caf13b4
JB
1189 thread_info = iterate_over_threads (thread_db_find_thread_from_tid,
1190 &thread);
1191 }
1192
1193 gdb_assert (thread_info != NULL);
1194
1195 return (thread_info->ptid);
1196}
1197
c906108c 1198void
fba45db2 1199_initialize_sol_thread (void)
c906108c
SS
1200{
1201 void *dlhandle;
1202
c906108c
SS
1203 dlhandle = dlopen ("libthread_db.so.1", RTLD_NOW);
1204 if (!dlhandle)
1205 goto die;
1206
1207#define resolve(X) \
b196bc4c 1208 if (!(p_##X = (X ## _ftype *) dlsym (dlhandle, #X))) \
c906108c
SS
1209 goto die;
1210
1211 resolve (td_log);
1212 resolve (td_ta_new);
1213 resolve (td_ta_delete);
1214 resolve (td_init);
1215 resolve (td_ta_get_ph);
1216 resolve (td_ta_get_nthreads);
1217 resolve (td_ta_tsd_iter);
1218 resolve (td_ta_thr_iter);
1219 resolve (td_thr_validate);
1220 resolve (td_thr_tsd);
1221 resolve (td_thr_get_info);
1222 resolve (td_thr_getfpregs);
1223 resolve (td_thr_getxregsize);
1224 resolve (td_thr_getxregs);
1225 resolve (td_thr_sigsetmask);
1226 resolve (td_thr_setprio);
1227 resolve (td_thr_setsigpending);
1228 resolve (td_thr_setfpregs);
1229 resolve (td_thr_setxregs);
1230 resolve (td_ta_map_id2thr);
1231 resolve (td_ta_map_lwp2thr);
1232 resolve (td_thr_getgregs);
1233 resolve (td_thr_setgregs);
1234
c5aa993b 1235 add_cmd ("sol-threads", class_maintenance, info_solthreads,
1a966eab 1236 _("Show info on Solaris user threads."), &maintenanceinfolist);
c906108c 1237
8d027a04 1238 /* Hook into new_objfile notification. */
76727919 1239 gdb::observers::new_objfile.attach (sol_thread_new_objfile);
c906108c
SS
1240 return;
1241
8d027a04
MK
1242 die:
1243 fprintf_unfiltered (gdb_stderr, "\
1244[GDB will not be able to debug user-mode threads: %s]\n", dlerror ());
c906108c
SS
1245
1246 if (dlhandle)
1247 dlclose (dlhandle);
1248
c906108c
SS
1249 return;
1250}