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