This is the mail archive of the gdb-patches@sources.redhat.com 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/SPARC] Prepare for 64-bit GNU/Linux SPARC support


Committed to the SPARC-branch.

Index: ChangeLog
from  Mark Kettenis  <kettenis@gnu.org>
 
	* sparc-tdep.h (struct sparc_gregset): Add r_y_size member.
	(sparc32_supply_gregset): Renamed from sparc_supply_gregset.
	(sparc32_collect_gregset): Renamed from sparc_collect_gregset.
	(sparc32_supply_fpregset): Renamed from sparc_supply_fpregset.
	(sparc32_collect_fpregset): Renamed from sparc_collect_fpregset.
	* sparc-tdep.c (sparc32_supply_gregset): Renamed from
	sparc_supply_gregset.
	(sparc32_collect_gregset): Renamed from sparc_collect_gregset.
	(sparc32_supply_fpregset): Renamed from sparc_supply_fpregset.
	(sparc32_collect_fpregset): Renamed from sparc_collect_fpregset.
	* sparc-linux-tdep.c: Include "solib-svr4.h".
	(sparc32_linux_svr4_fetch_link_map_offsets): New function.
	(sparc32_linux_init_abi): Set solib_svr4_fetch_link_map_offsets.
	* sparc-nat.h: New file.
	* sparc-nat.c: Add some more comments.  Include "sparc-nat.h".
	(PTRACE_GETREGS): Define to PT_GETREGS if not already defined.
	(PTRACE_SETREGS, PTRACE_GETFPREGS, PTRACE_SETFPREGS): Likewise.
	(sparc_supply_gregset, sparc_collect_gregset,
	sparc_supply_fpregset, sparc_collect_fpregset,
	sparc_gregset_supplies_p, sparc_fpregset_supplies_p): New function
	variables.
	(sparc32_gregset_supplies_p): Rename from
	sparc_gregset_supplies_p.
	(sparc32_fpregset_supplies_p): Rename from
	sparc_fpregset_supplies_p.
	(fetch_inferior_registers): Deal with GNU/Linux LWPs.
	(store_inferior_registers): Likewise.  Work around peculiarity in
	NetBSD when writing the floating-point registers.
	(_initialize_sparc_nat): Initialize sparc_supply_gregset,
	sparc_collect_gregset, sparc_supply_fpregset,
	sparc_collect_fpregset, sparc_gregset_supplies_p and
	sparc_fpregset_supplies_p if necessary.
	* sparc-sol2-nat.c (supply_gregset): Call sparc32_supply_gregset
	instead of sparc_supply_gregset.
	(supply_fpregset, fill_gregset, fill_fpregset): Likewise.

 
