[commit] NPTL support for ppc/ppc64

Daniel Jacobowitz drow@false.org
Wed Jul 13 15:20:00 GMT 2005


The NPTL support in gdbserver relies on ps_lgetregs, which is implemented on
top of the PTRACE_GETREGS support.  This patch just shuffles bits around so
that it's possible to provide an appropriate register set and fill_gregset
method, even if we should not use PTRACE_GETREGS.  That's all it takes to
make NPTL debugging start to work on ppc/ppc64.

This infrastructure will be handy later on, when I've implemented the
optional registers proposal.  Then we can use it to retrieve Altivec state
if available, without touching the 'g' packet layout.

Tested on powerpc64-linux and committed.

-- 
Daniel Jacobowitz
CodeSourcery, LLC

2005-07-13  Daniel Jacobowitz  <dan@codesourcery.com>

	* configure.ac: Define HAVE_LINUX_REGSETS even if PTRACE_GETREGS
	is not available.  Define HAVE_PTRACE_GETREGS if it is.
	* config.in, configure: Regenerated.
	* configure.srv: Set srv_linux_regsets for PowerPC and PowerPC64.
	* linux-i386-low.c, linux-m68k-low.c: Update to use
	HAVE_PTRACE_GETREGS.
	* linux-low.c (regsets_fetch_inferior_registers)
	(regsets_store_inferior_registers): Only return 0 if we processed
	GENERAL_REGS.
	* linux-ppc-low.c (ppc_fill_gregset, target_regsets): New.
	* linux-ppc64-low.c (ppc_fill_gregset, target_regsets): New.

Index: config.in
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/config.in,v
retrieving revision 1.10
diff -u -p -r1.10 config.in
--- config.in	1 Jul 2005 17:18:06 -0000	1.10
+++ config.in	13 Jul 2005 15:13:26 -0000
@@ -13,7 +13,7 @@
 /* Define to 1 if you have the <linux/elf.h> header file. */
 #undef HAVE_LINUX_ELF_H
 
-/* Define if the target supports PTRACE_GETREGS for register access. */
+/* Define if the target supports register sets. */
 #undef HAVE_LINUX_REGSETS
 
 /* Define if the target supports PTRACE_PEEKUSR for register access. */
@@ -41,6 +41,9 @@
    access. */
 #undef HAVE_PTRACE_GETFPXREGS
 
+/* Define if the target supports PTRACE_GETREGS for register access. */
+#undef HAVE_PTRACE_GETREGS
+
 /* Define to 1 if you have the <sgtty.h> header file. */
 #undef HAVE_SGTTY_H
 
Index: configure
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/configure,v
retrieving revision 1.19
diff -u -p -r1.19 configure
--- configure	1 Jul 2005 17:18:06 -0000	1.19
+++ configure	13 Jul 2005 15:13:27 -0000
@@ -3233,6 +3233,12 @@ _ACEOF
 fi
 
 if test "${srv_linux_regsets}" = "yes"; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_LINUX_REGSETS 1
+_ACEOF
+
+
   echo "$as_me:$LINENO: checking for PTRACE_GETREGS" >&5
 echo $ECHO_N "checking for PTRACE_GETREGS... $ECHO_C" >&6
   if test "${gdbsrv_cv_have_ptrace_getregs+set}" = set; then
@@ -3290,7 +3296,7 @@ echo "${ECHO_T}$gdbsrv_cv_have_ptrace_ge
   if test "${gdbsrv_cv_have_ptrace_getregs}" = "yes"; then
 
 cat >>confdefs.h <<\_ACEOF
-#define HAVE_LINUX_REGSETS 1
+#define HAVE_PTRACE_GETREGS 1
 _ACEOF
 
   fi
Index: configure.ac
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/configure.ac,v
retrieving revision 1.5
diff -u -p -r1.5 configure.ac
--- configure.ac	1 Jul 2005 17:18:06 -0000	1.5
+++ configure.ac	13 Jul 2005 15:13:27 -0000
@@ -53,6 +53,9 @@ if test "${srv_linux_usrregs}" = "yes"; 
 fi
 
 if test "${srv_linux_regsets}" = "yes"; then
