Fix ppc_collect/supply_ptrace_register() routines
authorEdjunior Barbosa Machado <emachado@linux.vnet.ibm.com>
Mon, 8 Sep 2014 16:37:23 +0000 (13:37 -0300)
committerEdjunior Barbosa Machado <emachado@linux.vnet.ibm.com>
Mon, 8 Sep 2014 16:37:23 +0000 (13:37 -0300)
This patch fixes the routines to collect and supply ptrace registers on ppc64le
gdbserver. Originally written for big endian arch, they were causing several
issues on little endian. With this fix, the number of unexpected failures in
the testsuite dropped from 263 to 72 on ppc64le.

gdb/gdbserver/ChangeLog

* linux-ppc-low.c (ppc_collect_ptrace_register): Adjust routine to take
endianness into account.
(ppc_supply_ptrace_register): Likewise.

gdb/gdbserver/ChangeLog
gdb/gdbserver/linux-ppc-low.c

index 3fb143c2cb3ab126ab94afaef0dc8d677f6fb226..c860daf172c5ff6623c4fffd86d160ebcc8bd1e4 100644 (file)
@@ -1,3 +1,9 @@
+2014-09-08  Edjunior Barbosa Machado  <emachado@linux.vnet.ibm.com>
+
+       * linux-ppc-low.c (ppc_collect_ptrace_register): Adjust routine to take
+       endianness into account.
+       (ppc_supply_ptrace_register): Likewise.
+
 2014-09-03  James Hogan  <james.hogan@imgtec.com>
 
        * linux-mips-low.c (mips_read_description): Reset errno to 0 prior
index d743311837812df5019d742f2b5d2a36c5466872..8fd4b386ee329b297ebe4a78f5d0674a2623fe9e 100644 (file)
@@ -202,25 +202,52 @@ ppc_cannot_fetch_register (int regno)
 static void
 ppc_collect_ptrace_register (struct regcache *regcache, int regno, char *buf)
 {
-  int size = register_size (regcache->tdesc, regno);
-
   memset (buf, 0, sizeof (long));
 
-  if (size < sizeof (long))
-    collect_register (regcache, regno, buf + sizeof (long) - size);
+  if (__BYTE_ORDER == __LITTLE_ENDIAN)
+    {
+      /* Little-endian values always sit at the left end of the buffer.  */
+      collect_register (regcache, regno, buf);
+    }
+  else if (__BYTE_ORDER == __BIG_ENDIAN)
+    {
+      /* Big-endian values sit at the right end of the buffer.  In case of
+         registers whose sizes are smaller than sizeof (long), we must use a
+         padding to access them correctly.  */
+      int size = register_size (regcache->tdesc, regno);
+
+      if (size < sizeof (long))
+       collect_register (regcache, regno, buf + sizeof (long) - size);
+      else
+       collect_register (regcache, regno, buf);
+    }
   else
-    collect_register (regcache, regno, buf);
+    perror_with_name ("Unexpected byte order");
 }
 
 static void
 ppc_supply_ptrace_register (struct regcache *regcache,
                            int regno, const char *buf)
 {
-  int size = register_size (regcache->tdesc, regno);
-  if (size < sizeof (long))
-    supply_register (regcache, regno, buf + sizeof (long) - size);
+  if (__BYTE_ORDER == __LITTLE_ENDIAN)
+    {
+      /* Little-endian values always sit at the left end of the buffer.  */
+      supply_register (regcache, regno, buf);
+    }
+  else if (__BYTE_ORDER == __BIG_ENDIAN)
+    {
+      /* Big-endian values sit at the right end of the buffer.  In case of
+         registers whose sizes are smaller than sizeof (long), we must use a
+         padding to access them correctly.  */
+      int size = register_size (regcache->tdesc, regno);
+
+      if (size < sizeof (long))
+       supply_register (regcache, regno, buf + sizeof (long) - size);
+      else
+       supply_register (regcache, regno, buf);
+    }
   else
-    supply_register (regcache, regno, buf);
+    perror_with_name ("Unexpected byte order");
 }