This is the mail archive of the rda@sources.redhat.com mailing list for the rda 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]

Re: [RFC] (2nd try) Revise interfaces for *_bytes_{from,to}_reg()


On Nov 27,  4:26pm, Kevin Buettner wrote:

> Here's my second try at revising the conversion interfaces between
> a buffer of bytes and a struct gdbserv_reg.  The primary difference
> between this patch and the one before is that a ``sign_extend'' flag
> has been added to the conversion functions.
> 
> Unfortunately, this patch contains a small part of my upcoming
> mips64 changes.  I was able to prune out most of it, but wasn't
> able to disentangle a small portion of it.
> 
> I'll commit this early next week unless someone objects...
> 
> Kevin
> 
> In ChangeLog:
> 	* include/gdbserv-utils.h, lib/gdbserv-utils.c
> 	(gdbserv_be_bytes_to_reg, gdbserv_le_bytes_to_reg)
> 	(gdbserv_be_bytes_from_reg, gdbserv_le_bytes_from_reg)
> 	(gdbserv_host_bytes_to_reg, gdbserv_host_bytes_from_reg):
> 	Revise interfaces.
> 
> In unix/ChangeLog:
> 
> 	* linux-target.c (linux_get_reg, linux_set_reg, reg_from_regset)
> 	(reg_to_regset, get_regset, put_regset reg_from_gregset)
> 	(reg_to_gregset, reg_from_fpregset, reg_to_fpregset)
> 	(reg_from_xregset, reg_to_xregset): Adjust all calls to
> 	gdbserv_host_bytes_to_reg() and gdbserv_host_bytes_from_reg()
> 	to account for change in interface.  Remove code which is
> 	no longer needed due to improvements in the aforementioned
> 	functions.

Committed.  Below is what actually got committed for linux-target.c.  (I
decided it wasn't worth disentangling my mips64 changes for the commit,
so I've committed those too...)

	* linux-target.c (linux_get_reg, linux_set_reg, reg_from_regset)
	(reg_to_regset, get_regset, put_regset reg_from_gregset)
	(reg_to_gregset, reg_from_fpregset, reg_to_fpregset)
	(reg_from_xregset, reg_to_xregset): Adjust all calls to
	gdbserv_host_bytes_to_reg() and gdbserv_host_bytes_from_reg()
	to account for change in interface.  Remove code which is
	no longer needed due to improvements in the aforementioned
	functions.
	(sign_extend): New constant.
	(FPR_BASE, PC, CAUSE, BADVADDR, MMHI, MMLO, FPC_CSR, FPC_EIR):
	Make sure these are defined.
	(PROTO_SIZE): Define.
	(reginfo) [MIPS_LINUX_TARGET]: Use PROTO_SIZE to initialize
	table with size (width) of registers to use when communicating
	with the client.
	(NUM_REGS, PC_REGNUM, reginfo) [MIPS64_LINUX_TARGET]: Define.

Index: include/gdbserv-utils.h
===================================================================
RCS file: /cvs/src/src/rda/include/gdbserv-utils.h,v
retrieving revision 1.1
diff -u -p -r1.1 gdbserv-utils.h
--- include/gdbserv-utils.h	28 Aug 2002 01:22:27 -0000	1.1
+++ include/gdbserv-utils.h	3 Dec 2002 03:10:35 -0000
@@ -60,43 +60,65 @@ extern void gdbserv_ulonglong_to_reg (st
 				      unsigned long long val,
 				      struct gdbserv_reg *reg);
 
-/* Convert between a REG and a buffer representing a numeric type.
-   Handle big endian and little endian cases explicitly.  */
+/* Convert between a REG and a buffer representing a (possibly signed)
+   numeric type.  Handle big endian and little endian cases explicitly.
+   When the source buffer is bigger than the destination buffer, the
+   least significant bytes (as appropriate for the endianess) are
+   transferred.  When the source buffer is smaller than the destination,
+   the most significant bytes of the destination are padded appropriately.
+   
+   Note that gdbserv_be_bytes_from_reg() and gdbserv_le_bytes_from_reg()
+   have a buffer length parameter, but not a register length
+   parameter.  This is because the register length was obtained from a
+   register packet sent by the debug client.  On the other hand,
+   gdbserv_be_bytes_to_reg() and gdbserv_le_bytes_to_reg() take both a
+   buffer length and the register length.  This is because we're
+   constructing a register (which will likely be sent to the client)
+   of a particular size.  */
 
 extern void gdbserv_be_bytes_to_reg (struct gdbserv *gdbserv,
 		                     const void *buf,
-		                     int len,
-		                     struct gdbserv_reg *reg);
+		                     int buflen,
+		                     struct gdbserv_reg *reg,
+				     int reglen,
+				     int sign_extend);
 
 extern void gdbserv_le_bytes_to_reg (struct gdbserv *gdbserv,
 		                     const void *buf,
 		                     int len,
-		                     struct gdbserv_reg *reg);
+		                     struct gdbserv_reg *reg,
+				     int reglen,
+				     int sign_extend);
 
 extern void gdbserv_be_bytes_from_reg (struct gdbserv *gdbserv,
 		                       void *buf,
-		                       int *lenp,
-                                       const struct gdbserv_reg *reg);
+		                       int buflen,
+                                       const struct gdbserv_reg *reg,
+				       int sign_extend);
 
 extern void gdbserv_le_bytes_from_reg (struct gdbserv *gdbserv,
 		                       void *buf,
-		                       int *lenp,
-                                       const struct gdbserv_reg *reg);
-
-/* Convert between a REG and a buffer representing a native numeric
-   type.  These are just wrappers for the routines above, but are
-   useful nonetheless since they free the caller from having to
+		                       int buflen,
+                                       const struct gdbserv_reg *reg,
+				       int sign_extend);
+
+/* Convert between a REG and a buffer representing a native unsigned
+   numeric type.  These are just wrappers for the routines above, but
+   are useful nonetheless since they free the caller from having to
    worry about byte order issues.  */
 
 extern void gdbserv_host_bytes_to_reg (struct gdbserv *gdbserv,
 		                       const void *buf,
-		                       int len,
-		                       struct gdbserv_reg *reg);
+		                       int buflen,
+		                       struct gdbserv_reg *reg,
+				       int reglen,
+				       int sign_extend);
 
 extern void gdbserv_host_bytes_from_reg (struct gdbserv *gdbserv,
 		                         void *buf,
-		                         int *lenp,
-                                         const struct gdbserv_reg *reg);
+		                         int buflen,
+                                         const struct gdbserv_reg *reg,
+					 int sign_extend);
 
 #ifdef __cplusplus
 }
