Makefiles: Flatten and sort file lists
[deliverable/binutils-gdb.git] / gdb / i386fbsd-nat.c
index bb516fedfea3688adeabbb42addcca706f0ce629..716b51364e5ccda75bedd6d356441958ec506561 100644 (file)
@@ -1,12 +1,12 @@
 /* Native-dependent code for FreeBSD/i386.
 
-   Copyright 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 2001-2016 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
@@ -15,9 +15,7 @@
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
 #include "inferior.h"
 #include <sys/types.h>
 #include <sys/ptrace.h>
 #include <sys/sysctl.h>
+#include <sys/user.h>
 
 #include "fbsd-nat.h"
 #include "i386-tdep.h"
+#include "x86-nat.h"
+#include "x86bsd-nat.h"
 #include "i386bsd-nat.h"
 
 /* Resume execution of the inferior process.  If STEP is nonzero,
    single-step it.  If SIGNAL is nonzero, give it that signal.  */
 
 static void
-i386fbsd_resume (ptid_t ptid, int step, enum target_signal signal)
+i386fbsd_resume (struct target_ops *ops,
+                ptid_t ptid, int step, enum gdb_signal signal)
 {
   pid_t pid = ptid_get_pid (ptid);
   int request = PT_STEP;
@@ -49,6 +51,7 @@ i386fbsd_resume (ptid_t ptid, int step, enum target_signal signal)
 
   if (!step)
     {
+      struct regcache *regcache = get_current_regcache ();
       ULONGEST eflags;
 
       /* Workaround for a bug in FreeBSD.  Make sure that the trace
@@ -61,10 +64,10 @@ i386fbsd_resume (ptid_t ptid, int step, enum target_signal signal)
         never goes through the kernel's trap() function which would
         normally clear it.  */
 
-      regcache_cooked_read_unsigned (current_regcache, I386_EFLAGS_REGNUM,
+      regcache_cooked_read_unsigned (regcache, I386_EFLAGS_REGNUM,
                                     &eflags);
       if (eflags & 0x0100)
-       regcache_cooked_write_unsigned (current_regcache, I386_EFLAGS_REGNUM,
+       regcache_cooked_write_unsigned (regcache, I386_EFLAGS_REGNUM,
                                        eflags & ~0x0100);
 
       request = PT_CONTINUE;
@@ -74,14 +77,13 @@ i386fbsd_resume (ptid_t ptid, int step, enum target_signal signal)
      was.  (If GDB wanted it to start some other way, we have already
      written a new PC value to the child.)  */
   if (ptrace (request, pid, (caddr_t) 1,
-             target_signal_to_host (signal)) == -1)
+             gdb_signal_to_host (signal)) == -1)
     perror_with_name (("ptrace"));
 }
 \f
 
 /* Support for debugging kernel virtual memory images.  */
 
-#include <sys/types.h>
 #include <machine/pcb.h>
 
 #include "bsd-kvm.h"
@@ -115,6 +117,37 @@ i386fbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
 }
 \f
 
+#ifdef PT_GETXSTATE_INFO
+/* Implement the to_read_description method.  */
+
+static const struct target_desc *
+i386fbsd_read_description (struct target_ops *ops)
+{
+  static int xsave_probed;
+  static uint64_t xcr0;
+
+  if (!xsave_probed)
+    {
+      struct ptrace_xstate_info info;
+
+      if (ptrace (PT_GETXSTATE_INFO, ptid_get_pid (inferior_ptid),
+                 (PTRACE_TYPE_ARG3) &info, sizeof (info)) == 0)
+       {
+         x86bsd_xsave_len = info.xsave_len;
+         xcr0 = info.xsave_mask;
+       }
+      xsave_probed = 1;
+    }
+
+  if (x86bsd_xsave_len != 0)
+    {
+      return i386_target_description (xcr0);
+    }
+  else
+    return tdesc_i386;
+}
+#endif
+
 /* Prevent warning from -Wmissing-prototypes.  */
 void _initialize_i386fbsd_nat (void);
 
@@ -125,34 +158,39 @@ _initialize_i386fbsd_nat (void)
 
   /* Add some extra features to the common *BSD/i386 target.  */
   t = i386bsd_target ();
+
+#ifdef PT_GETXSTATE_INFO
+  t->to_read_description = i386fbsd_read_description;
+#endif
+
   t->to_resume = i386fbsd_resume;
-  t->to_pid_to_exec_file = fbsd_pid_to_exec_file;
-  t->to_find_memory_regions = fbsd_find_memory_regions;
-  t->to_make_corefile_notes = fbsd_make_corefile_notes;
-  add_target (t);
+  fbsd_nat_add_target (t);
 
   /* Support debugging kernel virtual memory images.  */
   bsd_kvm_add_target (i386fbsd_supply_pcb);
 
-  /* FreeBSD provides a kern.ps_strings sysctl that we can use to
-     locate the sigtramp.  That way we can still recognize a sigtramp
-     if its location is changed in a new kernel.  Of course this is
-     still based on the assumption that the sigtramp is placed
-     directly under the location where the program arguments and
-     environment can be found.  */
-#ifdef KERN_PS_STRINGS
+#ifdef KERN_PROC_SIGTRAMP
+  /* Normally signal frames are detected via i386fbsd_sigtramp_p.
+     However, FreeBSD 9.2 through 10.1 do not include the page holding
+     the signal code in core dumps.  These releases do provide a
+     kern.proc.sigtramp.<pid> sysctl that returns the location of the
+     signal trampoline for a running process.  We fetch the location
+     of the current (gdb) process and use this to identify signal
+     frames in core dumps from these releases.  */
   {
-    int mib[2];
-    u_long ps_strings;
+    int mib[4];
+    struct kinfo_sigtramp kst;
     size_t len;
 
     mib[0] = CTL_KERN;
-    mib[1] = KERN_PS_STRINGS;
-    len = sizeof (ps_strings);
-    if (sysctl (mib, 2, &ps_strings, &len, NULL, 0) == 0)
+    mib[1] = KERN_PROC;
+    mib[2] = KERN_PROC_SIGTRAMP;
+    mib[3] = getpid ();
+    len = sizeof (kst);
+    if (sysctl (mib, 4, &kst, &len, NULL, 0) == 0)
       {
-       i386fbsd_sigtramp_start_addr = ps_strings - 128;
-       i386fbsd_sigtramp_end_addr = ps_strings;
+       i386fbsd_sigtramp_start_addr = (uintptr_t) kst.ksigtramp_start;
+       i386fbsd_sigtramp_end_addr = (uintptr_t) kst.ksigtramp_end;
       }
   }
 #endif
This page took 0.036057 seconds and 4 git commands to generate.