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