Index: lib/gdbserv-utils.c
===================================================================
RCS file: /cvs/src/src/rda/lib/gdbserv-utils.c,v
retrieving revision 1.1
diff -u -p -r1.1 gdbserv-utils.c
--- lib/gdbserv-utils.c	28 Aug 2002 01:22:28 -0000	1.1
+++ lib/gdbserv-utils.c	3 Dec 2002 03:10:35 -0000
@@ -227,67 +227,143 @@ reverse_copy_bytes (void *dest, const vo
 void
 gdbserv_be_bytes_to_reg (struct gdbserv *gdbserv,
 		         const void *buf,
-		         int len,
-		         struct gdbserv_reg *reg)
-{
+		         int buflen,
+		         struct gdbserv_reg *reg,
+			 int reglen,
+			 int sign_extend)
+{
+  int bufoffset = 0;
+  int regoffset = 0;
+  int len = buflen;
+
   reg->negative_p = 0;
-  reg->len = len;
-  memcpy (reg->buf, buf, len);
+  reg->len = reglen;
+
+  if (reglen > buflen)
+    {
+      memset (reg->buf,
+              (sign_extend && (((char *) buf)[0] & 0x80)) ? 0xff : 0,
+	      reglen - buflen);
+      regoffset = reglen - buflen;
+    }
+
+  if (buflen > reglen)
+    {
+      bufoffset = buflen - reglen;
+      len = reglen;
+    }
+
+  memcpy (reg->buf + regoffset, (char *)buf + bufoffset, len);
 }
 
 void
 gdbserv_be_bytes_from_reg (struct gdbserv *gdbserv,
 		           void *buf,
-		           int *lenp,
-                           const struct gdbserv_reg *reg)
-{
-  *lenp = reg->len;
-  memcpy (buf, reg->buf, reg->len);
+		           int buflen,
+                           const struct gdbserv_reg *reg,
+			   int sign_extend)
+{
+  int bufoffset = 0;
+  int regoffset = 0;
+  int len = reg->len;
+
+  if (reg->len > buflen)
+    {
+      regoffset = reg->len - buflen;
+      len = buflen;
+    }
+
+  if (buflen > reg->len)
+    {
+      memset (buf,
+              (sign_extend && (reg->buf[0] & 0x80)) ? 0xff : 0,
+	      buflen - reg->len);
+      bufoffset = buflen - reg->len;
+    }
+
+  memcpy ((char *)buf + bufoffset, reg->buf + regoffset, len);
 }
 
 void
 gdbserv_le_bytes_to_reg (struct gdbserv *gdbserv,
 		         const void *buf,
-		         int len,
-		         struct gdbserv_reg *reg)
+		         int buflen,
+		         struct gdbserv_reg *reg,
+			 int reglen,
+			 int sign_extend)
 {
+  int regoffset = 0;
+  int len = buflen;
+
   reg->negative_p = 0;
-  reg->len = len;
-  reverse_copy_bytes (reg->buf, buf, len);
+  reg->len = reglen;
+
+  if (reglen > buflen)
+    {
+      memset (reg->buf,
+              (sign_extend && (((char *) buf)[buflen - 1] & 0x80)) ? 0xff : 0,
+	      reglen - buflen);
+      regoffset = reglen - buflen;
+    }
+
+  if (buflen > reglen)
+      len = reglen;
+
+  reverse_copy_bytes (reg->buf + regoffset, buf, len);
 }
 
 void
 gdbserv_le_bytes_from_reg (struct gdbserv *gdbserv,
 		           void *buf,
-		           int *lenp,
-                           const struct gdbserv_reg *reg)
-{
-  *lenp = reg->len;
-  reverse_copy_bytes (buf, reg->buf, reg->len);
+		           int buflen,
+                           const struct gdbserv_reg *reg,
+			   int sign_extend)
+{
+  int bufoffset = 0;
+  int regoffset = 0;
+  int len = reg->len;
+
+  if (reg->len > buflen)
+    {
+      regoffset = reg->len - buflen;
+      len = buflen;
+    }
+
+  if (buflen > reg->len)
+    {
+      memset ((char *)buf + reg->len,
+              (sign_extend && (reg->buf[reg->len - 1] & 0x80)) ? 0xff : 0,
+	      buflen - reg->len);
+    }
+
+  reverse_copy_bytes (buf, reg->buf + regoffset, reg->len);
 }
 
 void
 gdbserv_host_bytes_to_reg (struct gdbserv *gdbserv,
 		           const void *buf,
-		           int len,
-		           struct gdbserv_reg *reg)
+		           int buflen,
+		           struct gdbserv_reg *reg,
+			   int reglen,
+			   int sign_extend)
 {
 #ifdef WORDS_BIGENDIAN
-  gdbserv_be_bytes_to_reg (gdbserv, buf, len, reg);
+  gdbserv_be_bytes_to_reg (gdbserv, buf, buflen, reg, reglen, sign_extend);
 #else
-  gdbserv_le_bytes_to_reg (gdbserv, buf, len, reg);
+  gdbserv_le_bytes_to_reg (gdbserv, buf, buflen, reg, reglen, sign_extend);
 #endif
 }
 
 void
 gdbserv_host_bytes_from_reg (struct gdbserv *gdbserv,
 		             void *buf,
-		             int *lenp,
-                             const struct gdbserv_reg *reg)
+		             int buflen,
+                             const struct gdbserv_reg *reg,
+			     int sign_extend)
 {
 #ifdef WORDS_BIGENDIAN
-  gdbserv_be_bytes_from_reg (gdbserv, buf, lenp, reg);
+  gdbserv_be_bytes_from_reg (gdbserv, buf, buflen, reg, sign_extend);
 #else
-  gdbserv_le_bytes_from_reg (gdbserv, buf, lenp, reg);
+  gdbserv_le_bytes_from_reg (gdbserv, buf, buflen, reg, sign_extend);
 #endif
 }
Index: unix/linux-target.c
===================================================================
RCS file: /cvs/src/src/rda/unix/linux-target.c,v
retrieving revision 1.1
diff -u -p -r1.1 linux-target.c
--- unix/linux-target.c	28 Aug 2002 01:22:28 -0000	1.1
+++ unix/linux-target.c	3 Dec 2002 03:10:36 -0000
@@ -205,7 +205,8 @@ struct peekuser_pokeuser_reginfo
 enum 
 { 
   PC_REGNUM = 15,
-  NUM_REGS = 26
+  NUM_REGS = 26,
+  sign_extend = 0
 };
 
 static struct getregs_setregs_reginfo reginfo[] =
@@ -261,7 +262,8 @@ static struct getregs_setregs_reginfo re
 enum 
 { 
   PC_REGNUM = 8,
-  NUM_REGS = 42
+  NUM_REGS = 42,
+  sign_extend = 0
 };
 
 
@@ -343,7 +345,8 @@ enum
   SIZEOF_REGMAP = 23,
   SIZEOF_MAPPEDREG = 4,
   NUM_REGS = 24,
-  PC_REGNUM = 16
+  PC_REGNUM = 16,
+  sign_extend = 0
 };
 
 static int regmap[SIZEOF_REGMAP] =
@@ -376,16 +379,47 @@ is_extended_reg (int regnum)
 
 /* End of SH_LINUX_TARGET */
 
