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