From cgf@redhat.com Tue Nov 26 19:46:00 2002 From: cgf@redhat.com (Christopher Faylor) Date: Tue, 26 Nov 2002 19:46:00 -0000 Subject: [ADMINISTRIVIA] New RDA mailing list In-Reply-To: <20021127034054.GA1477@redhat.com> References: <20021127034054.GA1477@redhat.com> Message-ID: <20021127034702.GA1689@redhat.com> [Reply-To set to the rda mailing list] (what is it about seeing email in a mailing list that makes you see the details that you missed?) On Tue, Nov 26, 2002 at 10:40:54PM -0500, Christopher Faylor wrote: >I've just created an RDA mailing list: rda at sources dot redhat dot >com. It is intended for discussions about and patches for RDA. You can >subscribe to it in the usual way. Either send email to > >rda-subscribe at sources dot redhat dot com > >or visit the http://sources.redhat.com/lists.html web page and subscribe >using the form. > >I also created a web site for rda but it has no content yet. Volunteers >welcome. Changes to the web site are through cvs, just like all of the >web pages on sources dot redhat dot com. > >Please send any questions or observations about rda to this mailing list, >including questions about what the mailing list should be used for, what >rda is, etc. I should point out that rda stands for "remote debug agent". It's intended to be used to debug applications on systems other than the local system using gdb's remote protocol. If you want more details, please ask on the list. cgf From muller@ics.u-strasbg.fr Wed Nov 27 01:00:00 2002 From: muller@ics.u-strasbg.fr (Pierre Muller) Date: Wed, 27 Nov 2002 01:00:00 -0000 Subject: [ADMINISTRIVIA] New RDA mailing list In-Reply-To: <20021127034054.GA1477@redhat.com> Message-ID: <5.0.2.1.2.20021127095625.02489ac0@ics.u-strasbg.fr> At 04:40 27/11/2002, Christopher Faylor wrote: >I've just created an RDA mailing list: rda at sources dot redhat dot >com. It is intended for discussions about and patches for RDA. You can >subscribe to it in the usual way. Either send email to > >rda-subscribe at sources dot redhat dot com > >or visit the http://sources.redhat.com/lists.html web page and subscribe >using the form. > >I also created a web site for rda but it has no content yet. Volunteers >welcome. Changes to the web site are through cvs, just like all of the >web pages on sources dot redhat dot com. > >Please send any questions or observations about rda to this mailing list, >including questions about what the mailing list should be used for, what >rda is, etc. > >cgf Hi Christopher, does that mean that things like my RFC [RFC] Correct gdbserver register packets http://sources.redhat.com/ml/gdb-patches/2002-11/msg00652.html about a modification to gdbserver should be discussed in that mailing list? Pierre Muller Institut Charles Sadron 6,rue Boussingault F 67083 STRASBOURG CEDEX (France) mailto:muller@ics.u-strasbg.fr Phone : (33)-3-88-41-40-07 Fax : (33)-3-88-41-40-99 From ac131313@redhat.com Wed Nov 27 07:18:00 2002 From: ac131313@redhat.com (Andrew Cagney) Date: Wed, 27 Nov 2002 07:18:00 -0000 Subject: [ADMINISTRIVIA] New RDA mailing list References: <5.0.2.1.2.20021127095625.02489ac0@ics.u-strasbg.fr> Message-ID: <3DE4E23E.5000104@redhat.com> > Hi Christopher, > > does that mean that things like my RFC > [RFC] Correct gdbserver register packets > > http://sources.redhat.com/ml/gdb-patches/2002-11/msg00652.html > > about a modification to gdbserver should be discussed in that mailing list? No. GDBSERVER is part of GDB (which is part of the FSF's GNU project) and it should continue to be discussed here. Andrew From kevinb@redhat.com Wed Nov 27 10:33:00 2002 From: kevinb@redhat.com (Kevin Buettner) Date: Wed, 27 Nov 2002 10:33:00 -0000 Subject: [RFC] Revise interfaces for *_bytes_{from,to}_reg() Message-ID: <1021127183338.ZM31443@localhost.localdomain> I recently discovered that rda (on Linux/MIPS) didn't work correctly when the space allocated to hold a register for the remote protocol is larger than that required by the ptrace interface. (In a GDB configured for a mips64 target, I was seeing the (32-bit) register contents in the most significant 32-bits.) The patch below revises the gdbserv_{be,le,host}_bytes_{to,from}_reg() interfaces so that the correct padding/truncation occurs when the source and destination sizes differ. (I've thought about the problem of sign extension on MIPS, but I'm punting on it for now.) I'm not sure what the checkin policies are for RDA. I assume I need approval for gdbserv-utils.[hc]. 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. 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 27 Nov 2002 17:57:17 -0000 @@ -60,42 +60,58 @@ 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 an unsigned 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 with zeros. + + 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); 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); extern void gdbserv_be_bytes_from_reg (struct gdbserv *gdbserv, void *buf, - int *lenp, + int buflen, const struct gdbserv_reg *reg); extern void gdbserv_le_bytes_from_reg (struct gdbserv *gdbserv, void *buf, - int *lenp, + int buflen, 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 +/* 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); extern void gdbserv_host_bytes_from_reg (struct gdbserv *gdbserv, void *buf, - int *lenp, + int buflen, const struct gdbserv_reg *reg); #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 27 Nov 2002 17:57:17 -0000 @@ -227,67 +227,129 @@ 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 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, 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, + int buflen, const struct gdbserv_reg *reg) { - *lenp = reg->len; - memcpy (buf, reg->buf, reg->len); + 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, 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 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, 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, + int buflen, const struct gdbserv_reg *reg) { - *lenp = reg->len; - reverse_copy_bytes (buf, reg->buf, reg->len); + 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, 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) { #ifdef WORDS_BIGENDIAN - gdbserv_be_bytes_to_reg (gdbserv, buf, len, reg); + gdbserv_be_bytes_to_reg (gdbserv, buf, buflen, reg, reglen); #else - gdbserv_le_bytes_to_reg (gdbserv, buf, len, reg); + gdbserv_le_bytes_to_reg (gdbserv, buf, buflen, reg, reglen); #endif } void gdbserv_host_bytes_from_reg (struct gdbserv *gdbserv, void *buf, - int *lenp, + int buflen, const struct gdbserv_reg *reg) { #ifdef WORDS_BIGENDIAN - gdbserv_be_bytes_from_reg (gdbserv, buf, lenp, reg); + gdbserv_be_bytes_from_reg (gdbserv, buf, buflen, reg); #else - gdbserv_le_bytes_from_reg (gdbserv, buf, lenp, reg); + gdbserv_le_bytes_from_reg (gdbserv, buf, buflen, reg); #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 27 Nov 2002 17:57:19 -0000 @@ -922,8 +1065,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 +1072,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); return 0; /* success */ @@ -958,17 +1102,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); /* Write the child's register. */ status = write_reg_bytes (process->pid, regno, tmp_buf); @@ -990,7 +1127,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 +1137,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); return 0; } @@ -1020,9 +1154,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 +1162,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); return 0; } @@ -1137,16 +1264,14 @@ 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, ®); + gdbserv_host_bytes_to_reg (serv, tmp_buf, reginfo[regno].ptrace_size, + ®, reginfo[regno].proto_size); /* Now insert them into the regset. */ reg_to_regset (serv, ®, regno, regset, whichregs); @@ -1173,20 +1298,14 @@ 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, ®, 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, ®); - if (len != reginfo[regno].proto_size) - return -1; + gdbserv_host_bytes_from_reg (serv, tmp_buf, + reginfo[regno].ptrace_size, ®); /* Write the child's register. */ status = write_reg_bytes (pid, regno, tmp_buf); @@ -1343,7 +1462,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 +1512,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); return 0; } @@ -1419,7 +1532,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 +1580,8 @@ 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); /* Write the register set to the process. */ if (reginfo[regno].whichregs == GREGS) @@ -1521,7 +1623,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 +1633,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); return 0; } @@ -1550,9 +1649,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 +1659,7 @@ 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); return 0; } @@ -1583,7 +1674,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 +1684,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); return 0; } @@ -1612,9 +1700,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 +1710,7 @@ 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); return 0; } @@ -1645,7 +1725,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 +1735,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, tmp_buf, reginfo[regno].ptrace_size, + reg, reginfo[regno].proto_size); return 0; } @@ -1674,9 +1751,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 +1761,7 @@ 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); return 0; } From kevinb@redhat.com Wed Nov 27 10:49:00 2002 From: kevinb@redhat.com (Kevin Buettner) Date: Wed, 27 Nov 2002 10:49:00 -0000 Subject: [RFC] Revise interfaces for *_bytes_{from,to}_reg() In-Reply-To: Kevin Buettner "[RFC] Revise interfaces for *_bytes_{from,to}_reg()" (Nov 27, 11:33am) References: <1021127183338.ZM31443@localhost.localdomain> Message-ID: <1021127184913.ZM31521@localhost.localdomain> On Nov 27, 11:33am, Kevin Buettner wrote: > The patch below revises the gdbserv_{be,le,host}_bytes_{to,from}_reg() > interfaces so that the correct padding/truncation occurs when the source > and destination sizes differ. (I've thought about the problem of sign > extension on MIPS, but I'm punting on it for now.) Since I'm doing MIPS, I really can't punt on it for very long, so I'm thinking some more about it now... I'm considering adding gdbserv_{host,le,be}_signed_bytes_{to,from}_reg(). Another approach is to add a parameter (flag) to the existing functions which indicate whether signed or unsigned extension should be done. Opinions? Kevin From kevinb@redhat.com Wed Nov 27 13:31:00 2002 From: kevinb@redhat.com (Kevin Buettner) Date: Wed, 27 Nov 2002 13:31:00 -0000 Subject: [PATCH] Update configury for mips64-linux targets Message-ID: <1021127213122.ZM32337@localhost.localdomain> I've just committed the patch below. * acinclude.m4: New file. * config.in (MIPS64_LINUX_TARGET, MIPS_ABI_N64, MIPS_ABI_N32) (MIPS_ABI_O32): New defines. * configure.in (mips64*linux*, mips64*linux*n64, mips64*linux*n32) (mips64*linux*o32): New targets. (mips64*linux*) : Define MIPS_ABI_O32. (HAVE_AC_DEFINE): Remove conditional definition; autoconf complained about it. * aclocal.m4, configure, Makefile.in: Regenerate. Index: acinclude.m4 =================================================================== RCS file: acinclude.m4 diff -N acinclude.m4 --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ acinclude.m4 27 Nov 2002 21:21:51 -0000 @@ -0,0 +1,10 @@ +sinclude(../../libtool.m4) +dnl The lines below arrange for aclocal not to bring libtool.m4 +dnl AM_PROG_LIBTOOL into aclocal.m4, while still arranging for automake +dnl to add a definition of LIBTOOL to Makefile.in. +ifelse(yes,no,[ +AC_DEFUN([AM_PROG_LIBTOOL],) +AC_DEFUN([AM_DISABLE_SHARED],) +AC_SUBST(LIBTOOL) +]) + Index: config.in =================================================================== RCS file: /cvs/src/src/rda/unix/config.in,v retrieving revision 1.1 diff -u -p -r1.1 config.in --- config.in 28 Aug 2002 01:22:28 -0000 1.1 +++ config.in 27 Nov 2002 21:21:51 -0000 @@ -92,8 +92,20 @@ /* Define if target is SH (3? 4?) Linux */ #undef SH_LINUX_TARGET -/* Define if target is MIPS Linux */ +/* Define if target is 64-bit MIPS Linux */ +#undef MIPS64_LINUX_TARGET + +/* Define if target is (32-bit) MIPS Linux */ #undef MIPS_LINUX_TARGET + +/* Define if target uses MIPS n64 ABI */ +#undef MIPS_ABI_N64 + +/* Define if target uses MIPS n32 ABI */ +#undef MIPS_ABI_N32 + +/* Define if target uses MIPS o32 ABI */ +#undef MIPS_ABI_O32 /* Define if target is any Linux */ #undef LINUX_TARGET Index: configure.in =================================================================== RCS file: /cvs/src/src/rda/unix/configure.in,v retrieving revision 1.1 diff -u -p -r1.1 configure.in --- configure.in 28 Aug 2002 01:22:28 -0000 1.1 +++ configure.in 27 Nov 2002 21:21:52 -0000 @@ -30,6 +30,16 @@ dnl define ptrace_xfer_type dnl define ptrace_arg3_type case "$target" in + mips64*linux*) + TARGET_MODULES="linux-target.o no-threads.o ptrace-target.o" + AC_DEFINE(LINUX_TARGET) + AC_DEFINE(GREGSET_T, prgregset_t) + AC_DEFINE(FPREGSET_T, prfpregset_t) + AC_DEFINE(HAVE_LWPID_T) + AC_DEFINE(HAVE_PSADDR_T) + AC_DEFINE(HAVE_PRGREGSET_T) + AC_DEFINE(HAVE_PRFPREGSET_T) + ;; i?86*linux* | \ powerpc*linux* | \ arm*linux* | \ @@ -84,8 +94,39 @@ case "$target" in AC_DEFINE(PTRACE_ARG3_TYPE_LONG) AC_DEFINE(PTRACE_ARG4_TYPE_LONG) ;; + mips64*linux*n64) + AC_DEFINE(MIPS64_LINUX_TARGET) + AC_DEFINE(MIPS_ABI_N64) + AC_DEFINE(PTRACE_XFER_SIZE, 8) + AC_DEFINE(PTRACE_XFER_TYPE_LONG) + AC_DEFINE(PTRACE_ARG1_TYPE_LONG) + AC_DEFINE(PTRACE_ARG2_TYPE_LONG) + AC_DEFINE(PTRACE_ARG3_TYPE_LONG) + AC_DEFINE(PTRACE_ARG4_TYPE_LONG) + ;; + mips64*linux*n32) + AC_DEFINE(MIPS64_LINUX_TARGET) + AC_DEFINE(MIPS_ABI_N32) + AC_DEFINE(PTRACE_XFER_SIZE, 8) + AC_DEFINE(PTRACE_XFER_TYPE_LONG_LONG) + AC_DEFINE(PTRACE_ARG1_TYPE_LONG_LONG) + AC_DEFINE(PTRACE_ARG2_TYPE_LONG_LONG) + AC_DEFINE(PTRACE_ARG3_TYPE_LONG_LONG) + AC_DEFINE(PTRACE_ARG4_TYPE_LONG_LONG) + ;; + mips64*linux*o32) + AC_DEFINE(MIPS64_LINUX_TARGET) + AC_DEFINE(MIPS_ABI_O32) + AC_DEFINE(PTRACE_XFER_SIZE, 4) + AC_DEFINE(PTRACE_XFER_TYPE_LONG) + AC_DEFINE(PTRACE_ARG1_TYPE_LONG) + AC_DEFINE(PTRACE_ARG2_TYPE_LONG) + AC_DEFINE(PTRACE_ARG3_TYPE_LONG) + AC_DEFINE(PTRACE_ARG4_TYPE_LONG) + ;; mips*linux*) AC_DEFINE(MIPS_LINUX_TARGET) + AC_DEFINE(MIPS_ABI_O32) AC_DEFINE(PTRACE_XFER_SIZE, 4) AC_DEFINE(PTRACE_XFER_TYPE_LONG) AC_DEFINE(PTRACE_ARG1_TYPE_LONG) @@ -149,10 +190,6 @@ case "$target" in fi ;; esac - -if test -f /usr/include/foo.h; then - AC_DEFINE(HAVE_AC_DEFINE, 1, [define if have AC_DEFINE]) -fi dnl Outputs AC_OUTPUT(Makefile) From kevinb@redhat.com Wed Nov 27 14:02:00 2002 From: kevinb@redhat.com (Kevin Buettner) Date: Wed, 27 Nov 2002 14:02:00 -0000 Subject: [RFC] Revise interfaces for *_bytes_{from,to}_reg() In-Reply-To: Kevin Buettner "Re: [RFC] Revise interfaces for *_bytes_{from,to}_reg()" (Nov 27, 11:49am) References: <1021127183338.ZM31443@localhost.localdomain> <1021127184913.ZM31521@localhost.localdomain> Message-ID: <1021127220214.ZM32427@localhost.localdomain> On Nov 27, 11:49am, Kevin Buettner wrote: > I'm considering adding gdbserv_{host,le,be}_signed_bytes_{to,from}_reg(). > Another approach is to add a parameter (flag) to the existing functions > which indicate whether signed or unsigned extension should be done. I've decided to add a ``sign_extend'' parameter to these functions. Kevin From kevinb@redhat.com Wed Nov 27 15:26:00 2002 From: kevinb@redhat.com (Kevin Buettner) Date: Wed, 27 Nov 2002 15:26:00 -0000 Subject: [RFC] (2nd try) Revise interfaces for *_bytes_{from,to}_reg() Message-ID: <1021127232634.ZM9395@localhost.localdomain> 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. 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 27 Nov 2002 23:16: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 27 Nov 2002 23:16: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 27 Nov 2002 23:16:35 -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[] = { @@ -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, ®); + gdbserv_host_bytes_to_reg (serv, tmp_buf, reginfo[regno].ptrace_size, + ®, reginfo[regno].proto_size, + sign_extend); /* Now insert them into the regset. */ reg_to_regset (serv, ®, 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, ®, 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, ®); - if (len != reginfo[regno].proto_size) - return -1; + gdbserv_host_bytes_from_reg (serv, tmp_buf, + reginfo[regno].ptrace_size, ®, + 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; } From drow@mvista.com Sun Dec 1 13:21:00 2002 From: drow@mvista.com (Daniel Jacobowitz) Date: Sun, 01 Dec 2002 13:21:00 -0000 Subject: [ADMINISTRIVIA] New RDA mailing list In-Reply-To: <3DE4E23E.5000104@redhat.com> References: <5.0.2.1.2.20021127095625.02489ac0@ics.u-strasbg.fr> <3DE4E23E.5000104@redhat.com> Message-ID: <20021201212149.GC12876@nevyn.them.org> On Wed, Nov 27, 2002 at 10:18:22AM -0500, Andrew Cagney wrote: > > >Hi Christopher, > > > >does that mean that things like my RFC > >[RFC] Correct gdbserver register packets > > > >http://sources.redhat.com/ml/gdb-patches/2002-11/msg00652.html > > > >about a modification to gdbserver should be discussed in that mailing list? > > No. GDBSERVER is part of GDB (which is part of the FSF's GNU project) > and it should continue to be discussed here. I really wish we could come to some resolution about the overlap. Should we sacrifice the FSF-owned gdbserver project in favor of extending RDA? As it is, there's a substantial amount of duplicated effort. I hate seeing effort wasted. -- Daniel Jacobowitz MontaVista Software Debian GNU/Linux Developer From ac131313@redhat.com Sun Dec 1 14:50:00 2002 From: ac131313@redhat.com (Andrew Cagney) Date: Sun, 01 Dec 2002 14:50:00 -0000 Subject: [ADMINISTRIVIA] New RDA mailing list References: <5.0.2.1.2.20021127095625.02489ac0@ics.u-strasbg.fr> <3DE4E23E.5000104@redhat.com> <20021201212149.GC12876@nevyn.them.org> Message-ID: <3DEA91A9.6010009@redhat.com> >> No. GDBSERVER is part of GDB (which is part of the FSF's GNU project) >> and it should continue to be discussed here. > > > I really wish we could come to some resolution about the overlap. > Should we sacrifice the FSF-owned gdbserver project in favor of > extending RDA? As it is, there's a substantial amount of duplicated > effort. I hate seeing effort wasted. gdb/gdbserver/ is the FSF's (and hence GDB's) remote debug agent. There is no benefit to the FSF, and its objectives, in replacing something (C) FSF with something (C) Red Hat. Andrew From drow@mvista.com Sun Dec 1 15:19:00 2002 From: drow@mvista.com (Daniel Jacobowitz) Date: Sun, 01 Dec 2002 15:19:00 -0000 Subject: [ADMINISTRIVIA] New RDA mailing list In-Reply-To: <3DEA91A9.6010009@redhat.com> References: <5.0.2.1.2.20021127095625.02489ac0@ics.u-strasbg.fr> <3DE4E23E.5000104@redhat.com> <20021201212149.GC12876@nevyn.them.org> <3DEA91A9.6010009@redhat.com> Message-ID: <20021201231925.GA16409@nevyn.them.org> On Sun, Dec 01, 2002 at 05:48:09PM -0500, Andrew Cagney wrote: > > >>No. GDBSERVER is part of GDB (which is part of the FSF's GNU project) > >>and it should continue to be discussed here. > > > > > >I really wish we could come to some resolution about the overlap. > >Should we sacrifice the FSF-owned gdbserver project in favor of > >extending RDA? As it is, there's a substantial amount of duplicated > >effort. I hate seeing effort wasted. > > gdb/gdbserver/ is the FSF's (and hence GDB's) remote debug agent. There > is no benefit to the FSF, and its objectives, in replacing something (C) > FSF with something (C) Red Hat. There is no benefit to the community in having a publicly developed RDA that I can see. Right now I don't believe it has any features that gdbserver doesn't, although I could be wrong - I only checked briefly - I know that it used to have threads support when gdbserver didn't but we implemented that before RDA was released. And now Red Hat employees can contribute things like tracepoint support to the community by adding them to the (c) Red Hat RDA, when the community would benefit as much or more having them in gdbserver. So we get two stubs with mostly-overlapping but different feature sets. Obviously Red Hat doesn't want to drop RDA in favor of gdbserver. But having gdbserver as a second-rate cousin until someone spends weeks playing feature catchup with RDA (e.g. I or someone else finds the time to implement the introspect stuff in gdbserver, if I can even do it...) does no one but Red Hat any good. I'm sorry to keep harping on this unpleasant subject, but it really irks me. There's a gdbserver project out there to contribute to. It was in bad shape; I like to think we've put it back together now! -- Daniel Jacobowitz MontaVista Software Debian GNU/Linux Developer From cgd@netbsd.org Mon Dec 2 12:02:00 2002 From: cgd@netbsd.org (Chris G. Demetriou) Date: Mon, 02 Dec 2002 12:02:00 -0000 Subject: [ADMINISTRIVIA] New RDA mailing list In-Reply-To: drow@mvista.com's message of "Sun, 1 Dec 2002 23:19:18 +0000 (UTC)" References: <5.0.2.1.2.20021127095625.02489ac0@ics.u-strasbg.fr> <3DE4E23E.5000104@redhat.com> <20021201212149.GC12876@nevyn.them.org> <3DEA91A9.6010009@redhat.com> <20021201231925.GA16409@nevyn.them.org> Message-ID: <87smxgi3ys.fsf@homeworld.netbsd.org> At Sun, 1 Dec 2002 23:19:21 +0000 (UTC), "Daniel Jacobowitz" wrote: > There is no benefit to the community in having a publicly developed RDA > that I can see. I got all excited about RDA when i saw the announcement, because i was hoping that it wasn't GPL'd. As it is, it's GPL'd but Copyright Red Hat. *sigh* It seems to me that this means that it pretty much equivalent to gdbserver (modulo implementation or feature differences) **EXCEPT**: * RH can use it however they wish w/o distributing source, and * RH can sell licenses to third parties, to allow them to use it under whatever terms they're willing to pay for. I think a non-GPL'd (i.e., "actually-free software" 8-) gdbserver/RDA-like thing would be of great benefit to the community. However, like you said, i think that the existing RDA is of benefit only to RedHat. Potential users who want to develop it or develop using it should be aware of that. cgd -- Chris Demetriou - cgd@netbsd.org - http://www.netbsd.org/People/Pages/cgd.html Disclaimer: Not speaking for NetBSD, just expressing my own opinion. From kevinb@redhat.com Mon Dec 2 19:25:00 2002 From: kevinb@redhat.com (Kevin Buettner) Date: Mon, 02 Dec 2002 19:25:00 -0000 Subject: [RFC] (2nd try) Revise interfaces for *_bytes_{from,to}_reg() In-Reply-To: Kevin Buettner "[RFC] (2nd try) Revise interfaces for *_bytes_{from,to}_reg()" (Nov 27, 4:26pm) References: <1021127232634.ZM9395@localhost.localdomain> Message-ID: <1021203032519.ZM6985@localhost.localdomain> 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, ®); + gdbserv_host_bytes_to_reg (serv, tmp_buf, reginfo[regno].ptrace_size, + ®, reginfo[regno].proto_size, + sign_extend); /* Now insert them into the regset. */ reg_to_regset (serv, ®, 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, ®, 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, ®); - if (len != reginfo[regno].proto_size) - return -1; + gdbserv_host_bytes_from_reg (serv, tmp_buf, + reginfo[regno].ptrace_size, ®, + 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; } From kevinb@redhat.com Wed Dec 18 12:31:00 2002 From: kevinb@redhat.com (Kevin Buettner) Date: Wed, 18 Dec 2002 12:31:00 -0000 Subject: [PATCH] unix/ptrace-target.[ch] changes Message-ID: <1021218203105.ZM8191@localhost.localdomain> The patch below mostly improves the ability to watch what ptrace() is doing. There are also some changes which handle the case in which sizeof (ptrace_xfer_type) != sizeof (long). Committed. * ptrace-target.h, ptrace-target.c (ptrace_write_user) (ptrace_read_user): Add struct gdbserv argument. * linux-target.c: Fix all callers (and callers of callers). * ptrace-target.c (ptrace_write_user, ptrace_read_user): Add debugging printf()s. (ptrace_xfer_mem): Fix debugging printf()s so that they'll print useful results when sizeof (long long) is the same as sizeof (ptrace_xfer_type). (ptrace_xfer_mem): Decode address using gdbserv_host_bytes_from_reg() instead of gdbserv_reg_to_ulong(). Index: linux-target.c =================================================================== RCS file: /cvs/src/src/rda/unix/linux-target.c,v retrieving revision 1.2 diff -u -p -r1.2 linux-target.c --- linux-target.c 3 Dec 2002 03:22:07 -0000 1.2 +++ linux-target.c 18 Dec 2002 20:22:34 -0000 @@ -982,7 +982,7 @@ is_extended_reg (int regnum) Returns 0 for success, -1 for failure. */ static int -read_reg_bytes (int pid, int regno, void *reg_bytes) +read_reg_bytes (struct gdbserv *serv, int pid, int regno, void *reg_bytes) { ptrace_arg3_type regaddr; int regsize; @@ -993,7 +993,7 @@ read_reg_bytes (int pid, int regno, void regaddr = reginfo[regno].ptrace_offset; regsize = reginfo[regno].ptrace_size; - status = ptrace_read_user (pid, regaddr, regsize, reg_bytes); + status = ptrace_read_user (serv, pid, regaddr, regsize, reg_bytes); /* A non-zero status is the errno value from the ptrace call */ if (status != 0) @@ -1011,7 +1011,8 @@ read_reg_bytes (int pid, int regno, void Returns 0 for success, -1 for failure. */ static int -write_reg_bytes (int pid, int regno, const void *reg_bytes) +write_reg_bytes (struct gdbserv *serv, int pid, int regno, + const void *reg_bytes) { ptrace_arg3_type regaddr; int regsize; @@ -1022,7 +1023,7 @@ write_reg_bytes (int pid, int regno, con regaddr = reginfo[regno].ptrace_offset; regsize = reginfo[regno].ptrace_size; - status = ptrace_write_user (pid, regaddr, regsize, reg_bytes); + status = ptrace_write_user (serv, pid, regaddr, regsize, reg_bytes); /* A non-zero status is the errno value from the ptrace call */ if (status != 0) @@ -1038,11 +1039,11 @@ write_reg_bytes (int pid, int regno, con /* Fetch and return the value of register REGNO. Helper function for debug_get_pc(). This is the PEEKUSER_POKEUSER_REGINFO version. */ static unsigned long -debug_get_reg (pid_t pid, int regno) +debug_get_reg (struct gdbserv *serv, pid_t pid, int regno) { ptrace_xfer_type value; - if (read_reg_bytes (pid, regno, &value) < 0) + if (read_reg_bytes (serv, pid, regno, &value) < 0) return 0; else return (unsigned long) value; @@ -1052,7 +1053,7 @@ debug_get_reg (pid_t pid, int regno) unsigned long debug_get_pc (struct gdbserv *serv, pid_t pid) { - return debug_get_reg (pid, PC_REGNUM); + return debug_get_reg (serv, pid, PC_REGNUM); } /* Function: get_reg @@ -1076,7 +1077,7 @@ linux_get_reg (struct gdbserv *serv, int if (reginfo[regno].whichregs != NOREGS) { /* Get the register value. */ - status = read_reg_bytes (process->pid, regno, tmp_buf); + status = read_reg_bytes (serv, process->pid, regno, tmp_buf); if (status < 0) return -1; /* fail */ } @@ -1116,7 +1117,7 @@ linux_set_reg (struct gdbserv *serv, int reg, sign_extend); /* Write the child's register. */ - status = write_reg_bytes (process->pid, regno, tmp_buf); + status = write_reg_bytes (serv, process->pid, regno, tmp_buf); if (status < 0) return -1; /* Fail */ } @@ -1273,7 +1274,7 @@ get_regset (struct gdbserv *serv, int pi int status; /* Get the register value. */ - status = read_reg_bytes (pid, regno, tmp_buf); + status = read_reg_bytes (serv, pid, regno, tmp_buf); if (status < 0) return -1; /* fail */ @@ -1318,7 +1319,7 @@ put_regset (struct gdbserv *serv, sign_extend); /* Write the child's register. */ - status = write_reg_bytes (pid, regno, tmp_buf); + status = write_reg_bytes (serv, pid, regno, tmp_buf); if (status < 0) return -1; /* Fail */ } @@ -1899,7 +1900,8 @@ enum { U_REGS_OFFSET = 0 }; /* FIXME??? Return -1 for failure, zero for success. */ static int -linux_read_reg (int pid, int regno, ptrace_xfer_type *regval) +linux_read_reg (struct gdbserv *serv, int pid, int regno, + ptrace_xfer_type *regval) { unsigned long u_regs_base = U_REGS_OFFSET; ptrace_arg3_type regaddr; @@ -1909,7 +1911,7 @@ linux_read_reg (int pid, int regno, ptra regaddr += U_REGS_OFFSET; errno = 0; - ptrace_read_user (pid, regaddr, sizeof (*regval), regval); + ptrace_read_user (serv, pid, regaddr, sizeof (*regval), regval); if (errno) { @@ -1925,17 +1927,18 @@ linux_read_reg (int pid, int regno, ptra Return -1 for failure, zero for success. */ static int -linux_write_reg (int pid, int regno, ptrace_xfer_type regval) +linux_write_reg (struct gdbserv *serv, int regno, ptrace_xfer_type regval) { unsigned long u_regs_base = U_REGS_OFFSET; ptrace_arg3_type regaddr; + struct child_process *process = gdbserv_target_data (serv); if ((regaddr = linux_register_offset (regno)) < 0) return -1; /* fail */ regaddr += U_REGS_OFFSET; errno = 0; - ptrace_write_user (pid, regaddr, sizeof (regval), ®val); + ptrace_write_user (serv, process->pid, regaddr, sizeof (regval), ®val); if (errno) { fprintf (stderr, "PT_WRITE_U 0x%08lx from 0x%08lx in process %d\n", @@ -1949,11 +1952,11 @@ linux_write_reg (int pid, int regno, ptr /* Helper function for debug_get_pc(). It fetches and returns the value of REGNO. */ static unsigned long -debug_get_reg (pid_t pid, int regno) +debug_get_reg (struct gdbserv *serv, pid_t pid, int regno) { ptrace_xfer_type value; - if (linux_read_reg (pid, regno, &value) < 0) + if (linux_read_reg (serv, pid, regno, &value) < 0) return 0; else return (unsigned long) value; @@ -1963,7 +1966,7 @@ debug_get_reg (pid_t pid, int regno) unsigned long debug_get_pc (struct gdbserv *serv, pid_t pid) { - return debug_get_reg (pid, PC_REGNUM); + return debug_get_reg (serv, pid, PC_REGNUM); } /* Function: reg_format @@ -2013,7 +2016,7 @@ linux_get_reg (struct gdbserv *serv, int ptrace_xfer_type regval; /* Get the register value. */ - if (linux_read_reg (process->pid, regno, ®val) < 0) + if (linux_read_reg (serv, process->pid, regno, ®val) < 0) { fprintf (stderr, "Error: linux_get_reg: Register %d out of bounds.\n", regno); return -1; @@ -2039,7 +2042,6 @@ linux_get_reg (struct gdbserv *serv, int static int linux_set_reg (struct gdbserv *serv, int regno, struct gdbserv_reg *reg) { - struct child_process *process = gdbserv_target_data (serv); ptrace_xfer_type regval; if (regno < 0 || regno >= NUM_REGS) @@ -2055,7 +2057,7 @@ linux_set_reg (struct gdbserv *serv, int gdbserv_reg_to_ulonglong (serv, reg, (unsigned long long *) ®val); /* Write the child's register. */ - if (linux_write_reg (process->pid, regno, regval) < 0) + if (linux_write_reg (serv, regno, regval) < 0) return -1; /* Fail */ return 0; /* success */ @@ -2187,7 +2189,8 @@ reg_to_xregset (struct gdbserv *serv, static int get_gregset (struct gdbserv *serv, int pid, GREGSET_T gregset) { - if (ptrace_read_user (pid, 0, sizeof (GREGSET_T), (char *) gregset) != 0) + if (ptrace_read_user (serv, pid, 0, sizeof (GREGSET_T), (char *) gregset) + != 0) return -1; return 0; } @@ -2199,7 +2202,7 @@ get_gregset (struct gdbserv *serv, int p static int put_gregset (struct gdbserv *serv, int pid, const GREGSET_T gregset) { - if (ptrace_write_user (pid, 0, sizeof (GREGSET_T), + if (ptrace_write_user (serv, pid, 0, sizeof (GREGSET_T), (char *) gregset) != 0) return -1; return 0; @@ -2495,7 +2498,7 @@ mips_get_reg(struct gdbserv *serv, int r struct child_process *process = gdbserv_target_data (serv); pid_t pid = process->pid; - if (read_reg_bytes (pid, regno, &value) < 0) + if (read_reg_bytes (serv, pid, regno, &value) < 0) return 0; else return value; Index: ptrace-target.c =================================================================== RCS file: /cvs/src/src/rda/unix/ptrace-target.c,v retrieving revision 1.2 diff -u -p -r1.2 ptrace-target.c --- ptrace-target.c 19 Nov 2002 22:24:31 -0000 1.2 +++ ptrace-target.c 18 Dec 2002 20:22:34 -0000 @@ -183,11 +183,13 @@ ptrace_kill_program (struct child_proces */ extern int -ptrace_read_user (int pid, +ptrace_read_user (struct gdbserv *serv, + int pid, ptrace_arg3_type addr, int len, void *buff) { + struct child_process *process = gdbserv_target_data (serv); int i; /* Require: addr is on the proper boundary, and @@ -199,6 +201,12 @@ ptrace_read_user (int pid, errno = 0; *(ptrace_xfer_type *) &((char *)buff)[i] = ptrace (PTRACE_PEEKUSER, pid, addr + i, 0); +#if 0 /* too noisy! */ + if (process->debug_backend) + fprintf (stderr, "PTRACE_PEEKUSER 0x%08llx in %d, 0x%08llx\n", + (long long) addr + i, pid, + (long long) * (ptrace_xfer_type *) &((char *)buff)[i]); +#endif if (errno != 0) return errno; } @@ -211,11 +219,13 @@ ptrace_read_user (int pid, */ extern int -ptrace_write_user (int pid, +ptrace_write_user (struct gdbserv *serv, + int pid, ptrace_arg3_type addr, int len, const void *buff) { + struct child_process *process = gdbserv_target_data (serv); int i; /* Require: addr is on the proper boundary, and @@ -231,6 +241,10 @@ ptrace_write_user (int pid, errno = 0; ptrace (PTRACE_POKEUSER, pid, addr + i, * (ptrace_xfer_type *) &((char *)buff)[i]); + if (process->debug_backend) + fprintf (stderr, "PTRACE_POKEUSER 0x%08llx in %d, 0x%08llx\n", + (long long) addr + i, pid, + (long long) * (ptrace_xfer_type *) &((char *)buff)[i]); #if defined(_MIPSEL) || defined(MIPS_LINUX_TARGET) /* mips linux kernel 2.4 has a bug where PTRACE_POKEUSER returns -ESRCH even when it succeeds */ @@ -956,12 +970,14 @@ ptrace_xfer_mem (struct gdbserv *serv, int i; /* Get request address. */ - gdbserv_reg_to_ulong (serv, addr, &request_base); + gdbserv_host_bytes_from_reg (serv, &request_base, sizeof (request_base), + addr, 0); /* Round down to a PTRACE word boundary. */ xfer_base = request_base & - PTRACE_XFER_SIZE; /* Round length up to a PTRACE word boundary. */ xfer_count = (((request_base + len) - xfer_base) + PTRACE_XFER_SIZE - 1) / PTRACE_XFER_SIZE; + /* Allocate space for xfer. */ buf = (ptrace_xfer_type *) alloca (xfer_count * PTRACE_XFER_SIZE); @@ -976,8 +992,8 @@ ptrace_xfer_mem (struct gdbserv *serv, buf[i] = ptrace (PTRACE_PEEKTEXT, process->pid, temp_addr, 0L); if (process->debug_backend) - fprintf (stderr, "PTRACE_PEEKTEXT-1 0x%08lx in %d, 0x%08lx\n", - (long) temp_addr, process->pid, (long) buf[i]); + fprintf (stderr, "PTRACE_PEEKTEXT-1 0x%08llx in %d, 0x%08llx\n", + (long long) temp_addr, process->pid, (long long) buf[i]); if (errno) { if (errno != EIO) @@ -1004,15 +1020,15 @@ ptrace_xfer_mem (struct gdbserv *serv, buf[0] = ptrace (PTRACE_PEEKTEXT, process->pid, xfer_base, 0L); if (process->debug_backend) - fprintf (stderr, "PTRACE_PEEKTEXT-2 0x%08lx in %d, 0x%08lx\n", - (long) xfer_base, process->pid, (long) buf[0]); + fprintf (stderr, "PTRACE_PEEKTEXT-2 0x%08llx in %d, 0x%08llx\n", + (long long) xfer_base, process->pid, (long long) buf[0]); if (errno) { if (errno != EIO) fprintf (stderr, - "xfer_mem(2): ptrace error at 0x%08lx in %d: %s\n", - (long) xfer_base, process->pid, strerror (errno)); + "xfer_mem(2): ptrace error at 0x%08llx in %d: %s\n", + (long long) xfer_base, process->pid, strerror (errno)); return -1; } } @@ -1025,9 +1041,9 @@ ptrace_xfer_mem (struct gdbserv *serv, buf[xfer_count - 1] = ptrace (PTRACE_PEEKTEXT, process->pid, temp_addr, 0L); if (process->debug_backend) - fprintf (stderr, "PTRACE_PEEKTEXT-3 0x%08lx in %d, 0x%08lx\n", - (long) temp_addr, process->pid, - (long) buf[xfer_count - 1]); + fprintf (stderr, "PTRACE_PEEKTEXT-3 0x%08llx in %d, 0x%08llx\n", + (long long) temp_addr, process->pid, + (long long) buf[xfer_count - 1]); if (errno) { @@ -1050,15 +1066,15 @@ ptrace_xfer_mem (struct gdbserv *serv, ptrace (PTRACE_POKETEXT, process->pid, temp_addr, buf[i]); if (process->debug_backend) - fprintf (stderr, "PTRACE_POKETEXT 0x%08lx in %d, 0x%08lx\n", - (long) temp_addr, process->pid, (long) buf[i]); + fprintf (stderr, "PTRACE_POKETEXT 0x%08llx in %d, 0x%08llx\n", + (long long) temp_addr, process->pid, (long long) buf[i]); if (errno) { if (errno != EIO) fprintf (stderr, - "xfer_mem(4): ptrace error at 0x%08lx in %d: %s\n", - (long) temp_addr, process->pid, strerror (errno)); + "xfer_mem(4): ptrace error at 0x%08llx in %d: %s\n", + (long long) temp_addr, process->pid, strerror (errno)); return -1; } } Index: ptrace-target.h =================================================================== RCS file: /cvs/src/src/rda/unix/ptrace-target.h,v retrieving revision 1.1 diff -u -p -r1.1 ptrace-target.h --- ptrace-target.h 28 Aug 2002 01:22:28 -0000 1.1 +++ ptrace-target.h 18 Dec 2002 20:22:34 -0000 @@ -67,8 +67,10 @@ typedef long ptrace_arg4_type; typedef long long ptrace_arg4_type; #endif -int ptrace_write_user (int, ptrace_arg3_type, int, const void *); -int ptrace_read_user (int, ptrace_arg3_type, int, void *); +int ptrace_write_user (struct gdbserv *serv, int pid, ptrace_arg3_type addr, + int len, const void *buff); +int ptrace_read_user (struct gdbserv *serv, int pid, ptrace_arg3_type addr, + int len, void *buff); int ptrace_get_gregs (struct gdbserv *serv, int alt_pid, void *buff); int ptrace_set_gregs (struct gdbserv *serv, int alt_pid, const void *buff); int ptrace_get_fpregs (struct gdbserv *serv, int alt_pid, void *buff);