-#elif defined(MIPS_LINUX_TARGET)
+#elif defined MIPS_LINUX_TARGET || (defined MIPS64_LINUX_TARGET && defined MIPS_ABI_O32)
 
 #define PEEKUSER_POKEUSER_REGINFO 1
 
 enum
 {
   NUM_REGS = 70,
-  PC_REGNUM = 37
+  PC_REGNUM = 37,
+  sign_extend = 1
 };
 
+#ifndef FPR_BASE
+#define FPR_BASE 32
+#endif
+#ifndef PC
+#define PC		64
+#endif
+#ifndef CAUSE
+#define CAUSE		65
+#endif
+#ifndef BADVADDR
+#define BADVADDR	66
+#endif
+#ifndef MMHI
+#define MMHI		67
+#endif
+#ifndef MMLO
+#define MMLO		68
+#endif
+#ifndef FPC_CSR
+#define FPC_CSR		69
+#endif
+#ifndef FPC_EIR
+#define FPC_EIR		70
+#endif
+
+#ifdef MIPS64_LINUX_TARGET
+#define PROTO_SIZE 8
+#else
+#define PROTO_SIZE 4
+#endif
 
 static struct peekuser_pokeuser_reginfo reginfo[] =
 {
@@ -395,41 +429,41 @@ static struct peekuser_pokeuser_reginfo 
      gregset_t is used by the thread library in its interfaces.  Since
      we're concerned about the latter, we'll use the gregset_t offsets
      in the table below.  */
-  { 0,             4, GREGS,  0 * 4,  4, 4 },      /* zero */
-  { 1,             4, GREGS,  1 * 4,  4, 4 },      /* at */
-  { 2,             4, GREGS,  2 * 4,  4, 4 },      /* v0 */
-  { 3,             4, GREGS,  3 * 4,  4, 4 },      /* v1 */
-  { 4,             4, GREGS,  4 * 4,  4, 4 },      /* a0 */
-  { 5,             4, GREGS,  5 * 4,  4, 4 },      /* a1 */
-  { 6,             4, GREGS,  6 * 4,  4, 4 },      /* a2 */
-  { 7,             4, GREGS,  7 * 4,  4, 4 },      /* a3 */
-  { 8,             4, GREGS,  8 * 4,  4, 4 },      /* t0 */
-  { 9,             4, GREGS,  9 * 4,  4, 4 },      /* t1 */
-  { 10,            4, GREGS,  10 * 4, 4, 4 },      /* t2 */
-  { 11,            4, GREGS,  11 * 4, 4, 4 },      /* t3 */
-  { 12,            4, GREGS,  12 * 4, 4, 4 },      /* t4 */
-  { 13,            4, GREGS,  13 * 4, 4, 4 },      /* t5 */
-  { 14,            4, GREGS,  14 * 4, 4, 4 },      /* t6 */
-  { 15,            4, GREGS,  15 * 4, 4, 4 },      /* t7 */
-  { 16,            4, GREGS,  16 * 4, 4, 4 },      /* s0 */
-  { 17,            4, GREGS,  17 * 4, 4, 4 },      /* s1 */
-  { 18,            4, GREGS,  18 * 4, 4, 4 },      /* s2 */
-  { 19,            4, GREGS,  19 * 4, 4, 4 },      /* s3 */
-  { 20,            4, GREGS,  20 * 4, 4, 4 },      /* s4 */
-  { 21,            4, GREGS,  21 * 4, 4, 4 },      /* s5 */
-  { 22,            4, GREGS,  22 * 4, 4, 4 },      /* s6 */
-  { 23,            4, GREGS,  23 * 4, 4, 4 },      /* s7 */
-  { 24,            4, GREGS,  24 * 4, 4, 4 },      /* t8 */
-  { 25,            4, GREGS,  25 * 4, 4, 4 },      /* t9 */
-  { 26,            4, GREGS,  26 * 4, 4, 4 },      /* k0 */
-  { 27,            4, GREGS,  27 * 4, 4, 4 },      /* k1 */
-  { 28,            4, GREGS,  28 * 4, 4, 4 },      /* gp */
-  { 29,            4, GREGS,  29 * 4, 4, 4 },      /* sp */
-  { 30,            4, GREGS,  30 * 4, 4, 4 },      /* s8/fp */
-  { 31,            4, GREGS,  31 * 4, 4, 4 },      /* ra */
-  { 0,             4, NOREGS, 0,      4, 4 },      /* sr */
-  { MMLO,          4, GREGS,  33 * 4, 4, 4 },      /* lo */
-  { MMHI,          4, GREGS,  32 * 4, 4, 4 },      /* hi */
+  { 0,             4, GREGS,  0 * 4,  4, PROTO_SIZE },      /* zero */
+  { 1,             4, GREGS,  1 * 4,  4, PROTO_SIZE },      /* at */
+  { 2,             4, GREGS,  2 * 4,  4, PROTO_SIZE },      /* v0 */
+  { 3,             4, GREGS,  3 * 4,  4, PROTO_SIZE },      /* v1 */
+  { 4,             4, GREGS,  4 * 4,  4, PROTO_SIZE },      /* a0 */
+  { 5,             4, GREGS,  5 * 4,  4, PROTO_SIZE },      /* a1 */
+  { 6,             4, GREGS,  6 * 4,  4, PROTO_SIZE },      /* a2 */
+  { 7,             4, GREGS,  7 * 4,  4, PROTO_SIZE },      /* a3 */
+  { 8,             4, GREGS,  8 * 4,  4, PROTO_SIZE },      /* t0 */
+  { 9,             4, GREGS,  9 * 4,  4, PROTO_SIZE },      /* t1 */
+  { 10,            4, GREGS,  10 * 4, 4, PROTO_SIZE },      /* t2 */
+  { 11,            4, GREGS,  11 * 4, 4, PROTO_SIZE },      /* t3 */
+  { 12,            4, GREGS,  12 * 4, 4, PROTO_SIZE },      /* t4 */
+  { 13,            4, GREGS,  13 * 4, 4, PROTO_SIZE },      /* t5 */
+  { 14,            4, GREGS,  14 * 4, 4, PROTO_SIZE },      /* t6 */
+  { 15,            4, GREGS,  15 * 4, 4, PROTO_SIZE },      /* t7 */
+  { 16,            4, GREGS,  16 * 4, 4, PROTO_SIZE },      /* s0 */
+  { 17,            4, GREGS,  17 * 4, 4, PROTO_SIZE },      /* s1 */
+  { 18,            4, GREGS,  18 * 4, 4, PROTO_SIZE },      /* s2 */
+  { 19,            4, GREGS,  19 * 4, 4, PROTO_SIZE },      /* s3 */
+  { 20,            4, GREGS,  20 * 4, 4, PROTO_SIZE },      /* s4 */
+  { 21,            4, GREGS,  21 * 4, 4, PROTO_SIZE },      /* s5 */
+  { 22,            4, GREGS,  22 * 4, 4, PROTO_SIZE },      /* s6 */
+  { 23,            4, GREGS,  23 * 4, 4, PROTO_SIZE },      /* s7 */
+  { 24,            4, GREGS,  24 * 4, 4, PROTO_SIZE },      /* t8 */
+  { 25,            4, GREGS,  25 * 4, 4, PROTO_SIZE },      /* t9 */
+  { 26,            4, GREGS,  26 * 4, 4, PROTO_SIZE },      /* k0 */
+  { 27,            4, GREGS,  27 * 4, 4, PROTO_SIZE },      /* k1 */
+  { 28,            4, GREGS,  28 * 4, 4, PROTO_SIZE },      /* gp */
+  { 29,            4, GREGS,  29 * 4, 4, PROTO_SIZE },      /* sp */
+  { 30,            4, GREGS,  30 * 4, 4, PROTO_SIZE },      /* s8/fp */
+  { 31,            4, GREGS,  31 * 4, 4, PROTO_SIZE },      /* ra */
+  { 0,             4, NOREGS, 0,      4, PROTO_SIZE },      /* sr */
+  { MMLO,          4, GREGS,  33 * 4, 4, PROTO_SIZE },      /* lo */
+  { MMHI,          4, GREGS,  32 * 4, 4, PROTO_SIZE },      /* hi */
 
   /* glibc's ucontext.h doesn't specify the order of the following
      three registerss.  But there is space allocated for them.  (Well,
@@ -439,9 +473,9 @@ static struct peekuser_pokeuser_reginfo 
      asm-mips/reg.h.  Note, however, that the kernel header sandwiches
      the status register (sr, above) in between ``bad'' and ``cause''.  */
 
-  { BADVADDR,      4, GREGS,  35 * 4, 4, 4 },      /* bad */
-  { CAUSE,         4, GREGS,  36 * 4, 4, 4 },      /* cause */
-  { PC,            4, GREGS,  34 * 4, 4, 4 },      /* pc */
+  { BADVADDR,      4, GREGS,  35 * 4, 4, PROTO_SIZE },      /* bad */
+  { CAUSE,         4, GREGS,  36 * 4, 4, PROTO_SIZE },      /* cause */
+  { PC,            4, GREGS,  34 * 4, 4, PROTO_SIZE },      /* pc */
 
   /* Linux/MIPS floating point is a bit of a mess.  On the one hand,
      the elf_fpregset_t contains space for 32 doubles plus the control
@@ -450,45 +484,159 @@ static struct peekuser_pokeuser_reginfo 
      16 double precision floats via ptrace().  It also means that only
      slightly more than half of elf_fpregset_t is unused.  */
 
-  { FPR_BASE + 0,  4, FPREGS, 0 * 4,  4, 4 },      /* $f0 */
-  { FPR_BASE + 1,  4, FPREGS, 1 * 4,  4, 4 },      /* $f1 */
-  { FPR_BASE + 2,  4, FPREGS, 2 * 4,  4, 4 },      /* $f2 */
-  { FPR_BASE + 3,  4, FPREGS, 3 * 4,  4, 4 },      /* $f3 */
-  { FPR_BASE + 4,  4, FPREGS, 4 * 4,  4, 4 },      /* $f4 */
-  { FPR_BASE + 5,  4, FPREGS, 5 * 4,  4, 4 },      /* $f5 */
-  { FPR_BASE + 6,  4, FPREGS, 6 * 4,  4, 4 },      /* $f6 */
-  { FPR_BASE + 7,  4, FPREGS, 7 * 4,  4, 4 },      /* $f7 */
-  { FPR_BASE + 8,  4, FPREGS, 8 * 4,  4, 4 },      /* $f8 */
-  { FPR_BASE + 9,  4, FPREGS, 9 * 4,  4, 4 },      /* $f9 */
-  { FPR_BASE + 10, 4, FPREGS, 10 * 4, 4, 4 },      /* $f10 */
-  { FPR_BASE + 11, 4, FPREGS, 11 * 4, 4, 4 },      /* $f11 */
-  { FPR_BASE + 12, 4, FPREGS, 12 * 4, 4, 4 },      /* $f12 */
-  { FPR_BASE + 13, 4, FPREGS, 13 * 4, 4, 4 },      /* $f13 */
-  { FPR_BASE + 14, 4, FPREGS, 14 * 4, 4, 4 },      /* $f14 */
-  { FPR_BASE + 15, 4, FPREGS, 15 * 4, 4, 4 },      /* $f15 */
-  { FPR_BASE + 16, 4, FPREGS, 16 * 4, 4, 4 },      /* $f16 */
-  { FPR_BASE + 17, 4, FPREGS, 17 * 4, 4, 4 },      /* $f17 */
-  { FPR_BASE + 18, 4, FPREGS, 18 * 4, 4, 4 },      /* $f18 */
-  { FPR_BASE + 19, 4, FPREGS, 19 * 4, 4, 4 },      /* $f19 */
-  { FPR_BASE + 20, 4, FPREGS, 20 * 4, 4, 4 },      /* $f20 */
-  { FPR_BASE + 21, 4, FPREGS, 21 * 4, 4, 4 },      /* $f21 */
-  { FPR_BASE + 22, 4, FPREGS, 22 * 4, 4, 4 },      /* $f22 */
-  { FPR_BASE + 23, 4, FPREGS, 23 * 4, 4, 4 },      /* $f23 */
-  { FPR_BASE + 24, 4, FPREGS, 24 * 4, 4, 4 },      /* $f24 */
-  { FPR_BASE + 25, 4, FPREGS, 25 * 4, 4, 4 },      /* $f25 */
-  { FPR_BASE + 26, 4, FPREGS, 26 * 4, 4, 4 },      /* $f26 */
-  { FPR_BASE + 27, 4, FPREGS, 27 * 4, 4, 4 },      /* $f27 */
-  { FPR_BASE + 28, 4, FPREGS, 28 * 4, 4, 4 },      /* $f28 */
-  { FPR_BASE + 29, 4, FPREGS, 29 * 4, 4, 4 },      /* $f29 */
-  { FPR_BASE + 30, 4, FPREGS, 30 * 4, 4, 4 },      /* $f30 */
-  { FPR_BASE + 31, 4, FPREGS, 31 * 4, 4, 4 },      /* $f31 */
-  { FPC_CSR,       4, FPREGS, 64 * 4, 4, 4 }       /* fsr */
+  { FPR_BASE + 0,  4, FPREGS, 0 * 4,  4, PROTO_SIZE },      /* $f0 */
+  { FPR_BASE + 1,  4, FPREGS, 1 * 4,  4, PROTO_SIZE },      /* $f1 */
+  { FPR_BASE + 2,  4, FPREGS, 2 * 4,  4, PROTO_SIZE },      /* $f2 */
+  { FPR_BASE + 3,  4, FPREGS, 3 * 4,  4, PROTO_SIZE },      /* $f3 */
+  { FPR_BASE + 4,  4, FPREGS, 4 * 4,  4, PROTO_SIZE },      /* $f4 */
+  { FPR_BASE + 5,  4, FPREGS, 5 * 4,  4, PROTO_SIZE },      /* $f5 */
+  { FPR_BASE + 6,  4, FPREGS, 6 * 4,  4, PROTO_SIZE },      /* $f6 */
+  { FPR_BASE + 7,  4, FPREGS, 7 * 4,  4, PROTO_SIZE },      /* $f7 */
+  { FPR_BASE + 8,  4, FPREGS, 8 * 4,  4, PROTO_SIZE },      /* $f8 */
+  { FPR_BASE + 9,  4, FPREGS, 9 * 4,  4, PROTO_SIZE },      /* $f9 */
+  { FPR_BASE + 10, 4, FPREGS, 10 * 4, 4, PROTO_SIZE },      /* $f10 */
+  { FPR_BASE + 11, 4, FPREGS, 11 * 4, 4, PROTO_SIZE },      /* $f11 */
+  { FPR_BASE + 12, 4, FPREGS, 12 * 4, 4, PROTO_SIZE },      /* $f12 */
+  { FPR_BASE + 13, 4, FPREGS, 13 * 4, 4, PROTO_SIZE },      /* $f13 */
+  { FPR_BASE + 14, 4, FPREGS, 14 * 4, 4, PROTO_SIZE },      /* $f14 */
+  { FPR_BASE + 15, 4, FPREGS, 15 * 4, 4, PROTO_SIZE },      /* $f15 */
+  { FPR_BASE + 16, 4, FPREGS, 16 * 4, 4, PROTO_SIZE },      /* $f16 */
+  { FPR_BASE + 17, 4, FPREGS, 17 * 4, 4, PROTO_SIZE },      /* $f17 */
+  { FPR_BASE + 18, 4, FPREGS, 18 * 4, 4, PROTO_SIZE },      /* $f18 */
+  { FPR_BASE + 19, 4, FPREGS, 19 * 4, 4, PROTO_SIZE },      /* $f19 */
+  { FPR_BASE + 20, 4, FPREGS, 20 * 4, 4, PROTO_SIZE },      /* $f20 */
+  { FPR_BASE + 21, 4, FPREGS, 21 * 4, 4, PROTO_SIZE },      /* $f21 */
+  { FPR_BASE + 22, 4, FPREGS, 22 * 4, 4, PROTO_SIZE },      /* $f22 */
+  { FPR_BASE + 23, 4, FPREGS, 23 * 4, 4, PROTO_SIZE },      /* $f23 */
+  { FPR_BASE + 24, 4, FPREGS, 24 * 4, 4, PROTO_SIZE },      /* $f24 */
+  { FPR_BASE + 25, 4, FPREGS, 25 * 4, 4, PROTO_SIZE },      /* $f25 */
+  { FPR_BASE + 26, 4, FPREGS, 26 * 4, 4, PROTO_SIZE },      /* $f26 */
+  { FPR_BASE + 27, 4, FPREGS, 27 * 4, 4, PROTO_SIZE },      /* $f27 */
+  { FPR_BASE + 28, 4, FPREGS, 28 * 4, 4, PROTO_SIZE },      /* $f28 */
+  { FPR_BASE + 29, 4, FPREGS, 29 * 4, 4, PROTO_SIZE },      /* $f29 */
+  { FPR_BASE + 30, 4, FPREGS, 30 * 4, 4, PROTO_SIZE },      /* $f30 */
+  { FPR_BASE + 31, 4, FPREGS, 31 * 4, 4, PROTO_SIZE },      /* $f31 */
+  { FPC_CSR,       4, FPREGS, 64 * 4, 4, PROTO_SIZE }       /* fsr */
 };
 
 static void mips_singlestep_program (struct gdbserv *serv);
 
 /* End of MIPS_LINUX_TARGET */
 
