* ppc-linux-nat.c (store_register, fetch_register): Remove
authorJim Blandy <jimb@codesourcery.com>
Fri, 4 Jun 2004 23:07:28 +0000 (23:07 +0000)
committerJim Blandy <jimb@codesourcery.com>
Fri, 4 Jun 2004 23:07:28 +0000 (23:07 +0000)
incorrect assertions.  Simplify and generalize handling of
transfers whose sizes are not multiples of, or less than, sizeof
(PTRACE_XFER_TYPE).

gdb/ChangeLog
gdb/ppc-linux-nat.c

index 0e830f4be7c9ca4ef9f54d22e676855d0c92d177..01e5533aefc25760a1e3d90d1ebc215206903c78 100644 (file)
@@ -1,3 +1,10 @@
+2004-06-04  Jim Blandy  <jimb@redhat.com>
+
+       * ppc-linux-nat.c (store_register, fetch_register): Remove
+       incorrect assertions.  Simplify and generalize handling of
+       transfers whose sizes are not multiples of, or less than, sizeof
+       (PTRACE_XFER_TYPE).
+
 2004-06-04  Jeff Johnston  <jjohnstn@redhat.com>
 
        * infrun.c (handle_inferior_event): Don't treat an invalid ptid
index f532a58b15f34cf7b4e6cf5f0ea01abe776e0ed4..0700d84b40f44697a6644e001cf13c5d106ae3a0 100644 (file)
@@ -209,7 +209,7 @@ fetch_register (int tid, int regno)
   struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
   /* This isn't really an address.  But ptrace thinks of it as one.  */
   CORE_ADDR regaddr = ppc_register_u_addr (regno);
-  int i;
+  int bytes_transferred;
   unsigned int offset;         /* Offset of registers within the u area. */
   char buf[MAX_REGISTER_SIZE];
 
@@ -236,19 +236,16 @@ fetch_register (int tid, int regno)
       return;
     }
 
-  /* If the current architecture has no floating-point registers, we
-     should never reach this point: ppc_register_u_addr should have
-     returned -1, and we should have caught that above.  */
-  gdb_assert (ppc_floating_point_unit_p (current_gdbarch));
-
   /* Read the raw register using PTRACE_XFER_TYPE sized chunks.  On a
      32-bit platform, 64-bit floating-point registers will require two
      transfers.  */
-  for (i = 0; i < DEPRECATED_REGISTER_RAW_SIZE (regno); i += sizeof (PTRACE_XFER_TYPE))
+  for (bytes_transferred = 0;
+       bytes_transferred < register_size (regno);
+       bytes_transferred += sizeof (PTRACE_XFER_TYPE))
     {
       errno = 0;
-      *(PTRACE_XFER_TYPE *) & buf[i] = ptrace (PT_READ_U, tid,
-                                              (PTRACE_ARG3_TYPE) regaddr, 0);
+      *(PTRACE_XFER_TYPE *) & buf[bytes_transferred]
+        = ptrace (PT_READ_U, tid, (PTRACE_ARG3_TYPE) regaddr, 0);
       regaddr += sizeof (PTRACE_XFER_TYPE);
       if (errno != 0)
        {
@@ -259,19 +256,25 @@ fetch_register (int tid, int regno)
        }
     }
 
-  /* Now supply the register.  Be careful to map between ptrace's and
-     the current_regcache's idea of the current wordsize.  */
-  if ((regno >= tdep->ppc_fp0_regnum
-       && regno < tdep->ppc_fp0_regnum + ppc_num_fprs)
-      || gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_LITTLE)
-    /* FPs are always 64 bits.  Little endian values are always found
-       at the left-hand end of the register.  */
-    regcache_raw_supply (current_regcache, regno, buf);
-  else
-    /* Big endian register, need to fetch the right-hand end.  */
-    regcache_raw_supply (current_regcache, regno,
-                        (buf + sizeof (PTRACE_XFER_TYPE)
-                         - register_size (current_gdbarch, regno)));
+  /* Now supply the register.  Keep in mind that the regcache's idea
+     of the register's size may not be a multiple of sizeof
+     (PTRACE_XFER_TYPE).  */
+  if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_LITTLE)
+    {
+      /* Little-endian values are always found at the left end of the
+         bytes transferred.  */
+      regcache_raw_supply (current_regcache, regno, buf);
+    }
+  else if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
+    {
+      /* Big-endian values are found at the right end of the bytes
+         transferred.  */
+      size_t padding = (bytes_transferred
+                        - register_size (current_gdbarch, regno));
+      regcache_raw_supply (current_regcache, regno, buf + padding);
+    }
+  else 
+    gdb_assert (0);
 }
 
 static void
@@ -407,6 +410,7 @@ store_register (int tid, int regno)
   /* This isn't really an address.  But ptrace thinks of it as one.  */
   CORE_ADDR regaddr = ppc_register_u_addr (regno);
   int i;
+  size_t bytes_to_transfer;
   char buf[MAX_REGISTER_SIZE];
 
   if (altivec_register_p (regno))
@@ -418,28 +422,26 @@ store_register (int tid, int regno)
   if (regaddr == -1)
     return;
 
-  /* If the current architecture has no floating-point registers, we
-     should never reach this point: ppc_register_u_addr should have
-     returned -1, and we should have caught that above.  */
-  gdb_assert (ppc_floating_point_unit_p (current_gdbarch));
-
-  /* First collect the register value from the regcache.  Be careful
-     to to convert the regcache's wordsize into ptrace's wordsize.  */
+  /* First collect the register.  Keep in mind that the regcache's
+     idea of the register's size may not be a multiple of sizeof
+     (PTRACE_XFER_TYPE).  */
   memset (buf, 0, sizeof buf);
-  if ((regno >= tdep->ppc_fp0_regnum
-       && regno < tdep->ppc_fp0_regnum + ppc_num_fprs)
-      || TARGET_BYTE_ORDER == BFD_ENDIAN_LITTLE)
-    /* Floats are always 64-bit.  Little endian registers are always
-       at the left-hand end of the register cache.  */
-    regcache_raw_collect (current_regcache, regno, buf);
-  else
-    /* Big-endian registers belong at the right-hand end of the
-       buffer.  */
-    regcache_raw_collect (current_regcache, regno,
-                         (buf + sizeof (PTRACE_XFER_TYPE)
-                          - register_size (current_gdbarch, regno)));
+  bytes_to_transfer = align_up (register_size (current_gdbarch, regno),
+                                sizeof (PTRACE_XFER_TYPE));
+  if (TARGET_BYTE_ORDER == BFD_ENDIAN_LITTLE)
+    {
+      /* Little-endian values always sit at the left end of the buffer.  */
+      regcache_raw_collect (current_regcache, regno, buf);
+    }
+  else if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+    {
+      /* Big-endian values sit at the right end of the buffer.  */
+      size_t padding = (bytes_to_transfer
+                        - register_size (current_gdbarch, regno));
+      regcache_raw_collect (current_regcache, regno, buf + padding);
+    }
 
-  for (i = 0; i < DEPRECATED_REGISTER_RAW_SIZE (regno); i += sizeof (PTRACE_XFER_TYPE))
+  for (i = 0; i < bytes_to_transfer; i += sizeof (PTRACE_XFER_TYPE))
     {
       errno = 0;
       ptrace (PT_WRITE_U, tid, (PTRACE_ARG3_TYPE) regaddr,