+  AC_DEFINE(HAVE_LINUX_REGSETS, 1,
+	    [Define if the target supports register sets.])
+
   AC_MSG_CHECKING(for PTRACE_GETREGS)
   AC_CACHE_VAL(gdbsrv_cv_have_ptrace_getregs,
   [AC_TRY_COMPILE([#include <sys/ptrace.h>],
@@ -61,7 +64,7 @@ if test "${srv_linux_regsets}" = "yes"; 
 		  [gdbsrv_cv_have_ptrace_getregs=no])])
   AC_MSG_RESULT($gdbsrv_cv_have_ptrace_getregs)
   if test "${gdbsrv_cv_have_ptrace_getregs}" = "yes"; then
-    AC_DEFINE(HAVE_LINUX_REGSETS, 1,
+    AC_DEFINE(HAVE_PTRACE_GETREGS, 1,
 	      [Define if the target supports PTRACE_GETREGS for register ]
 	      [access.])
   fi
Index: configure.srv
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/configure.srv,v
retrieving revision 1.11
diff -u -p -r1.11 configure.srv
--- configure.srv	28 May 2005 22:09:04 -0000	1.11
+++ configure.srv	13 Jul 2005 15:13:27 -0000
@@ -62,11 +62,13 @@ case "${target}" in
   powerpc64-*-linux*)	srv_regobj=reg-ppc64.o
 			srv_tgtobj="linux-low.o linux-ppc64-low.o"
 			srv_linux_usrregs=yes
+			srv_linux_regsets=yes
 			srv_linux_thread_db=yes
 			;;
   powerpc-*-linux*)	srv_regobj=reg-ppc.o
 			srv_tgtobj="linux-low.o linux-ppc-low.o"
 			srv_linux_usrregs=yes
+			srv_linux_regsets=yes
 			srv_linux_thread_db=yes
 			;;
   s390-*-linux*)	srv_regobj=reg-s390.o
Index: linux-i386-low.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/linux-i386-low.c,v
retrieving revision 1.7
diff -u -p -r1.7 linux-i386-low.c
--- linux-i386-low.c	13 Jun 2005 01:59:22 -0000	1.7
+++ linux-i386-low.c	13 Jul 2005 15:13:28 -0000
@@ -92,7 +92,7 @@ i386_cannot_fetch_register (int regno)
 }
 
 
-#ifdef HAVE_LINUX_REGSETS
+#ifdef HAVE_PTRACE_GETREGS
 #include <sys/procfs.h>
 #include <sys/ptrace.h>
 
@@ -142,24 +142,25 @@ i386_store_fpxregset (const void *buf)
   i387_fxsave_to_cache (buf);
 }
 
+#endif /* HAVE_PTRACE_GETREGS */
 
 struct regset_info target_regsets[] = {
+#ifdef HAVE_PTRACE_GETREGS
   { PTRACE_GETREGS, PTRACE_SETREGS, sizeof (elf_gregset_t),
     GENERAL_REGS,
     i386_fill_gregset, i386_store_gregset },
-#ifdef HAVE_PTRACE_GETFPXREGS
+# ifdef HAVE_PTRACE_GETFPXREGS
   { PTRACE_GETFPXREGS, PTRACE_SETFPXREGS, sizeof (elf_fpxregset_t),
     EXTENDED_REGS,
     i386_fill_fpxregset, i386_store_fpxregset },
-#endif
+# endif
   { PTRACE_GETFPREGS, PTRACE_SETFPREGS, sizeof (elf_fpregset_t),
     FP_REGS,
     i386_fill_fpregset, i386_store_fpregset },
+#endif /* HAVE_PTRACE_GETREGS */
   { 0, 0, -1, -1, NULL, NULL }
 };
 
-#endif /* HAVE_LINUX_REGSETS */
-
 static const unsigned char i386_breakpoint[] = { 0xCC };
 #define i386_breakpoint_len 1
 
Index: linux-low.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/linux-low.c,v
retrieving revision 1.40
diff -u -p -r1.40 linux-low.c
--- linux-low.c	13 Jul 2005 15:02:49 -0000	1.40
+++ linux-low.c	13 Jul 2005 15:13:28 -0000
@@ -1213,6 +1213,7 @@ static int
 regsets_fetch_inferior_registers ()
 {
   struct regset_info *regset;
+  int saw_general_regs = 0;
 
   regset = target_regsets;
 
@@ -1254,16 +1255,22 @@ regsets_fetch_inferior_registers ()
 	      perror (s);
 	    }
 	}
+      else if (regset->type == GENERAL_REGS)
+	saw_general_regs = 1;
       regset->store_function (buf);
       regset ++;
     }
-  return 0;
+  if (saw_general_regs)
+    return 0;
+  else
+    return 1;
 }
 
 static int
 regsets_store_inferior_registers ()
 {
   struct regset_info *regset;
+  int saw_general_regs = 0;
 
   regset = target_regsets;
 
@@ -1303,9 +1310,15 @@ regsets_store_inferior_registers ()
 	      perror ("Warning: ptrace(regsets_store_inferior_registers)");
 	    }
 	}