+#elif defined(MIPS64_LINUX_TARGET)
+
+#define PEEKUSER_POKEUSER_REGINFO 1
+
+enum
+{
+  NUM_REGS = 70,
+  PC_REGNUM = 37,
+  sign_extend = 1
+};
+
+
+static struct peekuser_pokeuser_reginfo reginfo[] =
+{
+  /* MIPS has differing elf_gregset_t and gregset_t structs.  (The
+     former contains some leading padding that the latter does not.)
+     elf_gregset_t is used to access registers from a core file whereas
+     gregset_t is used by the thread library in its interfaces.  Since
+     we're concerned about the latter, we'll use the gregset_t offsets
+     in the table below.  */
+  { 0,             8, GREGS,  0 * 8,  8, 8 },      /* zero */
+  { 1,             8, GREGS,  1 * 8,  8, 8 },      /* at */
+  { 2,             8, GREGS,  2 * 8,  8, 8 },      /* v0 */
+  { 3,             8, GREGS,  3 * 8,  8, 8 },      /* v1 */
+  { 4,             8, GREGS,  4 * 8,  8, 8 },      /* a0 */
+  { 5,             8, GREGS,  5 * 8,  8, 8 },      /* a1 */
+  { 6,             8, GREGS,  6 * 8,  8, 8 },      /* a2 */
+  { 7,             8, GREGS,  7 * 8,  8, 8 },      /* a3 */
+  { 8,             8, GREGS,  8 * 8,  8, 8 },      /* t0 */
+  { 9,             8, GREGS,  9 * 8,  8, 8 },      /* t1 */
+  { 10,            8, GREGS,  10 * 8, 8, 8 },      /* t2 */
+  { 11,            8, GREGS,  11 * 8, 8, 8 },      /* t3 */
+  { 12,            8, GREGS,  12 * 8, 8, 8 },      /* t4 */
+  { 13,            8, GREGS,  13 * 8, 8, 8 },      /* t5 */
+  { 14,            8, GREGS,  14 * 8, 8, 8 },      /* t6 */
+  { 15,            8, GREGS,  15 * 8, 8, 8 },      /* t7 */
+  { 16,            8, GREGS,  16 * 8, 8, 8 },      /* s0 */
+  { 17,            8, GREGS,  17 * 8, 8, 8 },      /* s1 */
+  { 18,            8, GREGS,  18 * 8, 8, 8 },      /* s2 */
+  { 19,            8, GREGS,  19 * 8, 8, 8 },      /* s3 */
+  { 20,            8, GREGS,  20 * 8, 8, 8 },      /* s4 */
+  { 21,            8, GREGS,  21 * 8, 8, 8 },      /* s5 */
+  { 22,            8, GREGS,  22 * 8, 8, 8 },      /* s6 */
+  { 23,            8, GREGS,  23 * 8, 8, 8 },      /* s7 */
+  { 24,            8, GREGS,  24 * 8, 8, 8 },      /* t8 */
+  { 25,            8, GREGS,  25 * 8, 8, 8 },      /* t9 */
+  { 26,            8, GREGS,  26 * 8, 8, 8 },      /* k0 */
+  { 27,            8, GREGS,  27 * 8, 8, 8 },      /* k1 */
+  { 28,            8, GREGS,  28 * 8, 8, 8 },      /* gp */
+  { 29,            8, GREGS,  29 * 8, 8, 8 },      /* sp */
+  { 30,            8, GREGS,  30 * 8, 8, 8 },      /* s8/fp */
+  { 31,            8, GREGS,  31 * 8, 8, 8 },      /* ra */
+  { 0,             8, NOREGS, 0,      8, 8 },      /* sr */
+  { 68,            8, GREGS,  33 * 4, 8, 8 },      /* lo */
+  { 67,            8, GREGS,  32 * 4, 8, 8 },      /* hi */
+
+  /* glibc's ucontext.h doesn't specify the order of the following
+     three registerss.  But there is space allocated for them.  (Well,
+     for something, anyway - the g_pad[] array is has three elements.)
+     We use the same order for these fields as that specified in the
+     kernel header for elf_gregset_t; see the EF_ constants in
+     asm-mips/reg.h.  Note, however, that the kernel header sandwiches
+     the status register (sr, above) in between ``bad'' and ``cause''.  */
+
+  { 66,            8, GREGS,  35 * 4, 8, 8 },      /* bad */
+  { 65,            8, GREGS,  36 * 4, 8, 8 },      /* cause */
+  { 64,            8, GREGS,  34 * 4, 8, 8 },      /* pc */
+
+  /* Linux/MIPS floating point is a bit of a mess.  On the one hand,
+     the elf_fpregset_t contains space for 32 doubles plus the control
+     word.  But on the other hand, the ptrace interface is only able to
+     fetch the 32 32-bit wide registers.  This means that we only get
+     16 double precision floats via ptrace().  It also means that only
+     slightly more than half of elf_fpregset_t is unused.  */
+
+  { 32       + 0,  8, FPREGS, 0 * 4,  8, 8 },      /* $f0 */
+  { 32       + 1,  8, FPREGS, 1 * 4,  8, 8 },      /* $f1 */
+  { 32       + 2,  8, FPREGS, 2 * 4,  8, 8 },      /* $f2 */
+  { 32       + 3,  8, FPREGS, 3 * 4,  8, 8 },      /* $f3 */
+  { 32       + 4,  8, FPREGS, 4 * 4,  8, 8 },      /* $f4 */
+  { 32       + 5,  8, FPREGS, 5 * 4,  8, 8 },      /* $f5 */
+  { 32       + 6,  8, FPREGS, 6 * 4,  8, 8 },      /* $f6 */
+  { 32       + 7,  8, FPREGS, 7 * 4,  8, 8 },      /* $f7 */
+  { 32       + 8,  8, FPREGS, 8 * 4,  8, 8 },      /* $f8 */
+  { 32       + 9,  8, FPREGS, 9 * 4,  8, 8 },      /* $f9 */
+  { 32       + 10, 8, FPREGS, 10 * 4, 8, 8 },      /* $f10 */
+  { 32       + 11, 8, FPREGS, 11 * 4, 8, 8 },      /* $f11 */
+  { 32       + 12, 8, FPREGS, 12 * 4, 8, 8 },      /* $f12 */
+  { 32       + 13, 8, FPREGS, 13 * 4, 8, 8 },      /* $f13 */
+  { 32       + 14, 8, FPREGS, 14 * 4, 8, 8 },      /* $f14 */
+  { 32       + 15, 8, FPREGS, 15 * 4, 8, 8 },      /* $f15 */
+  { 32       + 16, 8, FPREGS, 16 * 4, 8, 8 },      /* $f16 */
+  { 32       + 17, 8, FPREGS, 17 * 4, 8, 8 },      /* $f17 */
+  { 32       + 18, 8, FPREGS, 18 * 4, 8, 8 },      /* $f18 */
+  { 32       + 19, 8, FPREGS, 19 * 4, 8, 8 },      /* $f19 */
+  { 32       + 20, 8, FPREGS, 20 * 4, 8, 8 },      /* $f20 */
+  { 32       + 21, 8, FPREGS, 21 * 4, 8, 8 },      /* $f21 */
+  { 32       + 22, 8, FPREGS, 22 * 4, 8, 8 },      /* $f22 */
+  { 32       + 23, 8, FPREGS, 23 * 4, 8, 8 },      /* $f23 */
+  { 32       + 24, 8, FPREGS, 24 * 4, 8, 8 },      /* $f24 */
+  { 32       + 25, 8, FPREGS, 25 * 4, 8, 8 },      /* $f25 */
+  { 32       + 26, 8, FPREGS, 26 * 4, 8, 8 },      /* $f26 */
+  { 32       + 27, 8, FPREGS, 27 * 4, 8, 8 },      /* $f27 */
+  { 32       + 28, 8, FPREGS, 28 * 4, 8, 8 },      /* $f28 */
+  { 32       + 29, 8, FPREGS, 29 * 4, 8, 8 },      /* $f29 */
+  { 32       + 30, 8, FPREGS, 30 * 4, 8, 8 },      /* $f30 */
+  { 32       + 31, 8, FPREGS, 31 * 4, 8, 8 },      /* $f31 */
+  { 69,            8, FPREGS, 64 * 4, 8, 8 }       /* fsr */
+};
+
+static void mips_singlestep_program (struct gdbserv *serv);
+
+/* End of MIPS64_LINUX_TARGET */
+
 #elif M68K_LINUX_TARGET
 
 /* Needs to be converted to use either GETREGS_SETREGS_REGINFO or
@@ -500,7 +648,8 @@ enum 
   SIZEOF_REGMAP = 29, 		/* with FP regs */
   SIZEOF_MAPPEDREG = 4,
   NUM_REGS = 29,
