This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] OpenBSD/amd64 threads support


Similar to the code we already have for OpenBSD/i386.  Gets the number
of FAILs down to 50 :).

Comitted,

Mark

Index: ChangeLog
from  Mark Kettenis  <kettenis@gnu.org>

	* amd64obsd-tdep.c: Include "regcache.h" and "bsd-uthread.h".
	(amd64obsd_uthread_reg_offset): New variable.
	(AMD64OBSD_UTHREAD_RSP_OFFSET): New define.
	(amd64obsd_supply_uthread, amd64obsd_collect_uthread): New
	functions.
	(amd64obsd_init_abi): Set supply_uthread and collect_uthread.
	* Makefile.in (amd64obsd-tdep.o): Update dependencies.

Index: amd64obsd-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/amd64obsd-tdep.c,v
retrieving revision 1.16
diff -u -p -r1.16 amd64obsd-tdep.c
--- amd64obsd-tdep.c 8 May 2005 18:00:07 -0000 1.16
+++ amd64obsd-tdep.c 4 Dec 2005 20:05:21 -0000
@@ -25,6 +25,7 @@
 #include "symtab.h"
 #include "objfiles.h"
 #include "osabi.h"
+#include "regcache.h"
 #include "regset.h"
 #include "target.h"
 
@@ -34,6 +35,7 @@
 #include "amd64-tdep.h"
 #include "i387-tdep.h"
 #include "solib-svr4.h"
+#include "bsd-uthread.h"
 
 /* Support for core dumps.  */
 
@@ -211,6 +213,127 @@ static int amd64obsd_sc_reg_offset[] =
   15 * 8			/* %gs */
 };
 