Index: sparc-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/sparc-tdep.c,v
retrieving revision 1.127.2.3
diff -u -p -r1.127.2.3 sparc-tdep.c
--- sparc-tdep.c 25 Oct 2003 18:42:28 -0000 1.127.2.3
+++ sparc-tdep.c 2 Nov 2003 17:03:02 -0000
@@ -1079,12 +1079,10 @@ sparc_collect_rwindow (const struct regc
 
 /* Helper functions for dealing with register sets.  */
 
-/* FIXME: kettenis/20031125: Make these handle 64-bit register sets.  */
-
 void
-sparc_supply_gregset (const struct sparc_gregset *gregset,
-		      struct regcache *regcache,
-		      int regnum, const void *gregs)
+sparc32_supply_gregset (const struct sparc_gregset *gregset,
+			struct regcache *regcache,
+			int regnum, const void *gregs)
 {
   const char *regs = gregs;
   int i;
@@ -1146,9 +1144,9 @@ sparc_supply_gregset (const struct sparc
 }
 
 void
-sparc_collect_gregset (const struct sparc_gregset *gregset,
-		       const struct regcache *regcache,
-		       int regnum, void *gregs)
+sparc32_collect_gregset (const struct sparc_gregset *gregset,
+			 const struct regcache *regcache,
+			 int regnum, void *gregs)
 {
   char *regs = gregs;
   int i;
@@ -1201,8 +1199,8 @@ sparc_collect_gregset (const struct spar
 }
 
 void
-sparc_supply_fpregset (struct regcache *regcache,
-		       int regnum, const void *fpregs)
+sparc32_supply_fpregset (struct regcache *regcache,
+			 int regnum, const void *fpregs)
 {
   const char *regs = fpregs;
   int i;
@@ -1218,8 +1216,8 @@ sparc_supply_fpregset (struct regcache *
 }
 
 void
-sparc_collect_fpregset (const struct regcache *regcache,
-			int regnum, void *fpregs)
+sparc32_collect_fpregset (const struct regcache *regcache,
+			  int regnum, void *fpregs)
 {
   char *regs = fpregs;
   int i;
Index: sparc-tdep.h
===================================================================
RCS file: /cvs/src/src/gdb/sparc-tdep.h,v
retrieving revision 1.3.10.3
diff -u -p -r1.3.10.3 sparc-tdep.h
--- sparc-tdep.h 25 Oct 2003 18:42:28 -0000 1.3.10.3
+++ sparc-tdep.h 2 Nov 2003 17:03:02 -0000
@@ -38,6 +38,7 @@ struct sparc_gregset
   int r_tbr_offset;
   int r_g1_offset;
   int r_l0_offset;
+  int r_y_size;
 };
 
 /* SPARC architecture-specific information.  */
@@ -146,16 +147,16 @@ extern void sparc_collect_rwindow (const
 /* Register offsets for SunOS 4.  */
 extern const struct sparc_gregset sparc32_sunos4_gregset;
 
-extern void sparc_supply_gregset (const struct sparc_gregset *gregset,
-				  struct regcache *regcache,
-				  int regnum, const void *gregs);
-extern void sparc_collect_gregset (const struct sparc_gregset *gregset,
-				   const struct regcache *regcache,
-				   int regnum, void *gregs);
-extern void sparc_supply_fpregset (struct regcache *regcache,
-				   int regnum, const void *fpregs);
-extern void sparc_collect_fpregset (const struct regcache *regcache,
-				    int regnum, void *fpregs);
+extern void sparc32_supply_gregset (const struct sparc_gregset *gregset,
+				    struct regcache *regcache,
+				    int regnum, const void *gregs);
+extern void sparc32_collect_gregset (const struct sparc_gregset *gregset,
+				     const struct regcache *regcache,
+				     int regnum, void *gregs);
+extern void sparc32_supply_fpregset (struct regcache *regcache,
+				     int regnum, const void *fpregs);
+extern void sparc32_collect_fpregset (const struct regcache *regcache,
+				      int regnum, void *fpregs);
 
 /* Functions and variables exported from sparc-sol2-tdep.c.  */
 
@@ -163,6 +164,6 @@ extern void sparc_collect_fpregset (cons
 extern const struct sparc_gregset sparc32_sol2_gregset;
 
 extern void sparc32_sol2_init_abi (struct gdbarch_info info,
-				 struct gdbarch *gdbarch);
+				   struct gdbarch *gdbarch);
 
 #endif /* sparc-tdep.h */
Index: sparc-linux-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/Attic/sparc-linux-tdep.c,v
retrieving revision 1.1.2.1
diff -u -p -r1.1.2.1 sparc-linux-tdep.c
--- sparc-linux-tdep.c 25 Oct 2003 18:42:27 -0000 1.1.2.1
+++ sparc-linux-tdep.c 2 Nov 2003 17:03:02 -0000
@@ -22,9 +22,40 @@
 #include "defs.h"
 #include "gdbarch.h"
 #include "osabi.h"
+#include "solib-svr4.h"
 
 #include "sparc-tdep.h"
 
+static struct link_map_offsets *
+sparc32_linux_svr4_fetch_link_map_offsets (void)
+{
+  static struct link_map_offsets lmo;
+  static struct link_map_offsets *lmp = NULL;
+
+  if (lmp == NULL)
+    {
+      lmp = &lmo;
+
+      /* Everything we need is in the first 8 bytes.  */
+      lmo.r_debug_size = 8;
+      lmo.r_map_offset = 4;
+      lmo.r_map_size   = 4;
+
+      /* Everything we need is in the first 20 bytes.  */
+      lmo.link_map_size = 20;
+      lmo.l_addr_offset = 0;
+      lmo.l_addr_size   = 4;
+      lmo.l_name_offset = 4;
+      lmo.l_name_size   = 4;
+      lmo.l_next_offset = 12;
+      lmo.l_next_size   = 4;
+      lmo.l_prev_offset = 16;
+      lmo.l_prev_size   = 4;
+    }
+
+  return lmp;
+}
+
 static void
 sparc32_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 {
@@ -33,6 +64,9 @@ sparc32_linux_init_abi (struct gdbarch_i
 
   /* ... but doesn't have kernel-assisted single-stepping support.  */
   set_gdbarch_software_single_step (gdbarch, sparc_software_single_step);
+
+  set_solib_svr4_fetch_link_map_offsets
+    (gdbarch, sparc32_linux_svr4_fetch_link_map_offsets);
 }
 
 /* Provide a prototype to silence -Wmissing-prototypes.  */
Index: sparc-nat.c
===================================================================
RCS file: /cvs/src/src/gdb/sparc-nat.c,v
retrieving revision 1.21.2.1
diff -u -p -r1.21.2.1 sparc-nat.c
--- sparc-nat.c 25 Oct 2003 18:42:27 -0000 1.21.2.1
+++ sparc-nat.c 2 Nov 2003 17:03:02 -0000
@@ -23,7 +23,22 @@
 #include "inferior.h"
 #include "regcache.h"
 
-/* We need a data structure for use with ptrace(2).  SunOS 4 has
+#include <signal.h>
+#include "gdb_string.h"
+#include <sys/ptrace.h>
+#include "gdb_wait.h"
+#ifdef HAVE_MACHINE_REG_H
+#include <machine/reg.h>
+#endif
+
+#include "sparc-tdep.h"
+#include "sparc-nat.h"
+
+/* With some trickery we can use the code in this file for most (if
+   not all) ptrace(2) based SPARC systems, which includes SunOS 4,
+   Linux and the various SPARC BSD's.
+
+   First, we need a data structure for use with ptrace(2).  SunOS has
    `struct regs' and `struct fp_status' in <machine/reg.h>.  BSD's
    have `struct reg' and `struct fpreg' in <machine/reg.h>.  GNU/Linux
    has the same structures as SunOS 4, but they're in <asm/reg.h>,
@@ -35,11 +50,7 @@
    typedefs, providing them for the other systems, therefore solves
    the puzzle.  */
 
-#include <signal.h>
-#include <sys/ptrace.h>
-#include "gdb_wait.h"
 #ifdef HAVE_MACHINE_REG_H
-#include <machine/reg.h>
 #ifdef HAVE_STRUCT_REG
 typedef struct reg gregset_t;
 typedef struct fpreg fpregset_t;
@@ -49,15 +60,40 @@ typedef struct fp_status fpregset_t;
 #endif
 #endif
 
-#include "sparc-tdep.h"
+/* Second, we need to remap the BSD ptrace(2) requests to their SunOS
+   equivalents.  GNU/Linux already follows SunOS here.  */
+
+#ifndef PTRACE_GETREGS
+#define PTRACE_GETREGS PT_GETREGS
+#endif
+
+#ifndef PTRACE_SETREGS
+#define PTRACE_SETREGS PT_SETREGS
+#endif
+
+#ifndef PTRACE_GETFPREGS
+#define PTRACE_GETFPREGS PT_GETFPREGS
+#endif
+
+#ifndef PTRACE_SETFPREGS
+#define PTRACE_SETFPREGS PT_SETFPREGS
+#endif
 
 /* Register set description.  */
 const struct sparc_gregset *sparc_gregset;
+void (*sparc_supply_gregset) (const struct sparc_gregset *,
+			      struct regcache *, int , const void *);
+void (*sparc_collect_gregset) (const struct sparc_gregset *,
+			       const struct regcache *, int, void *);
+void (*sparc_supply_fpregset) (struct regcache *, int , const void *);
+void (*sparc_collect_fpregset) (const struct regcache *, int , void *);
+int (*sparc_gregset_supplies_p) (int);
+int (*sparc_fpregset_supplies_p) (int);
 
 /* Determine whether `gregset_t' contains register REGNUM.  */
 
 int
-sparc_gregset_supplies_p (int regnum)
+sparc32_gregset_supplies_p (int regnum)
 {
   /* Integer registers.  */
   if ((regnum >= SPARC_G1_REGNUM && regnum <= SPARC_G7_REGNUM)
@@ -78,8 +114,8 @@ sparc_gregset_supplies_p (int regnum)
 
 /* Determine whether `fpregset_t' contains register REGNUM.  */
 
-static int
-sparc_fpregset_supplies_p (int regnum)
+int
+sparc32_fpregset_supplies_p (int regnum)
 {
   /* Floating-point registers.  */
   if (regnum >= SPARC_F0_REGNUM && regnum <= SPARC_F31_REGNUM)
@@ -99,6 +135,24 @@ void
 fetch_inferior_registers (int regnum)
 {
   struct regcache *regcache = current_regcache;
+  int pid;
+
+  /* NOTE: cagney/2002-12-03: This code assumes that the currently
+     selected light weight processes' registers can be written
+     directly into the selected thread's register cache.  This works
+     fine when given an 1:1 LWP:thread model (such as found on
+     GNU/Linux) but will, likely, have problems when used on an N:1
+     (userland threads) or N:M (userland multiple LWP) model.  In the
+     case of the latter two, the LWP's registers do not necessarily
+     belong to the selected thread (the LWP could be in the middle of
+     executing the thread switch code).
+
+     These functions should instead be paramaterized with an explicit
+     object (struct regcache, struct thread_info?) into which the LWPs
+     registers can be written.  */
+  pid = TIDGET (inferior_ptid);
+  if (pid == 0)
+    pid = PIDGET (inferior_ptid);
 
   if (regnum == SPARC_G0_REGNUM)
     {
@@ -110,8 +164,7 @@ fetch_inferior_registers (int regnum)
     {
       gregset_t regs;
 
-      if (ptrace (PTRACE_GETREGS, PIDGET (inferior_ptid),
-		  (PTRACE_ARG3_TYPE) &regs, 0) == -1)
+      if (ptrace (PTRACE_GETREGS, pid, (PTRACE_ARG3_TYPE) &regs, 0) == -1)
 	perror_with_name ("Couldn't get registers");
 
       sparc_supply_gregset (sparc_gregset, regcache, -1, &regs);
@@ -123,8 +176,7 @@ fetch_inferior_registers (int regnum)
     {
       fpregset_t fpregs;
 
-      if (ptrace (PTRACE_GETFPREGS, PIDGET (inferior_ptid),
-		  (PTRACE_ARG3_TYPE) &fpregs, 0) == -1)
+      if (ptrace (PTRACE_GETFPREGS, pid, (PTRACE_ARG3_TYPE) &fpregs, 0) == -1)
 	perror_with_name ("Couldn't get floating point status");
 
       sparc_supply_fpregset (regcache, -1, &fpregs);
@@ -135,19 +187,24 @@ void
 store_inferior_registers (int regnum)
 {
   struct regcache *regcache = current_regcache;
+  int pid;
+
+  /* NOTE: cagney/2002-12-02: See comment in fetch_inferior_registers
+     about threaded assumptions.  */
+  pid = TIDGET (inferior_ptid);
+  if (pid == 0)
+    pid = PIDGET (inferior_ptid);
 
   if (regnum == -1 || sparc_gregset_supplies_p (regnum))
     {
       gregset_t regs;
 
-      if (ptrace (PTRACE_GETREGS, PIDGET (inferior_ptid),
-		  (PTRACE_ARG3_TYPE) &regs, 0) == -1)
+      if (ptrace (PTRACE_GETREGS, pid, (PTRACE_ARG3_TYPE) &regs, 0) == -1)
 	perror_with_name ("Couldn't get registers");
 
       sparc_collect_gregset (sparc_gregset, regcache, regnum, &regs);
 
-      if (ptrace (PTRACE_SETREGS, PIDGET (inferior_ptid),
-		  (PTRACE_ARG3_TYPE) &regs, 0) == -1)
+      if (ptrace (PTRACE_SETREGS, pid, (PTRACE_ARG3_TYPE) &regs, 0) == -1)
 	perror_with_name ("Couldn't write registers");
 
       /* Deal with the stack regs.  */
@@ -166,17 +223,24 @@ store_inferior_registers (int regnum)
 
   if (regnum == -1 || sparc_fpregset_supplies_p (regnum))
     {
-      fpregset_t fpregs;
+      fpregset_t fpregs, saved_fpregs;
 
-      if (ptrace (PTRACE_GETFPREGS, PIDGET (inferior_ptid),
-		  (PTRACE_ARG3_TYPE) &fpregs, 0) == -1)
+      if (ptrace (PTRACE_GETFPREGS, pid, (PTRACE_ARG3_TYPE) &fpregs, 0) == -1)
 	perror_with_name ("Couldn't get floating-point registers");
 
+      memcpy (&saved_fpregs, &fpregs, sizeof (fpregs));
       sparc_collect_fpregset (regcache, regnum, &fpregs);
 
-      if (ptrace (PTRACE_SETFPREGS, PIDGET (inferior_ptid),
-		  (PTRACE_ARG3_TYPE) &fpregs, 0) == -1)
-	perror_with_name ("Couldn't write floating-point registers");
+      /* Writing the floating-point registers will fail on NetBSD with
+	 EINVAL if the inferior process doesn't have an FPU state
+	 (i.e. if it didn't use the FPU yet).  Therefore we don't try
+	 to write the registers if nothing changed.  */
+      if (memcmp (&saved_fpregs, &fpregs, sizeof (fpregs)) != 0)
+	{
+	  if (ptrace (PTRACE_SETFPREGS, pid,
+		      (PTRACE_ARG3_TYPE) &fpregs, 0) == -1)
+	    perror_with_name ("Couldn't write floating-point registers");
+	}
 
       if (regnum != -1)
 	return;
@@ -193,4 +257,16 @@ _initialize_sparc_nat (void)
   /* Deafult to using SunOS 4 register sets.  */
   if (sparc_gregset == NULL)
     sparc_gregset = &sparc32_sunos4_gregset;
+  if (sparc_supply_gregset == NULL)
+    sparc_supply_gregset = sparc32_supply_gregset;
+  if (sparc_collect_gregset == NULL)
+    sparc_collect_gregset = sparc32_collect_gregset;
+  if (sparc_supply_fpregset == NULL)
+    sparc_supply_fpregset = sparc32_supply_fpregset;
+  if (sparc_collect_fpregset == NULL)
+    sparc_collect_fpregset = sparc32_collect_fpregset;
+  if (sparc_gregset_supplies_p == NULL)
+    sparc_gregset_supplies_p = sparc32_gregset_supplies_p;
+  if (sparc_fpregset_supplies_p == NULL)
+    sparc_fpregset_supplies_p = sparc32_fpregset_supplies_p;
 }
Index: sparc-nat.h
===================================================================
RCS file: sparc-nat.h
diff -N sparc-nat.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sparc-nat.h 2 Nov 2003 17:03:02 -0000
@@ -0,0 +1,40 @@
+/* Native-dependent code for SPARC.
+
+   Copyright 2003 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   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.  */
+
+#ifndef SPARC_NAT_H
+#define SPARC_NAT_H 1
+
+struct sparc_gregset;
+
+extern const struct sparc_gregset *sparc_gregset;
+extern void (*sparc_supply_gregset) (const struct sparc_gregset *,
+				     struct regcache *, int , const void *);
+extern void (*sparc_collect_gregset) (const struct sparc_gregset *,
+				      const struct regcache *, int, void *);
+extern void (*sparc_supply_fpregset) (struct regcache *, int , const void *);
+extern void (*sparc_collect_fpregset) (const struct regcache *, int , void *);
+extern int (*sparc_gregset_supplies_p) (int);
+extern int (*sparc_fpregset_supplies_p) (int);
+
+extern int sparc32_gregset_supplies_p (int regnum);
+extern int sparc32_fpregset_supplies_p (int regnum);
+
+#endif /* sparc-nat.h */
Index: sparc-sol2-nat.c
===================================================================
RCS file: /cvs/src/src/gdb/Attic/sparc-sol2-nat.c,v
retrieving revision 1.1.2.3
diff -u -p -r1.1.2.3 sparc-sol2-nat.c
--- sparc-sol2-nat.c 25 Oct 2003 18:42:28 -0000 1.1.2.3
+++ sparc-sol2-nat.c 2 Nov 2003 17:03:02 -0000
@@ -34,24 +34,24 @@
 void
 supply_gregset (prgregset_t *gregs)
 {
-  sparc_supply_gregset (&sparc32_sol2_gregset, current_regcache, -1, gregs);
+  sparc32_supply_gregset (&sparc32_sol2_gregset, current_regcache, -1, gregs);
 }
 
 void
 supply_fpregset (prfpregset_t *fpregs)
 {
-  sparc_supply_fpregset (current_regcache, -1, fpregs);
+  sparc32_supply_fpregset (current_regcache, -1, fpregs);
 }
 
 void
 fill_gregset (prgregset_t *gregs, int regnum)
 {
-  sparc_collect_gregset (&sparc32_sol2_gregset,
-			 current_regcache, regnum, gregs);
+  sparc32_collect_gregset (&sparc32_sol2_gregset,
+			   current_regcache, regnum, gregs);
 }
 
 void
 fill_fpregset (prfpregset_t *fpregs, int regnum)
 {
-  sparc_collect_fpregset (current_regcache, regnum, fpregs);
+  sparc32_collect_fpregset (current_regcache, regnum, fpregs);
 }


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