-  PC_REGNUM = 17
+  PC_REGNUM = 17,
+  sign_extend = 0
 };
 
 static int regmap[SIZEOF_REGMAP] =
@@ -557,7 +706,8 @@ is_extended_reg (int regnum)
 enum
 {
   NUM_REGS = 71,
-  PC_REGNUM = 64
+  PC_REGNUM = 64,
+  sign_extend = 0
 };
 
 static struct peekuser_pokeuser_reginfo reginfo[] =
@@ -646,7 +796,8 @@ enum 
   SIZEOF_REGMAP = 66, 
   SIZEOF_MAPPEDREG = 8,
   NUM_REGS = 66,
-  PC_REGNUM = 64
+  PC_REGNUM = 64,
+  sign_extend = 0
 };
 
 static int regmap[SIZEOF_REGMAP] = 
@@ -922,8 +1073,6 @@ linux_get_reg (struct gdbserv *serv, int
       return -1;
     }
 
-  memset (tmp_buf, 0, reginfo[regno].proto_size);
-
   if (reginfo[regno].whichregs != NOREGS)
     {
       /* Get the register value. */
@@ -931,9 +1080,12 @@ linux_get_reg (struct gdbserv *serv, int
       if (status < 0)
 	return -1;	/* fail */
     }
+  else
+    memset (tmp_buf, 0, reginfo[regno].ptrace_size);
 
   /* Copy the bytes to the gdbserv_reg struct.  */
-  gdbserv_host_bytes_to_reg (serv, tmp_buf, reginfo[regno].proto_size, reg);
+  gdbserv_host_bytes_to_reg (serv, tmp_buf, reginfo[regno].ptrace_size,
+                             reg, reginfo[regno].proto_size, sign_extend);
 
   return 0;	/* success */
   
@@ -958,17 +1110,10 @@ linux_set_reg (struct gdbserv *serv, int
       struct child_process *process = gdbserv_target_data (serv);
       char tmp_buf[MAX_REG_SIZE];
       int status;
-      int len;
-
-      /* Clear out a temporary buffer into which to fetch the bytes that
-	 we'll be setting.  We do this in case ptrace_size != proto_size.  */
-      memset (tmp_buf, 0, reginfo[regno].ptrace_size);
 
       /* Copy the bytes from the gdbserv_reg struct to our temporary buffer.  */
-      gdbserv_host_bytes_from_reg (serv, tmp_buf, &len, reg);
-
-      if (len != reginfo[regno].proto_size)
-	return -1;
+      gdbserv_host_bytes_from_reg (serv, tmp_buf, reginfo[regno].ptrace_size,
+                                   reg, sign_extend);
 
       /* Write the child's register. */
       status = write_reg_bytes (process->pid, regno, tmp_buf);
@@ -990,7 +1135,6 @@ reg_from_regset (struct gdbserv *serv, 
 		 const void *regset,
 		 enum regset whichregs)
 {
-  char tmp_buf[MAX_REG_SIZE];
   char *regbytes;
 
   if (regno < 0 || regno >= NUM_REGS 
@@ -1001,10 +1145,8 @@ reg_from_regset (struct gdbserv *serv, 
 
   regbytes = ((char *) regset) + reginfo[regno].regset_field_offset;
 
-  memset (tmp_buf, 0, reginfo[regno].proto_size);
-  memcpy (tmp_buf, regbytes, reginfo[regno].regset_field_size);
-
-  gdbserv_host_bytes_to_reg (serv, tmp_buf, reginfo[regno].proto_size, reg);
+  gdbserv_host_bytes_to_reg (serv, regbytes, reginfo[regno].regset_field_size,
+                             reg, reginfo[regno].proto_size, sign_extend);
 
   return 0;
 }
@@ -1020,9 +1162,7 @@ reg_to_regset (struct gdbserv *serv, 
 	       void *regset,
 	       enum regset whichregs)
 {
-  char tmp_buf[MAX_REG_SIZE];
   char *regbytes;
-  int len;
 
   if (regno < 0 || regno >= NUM_REGS 
       || reginfo[regno].whichregs != whichregs)
@@ -1030,15 +1170,10 @@ reg_to_regset (struct gdbserv *serv, 
       return -1;
     }
 
-  memset (tmp_buf, 0, reginfo[regno].regset_field_size);
-  gdbserv_host_bytes_from_reg (serv, tmp_buf, &len, reg);
-
-  if (len != reginfo[regno].proto_size)
-    return -1;
-
   regbytes = ((char *) regset) + reginfo[regno].regset_field_offset;
 
-  memcpy (regbytes, tmp_buf, reginfo[regno].regset_field_size);
+  gdbserv_host_bytes_from_reg (serv, regbytes, reginfo[regno].regset_field_size,
+                               reg, sign_extend);
 
   return 0;
 }
@@ -1137,16 +1272,15 @@ get_regset (struct gdbserv *serv, int pi
 	  struct gdbserv_reg reg;
 	  int status;
 
-	  memset (tmp_buf, 0, reginfo[regno].proto_size);
-
 	  /* Get the register value. */
 	  status = read_reg_bytes (pid, regno, tmp_buf);
 	  if (status < 0)
 	    return -1;	/* fail */
 
 	  /* Copy the bytes to the gdbserv_reg struct.  */
-	  gdbserv_host_bytes_to_reg (serv, tmp_buf,
-	                             reginfo[regno].proto_size, &reg);
+	  gdbserv_host_bytes_to_reg (serv, tmp_buf, reginfo[regno].ptrace_size,
+	                             &reg, reginfo[regno].proto_size,
+				     sign_extend);
 
 	  /* Now insert them into the regset.  */
 	  reg_to_regset (serv, &reg, regno, regset, whichregs);
@@ -1173,20 +1307,15 @@ put_regset (struct gdbserv *serv,
 	{
 	  char tmp_buf[MAX_REG_SIZE];
 	  struct gdbserv_reg reg;
-	  int len;
 	  int status;
 
 	  /* Fetch the reg from the regset.  */
 	  reg_from_regset (serv, &reg, regno, regset, whichregs);
 
-	  /* Clear out a temporary buffer into which to put the bytes that
-	     we'll be setting.  We do this in case ptrace_size != proto_size.  */
-	  memset (tmp_buf, 0, reginfo[regno].ptrace_size);
-
 	  /* Copy the bytes from the gdbserv_reg struct to our temporary buffer.  */
-	  gdbserv_host_bytes_from_reg (serv, tmp_buf, &len, &reg);
-	  if (len != reginfo[regno].proto_size)
-	    return -1;
+	  gdbserv_host_bytes_from_reg (serv, tmp_buf,
+	                               reginfo[regno].ptrace_size, &reg,
+				       sign_extend);
 
 	  /* Write the child's register. */
 	  status = write_reg_bytes (pid, regno, tmp_buf);
@@ -1343,7 +1472,6 @@ linux_get_reg (struct gdbserv *serv, int
   elf_fpregset_t fpregs;
   void *fpxregs;
   char *buf;
-  char tmp_buf[MAX_REG_SIZE];
 
   if (regno < 0 || regno >= NUM_REGS)
     {
@@ -1394,14 +1522,9 @@ linux_get_reg (struct gdbserv *serv, int
   /* Adjust buf to point at the starting byte of the register.  */
   buf += reginfo[regno].offset;
 
-  /* We go through these memset / memcpy shenanigans in case
-     proto_size != ptrace_size.  */
-  memset (tmp_buf, 0, reginfo[regno].proto_size);
-  if (reginfo[regno].ptrace_size > 0)
-    memcpy (tmp_buf, buf, reginfo[regno].ptrace_size);
-
   /* Copy the bytes to the gdbserv_reg struct.  */
-  gdbserv_host_bytes_to_reg (serv, tmp_buf, reginfo[regno].proto_size, reg);
+  gdbserv_host_bytes_to_reg (serv, buf, reginfo[regno].ptrace_size,
+                             reg, reginfo[regno].proto_size, sign_extend);
 
   return 0;
 }
@@ -1419,7 +1542,6 @@ linux_set_reg (struct gdbserv *serv, int
   void *fpxregs = NULL;
   char *buf;
   char tmp_buf[MAX_REG_SIZE];
-  int len;
 
   if (regno < 0 || regno >= NUM_REGS)
     {
@@ -1468,18 +1590,9 @@ linux_set_reg (struct gdbserv *serv, int
   /* Adjust buf to point at the starting byte of the register.  */
   buf += reginfo[regno].offset;
 
-  /* Clear out a temporary buffer into which to fetch the bytes that
-     we'll be setting.  We do this in case ptrace_size != proto_size.  */
-  memset (tmp_buf, 0, reginfo[regno].ptrace_size);
-
   /* Copy the bytes from the gdbserv_reg struct to our temporary buffer.  */
-  gdbserv_host_bytes_from_reg (serv, tmp_buf, &len, reg);
-
-  if (len != reginfo[regno].proto_size)
-    return -1;
-
-  /* Copy the bytes to the appropriate position in the ptrace struct.  */
-  memcpy (buf, tmp_buf, reginfo[regno].ptrace_size);
+  gdbserv_host_bytes_from_reg (serv, buf, reginfo[regno].ptrace_size, reg,
+                               sign_extend);
 
   /* Write the register set to the process.  */
   if (reginfo[regno].whichregs == GREGS)
@@ -1521,7 +1634,6 @@ reg_from_gregset (struct gdbserv *serv, 
 		  int regno, 
 		  const GREGSET_T gregset)
 {
-  char tmp_buf[MAX_REG_SIZE];
   char *regbytes;
 
   if (regno < 0 || regno >= NUM_REGS 
@@ -1532,10 +1644,8 @@ reg_from_gregset (struct gdbserv *serv, 
 
   regbytes = ((char *) gregset) + reginfo[regno].offset;
 
-  memset (tmp_buf, 0, reginfo[regno].proto_size);
-  memcpy (tmp_buf, regbytes, reginfo[regno].ptrace_size);
-
-  gdbserv_host_bytes_to_reg (serv, tmp_buf, reginfo[regno].proto_size, reg);
+  gdbserv_host_bytes_to_reg (serv, regbytes, reginfo[regno].ptrace_size,
+                             reg, reginfo[regno].proto_size, sign_extend);
 
   return 0;
 }
@@ -1550,9 +1660,7 @@ reg_to_gregset (struct gdbserv *serv, 
 		int regno, 
 		GREGSET_T gregset)
 {
-  char tmp_buf[MAX_REG_SIZE];
   char *regbytes;
-  int len;
 
   if (regno < 0 || regno >= NUM_REGS 
       || reginfo[regno].whichregs != GREGS)
@@ -1562,13 +1670,8 @@ reg_to_gregset (struct gdbserv *serv, 
 
   regbytes = ((char *) gregset) + reginfo[regno].offset;
 
-  memset (tmp_buf, 0, reginfo[regno].ptrace_size);
-  gdbserv_host_bytes_from_reg (serv, tmp_buf, &len, reg);
-
-  if (len != reginfo[regno].proto_size)
-    return -1;
-
-  memcpy (regbytes, tmp_buf, reginfo[regno].ptrace_size);
+  gdbserv_host_bytes_from_reg (serv, regbytes, reginfo[regno].ptrace_size, reg,
+                               sign_extend);
 
   return 0;
 }
@@ -1583,7 +1686,6 @@ reg_from_fpregset (struct gdbserv *serv,
 		   int regno, 
 		   const FPREGSET_T *fpregset)
 {
-  char tmp_buf[MAX_REG_SIZE];
   char *regbytes;
 
   if (regno < 0 || regno >= NUM_REGS 
@@ -1594,10 +1696,8 @@ reg_from_fpregset (struct gdbserv *serv,
 
   regbytes = ((char *) fpregset) + reginfo[regno].offset;
 
-  memset (tmp_buf, 0, reginfo[regno].proto_size);
-  memcpy (tmp_buf, regbytes, reginfo[regno].ptrace_size);
-
-  gdbserv_host_bytes_to_reg (serv, tmp_buf, reginfo[regno].proto_size, reg);
+  gdbserv_host_bytes_to_reg (serv, regbytes, reginfo[regno].ptrace_size,
+                             reg, reginfo[regno].proto_size, sign_extend);
 
   return 0;
 }
@@ -1612,9 +1712,7 @@ reg_to_fpregset (struct gdbserv *serv, 
 		 int regno, 
 		 FPREGSET_T *fpregset)
 {
-  char tmp_buf[MAX_REG_SIZE];
   char *regbytes;
-  int len;
 
   if (regno < 0 || regno >= NUM_REGS 
       || reginfo[regno].whichregs != FPREGS)
@@ -1624,13 +1722,8 @@ reg_to_fpregset (struct gdbserv *serv, 
 
   regbytes = ((char *) fpregset) + reginfo[regno].offset;
 
-  memset (tmp_buf, 0, reginfo[regno].ptrace_size);
-  gdbserv_host_bytes_from_reg (serv, tmp_buf, &len, reg);
-
-  if (len != reginfo[regno].proto_size)
-    return -1;
-
-  memcpy (regbytes, tmp_buf, reginfo[regno].ptrace_size);
+  gdbserv_host_bytes_from_reg (serv, regbytes, reginfo[regno].ptrace_size, reg,
+                               sign_extend);
 
   return 0;
 }
@@ -1645,7 +1738,6 @@ reg_from_xregset (struct gdbserv *serv, 
 		  int regno, 
 		  const void *xregset)
 {
-  char tmp_buf[MAX_REG_SIZE];
   char *regbytes;
 
   if (regno < 0 || regno >= NUM_REGS 
@@ -1656,10 +1748,8 @@ reg_from_xregset (struct gdbserv *serv, 
 
   regbytes = ((char *) xregset) + reginfo[regno].offset;
 
-  memset (tmp_buf, 0, reginfo[regno].proto_size);
-  memcpy (tmp_buf, regbytes, reginfo[regno].ptrace_size);
-
-  gdbserv_host_bytes_to_reg (serv, tmp_buf, reginfo[regno].proto_size, reg);
+  gdbserv_host_bytes_to_reg (serv, regbytes, reginfo[regno].ptrace_size,
+                             reg, reginfo[regno].proto_size, sign_extend);
 
   return 0;
 }
@@ -1674,9 +1764,7 @@ reg_to_xregset (struct gdbserv *serv, 
 		int regno, 
 		void *xregset)
 {
-  char tmp_buf[MAX_REG_SIZE];
   char *regbytes;
-  int len;
 
   if (regno < 0 || regno >= NUM_REGS 
       || reginfo[regno].whichregs != FPXREGS)
@@ -1686,13 +1774,8 @@ reg_to_xregset (struct gdbserv *serv, 
 
   regbytes = ((char *) xregset) + reginfo[regno].offset;
 
-  memset (tmp_buf, 0, reginfo[regno].ptrace_size);
-  gdbserv_host_bytes_from_reg (serv, tmp_buf, &len, reg);
-
-  if (len != reginfo[regno].proto_size)
-    return -1;
-
-  memcpy (regbytes, tmp_buf, reginfo[regno].ptrace_size);
+  gdbserv_host_bytes_from_reg (serv, regbytes, reginfo[regno].ptrace_size, reg,
+                               sign_extend);
 
   return 0;
 }


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