* i386obsd-tdep.c: Update copyright year. Include
authorMark Kettenis <kettenis@gnu.org>
Sun, 23 Jan 2005 19:35:05 +0000 (19:35 +0000)
committerMark Kettenis <kettenis@gnu.org>
Sun, 23 Jan 2005 19:35:05 +0000 (19:35 +0000)
"bsd-uthread.h".
(i386obsd_uthread_reg_offset): New variable.
(I386OBSD_UTHREAD_ESP_OFFSET): New define.
(i386obsd_supply_uthread, i386obsd_collect_uthread): New
functions.
(i386obsd_init_abi): Set supply_uthread and collect_uthread.
* Makefile.in (i386obsd-tdep.o): Update dependencies.
* config/i386/obsd.mt (TDEPFILES): Add bsd-uthread.o.

gdb/ChangeLog
gdb/Makefile.in
gdb/config/i386/obsd.mt
gdb/i386obsd-tdep.c

index 5f592885dd833ae1ff8ed0a70a8d4ce03ea28012..1843855c4121b1178daee82534bb23965accc2e2 100644 (file)
@@ -1,3 +1,15 @@
+2005-01-23  Mark Kettenis  <kettenis@gnu.org>
+
+       * i386obsd-tdep.c: Update copyright year.  Include
+       "bsd-uthread.h".
+       (i386obsd_uthread_reg_offset): New variable.
+       (I386OBSD_UTHREAD_ESP_OFFSET): New define.
+       (i386obsd_supply_uthread, i386obsd_collect_uthread): New
+       functions.
+       (i386obsd_init_abi): Set supply_uthread and collect_uthread.
+       * Makefile.in (i386obsd-tdep.o): Update dependencies.
+       * config/i386/obsd.mt (TDEPFILES): Add bsd-uthread.o.
+
 2005-01-23  Christopher Faylor  <cgf@timesys.com>
 
        * win32-nat.c: Update copyright year.
index 6a530ba8852aa0ee36210fe296e9a9f2d631d23a..5184070bac2abde54678b98badc512ea66c2c099 100644 (file)
@@ -2044,7 +2044,7 @@ i386obsd-nat.o: i386obsd-nat.c $(defs_h) $(i386_tdep_h)
 i386obsd-tdep.o: i386obsd-tdep.c $(defs_h) $(arch_utils_h) $(frame_h) \
        $(gdbcore_h) $(regcache_h) $(regset_h) $(symtab_h) $(objfiles_h) \
        $(osabi_h) $(target_h) $(gdb_assert_h) $(gdb_string_h) \
-       $(i386_tdep_h) $(i387_tdep_h) $(solib_svr4_h)
+       $(i386_tdep_h) $(i387_tdep_h) $(solib_svr4_h) $(bsd_uthread_h)
 i386-sol2-nat.o: i386-sol2-nat.c $(defs_h) $(regcache_h) $(gregset_h) \
        $(amd64_nat_h) $(amd64_tdep_h)
 i386-sol2-tdep.o: i386-sol2-tdep.c $(defs_h) $(value_h) $(osabi_h) \
index b90fbf38c03590bb6335a8aa881e1a523960c802..4ce78c1797dce0f373471f334b464dbc625922d5 100644 (file)
@@ -1,4 +1,4 @@
 # Target: OpenBSD/i386
 TDEPFILES= i386-tdep.o i387-tdep.o i386bsd-tdep.o i386obsd-tdep.o \
-       corelow.o solib.o solib-svr4.o
+       bsd-uthread.o corelow.o solib.o solib-svr4.o
 DEPRECATED_TM_FILE= solib.h
index 4c9b88d6152b1247db9849ff92a712871930089e..5eb0444a8b9009b71ed6e93536ff15a6ec2325c8 100644 (file)
@@ -1,7 +1,7 @@
 /* Target-dependent code for OpenBSD/i386.
 
    Copyright 1988, 1989, 1991, 1992, 1994, 1996, 2000, 2001, 2002,
-   2003, 2004
+   2003, 2004, 2005
    Free Software Foundation, Inc.
 
    This file is part of GDB.
@@ -38,6 +38,7 @@
 #include "i386-tdep.h"
 #include "i387-tdep.h"
 #include "solib-svr4.h"
+#include "bsd-uthread.h"
 
 /* Support for signal handlers.  */
 
@@ -186,6 +187,120 @@ int i386obsd_sc_reg_offset[I386_NUM_GREGS] =
   0 * 4                                /* %gs */
 };
 
