2007-07-23 Michael Snyder <msnyder@access-company.com>
[deliverable/binutils-gdb.git] / gdb / i386fbsd-tdep.c
index db14a67a5b535582aafbf722916468b30f72b17e..ff37665cb012c02d1c41229d299595ec31556551 100644 (file)
@@ -1,6 +1,6 @@
 /* Target-dependent code for FreeBSD/i386.
 
-   Copyright 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004, 2005, 2007 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 "arch-utils.h"
+#include "gdbcore.h"
 #include "osabi.h"
+#include "regcache.h"
+
+#include "gdb_assert.h"
 
 #include "i386-tdep.h"
 #include "i387-tdep.h"
+#include "bsd-uthread.h"
 #include "solib-svr4.h"
 
 /* FreeBSD 3.0-RELEASE or later.  */
@@ -45,7 +50,7 @@ CORE_ADDR i386fbsd_sigtramp_start_addr = 0xbfbfdf20;
 CORE_ADDR i386fbsd_sigtramp_end_addr = 0xbfbfdff0;
 
 /* From <machine/signal.h>.  */
-static int i386fbsd_sc_reg_offset[] =
+int i386fbsd_sc_reg_offset[] =
 {
   8 + 14 * 4,                  /* %eax */
   8 + 13 * 4,                  /* %ecx */
@@ -65,6 +70,60 @@ static int i386fbsd_sc_reg_offset[] =
   8 + 16 * 4                   /* %gs */
 };
 
+/* From /usr/src/lib/libc/i386/gen/_setjmp.S.  */
+static int i386fbsd_jmp_buf_reg_offset[] =
+{
+  -1,                          /* %eax */
+  -1,                          /* %ecx */
+  -1,                          /* %edx */
+  1 * 4,                       /* %ebx */
+  2 * 4,                       /* %esp */
+  3 * 4,                       /* %ebp */
+  4 * 4,                       /* %esi */
+  5 * 4,                       /* %edi */
+  0 * 4                                /* %eip */
+};
+
+static void
+i386fbsd_supply_uthread (struct regcache *regcache,
+                        int regnum, CORE_ADDR addr)
+{
+  char buf[4];
+  int i;
+
+  gdb_assert (regnum >= -1);
+
+  for (i = 0; i < ARRAY_SIZE (i386fbsd_jmp_buf_reg_offset); i++)
+    {
+      if (i386fbsd_jmp_buf_reg_offset[i] != -1
+         && (regnum == -1 || regnum == i))
+       {
+         read_memory (addr + i386fbsd_jmp_buf_reg_offset[i], buf, 4);
+         regcache_raw_supply (regcache, i, buf);
+       }
+    }
+}
+
+static void
+i386fbsd_collect_uthread (const struct regcache *regcache,
+                         int regnum, CORE_ADDR addr)
+{
+  char buf[4];
+  int i;
+
+  gdb_assert (regnum >= -1);
+
+  for (i = 0; i < ARRAY_SIZE (i386fbsd_jmp_buf_reg_offset); i++)
+    {
+      if (i386fbsd_jmp_buf_reg_offset[i] != -1
+         && (regnum == -1 || regnum == i))
+       {
+         regcache_raw_collect (regcache, i, buf);
+         write_memory (addr + i386fbsd_jmp_buf_reg_offset[i], buf, 4);
+       }
+    }
+}
+
 static void
 i386fbsdaout_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 {
@@ -90,6 +149,10 @@ i386fbsdaout_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   /* FreeBSD has a more complete `struct sigcontext'.  */
   tdep->sc_reg_offset = i386fbsd_sc_reg_offset;
   tdep->sc_num_regs = ARRAY_SIZE (i386fbsd_sc_reg_offset);
+
+  /* FreeBSD provides a user-level threads implementation.  */
+  bsd_uthread_set_supply_uthread (gdbarch, i386fbsd_supply_uthread);
+  bsd_uthread_set_collect_uthread (gdbarch, i386fbsd_collect_uthread);
 }
 
 static void
@@ -102,8 +165,6 @@ i386fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   i386_elf_init_abi (info, gdbarch);
 
   /* FreeBSD ELF uses SVR4-style shared libraries.  */
-  set_gdbarch_in_solib_call_trampoline
-    (gdbarch, generic_in_solib_call_trampoline);
   set_solib_svr4_fetch_link_map_offsets
     (gdbarch, svr4_ilp32_fetch_link_map_offsets);
 }
This page took 0.025338 seconds and 4 git commands to generate.