* Makefile.in (elf_common_h): Define.
[deliverable/binutils-gdb.git] / gdb / i386fbsd-nat.c
index a80d0a0af8935b7c82df645ac3e7f244c1447045..ec87bb852be52bbdbb2c671722b7e3f7fcf91e57 100644 (file)
@@ -1,5 +1,6 @@
 /* Native-dependent code for FreeBSD/i386.
-   Copyright 2001, 2002 Free Software Foundation, Inc.
+
+   Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 
    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.  */
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
 
 #include "defs.h"
 #include "inferior.h"
 #include "regcache.h"
+#include "target.h"
 
 #include <sys/types.h>
 #include <sys/ptrace.h>
 #include <sys/sysctl.h>
 
-/* Prevent warning from -Wmissing-prototypes.  */
-void _initialize_i386fbsd_nat (void);
+#include "fbsd-nat.h"
+#include "i386-tdep.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.  */
+/* Resume execution of the inferior process.  If STEP is nonzero,
+   single-step it.  If SIGNAL is nonzero, give it that signal.  */
 
-void
-child_resume (ptid_t ptid, int step, enum target_signal signal)
+static void
+i386fbsd_resume (ptid_t ptid, int step, enum target_signal signal)
 {
   pid_t pid = ptid_get_pid (ptid);
   int request = PT_STEP;
@@ -47,7 +49,7 @@ child_resume (ptid_t ptid, int step, enum target_signal signal)
 
   if (!step)
     {
-      unsigned int eflags;
+      ULONGEST eflags;
 
       /* Workaround for a bug in FreeBSD.  Make sure that the trace
         flag is off when doing a continue.  There is a code path
@@ -59,9 +61,11 @@ child_resume (ptid_t ptid, int step, enum target_signal signal)
         never goes through the kernel's trap() function which would
         normally clear it.  */
 
-      eflags = read_register (PS_REGNUM);
+      regcache_cooked_read_unsigned (current_regcache, I386_EFLAGS_REGNUM,
+                                    &eflags);
       if (eflags & 0x0100)
-       write_register (PS_REGNUM, eflags & ~0x0100);
+       regcache_cooked_write_unsigned (current_regcache, I386_EFLAGS_REGNUM,
+                                       eflags & ~0x0100);
 
       request = PT_CONTINUE;
     }
@@ -71,12 +75,65 @@ child_resume (ptid_t ptid, int step, enum target_signal signal)
      written a new PC value to the child.)  */
   if (ptrace (request, pid, (caddr_t) 1,
              target_signal_to_host (signal)) == -1)
-    perror_with_name ("ptrace");
+    perror_with_name (("ptrace"));
+}
+\f
+
+/* Support for debugging kernel virtual memory images.  */
+
+#include <sys/types.h>
+#include <machine/pcb.h>
+
+#include "bsd-kvm.h"
+
+static int
+i386fbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
+{
+  /* The following is true for FreeBSD 4.7:
+
+     The pcb contains %eip, %ebx, %esp, %ebp, %esi, %edi and %gs.
+     This accounts for all callee-saved registers specified by the
+     psABI and then some.  Here %esp contains the stack pointer at the
+     point just after the call to cpu_switch().  From this information
+     we reconstruct the register state as it would look when we just
+     returned from cpu_switch().  */
+
+  /* The stack pointer shouldn't be zero.  */
+  if (pcb->pcb_esp == 0)
+    return 0;
+
+  pcb->pcb_esp += 4;
+  regcache_raw_supply (regcache, I386_EDI_REGNUM, &pcb->pcb_edi);
+  regcache_raw_supply (regcache, I386_ESI_REGNUM, &pcb->pcb_esi);
+  regcache_raw_supply (regcache, I386_EBP_REGNUM, &pcb->pcb_ebp);
+  regcache_raw_supply (regcache, I386_ESP_REGNUM, &pcb->pcb_esp);
+  regcache_raw_supply (regcache, I386_EBX_REGNUM, &pcb->pcb_ebx);
+  regcache_raw_supply (regcache, I386_EIP_REGNUM, &pcb->pcb_eip);
+  regcache_raw_supply (regcache, I386_GS_REGNUM, &pcb->pcb_gs);
+
+  return 1;
 }
 \f
+
+/* Prevent warning from -Wmissing-prototypes.  */
+void _initialize_i386fbsd_nat (void);
+
 void
 _initialize_i386fbsd_nat (void)
 {
+  struct target_ops *t;
+
+  /* Add some extra features to the common *BSD/i386 target.  */
+  t = i386bsd_target ();
+  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);
+
+  /* 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
@@ -86,19 +143,16 @@ _initialize_i386fbsd_nat (void)
 #ifdef KERN_PS_STRINGS
   {
     int mib[2];
-    int ps_strings;
+    u_long ps_strings;
     size_t len;
 
-    extern CORE_ADDR i386fbsd_sigtramp_start;
-    extern CORE_ADDR i386fbsd_sigtramp_end;
-
     mib[0] = CTL_KERN;
     mib[1] = KERN_PS_STRINGS;
     len = sizeof (ps_strings);
     if (sysctl (mib, 2, &ps_strings, &len, NULL, 0) == 0)
       {
-       i386fbsd_sigtramp_start = ps_strings - 128;
-       i386fbsd_sigtramp_end = ps_strings;
+       i386fbsd_sigtramp_start_addr = ps_strings - 128;
+       i386fbsd_sigtramp_end_addr = ps_strings;
       }
   }
 #endif
This page took 0.024848 seconds and 4 git commands to generate.