This is the mail archive of the gdb-patches@sourceware.cygnus.com mailing list for the GDB project.


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

Fix remote RLE.


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)
  	    {

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