Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* Re : Debugging v8plus binaries on solaris
@ 2006-02-10 20:12 Olatunji Ruwase
  2006-02-17 22:52 ` Olatunji Ruwase
  0 siblings, 1 reply; 5+ messages in thread
From: Olatunji Ruwase @ 2006-02-10 20:12 UTC (permalink / raw)
  To: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 1178 bytes --]

Hi,
 I would like a review of the following changes that I would like to
eventually submit as patch. The changes add support for debugging v8plus
 binaries on solaris. Below is a description, please pardon the format
this is my first gdb contribution.

 Problem : Out and Global registers in v8plus are 64 bits, but v8plus
           follows the 32 bit abi.
           /proc provides /proc/<proc-id>/lwp/<lwp-id>/xregs for storing
           the upper 32 bits of these registers (and other extra
           register state info that dont fit in the 32 bit abi).

Fix     : * gdb should treat out/global registers as 64 bits for
             v8plus binaries, while respecting the abi requirements that
             only the low 32 bits are used at abi points.

           * gdb should also read/write xregs as needed.


Feature : Users will be able to view correct values of out/global
          registers when debugging v8plus binaries.
          Note that only v8plus built gdb and above will be able to
          debug v8plus binaries.

Testing : No regressions gdb-6.4 testsuite for v8plus and v9 gdb.
          Testing done with gcc 4.0.2, solaris 2.9.

Thanks

tunji








[-- Attachment #2: v8plus_patch.txt --]
[-- Type: text/plain, Size: 28540 bytes --]

diff -upr old_src/gregset.h new_src/gregset.h
--- old_src/gregset.h	2002-05-08 16:29:11.000000000 -0700
+++ new_src/gregset.h	2006-02-09 11:18:26.166141000 -0800
@@ -45,6 +45,19 @@ typedef GDB_FPREGSET_T gdb_fpregset_t;
 extern void supply_gregset (gdb_gregset_t *gregs);
 extern void supply_fpregset (gdb_fpregset_t *fpregs);
 
+#ifdef PCSXREG
+
+#ifndef GDB_XREGSET_T
+#define GDB_XREGSET_T prxregset_t
+#endif 
+
+typedef GDB_XREGSET_T gdb_xregset_t;
+
+extern void supply_xregset (gdb_xregset_t *);
+extern void fill_xregset (gdb_xregset_t *, int regno);
+
+#endif /* PCSXREG */
+
 /* Copy register values from GDB's register cache into
    the native target gregset/fpregset.  If regno is -1, 
    copy all the registers.  */
diff -upr old_src/procfs.c new_src/procfs.c
--- old_src/procfs.c	2005-02-15 07:49:14.000000000 -0800
+++ new_src/procfs.c	2006-02-09 17:34:37.112140000 -0800
@@ -328,6 +328,11 @@ typedef struct siginfo gdb_siginfo_t;
 /* the name of the proc status struct depends on the implementation */
 typedef pstatus_t   gdb_prstatus_t;
 typedef lwpstatus_t gdb_lwpstatus_t;
+
+#ifdef PCSXREG
+typedef prxregset_t gdb_prxregset_t;
+#endif  /* PCSXREG */
+
 #else /* ! NEW_PROC_API */
 /* format strings for /proc paths */
 # ifndef CTL_PROC_NAME_FMT
@@ -367,6 +372,10 @@ typedef struct procinfo {
   int status_fd;		/* File descriptor for /proc status file */
   int as_fd;			/* File descriptor for /proc as file */
 
+#ifdef PCSXREG
+  int xregs_fd;
+#endif 
+
   char pathname[MAX_PROC_NAME_SIZE];	/* Pathname to /proc entry */
 
   fltset_t saved_fltset;	/* Saved traced hardware fault set */
@@ -381,6 +390,10 @@ typedef struct procinfo {
   gdb_fpregset_t fpregset;	/* Current floating point registers */
 #endif
 
+#ifdef PCSXREG
+  gdb_prxregset_t xregset;
+#endif
+
 #ifdef DYNAMIC_SYSCALLS
   int num_syscalls;		/* Total number of syscalls */
   char **syscall_names;		/* Syscall number to name map */
@@ -392,6 +405,11 @@ typedef struct procinfo {
   int gregs_valid  : 1;
   int fpregs_valid : 1;
   int threads_valid: 1;
+
+#ifdef PCSXREG 
+  int xregs_valid : 1;
+#endif
+
 } procinfo;
 
 static char errmsg[128];	/* shared error msg buffer */
@@ -521,7 +539,7 @@ open_with_retry (const char *pathname, i
  * Return: file descriptor, or zero for failure.
  */
 
-enum { FD_CTL, FD_STATUS, FD_AS };
+enum { FD_CTL, FD_STATUS, FD_AS, FD_XREGS };
 
 static int
 open_procinfo_files (procinfo *pi, int which)
@@ -553,6 +571,7 @@ open_procinfo_files (procinfo *pi, int w
    *     Pathnames for an LWP (lwp-id):
    *       /proc/<proc-id>/lwp/<lwp-id>/lwpctl
    *       /proc/<proc-id>/lwp/<lwp-id>/lwpstatus
+   *       /proc/<proc-id>/lwp/<lwp-id>/xregs
    *   An LWP has no map or address space file descriptor, since
    *   the memory map and address space are shared by all LWPs.
    *
@@ -617,6 +636,17 @@ open_procinfo_files (procinfo *pi, int w
       return 0;		/* fail */
     pi->status_fd = fd;
     break;
+
+#if PCSXREG
+  case FD_XREGS:
+    strcat (tmp, "/lwp/1/xregs");
+    fd = open_with_retry (tmp, O_RDONLY);
+    if (fd <= 0)
+      return 0;		/* fail */
+    pi->xregs_fd = fd;
+    break;
+#endif /* PCSXREG */
+
   default:
     return 0;		/* unknown file descriptor */
   }
@@ -2597,6 +2627,71 @@ proc_get_gregs (procinfo *pi)
 #endif
 }
 
+#ifdef PCSXREG
+
+/* Return extra state registers for the process or LWP 
+   corresponding to PI. Upon failure return NULL.  */
+gdb_prxregset_t *
+proc_get_xregs (procinfo *pi)
+{
+  int size;
+  
+  if (pi->xregs_fd == 0 &&
+      open_procinfo_files (pi, FD_XREGS) == 0)
+    {
+      pi->xregs_valid = 0;
+      return NULL;
+    }
+  memset (&pi->xregset, 0, sizeof (gdb_prxregset_t));
+  if (lseek (pi->xregs_fd, 0, SEEK_SET) < 0)
+    {
+      pi->xregs_valid = 0;
+      return NULL;
+    }
+  size = read (pi->xregs_fd, (char *) &pi->xregset,
+               sizeof (gdb_prxregset_t)) ;
+  pi->xregs_valid = (size == sizeof (gdb_prxregset_t));
+  if (pi->xregs_valid)
+    return &pi->xregset;
+  else 
+    return NULL;
+
+}
+
+/* Write extra state registers back to the process or LWP
+   corresponding to PI. Return non-zero for success, zero
+   for failure.  */
+int 
+proc_set_xregs (procinfo *pi)
+{
+  int win;
+  gdb_xregset_t *xregs;
+  
+  xregs = proc_get_xregs (pi);
+  if (xregs == NULL)
+    return 0;
+  
+  if (pi->ctl_fd == 0 && open_procinfo_files (pi, FD_CTL) == 0)
+    {
+      return 0;
+    }
+  else
+    {
+      struct 
+      {
+        procfs_ctl_t cmd;
+        gdb_xregset_t xregs;
+      } arg;
+      arg.cmd = PCSXREG;
+      memcpy (&arg.xregs, xregs, sizeof (arg.xregs));
+      win = (write (pi->ctl_fd, (void *) &arg, sizeof (arg)) == sizeof (arg));
+    }
+  pi->xregs_valid = 0;  
+
+  return  win;
+}
+#endif /* PCSXREG */
+
 /* Return the general-purpose registers for the process or LWP
    corresponding to PI.  Upon failure, return NULL.  */
 
@@ -3686,6 +3781,11 @@ procfs_fetch_registers (int regnum)
   procinfo *pi;
   int pid = PIDGET (inferior_ptid);
   int tid = TIDGET (inferior_ptid);
+  unsigned long mach = gdbarch_bfd_arch_info (current_gdbarch)->mach;
+  int sparc_v8plus = (bfd_mach_sparc_v9_p (mach) && !bfd_mach_sparc_64bit_p (mach));
+#ifdef PCSXREG
+  gdb_prxregset_t *xregs;
+#endif
 
   /* First look up procinfo for the main process.  */
   pi = find_procinfo_or_die (pid, 0);
@@ -3706,6 +3806,15 @@ procfs_fetch_registers (int regnum)
 
   supply_gregset (gregs);
 
+  if (sparc_v8plus)  
+    {
+#ifdef PCSXREG
+      xregs = proc_get_xregs (pi);
+      if (xregs != NULL)
+        supply_xregset (xregs);
+#endif
+    }
+ 
   if (FP0_REGNUM >= 0)		/* Do we have an FPU?  */
     {
       gdb_fpregset_t *fpregs;
@@ -3754,6 +3863,11 @@ procfs_store_registers (int regnum)
   procinfo *pi;
   int pid = PIDGET (inferior_ptid);
   int tid = TIDGET (inferior_ptid);
+  unsigned long mach = gdbarch_bfd_arch_info (current_gdbarch)->mach;
+  int sparc_v8plus = (bfd_mach_sparc_v9_p (mach) && !bfd_mach_sparc_64bit_p (mach));
+#ifdef PCSXREG
+  gdb_prxregset_t *xregs;
+#endif
 
   /* First find procinfo for main process.  */
   pi = find_procinfo_or_die (pid, 0);
@@ -3776,6 +3890,19 @@ procfs_store_registers (int regnum)
   if (!proc_set_gregs (pi))
     proc_error (pi, "store_registers, set_gregs", __LINE__);
 
+  if (sparc_v8plus)
+    {
+#ifdef PCSXREG
+      xregs = proc_get_xregs (pi);
+      if (xregs != NULL)
+        {
+          fill_xregset (xregs, regnum);
+          proc_set_xregs (pi);
+        }
+#endif  
+    }
+  
+
   if (FP0_REGNUM >= 0)		/* Do we have an FPU?  */
     {
       gdb_fpregset_t *fpregs;
diff -upr old_src/sparc-sol2-nat.c new_src/sparc-sol2-nat.c
--- old_src/sparc-sol2-nat.c	2004-01-03 10:21:01.000000000 -0800
+++ new_src/sparc-sol2-nat.c	2006-02-09 15:21:38.093231000 -0800
@@ -24,6 +24,7 @@
 
 #include <sys/procfs.h>
 #include "gregset.h"
+#include <sys/ucontext.h>
 
 #include "sparc-tdep.h"
 
@@ -70,9 +71,12 @@
 
 #define sparc_sol2_gregset sparc32_sol2_gregset
 #define sparc_sol2_fpregset sparc32_sol2_fpregset
-
 #endif
 
+#define sparc_supply_xregset sparc32_supply_xregset 
+#define sparc_collect_xregset sparc32_collect_xregset
+#define sparc_sol2_xregset  sparc32_sol2_xregset
+
 void
 supply_gregset (prgregset_t *gregs)
 {
@@ -96,3 +100,14 @@ fill_fpregset (prfpregset_t *fpregs, int
 {
   sparc_collect_fpregset (current_regcache, regnum, fpregs);
 }
+
+void
+supply_xregset (prxregset_t *xregs)
+{
+  sparc_supply_xregset (&sparc_sol2_xregset, current_regcache, -1, xregs);
+}
+
+void fill_xregset (prxregset_t *xregs, int regnum)
+{
+  sparc_collect_xregset (&sparc_sol2_xregset, current_regcache, regnum, xregs);
+}
diff -upr old_src/sparc-sol2-tdep.c new_src/sparc-sol2-tdep.c
--- old_src/sparc-sol2-tdep.c	2005-08-13 15:09:06.000000000 -0700
+++ new_src/sparc-sol2-tdep.c	2006-02-09 17:28:50.748354000 -0800
@@ -48,6 +48,15 @@ const struct sparc_gregset sparc32_sol2_
   1 * 4,			/* %g1 */
   16 * 4,			/* %l0 */
 };
+
+#define XRS_ID              0x78727300    /* the string "xrs" */
+#define XRS_ID_OFFSET       224          /* offset of xrs in mcontext_t*/
+
+const struct sparc_xregset sparc32_sol2_xregset =
+{
+  148,                         /* xr_g1 */    
+};
+
 \f
 
 /* The Solaris signal trampolines reside in libc.  For normal signals,
@@ -74,6 +83,39 @@ sparc_sol2_pc_in_sigtramp (CORE_ADDR pc,
 		   || strcmp (name, "__sighndlr") == 0));
 }
 
+
+/* Extract and cache extra register state from uc_mcontext member of
+ ucontext_t instance if available.  */
+void 
+sparc32_sol2_frame_cache_xregs (CORE_ADDR mcontext_addr,
+                                struct frame_info *next_frame, 
+                                struct sparc_frame_cache *cache)
+{
+  CORE_ADDR addr;
+  int numregs = SPARC_O7_REGNUM + 1; 
+  int regnum, xrs_id;
+  
+  xrs_id = get_frame_memory_unsigned (next_frame, 
+                                      (mcontext_addr + XRS_ID_OFFSET), 4);
+  if (xrs_id != XRS_ID)
+    return;
+  
+  addr = get_frame_memory_unsigned (next_frame, 
+                                    (mcontext_addr + XRS_ID_OFFSET + 4), 4);
+  addr += sparc32_sol2_xregset.xr_g1_offset;
+  cache->saved_xregs = FRAME_OBSTACK_CALLOC (numregs,
+                                             struct trad_frame_saved_reg);
+  cache->saved_xregs[SPARC_G0_REGNUM].realreg = SPARC_G0_REGNUM;
+  cache->saved_xregs[SPARC_G0_REGNUM].addr = -1;
+  for (regnum = SPARC_G1_REGNUM; regnum < numregs; regnum++, addr +=4)
+    {
+      cache->saved_xregs[regnum].realreg = regnum;
+      cache->saved_xregs[regnum].addr = addr;
+    }
+  return;
+}
+
+
 static struct sparc_frame_cache *
 sparc32_sol2_sigtramp_frame_cache (struct frame_info *next_frame,
 				   void **this_cache)
@@ -81,7 +123,9 @@ sparc32_sol2_sigtramp_frame_cache (struc
   struct sparc_frame_cache *cache;
   CORE_ADDR mcontext_addr, addr;
   int regnum;
-
+  struct gdbarch *gdbarch = get_frame_arch (next_frame);
+  unsigned long mach = gdbarch_bfd_arch_info (current_gdbarch)->mach;
+  
   if (*this_cache)
     return *this_cache;
 
@@ -121,6 +165,9 @@ sparc32_sol2_sigtramp_frame_cache (struc
 	cache->saved_regs[regnum].addr = addr;
     }
 
+  if (bfd_mach_sparc_v8plus_p (mach))
+    sparc32_sol2_frame_cache_xregs (mcontext_addr, next_frame, cache);
+  
   return cache;
 }
 
@@ -135,6 +182,40 @@ sparc32_sol2_sigtramp_frame_this_id (str
   (*this_id) = frame_id_build (cache->base, cache->pc);
 }
 
+
+/* Read associate extra register state information.  */
+static 
+void sparc32_sol2_sigtramp_frame_prev_xregs (struct frame_info *next_frame,
+                                             struct sparc_frame_cache *cache,
+                                             int regnum, int *optimizedp,
+                                             enum lval_type *lvalp, CORE_ADDR *addrp,
+                                             int *realregp, gdb_byte *bufferp)
+     
+{
+  struct gdbarch *gdbarch = get_frame_arch (next_frame);
+
+  if (!trad_frame_addr_p (cache->saved_regs, regnum))
+    error (_("Register %s not saved in memory"),
+           gdbarch_register_name (gdbarch, regnum));
+
+  /* The register was saved in memory.  */
+  *optimizedp = 0;
+  *lvalp = lval_memory;
+  *addrp = cache->saved_regs[regnum].addr;
+  *realregp = -1;
+  if (bufferp != NULL)
+    {
+      /* Read the value in from memory.  */
+      memset (bufferp, 0, register_size (gdbarch, regnum));
+      get_frame_memory (next_frame, cache->saved_xregs[regnum].addr, bufferp, 4);
+      get_frame_memory (next_frame, cache->saved_regs[regnum].addr, 
+                        bufferp + 4, 4);
+    } 
+
+  return;
+}
+
+
 static void
 sparc32_sol2_sigtramp_frame_prev_register (struct frame_info *next_frame,
 					   void **this_cache,
@@ -148,6 +229,13 @@ sparc32_sol2_sigtramp_frame_prev_registe
 
   trad_frame_get_prev_register (next_frame, cache->saved_regs, regnum,
 				optimizedp, lvalp, addrp, realnump, valuep);
+  if (cache->saved_xregs && 
+      ((regnum >= SPARC_G0_REGNUM) && (regnum <= SPARC_O7_REGNUM))
+      && trad_frame_addr_p (cache->saved_regs, regnum))
+    {
+      sparc32_sol2_sigtramp_frame_prev_xregs (next_frame, cache, regnum,optimizedp, 
+                                              lvalp, addrp, realnump, valuep);
+    }
 }
 
 static const struct frame_unwind sparc32_sol2_sigtramp_frame_unwind =
diff -upr old_src/sparc-tdep.c new_src/sparc-tdep.c
--- old_src/sparc-tdep.c	2005-08-13 15:12:24.000000000 -0700
+++ new_src/sparc-tdep.c	2006-02-09 17:38:00.553882000 -0800
@@ -300,12 +300,22 @@ sparc32_register_name (int regnum)
 static struct type *
 sparc32_register_type (struct gdbarch *gdbarch, int regnum)
 {
+  unsigned long mach = gdbarch_bfd_arch_info (current_gdbarch)->mach;
+  
   if (regnum >= SPARC_F0_REGNUM && regnum <= SPARC_F31_REGNUM)
     return builtin_type_float;
-
+  
   if (regnum >= SPARC32_D0_REGNUM && regnum <= SPARC32_D30_REGNUM)
     return builtin_type_double;
-
+  
+  /* sparc_v8plus support. v8plus is 32 bit abi, but with v9 ISA. This
+     allows software to use global and out registers as 64 bits registers.  */
+  if (bfd_mach_sparc_v8plus_p (mach))
+    {
+      if ((regnum >= SPARC_G0_REGNUM) && (regnum <= SPARC_O7_REGNUM))
+        return builtin_type_int64;
+    }
+  
   if (regnum == SPARC_SP_REGNUM || regnum == SPARC_FP_REGNUM)
     return builtin_type_void_data_ptr;
 
@@ -372,7 +382,11 @@ sparc32_store_arguments (struct regcache
   int num_elements = 0;
   int element = 0;
   int i;
+  gdb_byte buf[8];
+  unsigned long mach = gdbarch_bfd_arch_info (current_gdbarch)->mach;
+  int sparc_v8plus = bfd_mach_sparc_v8plus_p (mach);
 
+  memset (buf, 0, sizeof (buf));
   for (i = 0; i < nargs; i++)
     {
       struct type *type = value_type (args[i]);
@@ -421,21 +435,38 @@ sparc32_store_arguments (struct regcache
      aligned."  */
   sp &= ~0x7;
 
+
   for (i = 0; i < nargs; i++)
     {
       const bfd_byte *valbuf = value_contents (args[i]);
       struct type *type = value_type (args[i]);
       int len = TYPE_LENGTH (type);
-
+      
       gdb_assert (len == 4 || len == 8);
-
+      
       if (element < 6)
 	{
 	  int regnum = SPARC_O0_REGNUM + element;
-
-	  regcache_cooked_write (regcache, regnum, valbuf);
+          
+          if (sparc_v8plus)
+            {
+              /* Although v8plus out registers are 64 bits,
+                 only the lower 32 bits are used for argument passing.  */
+              memcpy (buf + 4, valbuf, 4);
+              regcache_cooked_write (regcache, regnum, buf);
+            }
+          else 
+            regcache_cooked_write (regcache, regnum, valbuf);
 	  if (len > 4 && element < 5)
-	    regcache_cooked_write (regcache, regnum + 1, valbuf + 4);
+            {
+              if (sparc_v8plus)
+                {
+                  memcpy (buf + 4, valbuf + 4, 4);
+                  regcache_cooked_write (regcache, regnum + 1, buf);
+                }
+              else
+                regcache_cooked_write (regcache, regnum + 1, valbuf + 4);
+            }
 	}
 
       /* Always store the argument in memory.  */
@@ -743,6 +774,7 @@ sparc32_frame_prev_register (struct fram
 			     enum lval_type *lvalp, CORE_ADDR *addrp,
 			     int *realnump, gdb_byte *valuep)
 {
+  int prev_out_reg = 0;
   struct sparc_frame_cache *cache =
     sparc32_frame_cache (next_frame, this_cache);
 
@@ -815,14 +847,26 @@ sparc32_frame_prev_register (struct fram
      current frame's `in' registers.  */
   if (!cache->frameless_p
       && regnum >= SPARC_O0_REGNUM && regnum <= SPARC_O7_REGNUM)