+/* From /usr/src/lib/libpthread/arch/amd64/uthread_machdep.c.  */
+static int amd64obsd_uthread_reg_offset[] =
+{
+  19 * 8,			/* %rax */
+  16 * 8,			/* %rbx */
+  18 * 8,			/* %rcx */
+  17 * 8,			/* %rdx */
+  14 * 8,			/* %rsi */
+  13 * 8,			/* %rdi */
+  15 * 8,			/* %rbp */
+  -1,				/* %rsp */
+  12 * 8,			/* %r8 ... */
+  11 * 8,
+  10 * 8,
+  9 * 8,
+  8 * 8,
+  7 * 8,
+  6 * 8,
+  5 * 8,			/* ... %r15 */
+  20 * 8,			/* %rip */
+  4 * 8,			/* %eflags */
+  21 * 8,			/* %cs */
+  -1,				/* %ss */
+  3 * 8,			/* %ds */
+  2 * 8,			/* %es */
+  1 * 8,			/* %fs */
+  0 * 8				/* %gs */
+};
+
+/* Offset within the thread structure where we can find the saved
+   stack pointer (%esp).  */
+#define AMD64OBSD_UTHREAD_RSP_OFFSET	400
+
+static void
+amd64obsd_supply_uthread (struct regcache *regcache,
+			  int regnum, CORE_ADDR addr)
+{
+  CORE_ADDR sp_addr = addr + AMD64OBSD_UTHREAD_RSP_OFFSET;
+  CORE_ADDR sp = 0;
+  gdb_byte buf[8];
+  int i;
+
+  gdb_assert (regnum >= -1);
+
+  if (regnum == -1 || regnum == AMD64_RSP_REGNUM)
+    {
+      int offset;
+
+      /* Fetch stack pointer from thread structure.  */
+      sp = read_memory_unsigned_integer (sp_addr, 8);
+
+      /* Adjust the stack pointer such that it looks as if we just
+         returned from _thread_machdep_switch.  */
+      offset = amd64obsd_uthread_reg_offset[AMD64_RIP_REGNUM] + 8;
+      store_unsigned_integer (buf, 8, sp + offset);
+      regcache_raw_supply (regcache, AMD64_RSP_REGNUM, buf);
+    }
+
+  for (i = 0; i < ARRAY_SIZE (amd64obsd_uthread_reg_offset); i++)
+    {
+      if (amd64obsd_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, 8);
+
+	  /* Read the saved register from the stack frame.  */
+	  read_memory (sp + amd64obsd_uthread_reg_offset[i], buf, 8);
+	  regcache_raw_supply (regcache, i, buf);
+	}
+    }
+}
+
+static void
+amd64obsd_collect_uthread (const struct regcache *regcache,
+			   int regnum, CORE_ADDR addr)
+{
+  CORE_ADDR sp_addr = addr + AMD64OBSD_UTHREAD_RSP_OFFSET;
+  CORE_ADDR sp = 0;
+  gdb_byte buf[8];
+  int i;
+
+  gdb_assert (regnum >= -1);
+
+  if (regnum == -1 || regnum == AMD64_RSP_REGNUM)
+    {
+      int offset;
+
+      /* Calculate the stack pointer (frame pointer) that will be
+         stored into the thread structure.  */
+      offset = amd64obsd_uthread_reg_offset[AMD64_RIP_REGNUM] + 8;
+      regcache_raw_collect (regcache, AMD64_RSP_REGNUM, buf);
+      sp = extract_unsigned_integer (buf, 8) - offset;
+
+      /* Store the stack pointer.  */
+      write_memory_unsigned_integer (sp_addr, 8, sp);
+
+      /* The stack pointer was (potentially) modified.  Make sure we
+         build a proper stack frame.  */
+      regnum = -1;
+    }
+
+  for (i = 0; i < ARRAY_SIZE (amd64obsd_uthread_reg_offset); i++)
+    {
+      if (amd64obsd_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, 8);
+
+	  /* Write the register into the stack frame.  */
+	  regcache_raw_collect (regcache, i, buf);
+	  write_memory (sp + amd64obsd_uthread_reg_offset[i], buf, 8);
+	}
+    }
+}
+
 static void
 amd64obsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 {
@@ -233,6 +356,10 @@ amd64obsd_init_abi (struct gdbarch_info 
   tdep->sc_reg_offset = amd64obsd_sc_reg_offset;
   tdep->sc_num_regs = ARRAY_SIZE (amd64obsd_sc_reg_offset);
 
+  /* OpenBSD provides a user-level threads implementation.  */
+  bsd_uthread_set_supply_uthread (gdbarch, amd64obsd_supply_uthread);
+  bsd_uthread_set_collect_uthread (gdbarch, amd64obsd_collect_uthread);
+
   /* OpenBSD uses SVR4-style shared libraries.  */
   set_solib_svr4_fetch_link_map_offsets
     (gdbarch, svr4_lp64_fetch_link_map_offsets);
Index: Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.761
diff -u -p -r1.761 Makefile.in
--- Makefile.in 15 Nov 2005 12:03:07 -0000 1.761
+++ Makefile.in 4 Dec 2005 20:05:24 -0000
@@ -1716,9 +1716,9 @@ amd64obsd-nat.o: amd64obsd-nat.c $(defs_
 	$(target_h) $(gdb_assert_h) $(amd64_tdep_h) $(amd64_nat_h) \
 	$(bsd_kvm_h)
 amd64obsd-tdep.o: amd64obsd-tdep.c $(defs_h) $(frame_h) $(gdbcore_h) \
-	$(symtab_h) $(objfiles_h) $(osabi_h) $(regset_h) $(target_h) \
-	$(gdb_assert_h) $(gdb_string_h) $(amd64_tdep_h) $(i387_tdep_h) \
-	$(solib_svr4_h)
+	$(symtab_h) $(objfiles_h) $(osabi_h) $(regcache_h) $(regset_h) \
+	$(target_h) $(gdb_assert_h) $(gdb_string_h) $(amd64_tdep_h) \
+	$(i387_tdep_h) $(solib_svr4_h) $(bsd_uthread_h)
 amd64-sol2-tdep.o: amd64-sol2-tdep.c $(defs_h) $(frame_h) $(gdbcore_h) \
 	$(regcache_h) $(osabi_h) $(symtab_h) $(gdb_string_h) $(amd64_tdep_h) \
 	$(solib_svr4_h)


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]