Add IA64_MAX_FP_REGISTER_SIZE
[deliverable/binutils-gdb.git] / gdb / fbsd-nat.c
index 508ab1945e7123d0f810f29aaccc0ba22e66957f..ef5ad1ec92bee9f3cf2ea9ac6443b4ca98146e69 100644 (file)
@@ -1,6 +1,6 @@
 /* Native-dependent code for FreeBSD.
 
-   Copyright (C) 2002-2016 Free Software Foundation, Inc.
+   Copyright (C) 2002-2017 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -321,7 +321,7 @@ fbsd_fetch_kinfo_proc (pid_t pid, struct kinfo_proc *kp)
   FreeBSD's first thread support was via a "reentrant" version of libc
   (libc_r) that first shipped in 2.2.7.  This library multiplexed all
   of the threads in a process onto a single kernel thread.  This
-  library is supported via the bsd-uthread target.
+  library was supported via the bsd-uthread target.
 
   FreeBSD 5.1 introduced two new threading libraries that made use of
   multiple kernel threads.  The first (libkse) scheduled M user
@@ -368,7 +368,7 @@ fbsd_thread_alive (struct target_ops *ops, ptid_t ptid)
 /* Convert PTID to a string.  Returns the string in a static
    buffer.  */
 
-static char *
+static const char *
 fbsd_pid_to_str (struct target_ops *ops, ptid_t ptid)
 {
   lwpid_t lwp;
@@ -435,6 +435,9 @@ fbsd_enable_proc_events (pid_t pid)
              sizeof (events)) == -1)
     perror_with_name (("ptrace"));
   events |= PTRACE_FORK | PTRACE_LWP;
+#ifdef PTRACE_VFORK
+  events |= PTRACE_VFORK;
+#endif
   if (ptrace (PT_SET_EVENT_MASK, pid, (PTRACE_TYPE_ARG3)&events,
              sizeof (events)) == -1)
     perror_with_name (("ptrace"));
@@ -598,6 +601,7 @@ fbsd_is_child_pending (pid_t pid)
   return null_ptid;
 }
 
+#ifndef PTRACE_VFORK
 static struct fbsd_fork_info *fbsd_pending_vfork_done;
 
 /* Record a pending vfork done event.  */
@@ -647,38 +651,7 @@ fbsd_next_vfork_done (void)
   return null_ptid;
 }
 #endif
-
-static int
-resume_one_thread_cb (struct thread_info *tp, void *data)
-{
-  ptid_t *ptid = (ptid_t *) data;
-  int request;
-
-  if (ptid_get_pid (tp->ptid) != ptid_get_pid (*ptid))
-    return 0;
-
-  if (ptid_get_lwp (tp->ptid) == ptid_get_lwp (*ptid))
-    request = PT_RESUME;
-  else
-    request = PT_SUSPEND;
-
-  if (ptrace (request, ptid_get_lwp (tp->ptid), NULL, 0) == -1)
-    perror_with_name (("ptrace"));
-  return 0;
-}
-
-static int
-resume_all_threads_cb (struct thread_info *tp, void *data)
-{
-  ptid_t *filter = (ptid_t *) data;
-
-  if (!ptid_match (tp->ptid, *filter))
-    return 0;
-
-  if (ptrace (PT_RESUME, ptid_get_lwp (tp->ptid), NULL, 0) == -1)
-    perror_with_name (("ptrace"));
-  return 0;
-}
+#endif
 
 /* Implement the "to_resume" target_ops method.  */
 