+      else if (regset->type == GENERAL_REGS)
+	saw_general_regs = 1;
       regset ++;
       free (buf);
     }
+  if (saw_general_regs)
+    return 0;
+  else
+    return 1;
   return 0;
 }
 
Index: linux-m68k-low.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/linux-m68k-low.c,v
retrieving revision 1.6
diff -u -p -r1.6 linux-m68k-low.c
--- linux-m68k-low.c	13 Jun 2005 01:59:22 -0000	1.6
+++ linux-m68k-low.c	13 Jul 2005 15:13:28 -0000
@@ -65,7 +65,7 @@ m68k_cannot_fetch_register (int regno)
   return (regno >= m68k_num_regs);
 }
 
-#ifdef HAVE_LINUX_REGSETS
+#ifdef HAVE_PTRACE_GETREGS
 #include <sys/procfs.h>
 #include <sys/ptrace.h>
 
@@ -107,19 +107,20 @@ m68k_store_fpregset (const void *buf)
 			 + (m68k_regmap[i] - m68k_regmap[m68k_num_gregs])));
 }
 
+#endif /* HAVE_PTRACE_GETREGS */
 
 struct regset_info target_regsets[] = {
+#ifdef HAVE_PTRACE_GETREGS
   { PTRACE_GETREGS, PTRACE_SETREGS, sizeof (elf_gregset_t),
     GENERAL_REGS,
     m68k_fill_gregset, m68k_store_gregset },
   { PTRACE_GETFPREGS, PTRACE_SETFPREGS, sizeof (elf_fpregset_t),
     FP_REGS,
     m68k_fill_fpregset, m68k_store_fpregset },
+#endif /* HAVE_PTRACE_GETREGS */
   { 0, 0, -1, -1, NULL, NULL }
 };
 
-#endif /* HAVE_LINUX_REGSETS */
-
 static const unsigned char m68k_breakpoint[] = { 0x4E, 0x4F };
 #define m68k_breakpoint_len 2
 
Index: linux-ppc-low.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/linux-ppc-low.c,v
retrieving revision 1.6
diff -u -p -r1.6 linux-ppc-low.c
--- linux-ppc-low.c	13 Jun 2005 01:59:22 -0000	1.6
+++ linux-ppc-low.c	13 Jul 2005 15:13:28 -0000
@@ -101,6 +101,25 @@ ppc_breakpoint_at (CORE_ADDR where)
   return 0;
 }
 
+/* Provide only a fill function for the general register set.  ps_lgetregs
+   will use this for NPTL support.  */
+
+static void ppc_fill_gregset (void *buf)
+{
+  int i;
+
+  for (i = 0; i < 32; i++)
+    collect_register (i, (char *) buf + ppc_regmap[i]);
+
+  for (i = 64; i < 70; i++)
+    collect_register (i, (char *) buf + ppc_regmap[i]);
+}
+
+struct regset_info target_regsets[] = {
+  { 0, 0, 0, GENERAL_REGS, ppc_fill_gregset, NULL },
+  { 0, 0, -1, -1, NULL, NULL }
+};
+
 struct linux_target_ops the_low_target = {
   ppc_num_regs,
   ppc_regmap,
Index: linux-ppc64-low.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/linux-ppc64-low.c,v
retrieving revision 1.4
diff -u -p -r1.4 linux-ppc64-low.c
--- linux-ppc64-low.c	13 Jul 2005 14:48:58 -0000	1.4
+++ linux-ppc64-low.c	13 Jul 2005 15:13:28 -0000
@@ -97,6 +97,25 @@ ppc_breakpoint_at (CORE_ADDR where)
   return 0;
 }
 
+/* Provide only a fill function for the general register set.  ps_lgetregs
+   will use this for NPTL support.  */
+
+static void ppc_fill_gregset (void *buf)
+{
+  int i;
+
+  for (i = 0; i < 32; i++)
+    collect_register (i, (char *) buf + ppc_regmap[i]);
+
+  for (i = 64; i < 70; i++)
+    collect_register (i, (char *) buf + ppc_regmap[i]);
+}
+
+struct regset_info target_regsets[] = {
+  { 0, 0, 0, GENERAL_REGS, ppc_fill_gregset, NULL },
+  { 0, 0, -1, -1, NULL, NULL }
+};
+
 struct linux_target_ops the_low_target = {
   ppc_num_regs,
   ppc_regmap,



More information about the Gdb-patches mailing list