-    regnum += (SPARC_I0_REGNUM - SPARC_O0_REGNUM);
+    {
+      regnum += (SPARC_I0_REGNUM - SPARC_O0_REGNUM);
+      prev_out_reg = 1;
+    }
 
   *optimizedp = 0;
   *lvalp = lval_register;
   *addrp = 0;
   *realnump = regnum;
   if (valuep)
-    frame_unwind_register (next_frame, (*realnump), valuep);
+    {
+      if (bfd_mach_sparc_v8plus_p (gdbarch_bfd_arch_info (current_gdbarch)->mach)
+          && prev_out_reg)
+        {
+          memset (valuep, 0, 4);
+          frame_unwind_register (next_frame, (*realnump), valuep + 4);
+        }
+      else 
+        frame_unwind_register (next_frame, (*realnump), valuep);
+    }
 }
 
 static const struct frame_unwind sparc32_frame_unwind =
@@ -876,11 +920,12 @@ sparc32_extract_return_value (struct typ
 			      gdb_byte *valbuf)
 {
   int len = TYPE_LENGTH (type);
-  gdb_byte buf[8];
-
+  gdb_byte buf[MAX_REGISTER_SIZE];
+  
   gdb_assert (!sparc_structure_or_union_p (type));
   gdb_assert (!(sparc_floating_p (type) && len == 16));
 
+  memset (buf, 0, sizeof (buf));
   if (sparc_floating_p (type))
     {
       /* Floating return values.  */
@@ -892,20 +937,36 @@ sparc32_extract_return_value (struct typ
   else
     {
       /* Integral and pointer return values.  */
-      gdb_assert (sparc_integral_or_pointer_p (type));
+      int reg_size;
+      unsigned long mach = gdbarch_bfd_arch_info (current_gdbarch)->mach;
+      int sparc_v8plus = bfd_mach_sparc_v8plus_p (mach);
 
+      gdb_assert (sparc_integral_or_pointer_p (type));
+      
+      reg_size = register_size (current_gdbarch, SPARC_O0_REGNUM);
       regcache_cooked_read (regcache, SPARC_O0_REGNUM, buf);
       if (len > 4)
 	{
-	  regcache_cooked_read (regcache, SPARC_O1_REGNUM, buf + 4);
 	  gdb_assert (len == 8);
-	  memcpy (valbuf, buf, 8);
+
+          regcache_cooked_read (regcache, SPARC_O1_REGNUM, buf + reg_size);
+          if (sparc_v8plus)
+            {
+              /* The lower 4 bytes of v8plus %o0 and %o1 registers make up
+                 the return value.  */
+              memcpy (valbuf, buf + 4, 4);
+              memcpy (valbuf + 4, buf + 12, 4);
+            }
+          else 
+            {
+              memcpy (valbuf, buf, 8);
+            }
 	}
       else
 	{
 	  /* Just stripping off any unused bytes should preserve the
 	     signed-ness just fine.  */
-	  memcpy (valbuf, buf + 4 - len, len);
+          memcpy (valbuf, buf + reg_size - len, len);
 	}
     }
 }
@@ -918,11 +979,13 @@ sparc32_store_return_value (struct type 
 			    const gdb_byte *valbuf)
 {
   int len = TYPE_LENGTH (type);
-  gdb_byte buf[8];
-
+  gdb_byte buf[MAX_REGISTER_SIZE];
+  
   gdb_assert (!sparc_structure_or_union_p (type));
   gdb_assert (!(sparc_floating_p (type) && len == 16));
 
+  memset (buf, 0, MAX_REGISTER_SIZE);
+
   if (sparc_floating_p (type))
     {
       /* Floating return values.  */
@@ -934,20 +997,34 @@ sparc32_store_return_value (struct type 
   else
     {
       /* Integral and pointer return values.  */
+      int reg_size;
+      unsigned long mach = gdbarch_bfd_arch_info (current_gdbarch)->mach;
+      int sparc_v8plus = bfd_mach_sparc_v8plus_p (mach);
+
       gdb_assert (sparc_integral_or_pointer_p (type));
 
+      reg_size = register_size (current_gdbarch, SPARC_O0_REGNUM);
       if (len > 4)
 	{
 	  gdb_assert (len == 8);
-	  memcpy (buf, valbuf, 8);
-	  regcache_cooked_write (regcache, SPARC_O1_REGNUM, buf + 4);
+          if (sparc_v8plus)
+            {
+              memcpy (buf + 4, valbuf, 4);
+              memcpy (buf + 12, valbuf + 4, 4);
+            }
+          else 
+            {
+              memcpy (buf, valbuf, 8);
+            }
+          regcache_cooked_write (regcache, SPARC_O1_REGNUM, buf + reg_size);
 	}
       else
 	{
 	  /* ??? Do we need to do any sign-extension here?  */
-	  memcpy (buf + 4 - len, valbuf, len);
+          memcpy (buf + reg_size - len, valbuf, len);
 	}
-      regcache_cooked_write (regcache, SPARC_O0_REGNUM, buf);
+
+        regcache_cooked_write (regcache, SPARC_O0_REGNUM, buf);
     }
 }
 
@@ -1395,6 +1472,8 @@ sparc32_supply_gregset (const struct spa
 {
   const gdb_byte *regs = gregs;
   int i;
+  gdb_byte buf[8];
+  unsigned long mach = gdbarch_bfd_arch_info (current_gdbarch)->mach;
 
   if (regnum == SPARC32_PSR_REGNUM || regnum == -1)
     regcache_raw_supply (regcache, SPARC32_PSR_REGNUM,
@@ -1418,11 +1497,20 @@ sparc32_supply_gregset (const struct spa
   if ((regnum >= SPARC_G1_REGNUM && regnum <= SPARC_O7_REGNUM) || regnum == -1)
     {
       int offset = gregset->r_g1_offset;
-
+      
+      memset (buf, 0, sizeof (buf));
       for (i = SPARC_G1_REGNUM; i <= SPARC_O7_REGNUM; i++)
 	{
 	  if (regnum == i || regnum == -1)
-	    regcache_raw_supply (regcache, i, regs + offset);
+            {
+              if (bfd_mach_sparc_v8plus_p (mach))
+                {
+                  memcpy (buf + 4, regs + offset, 4);
+                  regcache_raw_supply (regcache, i, buf);
+                }
+              else
+                regcache_raw_supply (regcache, i, regs + offset);
+            }
 	  offset += 4;
 	}
     }
@@ -1459,6 +1547,8 @@ sparc32_collect_gregset (const struct sp
 {
   gdb_byte *regs = gregs;
   int i;
+  gdb_byte buf[8];
+  unsigned long mach = gdbarch_bfd_arch_info (current_gdbarch)->mach;
 
   if (regnum == SPARC32_PSR_REGNUM || regnum == -1)
     regcache_raw_collect (regcache, SPARC32_PSR_REGNUM,
@@ -1479,12 +1569,21 @@ sparc32_collect_gregset (const struct sp
   if ((regnum >= SPARC_G1_REGNUM && regnum <= SPARC_O7_REGNUM) || regnum == -1)
     {
       int offset = gregset->r_g1_offset;
-
+      
+      memset (buf, 0, sizeof (buf));
       /* %g0 is always zero.  */
       for (i = SPARC_G1_REGNUM; i <= SPARC_O7_REGNUM; i++)
 	{
 	  if (regnum == i || regnum == -1)
-	    regcache_raw_collect (regcache, i, regs + offset);
+            {
+              if (bfd_mach_sparc_v8plus_p (mach))
+                {
+                  regcache_raw_collect (regcache, i, buf);
+                  memcpy (regs + offset, buf + 4, 4);
+                }
+              else               
+                regcache_raw_collect (regcache, i, regs + offset);
+            }
 	  offset += 4;
 	}
     }
@@ -1507,6 +1606,71 @@ sparc32_collect_gregset (const struct sp
     }
 }
 
+void 
+sparc32_supply_xregset (const struct sparc_xregset *xregset,
+                        struct regcache *regcache,
+                        int regnum, const void *xregs)
+{
+  const gdb_byte *regs = xregs;
+  int i;
+  gdb_byte buf[8];
+  unsigned long mach = gdbarch_bfd_arch_info (current_gdbarch)->mach;
+
+  if (bfd_mach_sparc_v8plus_p (mach))
+    {
+      if ((regnum >= SPARC_G1_REGNUM && regnum <= SPARC_O7_REGNUM) || regnum == -1)
+        {
+          int offset = xregset->xr_g1_offset;
+          
+          /* %g0 is always zero.  */
+          for (i = SPARC_G1_REGNUM; i <= SPARC_O7_REGNUM; i++)
+            {
+              if (regnum == i || regnum == -1)
+                {
+                  memset (buf, 0, sizeof (buf));
+                  regcache_raw_collect (regcache, i, buf);
+                  memcpy (buf, regs + offset, 4);
+                  regcache_raw_supply (regcache, i, buf);
+                }
+              offset += 4;
+            }
+        }
+    }
+  return;
+}
+
+void 
+sparc32_collect_xregset (const struct sparc_xregset *xregset,
+                         struct regcache *regcache,
+                         int regnum, void *xregs)
+{
+  gdb_byte *regs = xregs;
+  int i;
+  gdb_byte buf[8];
+  unsigned long mach = gdbarch_bfd_arch_info (current_gdbarch)->mach;
+  
+  if (bfd_mach_sparc_v8plus_p (mach))
+    {
+      if ((regnum >= SPARC_G1_REGNUM && regnum <= SPARC_O7_REGNUM) || regnum == -1)
+        {
+          int offset = xregset->xr_g1_offset;
+          
+          memset (buf, 0, sizeof (buf));
+          /* %g0 is always zero.  */
+          for (i = SPARC_G1_REGNUM; i <= SPARC_O7_REGNUM; i++)
+            {
+              if (regnum == i || regnum == -1)
+                {
+                  regcache_raw_collect (regcache, i, buf);
+                  memcpy (regs + offset, buf, 4);
+                }
+              offset += 4;
+            }
+        }
+    }
+  return;
+}
+
 void
 sparc32_supply_fpregset (struct regcache *regcache,
 			 int regnum, const void *fpregs)
diff -upr old_src/sparc-tdep.h new_src/sparc-tdep.h
--- old_src/sparc-tdep.h	2004-11-29 07:20:27.000000000 -0800
+++ new_src/sparc-tdep.h	2006-02-09 17:28:41.454518000 -0800
@@ -28,6 +28,9 @@ struct regcache;
 struct regset;
 struct trad_frame_saved_reg;
 
+#define bfd_mach_sparc_v8plus_p(mach) \
+   (bfd_mach_sparc_v9_p (mach) && !bfd_mach_sparc_64bit_p (mach))
+ 
 /* Register offsets for the general-purpose register set.  */
 
 struct sparc_gregset
@@ -43,6 +46,12 @@ struct sparc_gregset
   int r_y_size;
 };
 
+struct sparc_xregset
+{
+  int xr_g1_offset;   /* offset of G1 register. */ 
+  /* Add other extra register state offsets as needed.  */
+};
+
 /* SPARC architecture-specific information.  */
 
 struct gdbarch_tdep
@@ -142,6 +151,9 @@ struct sparc_frame_cache
 
   /* Table of saved registers.  */
   struct trad_frame_saved_reg *saved_regs;
+
+  /* Table of saved extra registers.  */
+  struct trad_frame_saved_reg *saved_xregs;
 };
 
 /* Fetch the instruction at PC.  */
@@ -182,11 +194,18 @@ extern void sparc32_supply_fpregset (str
 				     int regnum, const void *fpregs);
 extern void sparc32_collect_fpregset (const struct regcache *regcache,
 				      int regnum, void *fpregs);
+extern void sparc32_supply_xregset  (const struct sparc_xregset *xregset,
+                                     struct regcache *regcache,
+                                     int regnum, const void *xregs);
+extern void sparc32_collect_xregset  (const struct sparc_xregset *xregset,
+                                      struct regcache *regcache,
+                                     int regnum, void *xregs);
 
 /* Functions and variables exported from sparc-sol2-tdep.c.  */
 
 /* Register offsets for Solaris 2.  */
 extern const struct sparc_gregset sparc32_sol2_gregset;
+extern const struct sparc_xregset sparc32_sol2_xregset;
 
 extern int sparc_sol2_pc_in_sigtramp (CORE_ADDR pc, char *name);
 
diff -upr old_src/sparc64-tdep.c new_src/sparc64-tdep.c
--- old_src/sparc64-tdep.c	2005-06-12 04:10:56.000000000 -0700
+++ new_src/sparc64-tdep.c	2006-02-09 09:47:02.765731000 -0800
@@ -1261,14 +1261,15 @@ sparc64_supply_gregset (const struct spa
   if ((regnum >= SPARC_G1_REGNUM && regnum <= SPARC_O7_REGNUM) || regnum == -1)
     {
       int offset = gregset->r_g1_offset;
-
-      if (sparc32)
-	offset += 4;
-
+      
+      if (sparc32 && 
+          !bfd_mach_sparc_v8plus_p (gdbarch_bfd_arch_info (current_gdbarch)->mach))
+        offset += 4;
+      
       for (i = SPARC_G1_REGNUM; i <= SPARC_O7_REGNUM; i++)
 	{
 	  if (regnum == i || regnum == -1)
-	    regcache_raw_supply (regcache, i, regs + offset);
+            regcache_raw_supply (regcache, i, regs + offset);
 	  offset += 8;
 	}
     }
@@ -1376,8 +1377,9 @@ sparc64_collect_gregset (const struct sp
     {
       int offset = gregset->r_g1_offset;
 
-      if (sparc32)
-	offset += 4;
+      if (sparc32 && 
+          !bfd_mach_sparc_v8plus_p (gdbarch_bfd_arch_info (current_gdbarch)->mach))
+        offset += 4;
 
       /* %g0 is always zero.  */
       for (i = SPARC_G1_REGNUM; i <= SPARC_O7_REGNUM; i++)
diff -upr old_src/trad-frame.c new_src/trad-frame.c
--- old_src/trad-frame.c	2005-05-22 07:53:34.000000000 -0700
+++ new_src/trad-frame.c	2006-02-09 16:55:53.357073000 -0800
@@ -148,8 +148,8 @@ trad_frame_get_prev_register (struct fra
       if (bufferp != NULL)
 	{
 	  /* Read the value in from memory.  */
-	  get_frame_memory (next_frame, this_saved_regs[regnum].addr, bufferp,
-			    register_size (gdbarch, regnum));
+          get_frame_memory (next_frame, this_saved_regs[regnum].addr, bufferp,
+                            register_size (gdbarch, regnum));
 	}
     }
   else if (trad_frame_realreg_p (this_saved_regs, regnum))

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Re : Debugging v8plus binaries on solaris
  2006-02-10 20:12 Re : Debugging v8plus binaries on solaris Olatunji Ruwase
@ 2006-02-17 22:52 ` Olatunji Ruwase
  2006-02-17 23:31   ` Mark Kettenis
  0 siblings, 1 reply; 5+ messages in thread
From: Olatunji Ruwase @ 2006-02-17 22:52 UTC (permalink / raw)
  To: gdb-patches

Hi,
 I wanted to find out if anyone was looking at this ?.

 Thanks

tunji

Olatunji Ruwase wrote On 02/10/06 12:12,:
> Hi,
>  I would like a review of the following changes that I would like to
> eventually submit as patch. The changes add support for debugging v8plus
>  binaries on solaris. Below is a description, please pardon the format
> this is my first gdb contribution.
> 
>  Problem : Out and Global registers in v8plus are 64 bits, but v8plus
>            follows the 32 bit abi.
>            /proc provides /proc/<proc-id>/lwp/<lwp-id>/xregs for storing
>            the upper 32 bits of these registers (and other extra
>            register state info that dont fit in the 32 bit abi).
> 
> Fix     : * gdb should treat out/global registers as 64 bits for
>              v8plus binaries, while respecting the abi requirements that
>              only the low 32 bits are used at abi points.
> 
>            * gdb should also read/write xregs as needed.
> 
> 
> Feature : Users will be able to view correct values of out/global
>           registers when debugging v8plus binaries.
>           Note that only v8plus built gdb and above will be able to
>           debug v8plus binaries.
> 
> Testing : No regressions gdb-6.4 testsuite for v8plus and v9 gdb.
>           Testing done with gcc 4.0.2, solaris 2.9.
> 
> Thanks
> 
> tunji
> 
> 
> 
> 
> 
> 
> 
> 
> 
> ------------------------------------------------------------------------
> 
> diff -upr old_src/gregset.h new_src/gregset.h
> --- old_src/gregset.h	2002-05-08 16:29:11.000000000 -0700
> +++ new_src/gregset.h	2006-02-09 11:18:26.166141000 -0800
> @@ -45,6 +45,19 @@ typedef GDB_FPREGSET_T gdb_fpregset_t;
>  extern void supply_gregset (gdb_gregset_t *gregs);
>  extern void supply_fpregset (gdb_fpregset_t *fpregs);
>  
> +#ifdef PCSXREG
> +
> +#ifndef GDB_XREGSET_T
> +#define GDB_XREGSET_T prxregset_t
> +#endif 
> +
> +typedef GDB_XREGSET_T gdb_xregset_t;
> +
> +extern void supply_xregset (gdb_xregset_t *);
> +extern void fill_xregset (gdb_xregset_t *, int regno);
> +
> +#endif /* PCSXREG */
> +
>  /* Copy register values from GDB's register cache into
>     the native target gregset/fpregset.  If regno is -1, 
>     copy all the registers.  */
> diff -upr old_src/procfs.c new_src/procfs.c
> --- old_src/procfs.c	2005-02-15 07:49:14.000000000 -0800
> +++ new_src/procfs.c	2006-02-09 17:34:37.112140000 -0800
> @@ -328,6 +328,11 @@ typedef struct siginfo gdb_siginfo_t;
>  /* the name of the proc status struct depends on the implementation */
>  typedef pstatus_t   gdb_prstatus_t;
>  typedef lwpstatus_t gdb_lwpstatus_t;
> +
> +#ifdef PCSXREG
> +typedef prxregset_t gdb_prxregset_t;
> +#endif  /* PCSXREG */
> +
>  #else /* ! NEW_PROC_API */
>  /* format strings for /proc paths */
>  # ifndef CTL_PROC_NAME_FMT
> @@ -367,6 +372,10 @@ typedef struct procinfo {
>    int status_fd;		/* File descriptor for /proc status file */
>    int as_fd;			/* File descriptor for /proc as file */
>  
> +#ifdef PCSXREG
> +  int xregs_fd;
> +#endif 
> +
>    char pathname[MAX_PROC_NAME_SIZE];	/* Pathname to /proc entry */
>  
>    fltset_t saved_fltset;	/* Saved traced hardware fault set */
> @@ -381,6 +390,10 @@ typedef struct procinfo {
>    gdb_fpregset_t fpregset;	/* Current floating point registers */
>  #endif
>  
> +#ifdef PCSXREG
> +  gdb_prxregset_t xregset;
> +#endif
> +
>  #ifdef DYNAMIC_SYSCALLS
>    int num_syscalls;		/* Total number of syscalls */
>    char **syscall_names;		/* Syscall number to name map */
> @@ -392,6 +405,11 @@ typedef struct procinfo {
>    int gregs_valid  : 1;
>    int fpregs_valid : 1;
>    int threads_valid: 1;
> +
> +#ifdef PCSXREG 
> +  int xregs_valid : 1;
> +#endif
> +
>  } procinfo;
>  
>  static char errmsg[128];	/* shared error msg buffer */
> @@ -521,7 +539,7 @@ open_with_retry (const char *pathname, i
>   * Return: file descriptor, or zero for failure.
>   */
>  
> -enum { FD_CTL, FD_STATUS, FD_AS };
> +enum { FD_CTL, FD_STATUS, FD_AS, FD_XREGS };
>  
>  static int
>  open_procinfo_files (procinfo *pi, int which)
> @@ -553,6 +571,7 @@ open_procinfo_files (procinfo *pi, int w
>     *     Pathnames for an LWP (lwp-id):
>     *       /proc/<proc-id>/lwp/<lwp-id>/lwpctl
>     *       /proc/<proc-id>/lwp/<lwp-id>/lwpstatus
> +   *       /proc/<proc-id>/lwp/<lwp-id>/xregs
>     *   An LWP has no map or address space file descriptor, since
>     *   the memory map and address space are shared by all LWPs.
>     *
> @@ -617,6 +636,17 @@ open_procinfo_files (procinfo *pi, int w
>        return 0;		/* fail */
>      pi->status_fd = fd;
>      break;
> +
> +#if PCSXREG
> +  case FD_XREGS:
> +    strcat (tmp, "/lwp/1/xregs");
> +    fd = open_with_retry (tmp, O_RDONLY);
> +    if (fd <= 0)
> +      return 0;		/* fail */
> +    pi->xregs_fd = fd;
> +    break;
> +#endif /* PCSXREG */
> +
>    default:
>      return 0;		/* unknown file descriptor */
>    }
> @@ -2597,6 +2627,71 @@ proc_get_gregs (procinfo *pi)
>  #endif
>  }
>  
> +#ifdef PCSXREG
> +
> +/* Return extra state registers for the process or LWP 
> +   corresponding to PI. Upon failure return NULL.  */
> +gdb_prxregset_t *
> +proc_get_xregs (procinfo *pi)
> +{
> +  int size;
> +  
> +  if (pi->xregs_fd == 0 &&
> +      open_procinfo_files (pi, FD_XREGS) == 0)
> +    {
> +      pi->xregs_valid = 0;
> +      return NULL;
> +    }
> +  memset (&pi->xregset, 0, sizeof (gdb_prxregset_t));
> +  if (lseek (pi->xregs_fd, 0, SEEK_SET) < 0)
> +    {
> +      pi->xregs_valid = 0;
> +      return NULL;
> +    }
> +  size = read (pi->xregs_fd, (char *) &pi->xregset,
> +               sizeof (gdb_prxregset_t)) ;
> +  pi->xregs_valid = (size == sizeof (gdb_prxregset_t));
> +  if (pi->xregs_valid)
> +    return &pi->xregset;
> +  else 
> +    return NULL;
> +
> +}
> +
> +/* Write extra state registers back to the process or LWP 
> +   corresponding to PI. Return non-zero for success, zero
> +   for failure.  */
> +int 
> +proc_set_xregs (procinfo *pi)
> +{
> +  int win;
> +  gdb_xregset_t *xregs;
> +  
> +  xregs = proc_get_xregs (pi);
> +  if (xregs == NULL)
> +    return 0;
> +  
> +  if (pi->ctl_fd == 0 && open_procinfo_files (pi, FD_CTL) == 0)
> +    {
> +      return 0;
> +    }
> +  else
> +    {
> +      struct 
> +      {
> +        procfs_ctl_t cmd;
> +        gdb_xregset_t xregs;
> +      } arg;
> +      arg.cmd = PCSXREG;
> +      memcpy (&arg.xregs, xregs, sizeof (arg.xregs));
> +      win = (write (pi->ctl_fd, (void *) &arg, sizeof (arg)) == sizeof (arg));
> +    }
> +  pi->xregs_valid = 0;  
> +
> +  return  win;
> +}
> +#endif /* PCSXREG */
> +
>  /* Return the general-purpose registers for the process or LWP
>     corresponding to PI.  Upon failure, return NULL.  */
>  
> @@ -3686,6 +3781,11 @@ procfs_fetch_registers (int regnum)
>    procinfo *pi;
>    int pid = PIDGET (inferior_ptid);
>    int tid = TIDGET (inferior_ptid);
> +  unsigned long mach = gdbarch_bfd_arch_info (current_gdbarch)->mach;
> +  int sparc_v8plus = (bfd_mach_sparc_v9_p (mach) && !bfd_mach_sparc_64bit_p (mach));
> +#ifdef PCSXREG
> +  gdb_prxregset_t *xregs;
> +#endif
>  
>    /* First look up procinfo for the main process.  */
>    pi = find_procinfo_or_die (pid, 0);
> @@ -3706,6 +3806,15 @@ procfs_fetch_registers (int regnum)
>  
>    supply_gregset (gregs);
>  
> +  if (sparc_v8plus)  
> +    {
> +#ifdef PCSXREG
> +      xregs = proc_get_xregs (pi);
> +      if (xregs != NULL)
> +        supply_xregset (xregs);
> +#endif
> +    }
> + 
>    if (FP0_REGNUM >= 0)		/* Do we have an FPU?  */
>      {
>        gdb_fpregset_t *fpregs;
> @@ -3754,6 +3863,11 @@ procfs_store_registers (int regnum)
>    procinfo *pi;
>    int pid = PIDGET (inferior_ptid);
>    int tid = TIDGET (inferior_ptid);
> +  unsigned long mach = gdbarch_bfd_arch_info (current_gdbarch)->mach;
> +  int sparc_v8plus = (bfd_mach_sparc_v9_p (mach) && !bfd_mach_sparc_64bit_p (mach));
> +#ifdef PCSXREG
> +  gdb_prxregset_t *xregs;
> +#endif
>  
>    /* First find procinfo for main process.  */
>    pi = find_procinfo_or_die (pid, 0);
> @@ -3776,6 +3890,19 @@ procfs_store_registers (int regnum)
>    if (!proc_set_gregs (pi))
>      proc_error (pi, "store_registers, set_gregs", __LINE__);
>  
> +  if (sparc_v8plus)
> +    {
> +#ifdef PCSXREG
> +      xregs = proc_get_xregs (pi);
> +      if (xregs != NULL)
> +        {
> +          fill_xregset (xregs, regnum);
> +          proc_set_xregs (pi);
> +        }
> +#endif  
> +    }
> +  
> +
>    if (FP0_REGNUM >= 0)		/* Do we have an FPU?  */
>      {
>        gdb_fpregset_t *fpregs;
> diff -upr old_src/sparc-sol2-nat.c new_src/sparc-sol2-nat.c
> --- old_src/sparc-sol2-nat.c	2004-01-03 10:21:01.000000000 -0800
> +++ new_src/sparc-sol2-nat.c	2006-02-09 15:21:38.093231000 -0800
> @@ -24,6 +24,7 @@
>  
>  #include <sys/procfs.h>
>  #include "gregset.h"
> +#include <sys/ucontext.h>
>  
>  #include "sparc-tdep.h"
>  
> @@ -70,9 +71,12 @@
>  
>  #define sparc_sol2_gregset sparc32_sol2_gregset
>  #define sparc_sol2_fpregset sparc32_sol2_fpregset
> -
>  #endif
>  
> +#define sparc_supply_xregset sparc32_supply_xregset 
> +#define sparc_collect_xregset sparc32_collect_xregset
> +#define sparc_sol2_xregset  sparc32_sol2_xregset
> +
>  void
>  supply_gregset (prgregset_t *gregs)
>  {
> @@ -96,3 +100,14 @@ fill_fpregset (prfpregset_t *fpregs, int
>  {
>    sparc_collect_fpregset (current_regcache, regnum, fpregs);
>  }
> +
> +void
> +supply_xregset (prxregset_t *xregs)
> +{
> +  sparc_supply_xregset (&sparc_sol2_xregset, current_regcache, -1, xregs);
> +}
> +
> +void fill_xregset (prxregset_t *xregs, int regnum)
> +{
> +  sparc_collect_xregset (&sparc_sol2_xregset, current_regcache, regnum, xregs);
> +}
> diff -upr old_src/sparc-sol2-tdep.c new_src/sparc-sol2-tdep.c
> --- old_src/sparc-sol2-tdep.c	2005-08-13 15:09:06.000000000 -0700
> +++ new_src/sparc-sol2-tdep.c	2006-02-09 17:28:50.748354000 -0800
> @@ -48,6 +48,15 @@ const struct sparc_gregset sparc32_sol2_
>    1 * 4,			/* %g1 */
>    16 * 4,			/* %l0 */
>  };
> +
> +#define XRS_ID              0x78727300    /* the string "xrs" */
> +#define XRS_ID_OFFSET       224          /* offset of xrs in mcontext_t*/
> +
> +const struct sparc_xregset sparc32_sol2_xregset =
> +{
> +  148,                         /* xr_g1 */    
> +};
> +
>  \f
>  
>  /* The Solaris signal trampolines reside in libc.  For normal signals,
> @@ -74,6 +83,39 @@ sparc_sol2_pc_in_sigtramp (CORE_ADDR pc,
>  		   || strcmp (name, "__sighndlr") == 0));
>  }
>  
> +
> +/* Extract and cache extra register state from uc_mcontext member of
> + ucontext_t instance if available.  */
> +void 
> +sparc32_sol2_frame_cache_xregs (CORE_ADDR mcontext_addr,
> +                                struct frame_info *next_frame, 
> +                                struct sparc_frame_cache *cache)
> +{
> +  CORE_ADDR addr;
> +  int numregs = SPARC_O7_REGNUM + 1; 
> +  int regnum, xrs_id;
> +  
> +  xrs_id = get_frame_memory_unsigned (next_frame, 
> +                                      (mcontext_addr + XRS_ID_OFFSET), 4);
> +  if (xrs_id != XRS_ID)
> +    return;
> +  
> +  addr = get_frame_memory_unsigned (next_frame, 
> +                                    (mcontext_addr + XRS_ID_OFFSET + 4), 4);
> +  addr += sparc32_sol2_xregset.xr_g1_offset;
> +  cache->saved_xregs = FRAME_OBSTACK_CALLOC (numregs,
> +                                             struct trad_frame_saved_reg);
> +  cache->saved_xregs[SPARC_G0_REGNUM].realreg = SPARC_G0_REGNUM;
> +  cache->saved_xregs[SPARC_G0_REGNUM].addr = -1;
> +  for (regnum = SPARC_G1_REGNUM; regnum < numregs; regnum++, addr +=4)
> +    {
> +      cache->saved_xregs[regnum].realreg = regnum;
> +      cache->saved_xregs[regnum].addr = addr;
> +    }
> +  return;
> +}
> +
> +
>  static struct sparc_frame_cache *
>  sparc32_sol2_sigtramp_frame_cache (struct frame_info *next_frame,
>  				   void **this_cache)
> @@ -81,7 +123,9 @@ sparc32_sol2_sigtramp_frame_cache (struc
>    struct sparc_frame_cache *cache;
>    CORE_ADDR mcontext_addr, addr;
>    int regnum;
> -
> +  struct gdbarch *gdbarch = get_frame_arch (next_frame);
> +  unsigned long mach = gdbarch_bfd_arch_info (current_gdbarch)->mach;
> +  
>    if (*this_cache)
>      return *this_cache;
>  
> @@ -121,6 +165,9 @@ sparc32_sol2_sigtramp_frame_cache (struc
>  	cache->saved_regs[regnum].addr = addr;
>      }
>  
> +  if (bfd_mach_sparc_v8plus_p (mach))
> +    sparc32_sol2_frame_cache_xregs (mcontext_addr, next_frame, cache);
> +  
>    return cache;
>  }
>  
> @@ -135,6 +182,40 @@ sparc32_sol2_sigtramp_frame_this_id (str
>    (*this_id) = frame_id_build (cache->base, cache->pc);
>  }
>  
> +
> +/* Read associate extra register state information.  */
> +static 
> +void sparc32_sol2_sigtramp_frame_prev_xregs (struct frame_info *next_frame,
> +                                             struct sparc_frame_cache *cache,
> +                                             int regnum, int *optimizedp,
> +                                             enum lval_type *lvalp, CORE_ADDR *addrp,
> +                                             int *realregp, gdb_byte *bufferp)
> +     
> +{
> +  struct gdbarch *gdbarch = get_frame_arch (next_frame);
> +
> +  if (!trad_frame_addr_p (cache->saved_regs, regnum))
> +    error (_("Register %s not saved in memory"),
> +           gdbarch_register_name (gdbarch, regnum));
> +
> +  /* The register was saved in memory.  */
> +  *optimizedp = 0;
> +  *lvalp = lval_memory;
> +  *addrp = cache->saved_regs[regnum].addr;
> +  *realregp = -1;
> +  if (bufferp != NULL)
> +    {
> +      /* Read the value in from memory.  */
> +      memset (bufferp, 0, register_size (gdbarch, regnum));
> +      get_frame_memory (next_frame, cache->saved_xregs[regnum].addr, bufferp, 4);
> +      get_frame_memory (next_frame, cache->saved_regs[regnum].addr, 
> +                        bufferp + 4, 4);
> +    } 
> +
> +  return;
> +}
> +
> +
>  static void
>  sparc32_sol2_sigtramp_frame_prev_register (struct frame_info *next_frame,
>  					   void **this_cache,
> @@ -148,6 +229,13 @@ sparc32_sol2_sigtramp_frame_prev_registe
>  
>    trad_frame_get_prev_register (next_frame, cache->saved_regs, regnum,
>  				optimizedp, lvalp, addrp, realnump, valuep);
> +  if (cache->saved_xregs && 
> +      ((regnum >= SPARC_G0_REGNUM) && (regnum <= SPARC_O7_REGNUM))
> +      && trad_frame_addr_p (cache->saved_regs, regnum))
> +    {
> +      sparc32_sol2_sigtramp_frame_prev_xregs (next_frame, cache, regnum,optimizedp, 
> +                                              lvalp, addrp, realnump, valuep);
> +    }
>  }
>  
>  static const struct frame_unwind sparc32_sol2_sigtramp_frame_unwind =
> diff -upr old_src/sparc-tdep.c new_src/sparc-tdep.c
> --- old_src/sparc-tdep.c	2005-08-13 15:12:24.000000000 -0700
> +++ new_src/sparc-tdep.c	2006-02-09 17:38:00.553882000 -0800
> @@ -300,12 +300,22 @@ sparc32_register_name (int regnum)
>  static struct type *
>  sparc32_register_type (struct gdbarch *gdbarch, int regnum)
>  {
> +  unsigned long mach = gdbarch_bfd_arch_info (current_gdbarch)->mach;
> +  
>    if (regnum >= SPARC_F0_REGNUM && regnum <= SPARC_F31_REGNUM)
>      return builtin_type_float;
> -
> +  
>    if (regnum >= SPARC32_D0_REGNUM && regnum <= SPARC32_D30_REGNUM)
>      return builtin_type_double;
> -
> +  
> +  /* sparc_v8plus support. v8plus is 32 bit abi, but with v9 ISA. This
> +     allows software to use global and out registers as 64 bits registers.  */
> +  if (bfd_mach_sparc_v8plus_p (mach))
> +    {
> +      if ((regnum >= SPARC_G0_REGNUM) && (regnum <= SPARC_O7_REGNUM))
> +        return builtin_type_int64;
> +    }
> +  
>    if (regnum == SPARC_SP_REGNUM || regnum == SPARC_FP_REGNUM)
>      return builtin_type_void_data_ptr;
>  
> @@ -372,7 +382,11 @@ sparc32_store_arguments (struct regcache
>    int num_elements = 0;
>    int element = 0;
>    int i;
> +  gdb_byte buf[8];
> +  unsigned long mach = gdbarch_bfd_arch_info (current_gdbarch)->mach;
> +  int sparc_v8plus = bfd_mach_sparc_v8plus_p (mach);
>  
> +  memset (buf, 0, sizeof (buf));
>    for (i = 0; i < nargs; i++)
>      {
>        struct type *type = value_type (args[i]);
> @@ -421,21 +435,38 @@ sparc32_store_arguments (struct regcache
>       aligned."  */
>    sp &= ~0x7;
>  
> +
>    for (i = 0; i < nargs; i++)
>      {
>        const bfd_byte *valbuf = value_contents (args[i]);
>        struct type *type = value_type (args[i]);
>        int len = TYPE_LENGTH (type);
> -
> +      
>        gdb_assert (len == 4 || len == 8);
> -
> +      
>        if (element < 6)
>  	{
>  	  int regnum = SPARC_O0_REGNUM + element;
> -
> -	  regcache_cooked_write (regcache, regnum, valbuf);
> +          
> +          if (sparc_v8plus)
> +            {
> +              /* Although v8plus out registers are 64 bits,
> +                 only the lower 32 bits are used for argument passing.  */
> +              memcpy (buf + 4, valbuf, 4);
> +              regcache_cooked_write (regcache, regnum, buf);
> +            }
> +          else 
> +            regcache_cooked_write (regcache, regnum, valbuf);
>  	  if (len > 4 && element < 5)
> -	    regcache_cooked_write (regcache, regnum + 1, valbuf + 4);
> +            {
> +              if (sparc_v8plus)
> +                {
> +                  memcpy (buf + 4, valbuf + 4, 4);
> +                  regcache_cooked_write (regcache, regnum + 1, buf);
> +                }
> +              else
> +                regcache_cooked_write (regcache, regnum + 1, valbuf + 4);
> +            }
>  	}
>  
>        /* Always store the argument in memory.  */
> @@ -743,6 +774,7 @@ sparc32_frame_prev_register (struct fram
>  			     enum lval_type *lvalp, CORE_ADDR *addrp,
>  			     int *realnump, gdb_byte *valuep)
>  {
> +  int prev_out_reg = 0;
>    struct sparc_frame_cache *cache =
>      sparc32_frame_cache (next_frame, this_cache);
>  
> @@ -815,14 +847,26 @@ sparc32_frame_prev_register (struct fram
>       current frame's `in' registers.  */
>    if (!cache->frameless_p
>        && regnum >= SPARC_O0_REGNUM && regnum <= SPARC_O7_REGNUM)
> -    regnum += (SPARC_I0_REGNUM - SPARC_O0_REGNUM);
> +    {
> +      regnum += (SPARC_I0_REGNUM - SPARC_O0_REGNUM);
> +      prev_out_reg = 1;
> +    }
>  
>    *optimizedp = 0;
>    *lvalp = lval_register;
>    *addrp = 0;
>    *realnump = regnum;
>    if (valuep)
> -    frame_unwind_register (next_frame, (*realnump), valuep);
> +    {
> +      if (bfd_mach_sparc_v8plus_p (gdbarch_bfd_arch_info (current_gdbarch)->mach)
> +          && prev_out_reg)
> +        {
> +          memset (valuep, 0, 4);
> +          frame_unwind_register (next_frame, (*realnump), valuep + 4);
> +        }
> +      else 
> +        frame_unwind_register (next_frame, (*realnump), valuep);
> +    }
>  }
>  
>  static const struct frame_unwind sparc32_frame_unwind =
> @@ -876,11 +920,12 @@ sparc32_extract_return_value (struct typ
>  			      gdb_byte *valbuf)
>  {
>    int len = TYPE_LENGTH (type);
> -  gdb_byte buf[8];
> -
> +  gdb_byte buf[MAX_REGISTER_SIZE];
> +  
>    gdb_assert (!sparc_structure_or_union_p (type));
>    gdb_assert (!(sparc_floating_p (type) && len == 16));
>  
> +  memset (buf, 0, sizeof (buf));
>    if (sparc_floating_p (type))
>      {
>        /* Floating return values.  */
> @@ -892,20 +937,36 @@ sparc32_extract_return_value (struct typ
>    else
>      {
>        /* Integral and pointer return values.  */
> -      gdb_assert (sparc_integral_or_pointer_p (type));
> +      int reg_size;
> +      unsigned long mach = gdbarch_bfd_arch_info (current_gdbarch)->mach;
> +      int sparc_v8plus = bfd_mach_sparc_v8plus_p (mach);
>  
> +      gdb_assert (sparc_integral_or_pointer_p (type));
> +      
> +      reg_size = register_size (current_gdbarch, SPARC_O0_REGNUM);
>        regcache_cooked_read (regcache, SPARC_O0_REGNUM, buf);
>        if (len > 4)
>  	{
> -	  regcache_cooked_read (regcache, SPARC_O1_REGNUM, buf + 4);
>  	  gdb_assert (len == 8);
> -	  memcpy (valbuf, buf, 8);
> +
> +          regcache_cooked_read (regcache, SPARC_O1_REGNUM, buf + reg_size);
> +          if (sparc_v8plus)
> +            {
> +              /* The lower 4 bytes of v8plus %o0 and %o1 registers make up
> +                 the return value.  */
> +              memcpy (valbuf, buf + 4, 4);
> +              memcpy (valbuf + 4, buf + 12, 4);
> +            }
> +          else 
> +            {
> +              memcpy (valbuf, buf, 8);
> +            }
>  	}
>        else
>  	{
>  	  /* Just stripping off any unused bytes should preserve the
>  	     signed-ness just fine.  */
> -	  memcpy (valbuf, buf + 4 - len, len);
> +          memcpy (valbuf, buf + reg_size - len, len);
>  	}
>      }
>  }
> @@ -918,11 +979,13 @@ sparc32_store_return_value (struct type 
>  			    const gdb_byte *valbuf)
>  {
>    int len = TYPE_LENGTH (type);
> -  gdb_byte buf[8];
> -
> +  gdb_byte buf[MAX_REGISTER_SIZE];
> +  
>    gdb_assert (!sparc_structure_or_union_p (type));
>    gdb_assert (!(sparc_floating_p (type) && len == 16));
>  
> +  memset (buf, 0, MAX_REGISTER_SIZE);
> +
>    if (sparc_floating_p (type))
>      {
>        /* Floating return values.  */
> @@ -934,20 +997,34 @@ sparc32_store_return_value (struct type 
>    else
>      {
>        /* Integral and pointer return values.  */
> +      int reg_size;
> +      unsigned long mach = gdbarch_bfd_arch_info (current_gdbarch)->mach;
> +      int sparc_v8plus = bfd_mach_sparc_v8plus_p (mach);
> +
>        gdb_assert (sparc_integral_or_pointer_p (type));
>  
> +      reg_size = register_size (current_gdbarch, SPARC_O0_REGNUM);
>        if (len > 4)
>  	{
>  	  gdb_assert (len == 8);
> -	  memcpy (buf, valbuf, 8);
> -	  regcache_cooked_write (regcache, SPARC_O1_REGNUM, buf + 4);
> +          if (sparc_v8plus)
> +            {
> +              memcpy (buf + 4, valbuf, 4);
> +              memcpy (buf + 12, valbuf + 4, 4);
> +            }
> +          else 
> +            {
> +              memcpy (buf, valbuf, 8);
> +            }
> +          regcache_cooked_write (regcache, SPARC_O1_REGNUM, buf + reg_size);
>  	}
>        else
>  	{
>  	  /* ??? Do we need to do any sign-extension here?  */
> -	  memcpy (buf + 4 - len, valbuf, len);
> +          memcpy (buf + reg_size - len, valbuf, len);
>  	}
> -      regcache_cooked_write (regcache, SPARC_O0_REGNUM, buf);
> +
> +        regcache_cooked_write (regcache, SPARC_O0_REGNUM, buf);
>      }
>  }
>  
> @@ -1395,6 +1472,8 @@ sparc32_supply_gregset (const struct spa
>  {
>    const gdb_byte *regs = gregs;
>    int i;
> +  gdb_byte buf[8];
> +  unsigned long mach = gdbarch_bfd_arch_info (current_gdbarch)->mach;
>  
>    if (regnum == SPARC32_PSR_REGNUM || regnum == -1)
>      regcache_raw_supply (regcache, SPARC32_PSR_REGNUM,
> @@ -1418,11 +1497,20 @@ sparc32_supply_gregset (const struct spa
>    if ((regnum >= SPARC_G1_REGNUM && regnum <= SPARC_O7_REGNUM) || regnum == -1)
>      {
>        int offset = gregset->r_g1_offset;
> -
> +      
> +      memset (buf, 0, sizeof (buf));
>        for (i = SPARC_G1_REGNUM; i <= SPARC_O7_REGNUM; i++)
>  	{
>  	  if (regnum == i || regnum == -1)
> -	    regcache_raw_supply (regcache, i, regs + offset);
> +            {
> +              if (bfd_mach_sparc_v8plus_p (mach))
> +                {
> +                  memcpy (buf + 4, regs + offset, 4);
> +                  regcache_raw_supply (regcache, i, buf);
> +                }
> +              else
> +                regcache_raw_supply (regcache, i, regs + offset);
> +            }
>  	  offset += 4;
>  	}
>      }
> @@ -1459,6 +1547,8 @@ sparc32_collect_gregset (const struct sp
>  {
>    gdb_byte *regs = gregs;
>    int i;
> +  gdb_byte buf[8];
> +  unsigned long mach = gdbarch_bfd_arch_info (current_gdbarch)->mach;
>  
>    if (regnum == SPARC32_PSR_REGNUM || regnum == -1)
>      regcache_raw_collect (regcache, SPARC32_PSR_REGNUM,
> @@ -1479,12 +1569,21 @@ sparc32_collect_gregset (const struct sp
>    if ((regnum >= SPARC_G1_REGNUM && regnum <= SPARC_O7_REGNUM) || regnum == -1)
>      {
>        int offset = gregset->r_g1_offset;
> -
> +      
> +      memset (buf, 0, sizeof (buf));
>        /* %g0 is always zero.  */
>        for (i = SPARC_G1_REGNUM; i <= SPARC_O7_REGNUM; i++)
>  	{
>  	  if (regnum == i || regnum == -1)
> -	    regcache_raw_collect (regcache, i, regs + offset);
> +            {
> +              if (bfd_mach_sparc_v8plus_p (mach))
> +                {
> +                  regcache_raw_collect (regcache, i, buf);
> +                  memcpy (regs + offset, buf + 4, 4);
> +                }
> +              else               
> +                regcache_raw_collect (regcache, i, regs + offset);
> +            }
>  	  offset += 4;
>  	}
>      }
> @@ -1507,6 +1606,71 @@ sparc32_collect_gregset (const struct sp
>      }
>  }
>  
> +void 
> +sparc32_supply_xregset (const struct sparc_xregset *xregset,
> +                        struct regcache *regcache,
> +                        int regnum, const void *xregs)
> +{
> +  const gdb_byte *regs = xregs;
> +  int i;
> +  gdb_byte buf[8];
> +  unsigned long mach = gdbarch_bfd_arch_info (current_gdbarch)->mach;
> +
> +  if (bfd_mach_sparc_v8plus_p (mach))
> +    {
> +      if ((regnum >= SPARC_G1_REGNUM && regnum <= SPARC_O7_REGNUM) || regnum == -1)
> +        {
> +          int offset = xregset->xr_g1_offset;
> +          
> +          /* %g0 is always zero.  */
> +          for (i = SPARC_G1_REGNUM; i <= SPARC_O7_REGNUM; i++)
> +            {
> +              if (regnum == i || regnum == -1)
> +                {
> +                  memset (buf, 0, sizeof (buf));
> +                  regcache_raw_collect (regcache, i, buf);
> +                  memcpy (buf, regs + offset, 4);
> +                  regcache_raw_supply (regcache, i, buf);
> +                }
> +              offset += 4;
> +            }
> +        }
> +    }
> +  return;
> +}
> +
> +void 
> +sparc32_collect_xregset (const struct sparc_xregset *xregset,
> +                         struct regcache *regcache,
> +                         int regnum, void *xregs)
> +{
> +  gdb_byte *regs = xregs;
> +  int i;
> +  gdb_byte buf[8];
> +  unsigned long mach = gdbarch_bfd_arch_info (current_gdbarch)->mach;
> +  
> +  if (bfd_mach_sparc_v8plus_p (mach))
> +    {
> +      if ((regnum >= SPARC_G1_REGNUM && regnum <= SPARC_O7_REGNUM) || regnum == -1)
> +        {
> +          int offset = xregset->xr_g1_offset;
> +          
> +          memset (buf, 0, sizeof (buf));
> +          /* %g0 is always zero.  */
> +          for (i = SPARC_G1_REGNUM; i <= SPARC_O7_REGNUM; i++)
> +            {
> +              if (regnum == i || regnum == -1)
> +                {
> +                  regcache_raw_collect (regcache, i, buf);
> +                  memcpy (regs + offset, buf, 4);
> +                }
> +              offset += 4;
> +            }
> +        }
> +    }
> +  return;
> +}
> +
>  void
>  sparc32_supply_fpregset (struct regcache *regcache,
>  			 int regnum, const void *fpregs)
> diff -upr old_src/sparc-tdep.h new_src/sparc-tdep.h
> --- old_src/sparc-tdep.h	2004-11-29 07:20:27.000000000 -0800
> +++ new_src/sparc-tdep.h	2006-02-09 17:28:41.454518000 -0800
> @@ -28,6 +28,9 @@ struct regcache;
>  struct regset;
>  struct trad_frame_saved_reg;
>  
> +#define bfd_mach_sparc_v8plus_p(mach) \
> +   (bfd_mach_sparc_v9_p (mach) && !bfd_mach_sparc_64bit_p (mach))
> + 
>  /* Register offsets for the general-purpose register set.  */
>  
>  struct sparc_gregset
> @@ -43,6 +46,12 @@ struct sparc_gregset
>    int r_y_size;
>  };
>  
> +struct sparc_xregset
> +{
> +  int xr_g1_offset;   /* offset of G1 register. */ 
> +  /* Add other extra register state offsets as needed.  */
> +};
> +
>  /* SPARC architecture-specific information.  */
>  
>  struct gdbarch_tdep
> @@ -142,6 +151,9 @@ struct sparc_frame_cache
>  
>    /* Table of saved registers.  */
>    struct trad_frame_saved_reg *saved_regs;
> +
> +  /* Table of saved extra registers.  */
> +  struct trad_frame_saved_reg *saved_xregs;
>  };
>  
>  /* Fetch the instruction at PC.  */
> @@ -182,11 +194,18 @@ extern void sparc32_supply_fpregset (str
>  				     int regnum, const void *fpregs);
>  extern void sparc32_collect_fpregset (const struct regcache *regcache,
>  				      int regnum, void *fpregs);
> +extern void sparc32_supply_xregset  (const struct sparc_xregset *xregset,
> +                                     struct regcache *regcache,
> +                                     int regnum, const void *xregs);
> +extern void sparc32_collect_xregset  (const struct sparc_xregset *xregset,
> +                                      struct regcache *regcache,
> +                                     int regnum, void *xregs);
>  
>  /* Functions and variables exported from sparc-sol2-tdep.c.  */
>  
>  /* Register offsets for Solaris 2.  */
>  extern const struct sparc_gregset sparc32_sol2_gregset;
> +extern const struct sparc_xregset sparc32_sol2_xregset;
>  
>  extern int sparc_sol2_pc_in_sigtramp (CORE_ADDR pc, char *name);
>  
> diff -upr old_src/sparc64-tdep.c new_src/sparc64-tdep.c
> --- old_src/sparc64-tdep.c	2005-06-12 04:10:56.000000000 -0700
> +++ new_src/sparc64-tdep.c	2006-02-09 09:47:02.765731000 -0800
> @@ -1261,14 +1261,15 @@ sparc64_supply_gregset (const struct spa
>    if ((regnum >= SPARC_G1_REGNUM && regnum <= SPARC_O7_REGNUM) || regnum == -1)
>      {
>        int offset = gregset->r_g1_offset;
> -
> -      if (sparc32)
> -	offset += 4;
> -
> +      
> +      if (sparc32 && 
> +          !bfd_mach_sparc_v8plus_p (gdbarch_bfd_arch_info (current_gdbarch)->mach))
> +        offset += 4;
> +      
>        for (i = SPARC_G1_REGNUM; i <= SPARC_O7_REGNUM; i++)
>  	{
>  	  if (regnum == i || regnum == -1)
> -	    regcache_raw_supply (regcache, i, regs + offset);
> +            regcache_raw_supply (regcache, i, regs + offset);
>  	  offset += 8;
>  	}
>      }
> @@ -1376,8 +1377,9 @@ sparc64_collect_gregset (const struct sp
>      {
>        int offset = gregset->r_g1_offset;
>  
> -      if (sparc32)
> -	offset += 4;
> +      if (sparc32 && 
> +          !bfd_mach_sparc_v8plus_p (gdbarch_bfd_arch_info (current_gdbarch)->mach))
> +        offset += 4;
>  
>        /* %g0 is always zero.  */
>        for (i = SPARC_G1_REGNUM; i <= SPARC_O7_REGNUM; i++)
> diff -upr old_src/trad-frame.c new_src/trad-frame.c
> --- old_src/trad-frame.c	2005-05-22 07:53:34.000000000 -0700
> +++ new_src/trad-frame.c	2006-02-09 16:55:53.357073000 -0800
> @@ -148,8 +148,8 @@ trad_frame_get_prev_register (struct fra
>        if (bufferp != NULL)
>  	{
>  	  /* Read the value in from memory.  */
> -	  get_frame_memory (next_frame, this_saved_regs[regnum].addr, bufferp,
> -			    register_size (gdbarch, regnum));
> +          get_frame_memory (next_frame, this_saved_regs[regnum].addr, bufferp,
> +                            register_size (gdbarch, regnum));
>  	}
>      }
>    else if (trad_frame_realreg_p (this_saved_regs, regnum))


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Re : Debugging v8plus binaries on solaris
  2006-02-17 22:52 ` Olatunji Ruwase
@ 2006-02-17 23:31   ` Mark Kettenis
  2006-02-22 18:24     ` Olatunji Ruwase
  2006-03-03 19:46     ` Olatunji Ruwase
  0 siblings, 2 replies; 5+ messages in thread
From: Mark Kettenis @ 2006-02-17 23:31 UTC (permalink / raw)
  To: Olatunji.Ruwase; +Cc: gdb-patches

> Date: Fri, 17 Feb 2006 14:51:31 -0800
> From: Olatunji Ruwase <Olatunji.Ruwase@Sun.COM>

Sorry, I spent most of the week in bed/on the couch in front of the
telly with a bad flu :(.  I had a first glance at it last week, but
I'm afraid it needs a bit more work.

For one thing, I think it's important to split the generic v8plus
target support out from the Solaris v8plus native support.  And
concentrate on the target support first.  The seperation is mostly
already there (*-tdep.c versus *-nat.c), but some of the Solaris
native "weirdness" (which I realize is necessary for backwards
compatibility) has crept into the target support.

Looking from an OS agnostic point onto the v8plus support code, I
really think v8plus should be a seperate architecture much in the same
way existing 64-bit support is seperate from the 32-bit support.  Of
course this v8plus architecture should reuse as much code from the
existing 32-bit code as possible, and if the 32-bit code can be
generalized to work for v8plus as well, that's great, but I think
constructs like

  if (sparc_v8plus)
    {
      ...
    }
  else
    {
      ...
    }

should be avoided.  I also think the xregset stuff should be moved
into Solaris-specific files, perhaps even into Solaris-specofic
*-nat.c files.  This depends a bit on how v8plus core dumps look.  If
they have the xregset stuff too, the code should probably be moved to
sparc-sol2-tdep.c or sparc64-sol2-tdep.c.

Is the v8plus ABI documented somewhere?

Mark


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Re : Debugging v8plus binaries on solaris
  2006-02-17 23:31   ` Mark Kettenis
@ 2006-02-22 18:24     ` Olatunji Ruwase
  2006-03-03 19:46     ` Olatunji Ruwase
  1 sibling, 0 replies; 5+ messages in thread
From: Olatunji Ruwase @ 2006-02-22 18:24 UTC (permalink / raw)
  To: Mark Kettenis; +Cc: gdb-patches



Mark Kettenis wrote On 02/17/06 15:31,:
>>Date: Fri, 17 Feb 2006 14:51:31 -0800
>>From: Olatunji Ruwase <Olatunji.Ruwase@Sun.COM>
> 
> 
> Sorry, I spent most of the week in bed/on the couch in front of the
> telly with a bad flu :(.  I had a first glance at it last week, but
Nice to have you back :).
> I'm afraid it needs a bit more work.
I suspected it would, this is my first stab at gdb development, and
the architecture of the code is still a bit fuzzy to me.
> 
> For one thing, I think it's important to split the generic v8plus
> target support out from the Solaris v8plus native support.  And
> concentrate on the target support first.  The seperation is mostly
> already there (*-tdep.c versus *-nat.c), but some of the Solaris
> native "weirdness" (which I realize is necessary for backwards
> compatibility) has crept into the target support.
> 
> Looking from an OS agnostic point onto the v8plus support code, I
> really think v8plus should be a seperate architecture much in the same
> way existing 64-bit support is seperate from the 32-bit support.  Of
> course this v8plus architecture should reuse as much code from the
> existing 32-bit code as possible, and if the 32-bit code can be
> generalized to work for v8plus as well, that's great, but I think
> constructs like
> 
>   if (sparc_v8plus)
>     {
>       ...
>     }
>   else
>     {
>       ...
>     }
> 
Most of my changes to the target support (sparc-tdep.c) are wrapped in
the above construct. sparc32 target support assumes that registers are
4 bytes. One way to eliminate the "if (sparc_v8plus)" is to rewrite
the code to also support 8 byte registers, while making sure that data
is only written and read from the low 4 bytes.  However this proposed
change will not work for sparc32_register_type(), but should work for
all other cases. Will  this be an acceptable complexity in the target
support code ?. If not I will start moving all the changes into
sparc32plus-* files.
> should be avoided.  I also think the xregset stuff should be moved
> into Solaris-specific files, perhaps even into Solaris-specofic
> *-nat.c files.  This depends a bit on how v8plus core dumps look.  If
> they have the xregset stuff too, the code should probably be moved to
> sparc-sol2-tdep.c or sparc64-sol2-tdep.c.
Yes the v8plus core dump has xregset stuff in it. And I now see why
these changes need to be restricted to solaris specific files.
> 
> Is the v8plus ABI documented somewhere?
Unfortunately I dont think it is, I cant find any :(.

Thanks


tunji
> 
> Mark


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Re : Debugging v8plus binaries on solaris
  2006-02-17 23:31   ` Mark Kettenis
  2006-02-22 18:24     ` Olatunji Ruwase
@ 2006-03-03 19:46     ` Olatunji Ruwase
  1 sibling, 0 replies; 5+ messages in thread
From: Olatunji Ruwase @ 2006-03-03 19:46 UTC (permalink / raw)
  To: Mark Kettenis; +Cc: gdb-patches



Mark Kettenis wrote On 02/17/06 15:31,:
>>Date: Fri, 17 Feb 2006 14:51:31 -0800
> Is the v8plus ABI documented somewhere?
> 
Location of is given the link below. I 'll work on making it easier to
access.

http://forum.sun.com/thread.jspa?threadID=29408&tstart=0

Thanks

tunji

> Mark


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2006-03-03 17:56 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-02-10 20:12 Re : Debugging v8plus binaries on solaris Olatunji Ruwase
2006-02-17 22:52 ` Olatunji Ruwase
2006-02-17 23:31   ` Mark Kettenis
2006-02-22 18:24     ` Olatunji Ruwase
2006-03-03 19:46     ` Olatunji Ruwase

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox