1/* $FreeBSD$ */
2/* FreeBSD libthread_db assisted debugging support.
3   Copyright 1999, 2000, 2001 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 2 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, write to the Free Software
19   Foundation, Inc., 59 Temple Place - Suite 330,
20   Boston, MA 02111-1307, USA.  */
21
22#include <dlfcn.h>
23#include <sys/types.h>
24#include <sys/ptrace.h>
25#include <signal.h>
26
27#include "proc_service.h"
28#include "thread_db.h"
29
30#include "defs.h"
31#include "bfd.h"
32#include "elf-bfd.h"
33#include "gdb_assert.h"
34#include "gdbcore.h"
35#include "gdbthread.h"
36#include "inferior.h"
37#include "objfiles.h"
38#include "regcache.h"
39#include "symfile.h"
40#include "symtab.h"
41#include "target.h"
42#include "gdbcmd.h"
43#include "solib-svr4.h"
44
45#include "gregset.h"
46#ifdef PT_GETXMMREGS
47#include "i387-tdep.h"
48#endif
49
50#define LIBTHREAD_DB_SO "libthread_db.so"
51
52struct ps_prochandle
53{
54  pid_t pid;
55};
56
57extern int child_suppress_run;
58
59extern struct target_ops child_ops;
60
61/* This module's target vectors.  */
62static struct target_ops fbsd_thread_ops;
63static struct target_ops fbsd_core_ops;
64
65/* Saved copy of orignal core_ops. */
66static struct target_ops orig_core_ops;
67extern struct target_ops core_ops;
68
69/* Pointer to the next function on the objfile event chain.  */
70static void (*target_new_objfile_chain) (struct objfile *objfile);
71
72/* Non-zero if there is a thread module */
73static int fbsd_thread_present;
74
75/* Non-zero if we're using this module's target vector.  */
76static int fbsd_thread_active;
77
78/* Non-zero if core_open is called */
79static int fbsd_thread_core = 0;
80
81/* Non-zero if we have to keep this module's target vector active
82   across re-runs.  */
83static int keep_thread_db;
84
85/* Structure that identifies the child process for the
86   <proc_service.h> interface.  */
87static struct ps_prochandle proc_handle;
88
89/* Connection to the libthread_db library.  */
90static td_thragent_t *thread_agent;
91
92/* The last thread we are single stepping */
93static ptid_t last_single_step_thread;
94
95/* Pointers to the libthread_db functions.  */
96
97static td_err_e (*td_init_p) (void);
98
99static td_err_e (*td_ta_new_p) (struct ps_prochandle *ps, td_thragent_t **ta);
100static td_err_e (*td_ta_delete_p) (td_thragent_t *);
101static td_err_e (*td_ta_map_id2thr_p) (const td_thragent_t *ta, thread_t pt,
102				       td_thrhandle_t *__th);
103static td_err_e (*td_ta_map_lwp2thr_p) (const td_thragent_t *ta, lwpid_t lwpid,
104					td_thrhandle_t *th);
105static td_err_e (*td_ta_thr_iter_p) (const td_thragent_t *ta,
106				     td_thr_iter_f *callback,
107				     void *cbdata_p, td_thr_state_e state,
108				     int ti_pri, sigset_t *ti_sigmask_p,
109				     unsigned int ti_user_flags);
110static td_err_e (*td_ta_event_addr_p) (const td_thragent_t *ta,
111				       td_event_e event, td_notify_t *ptr);
112static td_err_e (*td_ta_set_event_p) (const td_thragent_t *ta,
113				      td_thr_events_t *event);
114static td_err_e (*td_ta_event_getmsg_p) (const td_thragent_t *ta,
115					 td_event_msg_t *msg);
116static td_err_e (*td_thr_get_info_p) (const td_thrhandle_t *th,
117				      td_thrinfo_t *infop);
118#ifdef PT_GETXMMREGS
119static td_err_e (*td_thr_getxmmregs_p) (const td_thrhandle_t *th,
120					char *regset);
121#endif
122static td_err_e (*td_thr_getfpregs_p) (const td_thrhandle_t *th,
123				       prfpregset_t *regset);
124static td_err_e (*td_thr_getgregs_p) (const td_thrhandle_t *th,
125				      prgregset_t gregs);
126#ifdef PT_GETXMMREGS
127static td_err_e (*td_thr_setxmmregs_p) (const td_thrhandle_t *th,
128					const char *fpregs);
129#endif
130static td_err_e (*td_thr_setfpregs_p) (const td_thrhandle_t *th,
131				       const prfpregset_t *fpregs);
132static td_err_e (*td_thr_setgregs_p) (const td_thrhandle_t *th,
133				      prgregset_t gregs);
134static td_err_e (*td_thr_event_enable_p) (const td_thrhandle_t *th, int event);
135
136static td_err_e (*td_thr_sstep_p) (td_thrhandle_t *th, int step);
137
138static td_err_e (*td_ta_tsd_iter_p) (const td_thragent_t *ta,
139				 td_key_iter_f *func, void *data);
140static td_err_e (*td_thr_tls_get_addr_p) (const td_thrhandle_t *th,
141                                          void *map_address,
142                                          size_t offset, void **address);
143static td_err_e (*td_thr_dbsuspend_p) (const td_thrhandle_t *);
144static td_err_e (*td_thr_dbresume_p) (const td_thrhandle_t *);
145
146static CORE_ADDR td_create_bp_addr;
147
148/* Location of the thread death event breakpoint.  */
149static CORE_ADDR td_death_bp_addr;
150
151/* Prototypes for local functions.  */
152static void fbsd_thread_find_new_threads (void);
153static int fbsd_thread_alive (ptid_t ptid);
154static void attach_thread (ptid_t ptid, const td_thrhandle_t *th_p,
155               const td_thrinfo_t *ti_p, int verbose);
156static void fbsd_thread_detach (char *args, int from_tty);
157
158/* Building process ids.  */
159
160#define GET_PID(ptid)		ptid_get_pid (ptid)
161#define GET_LWP(ptid)		ptid_get_lwp (ptid)
162#define GET_THREAD(ptid)	ptid_get_tid (ptid)
163
164#define IS_LWP(ptid)		(GET_LWP (ptid) != 0)
165#define IS_THREAD(ptid)		(GET_THREAD (ptid) != 0)
166
167#define BUILD_LWP(lwp, pid)	ptid_build (pid, lwp, 0)
168#define BUILD_THREAD(tid, pid)	ptid_build (pid, 0, tid)
169
170static char *
171thread_db_err_str (td_err_e err)
172{
173  static char buf[64];
174
175  switch (err)
176    {
177    case TD_OK:
178      return "generic 'call succeeded'";
179    case TD_ERR:
180      return "generic error";
181    case TD_NOTHR:
182      return "no thread to satisfy query";
183    case TD_NOSV:
184      return "no sync handle to satisfy query";
185    case TD_NOLWP:
186      return "no LWP to satisfy query";
187    case TD_BADPH:
188      return "invalid process handle";
189    case TD_BADTH:
190      return "invalid thread handle";
191    case TD_BADSH:
192      return "invalid synchronization handle";
193    case TD_BADTA:
194      return "invalid thread agent";
195    case TD_BADKEY:
196      return "invalid key";
197    case TD_NOMSG:
198      return "no event message for getmsg";
199    case TD_NOFPREGS:
200      return "FPU register set not available";
201    case TD_NOLIBTHREAD:
202      return "application not linked with libthread";
203    case TD_NOEVENT:
204      return "requested event is not supported";
205    case TD_NOCAPAB:
206      return "capability not available";
207    case TD_DBERR:
208      return "debugger service failed";
209    case TD_NOAPLIC:
210      return "operation not applicable to";
211    case TD_NOTSD:
212      return "no thread-specific data for this thread";
213    case TD_MALLOC:
214      return "malloc failed";
215    case TD_PARTIALREG:
216      return "only part of register set was written/read";
217    case TD_NOXREGS:
218      return "X register set not available for this thread";
219    default:
220      snprintf (buf, sizeof (buf), "unknown thread_db error '%d'", err);
221      return buf;
222    }
223}
224
225static char *
226thread_db_state_str (td_thr_state_e state)
227{
228  static char buf[64];
229
230  switch (state)
231    {
232    case TD_THR_STOPPED:
233      return "stopped by debugger";
234    case TD_THR_RUN:
235      return "runnable";
236    case TD_THR_ACTIVE:
237      return "active";
238    case TD_THR_ZOMBIE:
239      return "zombie";
240    case TD_THR_SLEEP:
241      return "sleeping";
242    case TD_THR_STOPPED_ASLEEP:
243      return "stopped by debugger AND blocked";
244    default:
245      snprintf (buf, sizeof (buf), "unknown thread_db state %d", state);
246      return buf;
247    }
248}
249
250/* Convert LWP to user-level thread id. */
251static ptid_t
252thread_from_lwp (ptid_t ptid, td_thrhandle_t *th, td_thrinfo_t *ti)
253{
254  td_err_e err;
255
256  gdb_assert (IS_LWP (ptid));
257
258  if (fbsd_thread_active)
259    {
260      err = td_ta_map_lwp2thr_p (thread_agent, GET_LWP (ptid), th);
261      if (err == TD_OK)
262        {
263          err = td_thr_get_info_p (th, ti);
264          if (err != TD_OK)
265            error ("Cannot get thread info: %s", thread_db_err_str (err));
266          return BUILD_THREAD (ti->ti_tid, GET_PID (ptid));
267        }
268    }
269
270  /* the LWP is not mapped to user thread */
271  return BUILD_LWP (GET_LWP (ptid), GET_PID (ptid));
272}
273
274static void
275fbsd_core_get_first_lwp (bfd *abfd, asection *asect, void *obj)
276{
277  if (strncmp (bfd_section_name (abfd, asect), ".reg/", 5) != 0)
278    return;
279
280  if (*(lwpid_t *)obj != 0)
281    return;
282
283  *(lwpid_t *)obj = atoi (bfd_section_name (abfd, asect) + 5);
284}
285
286static long
287get_current_lwp (int pid)
288{
289  struct ptrace_lwpinfo pl;
290  lwpid_t lwpid;
291
292  if (!target_has_execution)
293    {
294      lwpid = 0;
295      bfd_map_over_sections (core_bfd, fbsd_core_get_first_lwp, &lwpid);
296      return lwpid;
297    }
298  if (ptrace (PT_LWPINFO, pid, (caddr_t)&pl, sizeof(pl)))
299    perror_with_name("PT_LWPINFO");
300
301  return (long)pl.pl_lwpid;
302}
303
304static void
305get_current_thread ()
306{
307  td_thrhandle_t th;
308  td_thrinfo_t ti;
309  long lwp;
310  ptid_t tmp, ptid;
311
312  lwp = get_current_lwp (proc_handle.pid);
313  tmp = BUILD_LWP (lwp, proc_handle.pid);
314  ptid = thread_from_lwp (tmp, &th, &ti);
315  if (!in_thread_list (ptid))
316    {
317      attach_thread (ptid, &th, &ti, 1);
318    }
319  inferior_ptid = ptid;
320}
321
322static td_err_e
323enable_thread_event (td_thragent_t *thread_agent, int event, CORE_ADDR *bp)
324{
325  td_notify_t notify;
326  td_err_e err;
327
328  /* Get the breakpoint address for thread EVENT.  */
329  err = td_ta_event_addr_p (thread_agent, event, &notify);
330  if (err != TD_OK)
331    return err;
332
333  /* Set up the breakpoint.  */
334  (*bp) = gdbarch_convert_from_func_ptr_addr (current_gdbarch,
335            extract_typed_address(&notify.u.bptaddr, builtin_type_void_func_ptr),
336            &current_target);
337  create_thread_event_breakpoint ((*bp));
338
339  return TD_OK;
340}
341
342static void
343enable_thread_event_reporting (void)
344{
345  td_thr_events_t events;
346  td_notify_t notify;
347  td_err_e err;
348
349  /* We cannot use the thread event reporting facility if these
350     functions aren't available.  */
351  if (td_ta_event_addr_p == NULL || td_ta_set_event_p == NULL
352      || td_ta_event_getmsg_p == NULL || td_thr_event_enable_p == NULL)
353    return;
354
355  /* Set the process wide mask saying which events we're interested in.  */
356  td_event_emptyset (&events);
357  td_event_addset (&events, TD_CREATE);
358  td_event_addset (&events, TD_DEATH);
359
360  err = td_ta_set_event_p (thread_agent, &events);
361  if (err != TD_OK)
362    {
363      warning ("Unable to set global thread event mask: %s",
364	       thread_db_err_str (err));
365      return;
366    }
367
368  /* Delete previous thread event breakpoints, if any.  */
369  remove_thread_event_breakpoints ();
370  td_create_bp_addr = 0;
371  td_death_bp_addr = 0;
372
373  /* Set up the thread creation event.  */
374  err = enable_thread_event (thread_agent, TD_CREATE, &td_create_bp_addr);
375  if (err != TD_OK)
376    {
377      warning ("Unable to get location for thread creation breakpoint: %s",
378	       thread_db_err_str (err));
379      return;
380    }
381
382  /* Set up the thread death event.  */
383  err = enable_thread_event (thread_agent, TD_DEATH, &td_death_bp_addr);
384  if (err != TD_OK)
385    {
386      warning ("Unable to get location for thread death breakpoint: %s",
387	       thread_db_err_str (err));
388      return;
389    }
390}
391
392static void
393disable_thread_event_reporting (void)
394{
395  td_thr_events_t events;
396
397  /* Set the process wide mask saying we aren't interested in any
398     events anymore.  */
399  td_event_emptyset (&events);
400  td_ta_set_event_p (thread_agent, &events);
401
402  /* Delete thread event breakpoints, if any.  */
403  remove_thread_event_breakpoints ();
404  td_create_bp_addr = 0;
405  td_death_bp_addr = 0;
406}
407
408static void
409fbsd_thread_activate (void)
410{
411  fbsd_thread_active = 1;
412  init_thread_list();
413  if (fbsd_thread_core == 0)
414    enable_thread_event_reporting ();
415  fbsd_thread_find_new_threads ();
416  get_current_thread ();
417}
418
419static void
420fbsd_thread_deactivate (void)
421{
422  if (fbsd_thread_core == 0)
423    disable_thread_event_reporting();
424  td_ta_delete_p (thread_agent);
425
426  inferior_ptid = pid_to_ptid (proc_handle.pid);
427  proc_handle.pid = 0;
428  fbsd_thread_active = 0;
429  fbsd_thread_present = 0;
430  init_thread_list ();
431}
432
433static char *
434fbsd_thread_get_name (lwpid_t lwpid)
435{
436  static char last_thr_name[MAXCOMLEN + 1];
437  char section_name[32];
438  struct ptrace_lwpinfo lwpinfo;
439  bfd_size_type size;
440  struct bfd_section *section;
441
442  if (target_has_execution)
443    {
444      if (ptrace (PT_LWPINFO, lwpid, (caddr_t)&lwpinfo, sizeof (lwpinfo)) == -1)
445        goto fail;
446      strncpy (last_thr_name, lwpinfo.pl_tdname, sizeof (last_thr_name) - 1);
447    }
448  else
449    {
450      snprintf (section_name, sizeof (section_name), ".tname/%u", lwpid);
451      section = bfd_get_section_by_name (core_bfd, section_name);
452      if (! section)
453        goto fail;
454
455      /* Section size fix-up. */
456      size = bfd_section_size (core_bfd, section);
457      if (size > sizeof (last_thr_name))
458        size = sizeof (last_thr_name);
459
460      if (! bfd_get_section_contents (core_bfd, section, last_thr_name,
461	       (file_ptr)0, size))
462        goto fail;
463      if (last_thr_name[0] == '\0')
464        goto fail;
465    }
466    last_thr_name[sizeof (last_thr_name) - 1] = '\0';
467    return last_thr_name;
468fail:
469     strcpy (last_thr_name, "<unknown>");
470     return last_thr_name;
471}
472
473static void
474fbsd_thread_new_objfile (struct objfile *objfile)
475{
476  td_err_e err;
477
478  if (objfile == NULL)
479    {
480      /* All symbols have been discarded.  If the thread_db target is
481         active, deactivate it now.  */
482      if (fbsd_thread_active)
483        {
484          gdb_assert (proc_handle.pid == 0);
485          fbsd_thread_active = 0;
486        }
487
488      goto quit;
489    }
490
491  if (!child_suppress_run)
492    goto quit;
493
494  /* Nothing to do.  The thread library was already detected and the
495     target vector was already activated.  */
496  if (fbsd_thread_active)
497    goto quit;
498
499  /* Initialize the structure that identifies the child process.  Note
500     that at this point there is no guarantee that we actually have a
501     child process.  */
502  proc_handle.pid = GET_PID (inferior_ptid);
503
504  /* Now attempt to open a connection to the thread library.  */
505  err = td_ta_new_p (&proc_handle, &thread_agent);
506  switch (err)
507    {
508    case TD_NOLIBTHREAD:
509      /* No thread library was detected.  */
510      break;
511
512    case TD_OK:
513      /* The thread library was detected.  Activate the thread_db target.  */
514      fbsd_thread_present = 1;
515
516      /* We can only poke around if there actually is a child process.
517         If there is no child process alive, postpone the steps below
518         until one has been created.  */
519      if (fbsd_thread_core == 0 && proc_handle.pid != 0)
520        {
521          push_target(&fbsd_thread_ops);
522          fbsd_thread_activate();
523        }
524      else
525        {
526          td_ta_delete_p(thread_agent);
527          thread_agent = NULL;
528        }
529      break;
530
531    default:
532      warning ("Cannot initialize thread debugging library: %s",
533               thread_db_err_str (err));
534      break;
535    }
536
537 quit:
538  if (target_new_objfile_chain)
539    target_new_objfile_chain (objfile);
540}
541
542static void
543fbsd_thread_attach (char *args, int from_tty)
544{
545  fbsd_thread_core = 0;
546
547  child_ops.to_attach (args, from_tty);
548
549  /* Must get symbols from solibs before libthread_db can run! */
550  SOLIB_ADD ((char *) 0, from_tty, (struct target_ops *) 0, auto_solib_add);
551
552  if (fbsd_thread_present && !fbsd_thread_active)
553    push_target(&fbsd_thread_ops);
554}
555
556static void
557fbsd_thread_post_attach (int pid)
558{
559  child_ops.to_post_attach (pid);
560
561  if (fbsd_thread_present && !fbsd_thread_active)
562    {
563      proc_handle.pid = GET_PID (inferior_ptid);
564      fbsd_thread_activate ();
565    }
566}
567
568static void
569fbsd_thread_detach (char *args, int from_tty)
570{
571  fbsd_thread_deactivate ();
572  unpush_target (&fbsd_thread_ops);
573
574  /* Clear gdb solib information and symbol file
575     cache, so that after detach and re-attach, new_objfile
576     hook will be called */
577
578  clear_solib();
579  symbol_file_clear(0);
580  proc_handle.pid = 0;
581  child_ops.to_detach (args, from_tty);
582}
583
584static int
585suspend_thread_callback (const td_thrhandle_t *th_p, void *data)
586{
587  int err = td_thr_dbsuspend_p (th_p);
588  if (err != 0)
589	fprintf_filtered(gdb_stderr, "%s %s\n", __func__, thread_db_err_str (err));
590  return (err);
591}
592
593static int
594resume_thread_callback (const td_thrhandle_t *th_p, void *data)
595{
596  int err = td_thr_dbresume_p (th_p);
597  if (err != 0)
598	fprintf_filtered(gdb_stderr, "%s %s\n", __func__, thread_db_err_str (err));
599  return (err);
600}
601
602static void
603fbsd_thread_resume (ptid_t ptid, int step, enum target_signal signo)
604{
605  td_thrhandle_t th;
606  td_thrinfo_t ti;
607  ptid_t work_ptid;
608  int resume_all, ret;
609  long lwp, thvalid = 0;
610
611  if (!fbsd_thread_active)
612    {
613      child_ops.to_resume (ptid, step, signo);
614      return;
615    }
616
617  if (GET_PID(ptid) != -1 && step != 0)
618    {
619      resume_all = 0;
620      work_ptid = ptid;
621    }
622  else
623    {
624      resume_all = 1;
625      work_ptid = inferior_ptid;
626    }
627
628  lwp = GET_LWP (work_ptid);
629  if (lwp == 0)
630    {
631      /* check user thread */
632      ret = td_ta_map_id2thr_p (thread_agent, GET_THREAD(work_ptid), &th);
633      if (ret)
634        error (thread_db_err_str (ret));
635
636      /* For M:N thread, we need to tell UTS to set/unset single step
637         flag at context switch time, the flag will be written into
638         thread mailbox. This becauses some architecture may not have
639         machine single step flag in ucontext, so we put the flag in mailbox,
640         when the thread switches back, kse_switchin restores the single step
641         state.  */
642      ret = td_thr_sstep_p (&th, step);
643      if (ret)
644        error (thread_db_err_str (ret));
645      ret = td_thr_get_info_p (&th, &ti);
646      if (ret)
647        error (thread_db_err_str (ret));
648      thvalid = 1;
649      lwp = ti.ti_lid;
650    }
651
652  if (lwp)
653    {
654      int req = step ? PT_SETSTEP : PT_CLEARSTEP;
655      if (ptrace (req, (pid_t) lwp, (caddr_t) 1, target_signal_to_host(signo)))
656        perror_with_name ("PT_SETSTEP/PT_CLEARSTEP");
657    }
658
659  if (!ptid_equal (last_single_step_thread, null_ptid))
660    {
661       ret = td_ta_thr_iter_p (thread_agent, resume_thread_callback, NULL,
662          TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
663          TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
664      if (ret != TD_OK)
665        error ("resume error: %s", thread_db_err_str (ret));
666    }
667
668  if (!resume_all)
669    {
670      ret = td_ta_thr_iter_p (thread_agent, suspend_thread_callback, NULL,
671          TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
672          TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
673      if (ret != TD_OK)
674        error ("suspend error: %s", thread_db_err_str (ret));
675      last_single_step_thread = work_ptid;
676    }
677  else
678    last_single_step_thread = null_ptid;
679
680  if (thvalid)
681    {
682      ret = td_thr_dbresume_p (&th);
683      if (ret != TD_OK)
684        error ("resume error: %s", thread_db_err_str (ret));
685    }
686  else
687    {
688      /* it is not necessary, put it here for completness */
689      ret = ptrace(PT_RESUME, lwp, 0, 0);
690    }
691
692  /* now continue the process, suspended thread wont run */
693  if (ptrace (PT_CONTINUE, proc_handle.pid , (caddr_t)1,
694	      target_signal_to_host(signo)))
695    perror_with_name ("PT_CONTINUE");
696}
697
698static void
699attach_thread (ptid_t ptid, const td_thrhandle_t *th_p,
700               const td_thrinfo_t *ti_p, int verbose)
701{
702  td_err_e err;
703
704  /* Add the thread to GDB's thread list.  */
705  if (!in_thread_list (ptid)) {
706    add_thread (ptid);
707    if (verbose)
708      printf_unfiltered ("[New %s]\n", target_pid_to_str (ptid));
709  }
710
711  if (ti_p->ti_state == TD_THR_UNKNOWN || ti_p->ti_state == TD_THR_ZOMBIE)
712    return;                     /* A zombie thread -- do not attach.  */
713
714  if (! IS_THREAD(ptid))
715    return;
716  if (fbsd_thread_core != 0)
717    return;
718  /* Enable thread event reporting for this thread. */
719  err = td_thr_event_enable_p (th_p, 1);
720  if (err != TD_OK)
721    error ("Cannot enable thread event reporting for %s: %s",
722           target_pid_to_str (ptid), thread_db_err_str (err));
723}
724
725static void
726detach_thread (ptid_t ptid, int verbose)
727{
728  if (verbose)
729    printf_unfiltered ("[%s exited]\n", target_pid_to_str (ptid));
730}
731
732static void
733check_event (ptid_t ptid)
734{
735  td_event_msg_t msg;
736  td_thrinfo_t ti;
737  td_err_e err;
738  CORE_ADDR stop_pc;
739  int loop = 0;
740
741  /* Bail out early if we're not at a thread event breakpoint.  */
742  stop_pc = read_pc_pid (ptid) - DECR_PC_AFTER_BREAK;
743  if (stop_pc != td_create_bp_addr && stop_pc != td_death_bp_addr)
744    return;
745  loop = 1;
746
747  do
748    {
749      err = td_ta_event_getmsg_p (thread_agent, &msg);
750      if (err != TD_OK)
751        {
752	  if (err == TD_NOMSG)
753	    return;
754          error ("Cannot get thread event message: %s",
755		 thread_db_err_str (err));
756        }
757      err = td_thr_get_info_p ((void *)(uintptr_t)msg.th_p, &ti);
758      if (err != TD_OK)
759        error ("Cannot get thread info: %s", thread_db_err_str (err));
760      ptid = BUILD_THREAD (ti.ti_tid, GET_PID (ptid));
761      switch (msg.event)
762        {
763        case TD_CREATE:
764          /* We may already know about this thread, for instance when the
765             user has issued the `info threads' command before the SIGTRAP
766             for hitting the thread creation breakpoint was reported.  */
767          attach_thread (ptid, (void *)(uintptr_t)msg.th_p, &ti, 1);
768          break;
769       case TD_DEATH:
770         if (!in_thread_list (ptid))
771           error ("Spurious thread death event.");
772         detach_thread (ptid, 1);
773         break;
774       default:
775          error ("Spurious thread event.");
776       }
777    }
778  while (loop);
779}
780
781static ptid_t
782fbsd_thread_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
783{
784  ptid_t ret;
785  long lwp;
786  CORE_ADDR stop_pc;
787  td_thrhandle_t th;
788  td_thrinfo_t ti;
789
790  ret = child_ops.to_wait (ptid, ourstatus);
791  if (GET_PID(ret) >= 0 && ourstatus->kind == TARGET_WAITKIND_STOPPED)
792    {
793      lwp = get_current_lwp (GET_PID(ret));
794      ret = thread_from_lwp (BUILD_LWP(lwp, GET_PID(ret)),
795         &th, &ti);
796      if (!in_thread_list(ret)) {
797        /*
798         * We have to enable event reporting for initial thread
799         * which was not mapped before.
800	 */
801        attach_thread(ret, &th, &ti, 1);
802      }
803      if (ourstatus->value.sig == TARGET_SIGNAL_TRAP)
804        check_event(ret);
805      /* this is a hack, if an event won't cause gdb to stop, for example,
806         SIGARLM, gdb resumes the process immediatly without setting
807         inferior_ptid to the new thread returned here, this is a bug
808         because inferior_ptid may already not exist there, and passing
809         a none existing thread to fbsd_thread_resume causes error. */
810      if (!fbsd_thread_alive (inferior_ptid))
811        {
812          delete_thread (inferior_ptid);
813          inferior_ptid = ret;
814        }
815    }
816
817  return (ret);
818}
819
820static int
821fbsd_thread_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
822                        struct mem_attrib *attrib, struct target_ops *target)
823{
824  int err;
825
826  if (target_has_execution)
827    err = child_ops.to_xfer_memory (memaddr, myaddr, len, write, attrib,
828	target);
829  else
830    err = orig_core_ops.to_xfer_memory (memaddr, myaddr, len, write, attrib,
831	target);
832
833  return (err);
834}
835
836static void
837fbsd_lwp_fetch_registers (int regno)
838{
839  gregset_t gregs;
840  fpregset_t fpregs;
841  lwpid_t lwp;
842#ifdef PT_GETXMMREGS
843  char xmmregs[512];
844#endif
845
846  if (!target_has_execution)
847    {
848      orig_core_ops.to_fetch_registers (-1);
849      return;
850    }
851
852  /* XXX: We've replaced the pid with the lwpid for GDB's benefit. */
853  lwp = GET_PID (inferior_ptid);
854
855  if (ptrace (PT_GETREGS, lwp, (caddr_t) &gregs, 0) == -1)
856    error ("Cannot get lwp %d registers: %s\n", lwp, safe_strerror (errno));
857  supply_gregset (&gregs);
858
859#ifdef PT_GETXMMREGS
860  if (ptrace (PT_GETXMMREGS, lwp, xmmregs, 0) == 0)
861    {
862      i387_supply_fxsave (current_regcache, -1, xmmregs);
863    }
864  else
865    {
866#endif
867      if (ptrace (PT_GETFPREGS, lwp, (caddr_t) &fpregs, 0) == -1)
868	error ("Cannot get lwp %d registers: %s\n ", lwp, safe_strerror (errno));
869      supply_fpregset (&fpregs);
870#ifdef PT_GETXMMREGS
871    }
872#endif
873}
874
875static void
876fbsd_thread_fetch_registers (int regno)
877{
878  prgregset_t gregset;
879  prfpregset_t fpregset;
880  td_thrhandle_t th;
881  td_err_e err;
882#ifdef PT_GETXMMREGS
883  char xmmregs[512];
884#endif
885
886  if (!IS_THREAD (inferior_ptid))
887    {
888      fbsd_lwp_fetch_registers (regno);
889      return;
890    }
891
892  err = td_ta_map_id2thr_p (thread_agent, GET_THREAD (inferior_ptid), &th);
893  if (err != TD_OK)
894    error ("Cannot find thread %d: Thread ID=%ld, %s",
895           pid_to_thread_id (inferior_ptid),
896           GET_THREAD (inferior_ptid), thread_db_err_str (err));
897
898  err = td_thr_getgregs_p (&th, gregset);
899  if (err != TD_OK)
900    error ("Cannot fetch general-purpose registers for thread %d: Thread ID=%ld, %s",
901           pid_to_thread_id (inferior_ptid),
902           GET_THREAD (inferior_ptid), thread_db_err_str (err));
903#ifdef PT_GETXMMREGS
904  err = td_thr_getxmmregs_p (&th, xmmregs);
905  if (err == TD_OK)
906    {
907      i387_supply_fxsave (current_regcache, -1, xmmregs);
908    }
909  else
910    {
911#endif
912      err = td_thr_getfpregs_p (&th, &fpregset);
913      if (err != TD_OK)
914	error ("Cannot get floating-point registers for thread %d: Thread ID=%ld, %s",
915	       pid_to_thread_id (inferior_ptid),
916	       GET_THREAD (inferior_ptid), thread_db_err_str (err));
917      supply_fpregset (&fpregset);
918#ifdef PT_GETXMMREGS
919    }
920#endif
921
922  supply_gregset (gregset);
923}
924
925static void
926fbsd_lwp_store_registers (int regno)
927{
928  gregset_t gregs;
929  fpregset_t fpregs;
930  lwpid_t lwp;
931#ifdef PT_GETXMMREGS
932  char xmmregs[512];
933#endif
934
935  /* FIXME, is it possible ? */
936  if (!IS_LWP (inferior_ptid))
937    {
938      child_ops.to_store_registers (regno);
939      return ;
940    }
941
942  lwp = GET_LWP (inferior_ptid);
943  if (regno != -1)
944    if (ptrace (PT_GETREGS, lwp, (caddr_t) &gregs, 0) == -1)
945      error ("Cannot get lwp %d registers: %s\n", lwp, safe_strerror (errno));
946
947  fill_gregset (&gregs, regno);
948  if (ptrace (PT_SETREGS, lwp, (caddr_t) &gregs, 0) == -1)
949      error ("Cannot set lwp %d registers: %s\n", lwp, safe_strerror (errno));
950
951#ifdef PT_GETXMMREGS
952  if (regno != -1)
953    if (ptrace (PT_GETXMMREGS, lwp, xmmregs, 0) == -1)
954      goto noxmm;
955
956  i387_fill_fxsave (xmmregs, regno);
957  if (ptrace (PT_SETXMMREGS, lwp, xmmregs, 0) == -1)
958    goto noxmm;
959
960  return;
961
962noxmm:
963#endif
964
965  if (regno != -1)
966    if (ptrace (PT_GETFPREGS, lwp, (caddr_t) &fpregs, 0) == -1)
967      error ("Cannot get lwp %d float registers: %s\n", lwp,
968             safe_strerror (errno));
969
970  fill_fpregset (&fpregs, regno);
971  if (ptrace (PT_SETFPREGS, lwp, (caddr_t) &fpregs, 0) == -1)
972     error ("Cannot set lwp %d float registers: %s\n", lwp,
973            safe_strerror (errno));
974}
975
976static void
977fbsd_thread_store_registers (int regno)
978{
979  prgregset_t gregset;
980  prfpregset_t fpregset;
981  td_thrhandle_t th;
982  td_err_e err;
983#ifdef PT_GETXMMREGS
984  char xmmregs[512];
985#endif
986
987  if (!IS_THREAD (inferior_ptid))
988    {
989      fbsd_lwp_store_registers (regno);
990      return;
991    }
992
993  err = td_ta_map_id2thr_p (thread_agent, GET_THREAD (inferior_ptid), &th);
994  if (err != TD_OK)
995    error ("Cannot find thread %d: Thread ID=%ld, %s",
996           pid_to_thread_id (inferior_ptid),
997           GET_THREAD (inferior_ptid),
998           thread_db_err_str (err));
999
1000  if (regno != -1)
1001    {
1002      char old_value[MAX_REGISTER_SIZE];
1003
1004      regcache_collect (regno, old_value);
1005      err = td_thr_getgregs_p (&th, gregset);
1006      if (err != TD_OK)
1007        error ("%s: td_thr_getgregs %s", __func__, thread_db_err_str (err));
1008#ifdef PT_GETXMMREGS
1009      err = td_thr_getxmmregs_p (&th, xmmregs);
1010      if (err != TD_OK)
1011        {
1012#endif
1013          err = td_thr_getfpregs_p (&th, &fpregset);
1014          if (err != TD_OK)
1015            error ("%s: td_thr_getfpgregs %s", __func__, thread_db_err_str (err));
1016#ifdef PT_GETXMMREGS
1017        }
1018#endif
1019      supply_register (regno, old_value);
1020    }
1021
1022  fill_gregset (gregset, regno);
1023  err = td_thr_setgregs_p (&th, gregset);
1024  if (err != TD_OK)
1025    error ("Cannot store general-purpose registers for thread %d: Thread ID=%d, %s",
1026           pid_to_thread_id (inferior_ptid), GET_THREAD (inferior_ptid),
1027           thread_db_err_str (err));
1028
1029#ifdef PT_GETXMMREGS
1030  i387_fill_fxsave (xmmregs, regno);
1031  err = td_thr_setxmmregs_p (&th, xmmregs);
1032  if (err == TD_OK)
1033    return;
1034#endif
1035
1036  fill_fpregset (&fpregset, regno);
1037  err = td_thr_setfpregs_p (&th, &fpregset);
1038  if (err != TD_OK)
1039    error ("Cannot store floating-point registers for thread %d: Thread ID=%d, %s",
1040           pid_to_thread_id (inferior_ptid), GET_THREAD (inferior_ptid),
1041           thread_db_err_str (err));
1042}
1043
1044static void
1045fbsd_thread_kill (void)
1046{
1047  child_ops.to_kill();
1048}
1049
1050static int
1051fbsd_thread_can_run (void)
1052{
1053  return child_suppress_run;
1054}
1055
1056static void
1057fbsd_thread_create_inferior (char *exec_file, char *allargs, char **env)
1058{
1059  if (fbsd_thread_present && !fbsd_thread_active)
1060    push_target(&fbsd_thread_ops);
1061
1062  child_ops.to_create_inferior (exec_file, allargs, env);
1063}
1064
1065static void
1066fbsd_thread_post_startup_inferior (ptid_t ptid)
1067{
1068  if (fbsd_thread_present && !fbsd_thread_active)
1069    {
1070      /* The child process is now the actual multi-threaded
1071         program.  Snatch its process ID... */
1072      proc_handle.pid = GET_PID (ptid);
1073      td_ta_new_p (&proc_handle, &thread_agent);
1074      fbsd_thread_activate();
1075    }
1076}
1077
1078static void
1079fbsd_thread_mourn_inferior (void)
1080{
1081  if (fbsd_thread_active)
1082    fbsd_thread_deactivate ();
1083
1084  unpush_target (&fbsd_thread_ops);
1085
1086  child_ops.to_mourn_inferior ();
1087}
1088
1089static void
1090fbsd_core_check_lwp (bfd *abfd, asection *asect, void *obj)
1091{
1092  lwpid_t lwp;
1093
1094  if (strncmp (bfd_section_name (abfd, asect), ".reg/", 5) != 0)
1095    return;
1096
1097  /* already found */
1098  if (*(lwpid_t *)obj == 0)
1099    return;
1100
1101  lwp = atoi (bfd_section_name (abfd, asect) + 5);
1102  if (*(lwpid_t *)obj == lwp)
1103    *(lwpid_t *)obj = 0;
1104}
1105
1106static int
1107fbsd_thread_alive (ptid_t ptid)
1108{
1109  td_thrhandle_t th;
1110  td_thrinfo_t ti;
1111  td_err_e err;
1112  gregset_t gregs;
1113  lwpid_t lwp;
1114
1115  if (IS_THREAD (ptid))
1116    {
1117      err = td_ta_map_id2thr_p (thread_agent, GET_THREAD (ptid), &th);
1118      if (err != TD_OK)
1119        return 0;
1120
1121      err = td_thr_get_info_p (&th, &ti);
1122      if (err != TD_OK)
1123        return 0;
1124
1125      /* A zombie thread. */
1126      if (ti.ti_state == TD_THR_UNKNOWN || ti.ti_state == TD_THR_ZOMBIE)
1127        return 0;
1128
1129      return 1;
1130    }
1131  else if (GET_LWP (ptid) == 0)
1132    {
1133      /* we sometimes are called with lwp == 0 */
1134      return 1;
1135    }
1136
1137  if (fbsd_thread_active)
1138    {
1139      err = td_ta_map_lwp2thr_p (thread_agent, GET_LWP (ptid), &th);
1140
1141      /*
1142       * if the lwp was already mapped to user thread, don't use it
1143       * directly, please use user thread id instead.
1144       */
1145      if (err == TD_OK)
1146        return 0;
1147    }
1148
1149  if (!target_has_execution)
1150    {
1151      lwp = GET_LWP (ptid);
1152      bfd_map_over_sections (core_bfd, fbsd_core_check_lwp, &lwp);
1153      return (lwp == 0);
1154    }
1155
1156  /* check lwp in kernel */
1157  return ptrace (PT_GETREGS, GET_LWP (ptid), (caddr_t)&gregs, 0) == 0;
1158}
1159
1160static void
1161fbsd_thread_files_info (struct target_ops *ignore)
1162{
1163  child_ops.to_files_info (ignore);
1164}
1165
1166static int
1167find_new_threads_callback (const td_thrhandle_t *th_p, void *data)
1168{
1169  td_thrinfo_t ti;
1170  td_err_e err;
1171  ptid_t ptid;
1172
1173  err = td_thr_get_info_p (th_p, &ti);
1174  if (err != TD_OK)
1175    error ("Cannot get thread info: %s", thread_db_err_str (err));
1176
1177  /* Ignore zombie */
1178  if (ti.ti_state == TD_THR_UNKNOWN || ti.ti_state == TD_THR_ZOMBIE)
1179    return 0;
1180
1181  ptid = BUILD_THREAD (ti.ti_tid, proc_handle.pid);
1182  attach_thread (ptid, th_p, &ti, 1);
1183  return 0;
1184}
1185
1186static void
1187fbsd_thread_find_new_threads (void)
1188{
1189  td_err_e err;
1190
1191  if (!fbsd_thread_active)
1192    return;
1193
1194  /* Iterate over all user-space threads to discover new threads. */
1195  err = td_ta_thr_iter_p (thread_agent, find_new_threads_callback, NULL,
1196          TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
1197          TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
1198  if (err != TD_OK)
1199    error ("Cannot find new threads: %s", thread_db_err_str (err));
1200}
1201
1202static char *
1203fbsd_thread_pid_to_str (ptid_t ptid)
1204{
1205  static char buf[64 + MAXCOMLEN];
1206
1207  if (IS_THREAD (ptid))
1208    {
1209      td_thrhandle_t th;
1210      td_thrinfo_t ti;
1211      td_err_e err;
1212
1213      err = td_ta_map_id2thr_p (thread_agent, GET_THREAD (ptid), &th);
1214      if (err != TD_OK)
1215        error ("Cannot find thread, Thread ID=%ld, %s",
1216                GET_THREAD (ptid), thread_db_err_str (err));
1217
1218      err = td_thr_get_info_p (&th, &ti);
1219      if (err != TD_OK)
1220        error ("Cannot get thread info, Thread ID=%ld, %s",
1221               GET_THREAD (ptid), thread_db_err_str (err));
1222
1223      if (ti.ti_lid != 0)
1224        {
1225          snprintf (buf, sizeof (buf), "Thread %llx (LWP %d/%s)",
1226                    (unsigned long long)th.th_thread, ti.ti_lid,
1227                    fbsd_thread_get_name (ti.ti_lid));
1228        }
1229      else
1230        {
1231          snprintf (buf, sizeof (buf), "Thread %llx (%s)",
1232		    (unsigned long long)th.th_thread,
1233		    thread_db_state_str (ti.ti_state));
1234        }
1235
1236      return buf;
1237    }
1238  else if (IS_LWP (ptid))
1239    {
1240      snprintf (buf, sizeof (buf), "LWP %d", (int) GET_LWP (ptid));
1241      return buf;
1242    }
1243  return normal_pid_to_str (ptid);
1244}
1245
1246CORE_ADDR
1247fbsd_thread_get_local_address(ptid_t ptid, struct objfile *objfile,
1248                              CORE_ADDR offset)
1249{
1250  td_thrhandle_t th;
1251  void *address;
1252  CORE_ADDR lm;
1253  void *lm2;
1254  int ret, is_library = (objfile->flags & OBJF_SHARED);
1255
1256  if (IS_THREAD (ptid))
1257    {
1258      if (!td_thr_tls_get_addr_p)
1259        error ("Cannot find thread-local interface in thread_db library.");
1260
1261      /* Get the address of the link map for this objfile. */
1262      lm = svr4_fetch_objfile_link_map (objfile);
1263
1264      /* Couldn't find link map. Bail out. */
1265      if (!lm)
1266        {
1267          if (is_library)
1268            error ("Cannot find shared library `%s' link_map in dynamic"
1269                   " linker's module list", objfile->name);
1270          else
1271            error ("Cannot find executable file `%s' link_map in dynamic"
1272                   " linker's module list", objfile->name);
1273        }
1274
1275      ret = td_ta_map_id2thr_p (thread_agent, GET_THREAD(ptid), &th);
1276
1277      /* get the address of the variable. */
1278      store_typed_address(&lm2, builtin_type_void_data_ptr, lm);
1279      ret = td_thr_tls_get_addr_p (&th, lm2, offset, &address);
1280
1281      if (ret != TD_OK)
1282        {
1283          if (is_library)
1284            error ("Cannot find thread-local storage for thread %ld, "
1285                   "shared library %s:\n%s",
1286                   (long) GET_THREAD (ptid),
1287                   objfile->name, thread_db_err_str (ret));
1288          else
1289            error ("Cannot find thread-local storage for thread %ld, "
1290                   "executable file %s:\n%s",
1291                   (long) GET_THREAD (ptid),
1292                   objfile->name, thread_db_err_str (ret));
1293        }
1294
1295      /* Cast assuming host == target. */
1296      return extract_typed_address(&address, builtin_type_void_data_ptr);
1297    }
1298  return (0);
1299}
1300
1301static int
1302tsd_cb (thread_key_t key, void (*destructor)(void *), void *ignore)
1303{
1304  struct minimal_symbol *ms;
1305  char *name;
1306
1307  ms = lookup_minimal_symbol_by_pc (
1308	extract_typed_address(&destructor, builtin_type_void_func_ptr));
1309  if (!ms)
1310    name = "???";
1311  else
1312    name = DEPRECATED_SYMBOL_NAME (ms);
1313
1314  printf_filtered ("Key %d, destructor %p <%s>\n", key, destructor, name);
1315  return 0;
1316}
1317
1318static void
1319fbsd_thread_tsd_cmd (char *exp, int from_tty)
1320{
1321  if (fbsd_thread_active)
1322    td_ta_tsd_iter_p (thread_agent, tsd_cb, NULL);
1323}
1324
1325static void
1326fbsd_print_sigset (sigset_t *set)
1327{
1328  int i;
1329
1330  for (i = 1; i <= _SIG_MAXSIG; ++i) {
1331     if (sigismember(set, i)) {
1332       if (i < sizeof(sys_signame)/sizeof(sys_signame[0]))
1333         printf_filtered("%s ", sys_signame[i]);
1334       else
1335         printf_filtered("sig%d ", i);
1336     }
1337  }
1338  printf_filtered("\n");
1339}
1340
1341static void
1342fbsd_thread_signal_cmd (char *exp, int from_tty)
1343{
1344  td_thrhandle_t th;
1345  td_thrinfo_t ti;
1346  td_err_e err;
1347  const char *code;
1348
1349  if (!fbsd_thread_active || !IS_THREAD(inferior_ptid))
1350    return;
1351
1352  err = td_ta_map_id2thr_p (thread_agent, GET_THREAD (inferior_ptid), &th);
1353  if (err != TD_OK)
1354    return;
1355
1356  err = td_thr_get_info_p (&th, &ti);
1357  if (err != TD_OK)
1358    return;
1359
1360  printf_filtered("signal mask:\n");
1361  fbsd_print_sigset(&ti.ti_sigmask);
1362  printf_filtered("signal pending:\n");
1363  fbsd_print_sigset(&ti.ti_pending);
1364  if (ti.ti_siginfo.si_signo != 0) {
1365   printf_filtered("si_signo %d si_errno %d", ti.ti_siginfo.si_signo,
1366     ti.ti_siginfo.si_errno);
1367   if (ti.ti_siginfo.si_errno != 0)
1368    printf_filtered(" (%s)", strerror(ti.ti_siginfo.si_errno));
1369   printf_filtered("\n");
1370   switch (ti.ti_siginfo.si_code) {
1371   case SI_NOINFO:
1372	code = "NOINFO";
1373	break;
1374    case SI_USER:
1375	code = "USER";
1376	break;
1377    case SI_QUEUE:
1378	code = "QUEUE";
1379	break;
1380    case SI_TIMER:
1381	code = "TIMER";
1382	break;
1383    case SI_ASYNCIO:
1384	code = "ASYNCIO";
1385	break;
1386    case SI_MESGQ:
1387	code = "MESGQ";
1388	break;
1389    case SI_KERNEL:
1390	code = "KERNEL";
1391	break;
1392    default:
1393	code = "UNKNOWN";
1394	break;
1395    }
1396    printf_filtered("si_code %s (%d) si_pid %d si_uid %d si_status %x "
1397      "si_addr %p\n",
1398      code, ti.ti_siginfo.si_code, ti.ti_siginfo.si_pid, ti.ti_siginfo.si_uid,
1399      ti.ti_siginfo.si_status, ti.ti_siginfo.si_addr);
1400  }
1401}
1402
1403static int
1404ignore (CORE_ADDR addr, char *contents)
1405{
1406  return 0;
1407}
1408
1409static void
1410fbsd_core_open (char *filename, int from_tty)
1411{
1412  int err;
1413
1414  fbsd_thread_core = 1;
1415
1416  orig_core_ops.to_open (filename, from_tty);
1417
1418  if (fbsd_thread_present)
1419    {
1420      err = td_ta_new_p (&proc_handle, &thread_agent);
1421      if (err == TD_OK)
1422        {
1423          proc_handle.pid = elf_tdata (core_bfd)->core_pid;
1424          fbsd_thread_activate ();
1425        }
1426      else
1427        error ("fbsd_core_open: td_ta_new: %s", thread_db_err_str (err));
1428    }
1429}
1430
1431static void
1432fbsd_core_close (int quitting)
1433{
1434  orig_core_ops.to_close (quitting);
1435}
1436
1437static void
1438fbsd_core_detach (char *args, int from_tty)
1439{
1440  if (fbsd_thread_active)
1441    fbsd_thread_deactivate ();
1442  unpush_target (&fbsd_thread_ops);
1443  orig_core_ops.to_detach (args, from_tty);
1444
1445  /* Clear gdb solib information and symbol file
1446     cache, so that after detach and re-attach, new_objfile
1447     hook will be called */
1448  clear_solib();
1449  symbol_file_clear(0);
1450}
1451
1452static void
1453fbsd_core_files_info (struct target_ops *ignore)
1454{
1455  orig_core_ops.to_files_info (ignore);
1456}
1457
1458static void
1459init_fbsd_core_ops (void)
1460{
1461  fbsd_core_ops.to_shortname = "FreeBSD-core";
1462  fbsd_core_ops.to_longname = "FreeBSD multithreaded core dump file";
1463  fbsd_core_ops.to_doc =
1464    "Use a core file as a target.  Specify the filename of the core file.";
1465  fbsd_core_ops.to_open = fbsd_core_open;
1466  fbsd_core_ops.to_close = fbsd_core_close;
1467  fbsd_core_ops.to_attach = 0;
1468  fbsd_core_ops.to_post_attach = 0;
1469  fbsd_core_ops.to_detach = fbsd_core_detach;
1470  /* fbsd_core_ops.to_resume  = 0; */
1471  /* fbsd_core_ops.to_wait  = 0;  */
1472  fbsd_core_ops.to_fetch_registers = fbsd_thread_fetch_registers;
1473  /* fbsd_core_ops.to_store_registers  = 0; */
1474  /* fbsd_core_ops.to_prepare_to_store  = 0; */
1475  fbsd_core_ops.to_xfer_memory = fbsd_thread_xfer_memory;
1476  fbsd_core_ops.to_files_info = fbsd_core_files_info;
1477  fbsd_core_ops.to_insert_breakpoint = ignore;
1478  fbsd_core_ops.to_remove_breakpoint = ignore;
1479  /* fbsd_core_ops.to_lookup_symbol  = 0; */
1480  fbsd_core_ops.to_create_inferior = fbsd_thread_create_inferior;
1481  fbsd_core_ops.to_stratum = core_stratum;
1482  fbsd_core_ops.to_has_all_memory = 0;
1483  fbsd_core_ops.to_has_memory = 1;
1484  fbsd_core_ops.to_has_stack = 1;
1485  fbsd_core_ops.to_has_registers = 1;
1486  fbsd_core_ops.to_has_execution = 0;
1487  fbsd_core_ops.to_has_thread_control = tc_none;
1488  fbsd_core_ops.to_thread_alive = fbsd_thread_alive;
1489  fbsd_core_ops.to_pid_to_str = fbsd_thread_pid_to_str;
1490  fbsd_core_ops.to_find_new_threads = fbsd_thread_find_new_threads;
1491  fbsd_core_ops.to_sections = 0;
1492  fbsd_core_ops.to_sections_end = 0;
1493  fbsd_core_ops.to_magic = OPS_MAGIC;
1494}
1495
1496static void
1497init_fbsd_thread_ops (void)
1498{
1499  fbsd_thread_ops.to_shortname = "freebsd-threads";
1500  fbsd_thread_ops.to_longname = "FreeBSD multithreaded child process.";
1501  fbsd_thread_ops.to_doc = "FreeBSD threads support.";
1502  fbsd_thread_ops.to_attach = fbsd_thread_attach;
1503  fbsd_thread_ops.to_detach = fbsd_thread_detach;
1504  fbsd_thread_ops.to_post_attach = fbsd_thread_post_attach;
1505  fbsd_thread_ops.to_resume = fbsd_thread_resume;
1506  fbsd_thread_ops.to_wait = fbsd_thread_wait;
1507  fbsd_thread_ops.to_fetch_registers = fbsd_thread_fetch_registers;
1508  fbsd_thread_ops.to_store_registers = fbsd_thread_store_registers;
1509  fbsd_thread_ops.to_xfer_memory = fbsd_thread_xfer_memory;
1510  fbsd_thread_ops.to_files_info = fbsd_thread_files_info;
1511  fbsd_thread_ops.to_kill = fbsd_thread_kill;
1512  fbsd_thread_ops.to_create_inferior = fbsd_thread_create_inferior;
1513  fbsd_thread_ops.to_post_startup_inferior = fbsd_thread_post_startup_inferior;
1514  fbsd_thread_ops.to_mourn_inferior = fbsd_thread_mourn_inferior;
1515  fbsd_thread_ops.to_can_run = fbsd_thread_can_run;
1516  fbsd_thread_ops.to_thread_alive = fbsd_thread_alive;
1517  fbsd_thread_ops.to_find_new_threads = fbsd_thread_find_new_threads;
1518  fbsd_thread_ops.to_pid_to_str = fbsd_thread_pid_to_str;
1519  fbsd_thread_ops.to_stratum = thread_stratum;
1520  fbsd_thread_ops.to_has_thread_control = tc_none;
1521  fbsd_thread_ops.to_has_all_memory = 1;
1522  fbsd_thread_ops.to_has_memory = 1;
1523  fbsd_thread_ops.to_has_stack = 1;
1524  fbsd_thread_ops.to_has_registers = 1;
1525  fbsd_thread_ops.to_has_execution = 1;
1526  fbsd_thread_ops.to_insert_breakpoint = memory_insert_breakpoint;
1527  fbsd_thread_ops.to_remove_breakpoint = memory_remove_breakpoint;
1528  fbsd_thread_ops.to_get_thread_local_address = fbsd_thread_get_local_address;
1529  fbsd_thread_ops.to_magic = OPS_MAGIC;
1530}
1531
1532static int
1533thread_db_load (void)
1534{
1535  void *handle;
1536  td_err_e err;
1537
1538  handle = dlopen (LIBTHREAD_DB_SO, RTLD_NOW);
1539  if (handle == NULL)
1540      return 0;
1541
1542#define resolve(X)			\
1543 if (!(X##_p = dlsym (handle, #X)))	\
1544   return 0;
1545
1546  resolve(td_init);
1547  resolve(td_ta_new);
1548  resolve(td_ta_delete);
1549  resolve(td_ta_map_id2thr);
1550  resolve(td_ta_map_lwp2thr);
1551  resolve(td_ta_thr_iter);
1552  resolve(td_thr_get_info);
1553#ifdef PT_GETXMMREGS
1554  resolve(td_thr_getxmmregs);
1555#endif
1556  resolve(td_thr_getfpregs);
1557  resolve(td_thr_getgregs);
1558#ifdef PT_GETXMMREGS
1559  resolve(td_thr_setxmmregs);
1560#endif
1561  resolve(td_thr_setfpregs);
1562  resolve(td_thr_setgregs);
1563  resolve(td_thr_sstep);
1564  resolve(td_ta_tsd_iter);
1565  resolve(td_thr_dbsuspend);
1566  resolve(td_thr_dbresume);
1567  resolve(td_thr_tls_get_addr);
1568
1569  /* Initialize the library.  */
1570  err = td_init_p ();
1571  if (err != TD_OK)
1572    {
1573      warning ("Cannot initialize libthread_db: %s", thread_db_err_str (err));
1574      return 0;
1575    }
1576
1577  /* These are not essential.  */
1578  td_ta_event_addr_p = dlsym (handle, "td_ta_event_addr");
1579  td_ta_set_event_p = dlsym (handle, "td_ta_set_event");
1580  td_ta_event_getmsg_p = dlsym (handle, "td_ta_event_getmsg");
1581  td_thr_event_enable_p = dlsym (handle, "td_thr_event_enable");
1582  td_thr_tls_get_addr_p = dlsym (handle, "td_thr_tls_get_addr");
1583
1584  return 1;
1585}
1586
1587/* we suppress the call to add_target of core_ops in corelow because
1588   if there are two targets in the stratum core_stratum, find_core_target
1589   won't know which one to return.  see corelow.c for an additonal
1590   comment on coreops_suppress_target. */
1591
1592int coreops_suppress_target = 1;
1593
1594/* similarly we allow this target to be completely skipped.  This is used
1595   by kgdb which uses its own core target. */
1596
1597int fbsdcoreops_suppress_target;
1598
1599void
1600_initialize_thread_db (void)
1601{
1602
1603  if (fbsdcoreops_suppress_target)
1604    return;
1605  init_fbsd_thread_ops ();
1606  init_fbsd_core_ops ();
1607
1608  if (thread_db_load ())
1609    {
1610      add_target (&fbsd_thread_ops);
1611
1612      /* "thread tsd" command */
1613      add_cmd ("tsd", class_run, fbsd_thread_tsd_cmd,
1614            "Show the thread-specific data keys and destructors "
1615            "for the process.\n",
1616           &thread_cmd_list);
1617
1618      add_cmd ("signal", class_run, fbsd_thread_signal_cmd,
1619            "Show the thread signal info.\n",
1620           &thread_cmd_list);
1621
1622      memcpy (&orig_core_ops, &core_ops, sizeof (struct target_ops));
1623      memcpy (&core_ops, &fbsd_core_ops, sizeof (struct target_ops));
1624      add_target (&core_ops);
1625
1626      /* Add ourselves to objfile event chain. */
1627      target_new_objfile_chain = target_new_objfile_hook;
1628      target_new_objfile_hook = fbsd_thread_new_objfile;
1629
1630      child_suppress_run = 1;
1631    }
1632  else
1633    {
1634      fprintf_unfiltered (gdb_stderr,
1635        "[GDB will not be able to debug user-mode threads: %s]\n", dlerror());
1636
1637      /* allow the user to debug non-threaded core files */
1638      add_target (&core_ops);
1639    }
1640}
1641
1642/* proc service functions */
1643void
1644ps_plog (const char *fmt, ...)
1645{
1646  va_list args;
1647
1648  va_start (args, fmt);
1649  vfprintf_filtered (gdb_stderr, fmt, args);
1650  va_end (args);
1651}
1652
1653ps_err_e
1654ps_pglobal_lookup (struct ps_prochandle *ph, const char *obj,
1655   const char *name, psaddr_t *sym_addr)
1656{
1657  struct minimal_symbol *ms;
1658  CORE_ADDR addr;
1659
1660  ms = lookup_minimal_symbol (name, NULL, NULL);
1661  if (ms == NULL)
1662    return PS_NOSYM;
1663
1664  addr = SYMBOL_VALUE_ADDRESS (ms);
1665  store_typed_address(sym_addr, builtin_type_void_data_ptr, addr);
1666  return PS_OK;
1667}
1668
1669ps_err_e
1670ps_pread (struct ps_prochandle *ph, psaddr_t addr, void *buf, size_t len)
1671{
1672  int err = target_read_memory (
1673    extract_typed_address(&addr, builtin_type_void_data_ptr), buf, len);
1674  return (err == 0 ? PS_OK : PS_ERR);
1675}
1676
1677ps_err_e
1678ps_pwrite (struct ps_prochandle *ph, psaddr_t addr, const void *buf,
1679            size_t len)
1680{
1681  int err = target_write_memory (
1682    extract_typed_address(&addr, builtin_type_void_data_ptr), (void *)buf, len);
1683  return (err == 0 ? PS_OK : PS_ERR);
1684}
1685
1686ps_err_e
1687ps_lgetregs (struct ps_prochandle *ph, lwpid_t lwpid, prgregset_t gregset)
1688{
1689  struct cleanup *old_chain;
1690
1691  old_chain = save_inferior_ptid ();
1692
1693  /* XXX: Target operation isn't lwp aware: replace pid with lwp */
1694  inferior_ptid = BUILD_LWP (0, lwpid);
1695
1696  target_fetch_registers (-1);
1697  fill_gregset (gregset, -1);
1698  do_cleanups (old_chain);
1699  return PS_OK;
1700}
1701
1702ps_err_e
1703ps_lsetregs (struct ps_prochandle *ph, lwpid_t lwpid, const prgregset_t gregset)
1704{
1705  struct cleanup *old_chain;
1706
1707  old_chain = save_inferior_ptid ();
1708  inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
1709  supply_gregset ((gdb_gregset_t *) gregset);
1710  target_store_registers (-1);
1711  do_cleanups (old_chain);
1712  return PS_OK;
1713}
1714
1715ps_err_e
1716ps_lgetfpregs (struct ps_prochandle *ph, lwpid_t lwpid, prfpregset_t *fpregset)
1717{
1718  struct cleanup *old_chain;
1719
1720  old_chain = save_inferior_ptid ();
1721  inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
1722  target_fetch_registers (-1);
1723  fill_fpregset (fpregset, -1);
1724  do_cleanups (old_chain);
1725  return PS_OK;
1726}
1727
1728ps_err_e
1729ps_lsetfpregs (struct ps_prochandle *ph, lwpid_t lwpid,
1730               const prfpregset_t *fpregset)
1731{
1732  struct cleanup *old_chain;
1733
1734  old_chain = save_inferior_ptid ();
1735  inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
1736  supply_fpregset ((gdb_fpregset_t *) fpregset);
1737  target_store_registers (-1);
1738  do_cleanups (old_chain);
1739  return PS_OK;
1740}
1741
1742#ifdef PT_GETXMMREGS
1743ps_err_e
1744ps_lgetxmmregs (struct ps_prochandle *ph, lwpid_t lwpid, char *xmmregs)
1745{
1746  struct cleanup *old_chain;
1747
1748  old_chain = save_inferior_ptid ();
1749  inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
1750  target_fetch_registers (-1);
1751  i387_fill_fxsave (xmmregs, -1);
1752  do_cleanups (old_chain);
1753  return PS_OK;
1754}
1755
1756ps_err_e
1757ps_lsetxmmregs (struct ps_prochandle *ph, lwpid_t lwpid,
1758		const char *xmmregs)
1759{
1760  struct cleanup *old_chain;
1761
1762  old_chain = save_inferior_ptid ();
1763  inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
1764  i387_supply_fxsave (current_regcache, -1, xmmregs);
1765  target_store_registers (-1);
1766  do_cleanups (old_chain);
1767  return PS_OK;
1768}
1769#endif
1770
1771ps_err_e
1772ps_lstop(struct ps_prochandle *ph, lwpid_t lwpid)
1773{
1774  if (ptrace (PT_SUSPEND, lwpid, 0, 0) == -1)
1775    return PS_ERR;
1776  return PS_OK;
1777}
1778
1779ps_err_e
1780ps_lcontinue(struct ps_prochandle *ph, lwpid_t lwpid)
1781{
1782  if (ptrace (PT_RESUME, lwpid, 0, 0) == -1)
1783    return PS_ERR;
1784  return PS_OK;
1785}
1786
1787ps_err_e
1788ps_linfo(struct ps_prochandle *ph, lwpid_t lwpid, void *info)
1789{
1790  if (fbsd_thread_core) {
1791    /* XXX should verify lwpid and make a pseudo lwp info */
1792    memset(info, 0, sizeof(struct ptrace_lwpinfo));
1793    return PS_OK;
1794  }
1795
1796  if (ptrace (PT_LWPINFO, lwpid, info, sizeof(struct ptrace_lwpinfo)) == -1)
1797    return PS_ERR;
1798  return PS_OK;
1799}
1800