This is the mail archive of the
gdb-patches@sourceware.cygnus.com
mailing list for the GDB project.
Fix remote RLE.
- To: GDB Patches <gdb-patches at sourceware dot cygnus dot com>
- Subject: Fix remote RLE.
- From: Andrew Cagney <ac131313 at cygnus dot com>
- Date: Sat, 04 Dec 1999 01:15:35 +1100
- Organization: Cygnus Solutions
FYI,
I've checked in the attatched which fixes a RLE problem introduced
during a cleanup of the Cisco code :-(
Andrew
Fri Dec 3 17:38:06 1999 Andrew Cagney <cagney@b1.cygnus.com>
* (read_frame): Add sizeof_buf parameter. Don't allow repeat when
first character. Always leave space at the end of the buffer.
Return size of packet or -1.
(getpkt): Update. Pass in PBUFSIZ.
Index: remote.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/remote.c,v
retrieving revision 1.259
diff -p -r1.259 remote.c
*** remote.c 1999/11/29 01:19:26 1.259
--- remote.c 1999/12/03 13:46:43
*************** static int remote_thread_alive PARAMS ((
*** 139,145 ****
static void get_offsets PARAMS ((void));
! static int read_frame PARAMS ((char *));
static int remote_insert_breakpoint PARAMS ((CORE_ADDR, char *));
--- 139,145 ----
static void get_offsets PARAMS ((void));
! static long read_frame (char *buf, long sizeof_buf);
static int remote_insert_breakpoint PARAMS ((CORE_ADDR, char *));
*************** static int remote_cisco_mode;
*** 3769,3813 ****
/* Come here after finding the start of the frame. Collect the rest
into BUF, verifying the checksum, length, and handling run-length
! compression. Returns 0 on any error, 1 on success. */
! static int
! read_frame (buf)
! char *buf;
{
unsigned char csum;
! char *bp;
int c;
csum = 0;
! bp = buf;
while (1)
{
c = readchar (remote_timeout);
-
switch (c)
{
case SERIAL_TIMEOUT:
if (remote_debug)
fputs_filtered ("Timeout in mid-packet, retrying\n", gdb_stdlog);
! return 0;
case '$':
if (remote_debug)
fputs_filtered ("Saw new packet start in middle of old one\n",
gdb_stdlog);
! return 0; /* Start a new packet, count retries */
case '#':
{
unsigned char pktcsum;
! *bp = '\000';
pktcsum = fromhex (readchar (remote_timeout)) << 4;
pktcsum |= fromhex (readchar (remote_timeout));
if (csum == pktcsum)
! return 1;
if (remote_debug)
{
--- 3769,3818 ----
/* Come here after finding the start of the frame. Collect the rest
into BUF, verifying the checksum, length, and handling run-length
! compression. No more than sizeof_buf-1 characters are read so that
! the buffer can be NUL terminated.
! Returns -1 on error, number of characters in buffer (ignoring the
! trailing NULL) on success. (could be extended to return one of the
! SERIAL status indications). */
!
! static long
! read_frame (char *buf,
! long sizeof_buf)
{
unsigned char csum;
! long bc;
int c;
csum = 0;
! bc = 0;
while (1)
{
+ /* ASSERT (bc < sizeof_buf - 1) - space for trailing NUL */
c = readchar (remote_timeout);
switch (c)
{
case SERIAL_TIMEOUT:
if (remote_debug)
fputs_filtered ("Timeout in mid-packet, retrying\n", gdb_stdlog);
! return -1;
case '$':
if (remote_debug)
fputs_filtered ("Saw new packet start in middle of old one\n",
gdb_stdlog);
! return -1; /* Start a new packet, count retries */
case '#':
{
unsigned char pktcsum;
! buf[bc] = '\0';
pktcsum = fromhex (readchar (remote_timeout)) << 4;
pktcsum |= fromhex (readchar (remote_timeout));
if (csum == pktcsum)
! return bc;
if (remote_debug)
{
*************** read_frame (buf)
*** 3817,3823 ****
fputs_filtered (buf, gdb_stdlog);
fputs_filtered ("\n", gdb_stdlog);
}
! return 0;
}
case '*': /* Run length encoding */
{
--- 3822,3830 ----
fputs_filtered (buf, gdb_stdlog);
fputs_filtered ("\n", gdb_stdlog);
}
! /* Number of characters in buffer ignoring trailing
! NUL. */
! return -1;
}
case '*': /* Run length encoding */
{
*************** read_frame (buf)
*** 3843,3889 ****
repeat += fromhex (c);
}
if (repeat > 0 && repeat <= 255
! && bp + repeat - 1 < buf + PBUFSIZ - 1)
{
! memset (bp, *(bp - 1), repeat);
! bp += c;
continue;
}
! *bp = '\0';
printf_filtered ("Repeat count %d too large for buffer: ", repeat);
puts_filtered (buf);
puts_filtered ("\n");
! return 0;
}
default:
! if (bp < buf + PBUFSIZ - 1)
{
! *bp++ = c;
csum += c;
continue;
}
! *bp = '\0';
puts_filtered ("Remote packet too long: ");
puts_filtered (buf);
puts_filtered ("\n");
! return 0;
}
}
}
/* Read a packet from the remote machine, with error checking, and
! store it in BUF. BUF is expected to be of size PBUFSIZ. If
! FOREVER, wait forever rather than timing out; this is used while
! the target is executing user code. */
void
! getpkt (buf, forever)
! char *buf;
! int forever;
{
int c;
int tries;
--- 3850,3898 ----
repeat += fromhex (c);
}
+ /* The character before ``*'' is repeated. */
+
if (repeat > 0 && repeat <= 255
! && bc > 0
! && bc + repeat < sizeof_buf - 1)
{
! memset (&buf[bc], buf[bc - 1], repeat);
! bc += repeat;
continue;
}
! buf[bc] = '\0';
printf_filtered ("Repeat count %d too large for buffer: ", repeat);
puts_filtered (buf);
puts_filtered ("\n");
! return -1;
}
default:
! if (bc < sizeof_buf - 1)
{
! buf[bc++] = c;
csum += c;
continue;
}
! buf[bc] = '\0';
puts_filtered ("Remote packet too long: ");
puts_filtered (buf);
puts_filtered ("\n");
! return -1;
}
}
}
/* Read a packet from the remote machine, with error checking, and
! store it in BUF. If FOREVER, wait forever rather than timing out;
! this is used (in synchronous mode) to wait for a target that is is
! executing user code to stop. */
void
! getpkt (char *buf,
! int forever)
{
int c;
int tries;
*************** getpkt (buf, forever)
*** 3933,3941 ****
/* We've found the start of a packet, now collect the data. */
! val = read_frame (buf);
! if (val == 1)
{
if (remote_debug)
{
--- 3942,3950 ----
/* We've found the start of a packet, now collect the data. */
! val = read_frame (buf, PBUFSIZ);
! if (val >= 0)
{
if (remote_debug)
{