+/* From /usr/src/lib/libpthread/arch/i386/uthread_machdep.c.  */
+static int i386obsd_uthread_reg_offset[] =
+{
+  11 * 4,                      /* %eax */
+  10 * 4,                      /* %ecx */
+  9 * 4,                       /* %edx */
+  8 * 4,                       /* %ebx */
+  -1,                          /* %esp */
+  6 * 4,                       /* %ebp */
+  5 * 4,                       /* %esi */
+  4 * 4,                       /* %edi */
+  12 * 4,                      /* %eip */
+  -1,                          /* %eflags */
+  13 * 4,                      /* %cs */
+  -1,                          /* %ss */
+  3 * 4,                       /* %ds */
+  2 * 4,                       /* %es */
+  1 * 4,                       /* %fs */
+  0 * 4                                /* %gs */
+};
+
+/* Offset within the thread structure where we can find the saved
+   stack pointer (%esp).  */
+#define I386OBSD_UTHREAD_ESP_OFFSET    176
+
+static void
+i386obsd_supply_uthread (struct regcache *regcache,
+                        int regnum, CORE_ADDR addr)
+{
+  CORE_ADDR sp_addr = addr + I386OBSD_UTHREAD_ESP_OFFSET;
+  CORE_ADDR sp = 0;
+  char buf[4];
+  int i;
+
+  gdb_assert (regnum >= -1);
+
+  if (regnum == -1 || regnum == I386_ESP_REGNUM)
+    {
+      int offset;
+
+      /* Fetch stack pointer from thread structure.  */
+      sp = read_memory_unsigned_integer (sp_addr, 4);
+
+      /* Adjust the stack pointer such that it looks as if we just
+         returned from _thread_machdep_switch.  */
+      offset = i386obsd_uthread_reg_offset[I386_EIP_REGNUM] + 4;
+      store_unsigned_integer (buf, 4, sp + offset);
+      regcache_raw_supply (regcache, I386_ESP_REGNUM, buf);
+    }
+
+  for (i = 0; i < ARRAY_SIZE (i386obsd_uthread_reg_offset); i++)
+    {
+      if (i386obsd_uthread_reg_offset[i] != -1
+         && (regnum == -1 || regnum == i))
+       {
+         /* Fetch stack pointer from thread structure (if we didn't
+             do so already).  */
+         if (sp == 0)
+           sp = read_memory_unsigned_integer (sp_addr, 4);
+
+         /* Read the saved register from the stack frame.  */
+         read_memory (sp + i386obsd_uthread_reg_offset[i], buf, 4);
+         regcache_raw_supply (regcache, i, buf);
+       }
+    }
+
+}
+
+static void
+i386obsd_collect_uthread (const struct regcache *regcache,
+                         int regnum, CORE_ADDR addr)
+{
+  CORE_ADDR sp_addr = addr + I386OBSD_UTHREAD_ESP_OFFSET;
+  CORE_ADDR sp = 0;
+  char buf[4];
+  int i;
+
+  gdb_assert (regnum >= -1);
+
+  if (regnum == -1 || regnum == I386_ESP_REGNUM)
+    {
+      int offset;
+
+      /* Calculate the stack pointer (frame pointer) that will be
+         stored into the thread structure.  */
+      offset = i386obsd_uthread_reg_offset[I386_EIP_REGNUM] + 4;
+      regcache_raw_collect (regcache, I386_ESP_REGNUM, buf);
+      sp = extract_unsigned_integer (buf, 4) - offset;
+
+      /* Store the stack pointer.  */
+      write_memory_unsigned_integer (sp_addr, 4, sp);
+
+      /* The stack pointer was (potentially) modified.  Make sure we
+         build a proper stack frame.  */
+      regnum = -1;
+    }
+
+  for (i = 0; i < ARRAY_SIZE (i386obsd_uthread_reg_offset); i++)
+    {
+      if (i386obsd_uthread_reg_offset[i] != -1
+         && (regnum == -1 || regnum == i))
+       {
+         /* Fetch stack pointer from thread structure (if we didn't
+             calculate it already).  */
+         if (sp == 0)
+           sp = read_memory_unsigned_integer (sp_addr, 4);
+
+         /* Write the register into the stack frame.  */
+         regcache_raw_collect (regcache, i, buf);
+         write_memory (sp + i386obsd_uthread_reg_offset[i], buf, 4);
+       }
+    }
+}
+
 static void 
 i386obsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 {
@@ -211,6 +326,10 @@ i386obsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
      original 4.3 BSD.  */
   tdep->sc_reg_offset = i386obsd_sc_reg_offset;
   tdep->sc_num_regs = ARRAY_SIZE (i386obsd_sc_reg_offset);
+
+  /* OpenBSD provides a user-level threads implementation.  */
+  bsd_uthread_set_supply_uthread (gdbarch, i386obsd_supply_uthread);
+  bsd_uthread_set_collect_uthread (gdbarch, i386obsd_collect_uthread);
 }
 
 /* OpenBSD a.out.  */