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