GDB (xrefs)
Loading...
Searching...
No Matches
sol-thread.c
Go to the documentation of this file.
1/* Solaris threads debugging interface.
2
3 Copyright (C) 1996-2023 Free Software Foundation, Inc.
4
5 This file is part of GDB.
6
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
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11
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.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19
20/* This module implements a sort of half target that sits between the
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 respectively) 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
38 sleeping thread may not be associated with an LWP at all!
39
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. */
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>
59#include <sys/stat.h>
60#include <dlfcn.h>
61#include "gdbcmd.h"
62#include "gdbcore.h"
63#include "regcache.h"
64#include "solib.h"
65#include "symfile.h"
66#include "observable.h"
67#include "procfs.h"
68#include "symtab.h"
69#include "minsyms.h"
70#include "objfiles.h"
71
73 "solaris-threads",
74 N_("Solaris threads and pthread."),
75 N_("Solaris threads and pthread support.")
76};
77
78class sol_thread_target final : public target_ops
79{
80public:
81 const target_info &info () const override
82 { return thread_db_target_info; }
83
84 strata stratum () const override { return thread_stratum; }
85
86 void detach (inferior *, int) override;
87 ptid_t wait (ptid_t, struct target_waitstatus *, target_wait_flags) override;
88 void resume (ptid_t, int, enum gdb_signal) override;
89 void mourn_inferior () override;
90 std::string pid_to_str (ptid_t) override;
91 ptid_t get_ada_task_ptid (long lwp, ULONGEST thread) override;
92
93 void fetch_registers (struct regcache *, int) override;
94 void store_registers (struct regcache *, int) override;
95
97 const char *annex,
98 gdb_byte *readbuf,
99 const gdb_byte *writebuf,
100 ULONGEST offset, ULONGEST len,
101 ULONGEST *xfered_len) override;
102
103 bool thread_alive (ptid_t ptid) override;
104 void update_thread_list () override;
105};
106
108
109/* Prototypes for supply_gregset etc. */
110#include "gregset.h"
111
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. */
115
116struct ps_prochandle
117{
118 ptid_t ptid;
119};
120
122{
123 int num;
124 const char *str;
125};
126
127static struct ps_prochandle main_ph;
129static int sol_thread_active = 0;
130
131/* Default definitions: These must be defined in tm.h if they are to
132 be shared with a process module such as procfs. */
133
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);
140typedef td_err_e (td_init_ftype)(void);
142 struct ps_prochandle **ph_pp);
144 int *nthread_p);
146 td_key_iter_f *cb, void *cbdata_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);
154 const thread_key_t key, void **data_pp);
156 td_thrinfo_t *ti_p);
158 prfpregset_t *fpregset);
160 int *xregsize);
162 const caddr_t xregset);
164 const sigset_t ti_sigmask);
166 const int ti_pri);
168 const uchar_t ti_pending_flag,
169 const sigset_t ti_pending);
171 const prfpregset_t *fpregset);
173 const caddr_t xregset);
175 thread_t tid,
176 td_thrhandle_t *th_p);
178 lwpid_t lwpid,
179 td_thrhandle_t *th_p);
181 prgregset_t regset);
183 const prgregset_t regset);
184
185/* Pointers to routines from libthread_db resolved by dlopen(). */
186
210
211
212/* Return the libthread_db error string associated with ERRCODE. If
213 ERRCODE is unknown, return an appropriate message. */
214
215static const char *
217{
218 static struct string_map td_err_table[] =
219 {
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" }
241 };
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;
249
250 xsnprintf (buf, sizeof (buf), "Unknown libthread_db error code: %d",
251 errcode);
252
253 return buf;
254}
255
256/* Return the libthread_db state string associated with STATECODE.
257 If STATECODE is unknown, return an appropriate message. */
258
259static const char *
261{
262 static struct string_map td_thr_state_table[] =
263 {
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" }
272 };
273 const int td_thr_state_table_size =
274 sizeof td_thr_state_table / sizeof (struct string_map);
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;
281
282 xsnprintf (buf, sizeof (buf), "Unknown libthread_db state code: %d",
283 statecode);
284
285 return buf;
286}
287
288
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
291 DEFAULT_LWP.
292
293 NOTE: This function probably shouldn't call error(). */
294
295static ptid_t
296thread_to_lwp (ptid_t thread_id, int default_lwp)
297{
298 td_thrinfo_t ti;
300 td_err_e val;
301
302 if (thread_id.lwp_p ())
303 return thread_id; /* It's already an LWP ID. */
304
305 /* It's a thread. Convert to LWP. */
306
307 val = p_td_ta_map_id2thr (main_ta, thread_id.tid (), &th);
308 if (val == TD_NOTHR)
309 return ptid_t (-1); /* Thread must have terminated. */
310 else if (val != TD_OK)
311 error (_("thread_to_lwp: td_ta_map_id2thr %s"), td_err_string (val));
312
313 val = p_td_thr_get_info (&th, &ti);
314 if (val == TD_NOTHR)
315 return ptid_t (-1); /* Thread must have terminated. */
316 else if (val != TD_OK)
317 error (_("thread_to_lwp: td_thr_get_info: %s"), td_err_string (val));
318
319 if (ti.ti_state != TD_THR_ACTIVE)
320 {
321 if (default_lwp != -1)
322 return ptid_t (default_lwp);
323 error (_("thread_to_lwp: thread state not active: %s"),
325 }
326
327 return ptid_t (thread_id.pid (), ti.ti_lid, 0);
328}
329
330/* Convert an LWP ID into a POSIX or Solaris thread ID. If LWP_ID
331 doesn't exists, that's an error.
332
333 NOTE: This function probably shouldn't call error(). */
334
335static ptid_t
336lwp_to_thread (ptid_t lwp)
337{
338 td_thrinfo_t ti;
340 td_err_e val;
341
342 if (lwp.tid_p ())
343 return lwp; /* It's already a thread ID. */
344
345 /* It's an LWP. Convert it to a thread ID. */
346
347 if (!target_thread_alive (lwp))
348 return ptid_t (-1); /* Must be a defunct LPW. */
349
350 val = p_td_ta_map_lwp2thr (main_ta, lwp.lwp (), &th);
351 if (val == TD_NOTHR)
352 return ptid_t (-1); /* Thread must have terminated. */
353 else if (val != TD_OK)
354 error (_("lwp_to_thread: td_ta_map_lwp2thr: %s."), td_err_string (val));
355
356 val = p_td_thr_validate (&th);
357 if (val == TD_NOTHR)
358 return lwp; /* Unknown to libthread; just return LPW, */
359 else if (val != TD_OK)
360 error (_("lwp_to_thread: td_thr_validate: %s."), td_err_string (val));
361
362 val = p_td_thr_get_info (&th, &ti);
363 if (val == TD_NOTHR)
364 return ptid_t (-1); /* Thread must have terminated. */
365 else if (val != TD_OK)
366 error (_("lwp_to_thread: td_thr_get_info: %s."), td_err_string (val));
367
368 return ptid_t (lwp.pid (), 0 , ti.ti_tid);
369}
370
371
372/* Most target vector functions from here on actually just pass
373 through to the layer beneath, as they don't need to do anything
374 specific for threads. */
375
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). */
382
383void
385{
386 target_ops *beneath = this->beneath ();
387
389 inferior_ptid = ptid_t (main_ph.ptid.pid ());
390 inf->unpush_target (this);
391 beneath->detach (inf, from_tty);
392}
393
394/* Resume execution of process PTID. If STEP is nonzero, 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. */
398
399void
400sol_thread_target::resume (ptid_t ptid, int step, enum gdb_signal signo)
401{
402 scoped_restore save_inferior_ptid = make_scoped_restore (&inferior_ptid);
403
405 if (inferior_ptid.pid () == -1)
407
408 if (ptid.pid () != -1)
409 {
410 ptid_t save_ptid = ptid;
411
412 ptid = thread_to_lwp (ptid, -2);
413 if (ptid.pid () == -2) /* Inactive thread. */
414 error (_("This version of Solaris can't start inactive threads."));
415 if (info_verbose && ptid.pid () == -1)
416 warning (_("Specified thread %s seems to have terminated"),
417 pulongest (save_ptid.tid ()));
418 }
419
420 beneath ()->resume (ptid, step, signo);
421}
422
423/* Wait for any threads to stop. We may have to convert PTID from a
424 thread ID to an LWP ID, and vice versa on the way out. */
425
426ptid_t
427sol_thread_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
428 target_wait_flags options)
429{
430 if (ptid.pid () != -1)
431 {
432 ptid_t ptid_for_warning = ptid;
433
434 ptid = thread_to_lwp (ptid, -2);
435 if (ptid.pid () == -2) /* Inactive thread. */
436 error (_("This version of Solaris can't start inactive threads."));
437 if (info_verbose && ptid.pid () == -1)
438 warning (_("Specified thread %s seems to have terminated"),
439 pulongest (ptid_for_warning.tid ()));
440 }
441
442 ptid_t rtnval = beneath ()->wait (ptid, ourstatus, options);
443
444 if (ourstatus->kind () != TARGET_WAITKIND_EXITED)
445 {
446 /* Map the LWP of interest back to the appropriate thread ID. */
447 ptid_t thr_ptid = lwp_to_thread (rtnval);
448 if (thr_ptid.pid () != -1)
449 rtnval = thr_ptid;
450
451 /* See if we have a new thread. */
452 if (rtnval.tid_p ())
453 {
455 if (thr == NULL || thr->state == THREAD_EXITED)
456 {
457 process_stratum_target *proc_target
459 add_thread (proc_target, rtnval);
460 }
461 }
462 }
463
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. */
467
468 return rtnval;
469}
470
471void
473{
474 thread_t thread;
475 td_thrhandle_t thandle;
476 td_err_e val;
477 prgregset_t gregset;
478 prfpregset_t fpregset;
479 gdb_gregset_t *gregset_p = &gregset;
480 gdb_fpregset_t *fpregset_p = &fpregset;
481 ptid_t ptid = regcache->ptid ();
482
483 if (!ptid.tid_p ())
484 {
485 /* It's an LWP; pass the request on to the layer beneath. */
487 return;
488 }
489
490 /* Solaris thread: convert PTID into a td_thrhandle_t. */
491 thread = ptid.tid ();
492 if (thread == 0)
493 error (_("sol_thread_fetch_registers: thread == 0"));
494
495 val = p_td_ta_map_id2thr (main_ta, thread, &thandle);
496 if (val != TD_OK)
497 error (_("sol_thread_fetch_registers: td_ta_map_id2thr: %s"),
498 td_err_string (val));
499
500 /* Get the general-purpose registers. */
501
502 val = p_td_thr_getgregs (&thandle, gregset);
503 if (val != TD_OK && val != TD_PARTIALREG)
504 error (_("sol_thread_fetch_registers: td_thr_getgregs %s"),
505 td_err_string (val));
506
507 /* For SPARC, TD_PARTIALREG means that only %i0...%i7, %l0..%l7, %pc
508 and %sp are saved (by a thread context switch). */
509
510 /* And, now the floating-point registers. */
511
512 val = p_td_thr_getfpregs (&thandle, &fpregset);
513 if (val != TD_OK && val != TD_NOFPREGS)
514 error (_("sol_thread_fetch_registers: td_thr_getfpregs %s"),
515 td_err_string (val));
516
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. */
520
521 supply_gregset (regcache, (const gdb_gregset_t *) gregset_p);
522 supply_fpregset (regcache, (const gdb_fpregset_t *) fpregset_p);
523}
524
525void
527{
528 thread_t thread;
529 td_thrhandle_t thandle;
530 td_err_e val;
531 prgregset_t gregset;
532 prfpregset_t fpregset;
533 ptid_t ptid = regcache->ptid ();
534
535 if (!ptid.tid_p ())
536 {
537 /* It's an LWP; pass the request on to the layer beneath. */
539 return;
540 }
541
542 /* Solaris thread: convert PTID into a td_thrhandle_t. */
543 thread = ptid.tid ();
544
545 val = p_td_ta_map_id2thr (main_ta, thread, &thandle);
546 if (val != TD_OK)
547 error (_("sol_thread_store_registers: td_ta_map_id2thr %s"),
548 td_err_string (val));
549
550 if (regnum != -1)
551 {
552 val = p_td_thr_getgregs (&thandle, gregset);
553 if (val != TD_OK)
554 error (_("sol_thread_store_registers: td_thr_getgregs %s"),
555 td_err_string (val));
556 val = p_td_thr_getfpregs (&thandle, &fpregset);
557 if (val != TD_OK)
558 error (_("sol_thread_store_registers: td_thr_getfpregs %s"),
559 td_err_string (val));
560 }
561
562 fill_gregset (regcache, (gdb_gregset_t *) &gregset, regnum);
564
565 val = p_td_thr_setgregs (&thandle, gregset);
566 if (val != TD_OK)
567 error (_("sol_thread_store_registers: td_thr_setgregs %s"),
568 td_err_string (val));
569 val = p_td_thr_setfpregs (&thandle, &fpregset);
570 if (val != TD_OK)
571 error (_("sol_thread_store_registers: td_thr_setfpregs %s"),
572 td_err_string (val));
573}
574
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. */
578
581 const char *annex, gdb_byte *readbuf,
582 const gdb_byte *writebuf,
583 ULONGEST offset, ULONGEST len,
584 ULONGEST *xfered_len)
585{
586 scoped_restore save_inferior_ptid = make_scoped_restore (&inferior_ptid);
587
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. */
596 }
597
598 return beneath ()->xfer_partial (object, annex, readbuf,
599 writebuf, offset, len, xfered_len);
600}
601
602static void
604{
606 ptid_t ptid;
607
608 /* Don't attempt to use thread_db for remote targets. */
609 if (!(target_can_run () || core_bfd))
610 return;
611
612 /* Do nothing if we couldn't load libthread_db.so.1. */
613 if (p_td_ta_new == NULL)
614 return;
615
617 /* Nothing to do. The thread library was already detected and the
618 target vector was already activated. */
619 return;
620
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. */
624
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 }
631
632 /* Now attempt to open a connection to the thread library. */
634 switch (err)
635 {
636 case TD_NOLIBTHREAD:
637 /* No thread library was detected. */
638 break;
639
640 case TD_OK:
641 gdb_printf (_("[Thread debugging using libthread_db enabled]\n"));
642
643 /* The thread library was detected. Activate the sol_thread target. */
646
647 main_ph.ptid = inferior_ptid; /* Save for xfer_memory. */
649 if (ptid.pid () != -1)
650 inferior_ptid = ptid;
651
653 break;
654
655 default:
656 warning (_("Cannot initialize thread debugging library: %s"),
658 break;
659 }
660}
661
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
666 the library gets mapped and the symbol table is read in. */
667
668static void
670{
671 if (objfile != NULL)
673}
674
675/* Clean up after the inferior dies. */
676
677void
679{
680 target_ops *beneath = this->beneath ();
681
683
685
686 beneath->mourn_inferior ();
687}
688
689/* Return true if PTID is still active in the inferior. */
690
691bool
693{
694 if (ptid.tid_p ())
695 {
696 /* It's a (user-level) thread. */
697 td_err_e val;
699 int pid;
700
701 pid = ptid.tid ();
702 val = p_td_ta_map_id2thr (main_ta, pid, &th);
703 if (val != TD_OK)
704 return false; /* Thread not found. */
705 val = p_td_thr_validate (&th);
706 if (val != TD_OK)
707 return false; /* Thread not valid. */
708 return true; /* Known thread. */
709 }
710 else
711 {
712 /* It's an LPW; pass the request on to the layer below. */
713 return beneath ()->thread_alive (ptid);
714 }
715}
716
717
718/* These routines implement the lower half of the thread_db interface,
719 i.e. the ps_* routines. */
720
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. */
725
726/* Process stop. */
727
728ps_err_e
730{
731 return PS_OK;
732}
733
734/* Process continue. */
735
736ps_err_e
738{
739 return PS_OK;
740}
741
742/* LWP stop. */
743
744ps_err_e
745ps_lstop (struct ps_prochandle *ph, lwpid_t lwpid)
746{
747 return PS_OK;
748}
749
750/* LWP continue. */
751
752ps_err_e
753ps_lcontinue (struct ps_prochandle *ph, lwpid_t lwpid)
754{
755 return PS_OK;
756}
757
758/* Looks up the symbol LD_SYMBOL_NAME in the debugger's symbol table. */
759
760ps_err_e
761ps_pglobal_lookup (struct ps_prochandle *ph, const char *ld_object_name,
762 const char *ld_symbol_name, psaddr_t *ld_symbol_addr)
763{
764 struct bound_minimal_symbol ms;
765
766 ms = lookup_minimal_symbol (ld_symbol_name, NULL, NULL);
767 if (!ms.minsym)
768 return PS_NOSYM;
769
770 *ld_symbol_addr = ms.value_address ();
771 return PS_OK;
772}
773
774/* Common routine for reading and writing memory. */
775
776static ps_err_e
777rw_common (int dowrite, const struct ps_prochandle *ph, psaddr_t addr,
778 gdb_byte *buf, int size)
779{
780 int ret;
781
782 scoped_restore save_inferior_ptid = make_scoped_restore (&inferior_ptid);
783
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. */
792 }
793
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. */
797 if (bfd_get_arch_size (current_program_space->exec_bfd ()) == 32)
798 addr &= 0xffffffff;
799#endif
800
801 if (dowrite)
802 ret = target_write_memory (addr, (gdb_byte *) buf, size);
803 else
804 ret = target_read_memory (addr, (gdb_byte *) buf, size);
805
806 return (ret == 0 ? PS_OK : PS_ERR);
807}
808
809/* Copies SIZE bytes from target process .data segment to debugger memory. */
810
811ps_err_e
812ps_pdread (struct ps_prochandle *ph, psaddr_t addr, void *buf, size_t size)
813{
814 return rw_common (0, ph, addr, (gdb_byte *) buf, size);
815}
816
817/* Copies SIZE bytes from debugger memory .data segment to target process. */
818
819ps_err_e
820ps_pdwrite (struct ps_prochandle *ph, psaddr_t addr,
821 const void *buf, size_t size)
822{
823 return rw_common (1, ph, addr, (gdb_byte *) buf, size);
824}
825
826/* Copies SIZE bytes from target process .text segment to debugger memory. */
827
828ps_err_e
829ps_ptread (struct ps_prochandle *ph, psaddr_t addr, void *buf, size_t size)
830{
831 return rw_common (0, ph, addr, (gdb_byte *) buf, size);
832}
833
834/* Copies SIZE bytes from debugger memory .text segment to target process. */
835
836ps_err_e
837ps_ptwrite (struct ps_prochandle *ph, psaddr_t addr,
838 const void *buf, size_t size)
839{
840 return rw_common (1, ph, addr, (gdb_byte *) buf, size);
841}
842
843/* Get general-purpose registers for LWP. */
844
845ps_err_e
846ps_lgetregs (struct ps_prochandle *ph, lwpid_t lwpid, prgregset_t gregset)
847{
848 ptid_t ptid = ptid_t (current_inferior ()->pid, lwpid, 0);
849 struct regcache *regcache
850 = get_thread_arch_regcache (current_inferior ()->process_target (),
851 ptid, target_gdbarch ());
852
854 fill_gregset (regcache, (gdb_gregset_t *) gregset, -1);
855
856 return PS_OK;
857}
858
859/* Set general-purpose registers for LWP. */
860
861ps_err_e
862ps_lsetregs (struct ps_prochandle *ph, lwpid_t lwpid,
863 const prgregset_t gregset)
864{
865 ptid_t ptid = ptid_t (current_inferior ()->pid, lwpid, 0);
866 struct regcache *regcache
867 = get_thread_arch_regcache (current_inferior ()->process_target (),
868 ptid, target_gdbarch ());
869
870 supply_gregset (regcache, (const gdb_gregset_t *) gregset);
872
873 return PS_OK;
874}
875
876/* Log a message (sends to gdb_stderr). */
877
878void
879ps_plog (const char *fmt, ...)
880{
881 va_list args;
882
883 va_start (args, fmt);
884
885 gdb_vprintf (gdb_stderr, fmt, args);
886}
887
888/* Get size of extra register set. Currently a noop. */
889
890ps_err_e
891ps_lgetxregsize (struct ps_prochandle *ph, lwpid_t lwpid, int *xregsize)
892{
893 return PS_OK;
894}
895
896/* Get extra register set. Currently a noop. */
897
898ps_err_e
899ps_lgetxregs (struct ps_prochandle *ph, lwpid_t lwpid, caddr_t xregset)
900{
901 return PS_OK;
902}
903
904/* Set extra register set. Currently a noop. */
905
906ps_err_e
907ps_lsetxregs (struct ps_prochandle *ph, lwpid_t lwpid, caddr_t xregset)
908{
909 return PS_OK;
910}
911
912/* Get floating-point registers for LWP. */
913
914ps_err_e
915ps_lgetfpregs (struct ps_prochandle *ph, lwpid_t lwpid,
916 prfpregset_t *fpregset)
917{
918 ptid_t ptid = ptid_t (current_inferior ()->pid, lwpid, 0);
919 struct regcache *regcache
920 = get_thread_arch_regcache (current_inferior ()->process_target (),
921 ptid, target_gdbarch ());
922
924 fill_fpregset (regcache, (gdb_fpregset_t *) fpregset, -1);
925
926 return PS_OK;
927}
928
929/* Set floating-point regs for LWP. */
930
931ps_err_e
932ps_lsetfpregs (struct ps_prochandle *ph, lwpid_t lwpid,
933 const prfpregset_t * fpregset)
934{
935 ptid_t ptid = ptid_t (current_inferior ()->pid, lwpid, 0);
936 struct regcache *regcache
937 = get_thread_arch_regcache (current_inferior ()->process_target (),
938 ptid, target_gdbarch ());
939
940 supply_fpregset (regcache, (const gdb_fpregset_t *) fpregset);
942
943 return PS_OK;
944}
945
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. */
949
950ps_err_e
951ps_pdmodel (struct ps_prochandle *ph, int *data_model)
952{
953 if (current_program_space->exec_bfd () == 0)
954 *data_model = PR_MODEL_UNKNOWN;
955 else if (bfd_get_arch_size (current_program_space->exec_bfd ()) == 32)
956 *data_model = PR_MODEL_ILP32;
957 else
958 *data_model = PR_MODEL_LP64;
959
960 return PS_OK;
961}
962
963
964/* Convert PTID to printable form. */
965
966std::string
968{
969 if (ptid.tid_p ())
970 {
971 ptid_t lwp;
972
973 lwp = thread_to_lwp (ptid, -2);
974
975 if (lwp.pid () == -1)
976 return string_printf ("Thread %s (defunct)",
977 pulongest (ptid.tid ()));
978 else if (lwp.pid () != -2)
979 return string_printf ("Thread %s (LWP %ld)",
980 pulongest (ptid.tid ()), lwp.lwp ());
981 else
982 return string_printf ("Thread %s ",
983 pulongest (ptid.tid ()));
984 }
985 else if (ptid.lwp () != 0)
986 return string_printf ("LWP %ld ", ptid.lwp ());
987 else
988 return string_printf ("process %d ", ptid.pid ());
989}
990
991
992/* Worker bee for update_thread_list. Callback function that gets
993 called once per user-level thread (i.e. not for LWP's). */
994
995static int
997{
998 td_err_e retval;
999 td_thrinfo_t ti;
1000
1001 retval = p_td_thr_get_info (th, &ti);
1002 if (retval != TD_OK)
1003 return -1;
1004
1005 ptid_t ptid = ptid_t (current_inferior ()->pid, 0, ti.ti_tid);
1007 if (thr == NULL || thr->state == THREAD_EXITED)
1008 {
1009 process_stratum_target *proc_target
1011 add_thread (proc_target, ptid);
1012 }
1013
1014 return 0;
1015}
1016
1017void
1019{
1020 /* Delete dead threads. */
1021 prune_threads ();
1022
1023 /* Find any new LWP's. */
1025
1026 /* Then find any new user-level threads. */
1030}
1031
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. */
1036
1037static int
1038info_cb (const td_thrhandle_t *th, void *s)
1039{
1040 td_err_e ret;
1041 td_thrinfo_t ti;
1042
1043 ret = p_td_thr_get_info (th, &ti);
1044 if (ret == TD_OK)
1045 {
1046 gdb_printf ("%s thread #%d, lwp %d, ",
1047 ti.ti_type == TD_THR_SYSTEM ? "system" : "user ",
1048 ti.ti_tid, ti.ti_lid);
1049 switch (ti.ti_state)
1050 {
1051 default:
1052 case TD_THR_UNKNOWN:
1053 gdb_printf ("<unknown state>");
1054 break;
1055 case TD_THR_STOPPED:
1056 gdb_printf ("(stopped)");
1057 break;
1058 case TD_THR_RUN:
1059 gdb_printf ("(run) ");
1060 break;
1061 case TD_THR_ACTIVE:
1062 gdb_printf ("(active) ");
1063 break;
1064 case TD_THR_ZOMBIE:
1065 gdb_printf ("(zombie) ");
1066 break;
1067 case TD_THR_SLEEP:
1068 gdb_printf ("(asleep) ");
1069 break;
1071 gdb_printf ("(stopped asleep)");
1072 break;
1073 }
1074 /* Print thr_create start function. */
1075 if (ti.ti_startfunc != 0)
1076 {
1077 const struct bound_minimal_symbol msym
1079
1080 gdb_printf (" startfunc=%s",
1081 msym.minsym
1082 ? msym.minsym->print_name ()
1084 }
1085
1086 /* If thread is asleep, print function that went to sleep. */
1087 if (ti.ti_state == TD_THR_SLEEP)
1088 {
1089 const struct bound_minimal_symbol msym
1091
1092 gdb_printf (" sleepfunc=%s",
1093 msym.minsym
1094 ? msym.minsym->print_name ()
1095 : paddress (target_gdbarch (), ti.ti_pc));
1096 }
1097
1098 gdb_printf ("\n");
1099 }
1100 else
1101 warning (_("info sol-thread: failed to get info for thread."));
1102
1103 return 0;
1104}
1105
1106/* List some state about each Solaris user-level thread in the
1107 inferior. */
1108
1109static void
1110info_solthreads (const char *args, int from_tty)
1111{
1112 p_td_ta_thr_iter (main_ta, info_cb, (void *) args,
1115}
1116
1117/* Callback routine used to find a thread based on the TID part of
1118 its PTID. */
1119
1120static int
1122{
1123 ULONGEST *tid = (ULONGEST *) data;
1124
1125 if (thread->ptid.tid () == *tid)
1126 return 1;
1127
1128 return 0;
1129}
1130
1131ptid_t
1132sol_thread_target::get_ada_task_ptid (long lwp, ULONGEST thread)
1133{
1134 struct thread_info *thread_info =
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. */
1143 &thread);
1144 }
1145
1146 gdb_assert (thread_info != NULL);
1147
1148 return (thread_info->ptid);
1149}
1150
1152void
1154{
1155 void *dlhandle;
1156
1157 dlhandle = dlopen ("libthread_db.so.1", RTLD_NOW);
1158 if (!dlhandle)
1159 goto die;
1160
1161#define resolve(X) \
1162 if (!(p_##X = (X ## _ftype *) dlsym (dlhandle, #X))) \
1163 goto die;
1164
1165 resolve (td_log);
1168 resolve (td_init);
1188
1189 add_cmd ("sol-threads", class_maintenance, info_solthreads,
1190 _("Show info on Solaris user threads."), &maintenanceinfolist);
1191
1192 /* Hook into new_objfile notification. */
1194 return;
1195
1196 die:
1198[GDB will not be able to debug user-mode threads: %s]\n", dlerror ());
1199
1200 if (dlhandle)
1201 dlclose (dlhandle);
1202
1203 return;
1204}
void supply_gregset(struct regcache *regcache, const gdb_gregset_t *gregsetp)
void fill_gregset(const struct regcache *regcache, gdb_gregset_t *gregsetp, int regno)
void supply_fpregset(struct regcache *regcache, const gdb_fpregset_t *fpregsetp)
void fill_fpregset(const struct regcache *regcache, gdb_fpregset_t *fpregsetp, int regno)
int regnum
struct gdbarch * target_gdbarch(void)
int unpush_target(struct target_ops *t)
Definition inferior.c:98
void push_target(struct target_ops *t)
Definition inferior.h:376
struct process_stratum_target * process_target()
Definition inferior.h:419
ptid_t ptid() const
Definition regcache.h:407
void mourn_inferior() override
Definition sol-thread.c:678
void store_registers(struct regcache *, int) override
Definition sol-thread.c:526
void resume(ptid_t, int, enum gdb_signal) override
Definition sol-thread.c:400
enum target_xfer_status xfer_partial(enum target_object object, const char *annex, gdb_byte *readbuf, const gdb_byte *writebuf, ULONGEST offset, ULONGEST len, ULONGEST *xfered_len) override
Definition sol-thread.c:580
void fetch_registers(struct regcache *, int) override
Definition sol-thread.c:472
void detach(inferior *, int) override
Definition sol-thread.c:384
std::string pid_to_str(ptid_t) override
Definition sol-thread.c:967
ptid_t get_ada_task_ptid(long lwp, ULONGEST thread) override
bool thread_alive(ptid_t ptid) override
Definition sol-thread.c:692
ptid_t wait(ptid_t, struct target_waitstatus *, target_wait_flags) override
Definition sol-thread.c:427
void update_thread_list() override
const target_info & info() const override
Definition sol-thread.c:81
strata stratum() const override
Definition sol-thread.c:84
enum thread_state state
Definition gdbthread.h:336
ptid_t ptid
Definition gdbthread.h:256
struct cmd_list_element * maintenanceinfolist
Definition cli-cmds.c:145
struct cmd_list_element * add_cmd(const char *name, enum command_class theclass, const char *doc, struct cmd_list_element **list)
Definition cli-decode.c:233
@ class_maintenance
Definition command.h:65
bool info_verbose
Definition top.c:2022
#define core_bfd
Definition gdbcore.h:130
struct thread_info * add_thread(process_stratum_target *targ, ptid_t ptid)
Definition thread.c:303
thread_info * find_thread_ptid(inferior *inf, ptid_t ptid)
Definition thread.c:528
@ THREAD_EXITED
Definition gdbthread.h:79
struct thread_info * iterate_over_threads(thread_callback_func, void *)
Definition thread.c:565
void prune_threads(void)
Definition thread.c:718
td_err_e
@ TD_NOAPLIC
@ TD_BADTA
@ TD_BADPH
@ TD_DBERR
@ TD_MALLOC
@ TD_NOFPREGS
@ TD_BADKEY
@ TD_NOCAPAB
@ TD_ERR
@ TD_NOTSD
@ TD_NOMSG
@ TD_NOTHR
@ TD_OK
@ TD_BADTH
@ TD_NOXREGS
@ TD_NOSV
@ TD_NOLIBTHREAD
@ TD_PARTIALREG
@ TD_NOEVENT
@ TD_NOLWP
@ TD_BADSH
td_err_e td_thr_setprio(const td_thrhandle_t *__th, int __prio)
pthread_key_t thread_key_t
td_err_e td_ta_tsd_iter(const td_thragent_t *__ta, td_key_iter_f *__ki, void *__p)
#define TD_SIGNO_MASK
td_err_e td_thr_getxregs(const td_thrhandle_t *__th, void *__xregs)
td_err_e td_thr_setgregs(const td_thrhandle_t *__th, prgregset_t __gregs)
int td_key_iter_f(thread_key_t, void(*)(void *), void *)
td_err_e td_thr_getfpregs(const td_thrhandle_t *__th, prfpregset_t *__regset)
td_err_e td_ta_map_id2thr(const td_thragent_t *__ta, pthread_t __pt, td_thrhandle_t *__th)
#define TD_THR_LOWEST_PRIORITY
td_err_e td_thr_sigsetmask(const td_thrhandle_t *__th, const sigset_t *__ss)
int td_thr_iter_f(const td_thrhandle_t *, void *)
td_err_e td_thr_setfpregs(const td_thrhandle_t *__th, const prfpregset_t *__fpregs)
td_err_e td_ta_new(struct ps_prochandle *__ps, td_thragent_t **__ta)
td_err_e td_thr_setxregs(const td_thrhandle_t *__th, const void *__addr)
td_err_e td_thr_tsd(const td_thrhandle_t *__th, const thread_key_t __tk, void **__data)
td_err_e td_ta_get_nthreads(const td_thragent_t *__ta, int *__np)
td_thr_state_e
@ TD_THR_SLEEP
@ TD_THR_RUN
@ TD_THR_STOPPED
@ TD_THR_ANY_STATE
@ TD_THR_STOPPED_ASLEEP
@ TD_THR_ACTIVE
@ TD_THR_ZOMBIE
@ TD_THR_UNKNOWN
struct td_thragent td_thragent_t
td_err_e td_ta_thr_iter(const td_thragent_t *__ta, td_thr_iter_f *__callback, void *__cbdata_p, td_thr_state_e __state, int __ti_pri, sigset_t *__ti_sigmask_p, unsigned int __ti_user_flags)
td_err_e td_thr_getxregsize(const td_thrhandle_t *__th, int *__sizep)
td_err_e td_log(void)
td_err_e td_ta_get_ph(const td_thragent_t *__ta, struct ps_prochandle **__ph)
pthread_t thread_t
td_err_e td_ta_map_lwp2thr(const td_thragent_t *__ta, lwpid_t __lwpid, td_thrhandle_t *__th)
td_err_e td_thr_setsigpending(const td_thrhandle_t *__th, unsigned char __n, const sigset_t *__ss)
@ TD_THR_SYSTEM
td_err_e td_init(void)
#define TD_THR_ANY_USER_FLAGS
td_err_e td_thr_validate(const td_thrhandle_t *__th)
td_err_e td_thr_getgregs(const td_thrhandle_t *__th, prgregset_t __gregs)
td_err_e td_ta_delete(td_thragent_t *__ta)
td_err_e td_thr_get_info(const td_thrhandle_t *__th, td_thrinfo_t *__infop)
mach_port_t mach_port_t name mach_port_t mach_port_t name kern_return_t err
Definition gnu-nat.c:1790
mach_port_t mach_port_t name mach_port_t mach_port_t name kern_return_t int int rusage_t pid_t pid
Definition gnu-nat.c:1792
size_t size
Definition go32-nat.c:241
GDB_FPREGSET_T gdb_fpregset_t
Definition gregset.h:35
GDB_GREGSET_T gdb_gregset_t
Definition gregset.h:34
ptid_t inferior_ptid
Definition infcmd.c:91
struct inferior * current_inferior(void)
Definition inferior.c:54
struct bound_minimal_symbol lookup_minimal_symbol(const char *name, const char *sfile, struct objfile *objf)
Definition minsyms.c:363
struct bound_minimal_symbol lookup_minimal_symbol_by_pc(CORE_ADDR pc)
Definition minsyms.c:977
observable< struct objfile * > new_objfile
ptid_t procfs_first_available(void)
Definition procfs.c:3472
struct program_space * current_program_space
Definition progspace.c:39
struct regcache * get_thread_arch_regcache(process_stratum_target *target, ptid_t ptid, struct gdbarch *gdbarch)
Definition regcache.c:382
static td_thr_validate_ftype * p_td_thr_validate
Definition sol-thread.c:195
ps_err_e ps_lgetxregsize(struct ps_prochandle *ph, lwpid_t lwpid, int *xregsize)
Definition sol-thread.c:891
td_err_e() td_thr_sigsetmask_ftype(const td_thrhandle_t *th_p, const sigset_t ti_sigmask)
Definition sol-thread.c:163
static td_thr_getgregs_ftype * p_td_thr_getgregs
Definition sol-thread.c:208
td_err_e() td_thr_getxregsize_ftype(const td_thrhandle_t *th_p, int *xregsize)
Definition sol-thread.c:159
static td_log_ftype * p_td_log
Definition sol-thread.c:187
td_err_e() td_thr_setsigpending_ftype(const td_thrhandle_t *th_p, const uchar_t ti_pending_flag, const sigset_t ti_pending)
Definition sol-thread.c:167
td_err_e() td_thr_validate_ftype(const td_thrhandle_t *th_p)
Definition sol-thread.c:152
ps_err_e ps_pcontinue(struct ps_prochandle *ph)
Definition sol-thread.c:737
ps_err_e ps_lstop(struct ps_prochandle *ph, lwpid_t lwpid)
Definition sol-thread.c:745
static td_ta_delete_ftype * p_td_ta_delete
Definition sol-thread.c:189
static td_ta_new_ftype * p_td_ta_new
Definition sol-thread.c:188
ps_err_e ps_lcontinue(struct ps_prochandle *ph, lwpid_t lwpid)
Definition sol-thread.c:753
static td_thr_sigsetmask_ftype * p_td_thr_sigsetmask
Definition sol-thread.c:201
td_err_e() td_thr_getfpregs_ftype(const td_thrhandle_t *th_p, prfpregset_t *fpregset)
Definition sol-thread.c:157
td_err_e() td_thr_setgregs_ftype(const td_thrhandle_t *th_p, const prgregset_t regset)
Definition sol-thread.c:182
static ptid_t lwp_to_thread(ptid_t lwp)
Definition sol-thread.c:336
td_err_e() td_thr_getxregs_ftype(const td_thrhandle_t *th_p, const caddr_t xregset)
Definition sol-thread.c:161
static td_thr_setprio_ftype * p_td_thr_setprio
Definition sol-thread.c:202
static td_thr_setxregs_ftype * p_td_thr_setxregs
Definition sol-thread.c:205
static sol_thread_target sol_thread_ops
Definition sol-thread.c:107
static td_ta_get_ph_ftype * p_td_ta_get_ph
Definition sol-thread.c:191
td_err_e() td_ta_get_ph_ftype(const td_thragent_t *ta_p, struct ps_prochandle **ph_pp)
Definition sol-thread.c:141
td_err_e() td_ta_map_lwp2thr_ftype(const td_thragent_t *ta_p, lwpid_t lwpid, td_thrhandle_t *th_p)
Definition sol-thread.c:177
void _initialize_sol_thread()
static td_thragent_t * main_ta
Definition sol-thread.c:128
static const char * td_state_string(td_thr_state_e statecode)
Definition sol-thread.c:260
static ps_err_e rw_common(int dowrite, const struct ps_prochandle *ph, psaddr_t addr, gdb_byte *buf, int size)
Definition sol-thread.c:777
ps_err_e ps_lgetxregs(struct ps_prochandle *ph, lwpid_t lwpid, caddr_t xregset)
Definition sol-thread.c:899
static td_thr_tsd_ftype * p_td_thr_tsd
Definition sol-thread.c:196
static int info_cb(const td_thrhandle_t *th, void *s)
td_err_e() td_init_ftype(void)
Definition sol-thread.c:140
td_err_e() td_thr_get_info_ftype(const td_thrhandle_t *th_p, td_thrinfo_t *ti_p)
Definition sol-thread.c:155
ps_err_e ps_ptwrite(struct ps_prochandle *ph, psaddr_t addr, const void *buf, size_t size)
Definition sol-thread.c:837
td_err_e() td_ta_tsd_iter_ftype(const td_thragent_t *ta_p, td_key_iter_f *cb, void *cbdata_p)
Definition sol-thread.c:145
ps_err_e ps_lgetfpregs(struct ps_prochandle *ph, lwpid_t lwpid, prfpregset_t *fpregset)
Definition sol-thread.c:915
td_err_e() td_thr_getgregs_ftype(const td_thrhandle_t *th_p, prgregset_t regset)
Definition sol-thread.c:180
static int sol_thread_active
Definition sol-thread.c:129
td_err_e() td_thr_setxregs_ftype(const td_thrhandle_t *th_p, const caddr_t xregset)
Definition sol-thread.c:172
static const target_info thread_db_target_info
Definition sol-thread.c:72
static td_ta_thr_iter_ftype * p_td_ta_thr_iter
Definition sol-thread.c:194
td_err_e() td_ta_map_id2thr_ftype(const td_thragent_t *ta_p, thread_t tid, td_thrhandle_t *th_p)
Definition sol-thread.c:174
td_err_e() td_ta_get_nthreads_ftype(const td_thragent_t *ta_p, int *nthread_p)
Definition sol-thread.c:143
void ps_plog(const char *fmt,...)
Definition sol-thread.c:879
ps_err_e ps_lgetregs(struct ps_prochandle *ph, lwpid_t lwpid, prgregset_t gregset)
Definition sol-thread.c:846
static td_thr_getxregsize_ftype * p_td_thr_getxregsize
Definition sol-thread.c:199
static int sol_update_thread_list_callback(const td_thrhandle_t *th, void *ignored)
Definition sol-thread.c:996
ps_err_e ps_ptread(struct ps_prochandle *ph, psaddr_t addr, void *buf, size_t size)
Definition sol-thread.c:829
ps_err_e ps_lsetfpregs(struct ps_prochandle *ph, lwpid_t lwpid, const prfpregset_t *fpregset)
Definition sol-thread.c:932
static int thread_db_find_thread_from_tid(struct thread_info *thread, void *data)
static void check_for_thread_db(void)
Definition sol-thread.c:603
td_err_e() td_thr_setprio_ftype(const td_thrhandle_t *th_p, const int ti_pri)
Definition sol-thread.c:165
static td_thr_setfpregs_ftype * p_td_thr_setfpregs
Definition sol-thread.c:204
static td_ta_tsd_iter_ftype * p_td_ta_tsd_iter
Definition sol-thread.c:193
static void sol_thread_new_objfile(struct objfile *objfile)
Definition sol-thread.c:669
ps_err_e ps_pdread(struct ps_prochandle *ph, psaddr_t addr, void *buf, size_t size)
Definition sol-thread.c:812
td_err_e() td_thr_setfpregs_ftype(const td_thrhandle_t *th_p, const prfpregset_t *fpregset)
Definition sol-thread.c:170
static td_ta_get_nthreads_ftype * p_td_ta_get_nthreads
Definition sol-thread.c:192
ps_err_e ps_pglobal_lookup(struct ps_prochandle *ph, const char *ld_object_name, const char *ld_symbol_name, psaddr_t *ld_symbol_addr)
Definition sol-thread.c:761
#define resolve(X)
static td_thr_get_info_ftype * p_td_thr_get_info
Definition sol-thread.c:197
static td_thr_getfpregs_ftype * p_td_thr_getfpregs
Definition sol-thread.c:198
ps_err_e ps_pstop(struct ps_prochandle *ph)
Definition sol-thread.c:729
td_err_e() td_ta_thr_iter_ftype(const td_thragent_t *ta_p, td_thr_iter_f *cb, void *cbdata_p, td_thr_state_e state, int ti_pri, sigset_t *ti_sigmask_p, unsigned ti_user_flags)
Definition sol-thread.c:147
ps_err_e ps_pdwrite(struct ps_prochandle *ph, psaddr_t addr, const void *buf, size_t size)
Definition sol-thread.c:820
static td_thr_setgregs_ftype * p_td_thr_setgregs
Definition sol-thread.c:209
td_err_e() td_ta_delete_ftype(td_thragent_t *ta_p)
Definition sol-thread.c:139
static td_ta_map_id2thr_ftype * p_td_ta_map_id2thr
Definition sol-thread.c:206
static td_init_ftype * p_td_init
Definition sol-thread.c:190
td_err_e() td_ta_new_ftype(const struct ps_prochandle *ph_p, td_thragent_t **ta_pp)
Definition sol-thread.c:137
static struct ps_prochandle main_ph
Definition sol-thread.c:127
ps_err_e ps_lsetxregs(struct ps_prochandle *ph, lwpid_t lwpid, caddr_t xregset)
Definition sol-thread.c:907
ps_err_e ps_pdmodel(struct ps_prochandle *ph, int *data_model)
Definition sol-thread.c:951
void() td_log_ftype(const int on_off)
Definition sol-thread.c:136
static const char * td_err_string(td_err_e errcode)
Definition sol-thread.c:216
static td_thr_getxregs_ftype * p_td_thr_getxregs
Definition sol-thread.c:200
ps_err_e ps_lsetregs(struct ps_prochandle *ph, lwpid_t lwpid, const prgregset_t gregset)
Definition sol-thread.c:862
static ptid_t thread_to_lwp(ptid_t thread_id, int default_lwp)
Definition sol-thread.c:296
static void info_solthreads(const char *args, int from_tty)
static td_ta_map_lwp2thr_ftype * p_td_ta_map_lwp2thr
Definition sol-thread.c:207
td_err_e() td_thr_tsd_ftype(const td_thrhandle_t *th_p, const thread_key_t key, void **data_pp)
Definition sol-thread.c:153
static td_thr_setsigpending_ftype * p_td_thr_setsigpending
Definition sol-thread.c:203
CORE_ADDR value_address() const
Definition minsyms.h:41
struct minimal_symbol * minsym
Definition minsyms.h:49
const char * print_name() const
Definition symtab.h:474
Definition gnu-nat.c:154
bfd * exec_bfd() const
Definition progspace.h:264
const char * str
Definition sol-thread.c:124
virtual ptid_t wait(ptid_t, struct target_waitstatus *, target_wait_flags options) TARGET_DEFAULT_FUNC(default_target_wait)
virtual void fetch_registers(struct regcache *, int) TARGET_DEFAULT_IGNORE()
virtual void detach(inferior *, int) TARGET_DEFAULT_IGNORE()
target_ops * beneath() const
Definition target.c:3020
virtual void store_registers(struct regcache *, int) TARGET_DEFAULT_NORETURN(noprocess())
virtual enum target_xfer_status xfer_partial(enum target_object object, const char *annex, gdb_byte *readbuf, const gdb_byte *writebuf, ULONGEST offset, ULONGEST len, ULONGEST *xfered_len) TARGET_DEFAULT_RETURN(TARGET_XFER_E_IO)
virtual void resume(ptid_t, int TARGET_DEBUG_PRINTER(target_debug_print_step), enum gdb_signal) TARGET_DEFAULT_NORETURN(noprocess())
virtual void update_thread_list() TARGET_DEFAULT_IGNORE()
virtual void mourn_inferior() TARGET_DEFAULT_FUNC(default_mourn_inferior)
virtual bool thread_alive(ptid_t ptid) TARGET_DEFAULT_RETURN(false)
target_waitkind kind() const
Definition waitstatus.h:345
td_thr_state_e ti_state
td_thr_type_e ti_type
thread_t ti_tid
psaddr_t ti_startfunc
void target_fetch_registers(struct regcache *regcache, int regno)
Definition target.c:3921
int target_can_run()
Definition target.c:3062
void target_update_thread_list(void)
Definition target.c:3769
int target_write_memory(CORE_ADDR memaddr, const gdb_byte *myaddr, ssize_t len)
Definition target.c:1847
int target_read_memory(CORE_ADDR memaddr, gdb_byte *myaddr, ssize_t len)
Definition target.c:1771
int target_thread_alive(ptid_t ptid)
Definition target.c:3763
void target_store_registers(struct regcache *regcache, int regno)
Definition target.c:3929
target_xfer_status
Definition target.h:214
target_object
Definition target.h:138
strata
Definition target.h:89
@ thread_stratum
Definition target.h:93
void gdb_vprintf(struct ui_file *stream, const char *format, va_list args)
Definition utils.c:1853
const char * paddress(struct gdbarch *gdbarch, CORE_ADDR addr)
Definition utils.c:3114
void gdb_printf(struct ui_file *stream, const char *format,...)
Definition utils.c:1865
#define gdb_stderr
Definition utils.h:193
@ TARGET_WAITKIND_EXITED
Definition waitstatus.h:32