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