@@ -686,7 +659,7 @@ static void
 fbsd_resume (struct target_ops *ops,
             ptid_t ptid, int step, enum gdb_signal signo)
 {
-#ifdef TDP_RFPPWAIT
+#if defined(TDP_RFPPWAIT) && !defined(PTRACE_VFORK)
   pid_t pid;
 
   /* Don't PT_CONTINUE a process which has a pending vfork done event.  */
@@ -706,13 +679,37 @@ fbsd_resume (struct target_ops *ops,
   if (ptid_lwp_p (ptid))
     {
       /* If ptid is a specific LWP, suspend all other LWPs in the process.  */
-      iterate_over_threads (resume_one_thread_cb, &ptid);
+      struct thread_info *tp;
+      int request;
+
+      ALL_NON_EXITED_THREADS (tp)
+        {
+         if (ptid_get_pid (tp->ptid) != ptid_get_pid (ptid))
+           continue;
+
+         if (ptid_get_lwp (tp->ptid) == ptid_get_lwp (ptid))
+           request = PT_RESUME;
+         else
+           request = PT_SUSPEND;
+
+         if (ptrace (request, ptid_get_lwp (tp->ptid), NULL, 0) == -1)
+           perror_with_name (("ptrace"));
+       }
     }
   else
     {
       /* If ptid is a wildcard, resume all matching threads (they won't run
         until the process is continued however).  */
-      iterate_over_threads (resume_all_threads_cb, &ptid);
+      struct thread_info *tp;
+
+      ALL_NON_EXITED_THREADS (tp)
+        {
+         if (!ptid_match (tp->ptid, ptid))
+           continue;
+
+         if (ptrace (PT_RESUME, ptid_get_lwp (tp->ptid), NULL, 0) == -1)
+           perror_with_name (("ptrace"));
+       }
       ptid = inferior_ptid;
     }
   super_resume (ops, ptid, step, signo);
@@ -731,12 +728,14 @@ fbsd_wait (struct target_ops *ops,
 
   while (1)
     {
+#ifndef PTRACE_VFORK
       wptid = fbsd_next_vfork_done ();
       if (!ptid_equal (wptid, null_ptid))
        {
          ourstatus->kind = TARGET_WAITKIND_VFORK_DONE;
          return wptid;
        }
+#endif
       wptid = super_wait (ops, ptid, ourstatus, target_options);
       if (ourstatus->kind == TARGET_WAITKIND_STOPPED)
        {
@@ -812,12 +811,18 @@ fbsd_wait (struct target_ops *ops,
 #ifdef TDP_RFPPWAIT
          if (pl.pl_flags & PL_FLAG_FORKED)
            {
+#ifndef PTRACE_VFORK
              struct kinfo_proc kp;
+#endif
              ptid_t child_ptid;
              pid_t child;
 
              child = pl.pl_child_pid;
              ourstatus->kind = TARGET_WAITKIND_FORKED;
+#ifdef PTRACE_VFORK
+             if (pl.pl_flags & PL_FLAG_VFORKED)
+               ourstatus->kind = TARGET_WAITKIND_VFORKED;
+#endif
 
              /* Make sure the other end of the fork is stopped too.  */
              child_ptid = fbsd_is_child_pending (child);
@@ -836,11 +841,16 @@ fbsd_wait (struct target_ops *ops,
                  child_ptid = ptid_build (child, pl.pl_lwpid, 0);
                }
 
+             /* Enable additional events on the child process.  */
+             fbsd_enable_proc_events (ptid_get_pid (child_ptid));
+
+#ifndef PTRACE_VFORK
              /* For vfork, the child process will have the P_PPWAIT
                 flag set.  */
              fbsd_fetch_kinfo_proc (child, &kp);
              if (kp.ki_flag & P_PPWAIT)
                ourstatus->kind = TARGET_WAITKIND_VFORKED;
+#endif
              ourstatus->value.related_pid = child_ptid;
 
              return wptid;
@@ -854,6 +864,14 @@ fbsd_wait (struct target_ops *ops,
              fbsd_remember_child (wptid);
              continue;
            }
+
+#ifdef PTRACE_VFORK
+         if (pl.pl_flags & PL_FLAG_VFORK_DONE)
+           {
+             ourstatus->kind = TARGET_WAITKIND_VFORK_DONE;
+             return wptid;
+           }
+#endif
 #endif
 
 #ifdef PL_FLAG_EXEC
@@ -915,7 +933,6 @@ fbsd_follow_fork (struct target_ops *ops, int follow_child,
   if (!follow_child && detach_fork)
     {
       struct thread_info *tp = inferior_thread ();
-      int has_vforked = tp->pending_follow.kind == TARGET_WAITKIND_VFORKED;
       pid_t child_pid = ptid_get_pid (tp->pending_follow.value.related_pid);
 
       /* Breakpoints have already been detached from the child by
@@ -924,7 +941,8 @@ fbsd_follow_fork (struct target_ops *ops, int follow_child,
       if (ptrace (PT_DETACH, child_pid, (PTRACE_TYPE_ARG3)1, 0) == -1)
        perror_with_name (("ptrace"));
 
-      if (has_vforked)
+#ifndef PTRACE_VFORK
+      if (tp->pending_follow.kind == TARGET_WAITKIND_VFORKED)
        {
          /* We can't insert breakpoints until the child process has
             finished with the shared memory region.  The parent
@@ -950,6 +968,7 @@ fbsd_follow_fork (struct target_ops *ops, int follow_child,
             wait.  */
          fbsd_add_vfork_done (inferior_ptid);
        }
+#endif
     }
 
   return 0;
This page took 0.026848 seconds and 4 git commands to generate.