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]

remote.c run-length encoding patch


The Cisco remote protocol varient (notice that I didn't say mutant
remote protocol this time :-) uses two hex characters instead of a
ASCII encoding for the run length but is otherwise the same as the
standard protocol.

However, the code implementing the decoding is quite different for the
two encodings.  The standard encoding is expanded as the packet is
read, while the Cisco varient reads the entire packet and then expands
it in place (actually it expands it to another buffer, and the copies
that buffer into the first).  Unlike the code implementing the
standard encoding, the Cisco varient does not detect a packet that
would expand to larger than the buffer size, which could lead to
corruption within GDB.

In this patch, I decided to handle both encodings in the same manner.

        --jtc

1999-08-20  J.T. Conklin  <jtc@redback.com>

	* remote.c (read_frame): expand cisco run-length encoding variant
 	inline as is done for the standard encoding.
	(remote_cisco_expand): Removed.

Index: remote.c
===================================================================
RCS file: /home/jtc/CVSROOT/gdb/gdb/remote.c,v
retrieving revision 1.1.1.12
diff -c -r1.1.1.12 remote.c
*** remote.c	1999/08/11 04:07:51	1.1.1.12
--- remote.c	1999/08/20 22:35:48
***************
*** 3530,3562 ****
  
  static int remote_cisco_mode;
  
- static void
- remote_cisco_expand (src, dest)
-      char *src;
-      char *dest;
- {
-   int i;
-   int repeat;
- 
-   do
-     {
-       if (*src == '*')
- 	{
- 	  repeat = (fromhex (src[1]) << 4) + fromhex (src[2]);
- 	  for (i = 0; i < repeat; i++)
- 	    {
- 	      *dest++ = *(src - 1);
- 	    }
- 	  src += 2;
- 	}
-       else
- 	{
- 	  *dest++ = *src;
- 	}
-     }
-   while (*src++);
- }
- 
  /* 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.  */
--- 3530,3535 ----
***************
*** 3597,3612 ****
  	    pktcsum |= fromhex (readchar (remote_timeout));
  
  	    if (csum == pktcsum)
! 	      {
! 		if (remote_cisco_mode)	/* variant run-length-encoding */
! 		  {
! 		    char *tmp_buf = alloca (PBUFSIZ);
! 
! 		    remote_cisco_expand (buf, tmp_buf);
! 		    strcpy (buf, tmp_buf);
! 		  }
! 		return 1;
! 	      }
  
  	    if (remote_debug)
  	      {
--- 3570,3576 ----
  	    pktcsum |= fromhex (readchar (remote_timeout));
  
  	    if (csum == pktcsum)
!               return 1;
  
  	    if (remote_debug)
  	      {
***************
*** 3619,3645 ****
  	    return 0;
  	  }
  	case '*':		/* Run length encoding */
! 	  if (remote_cisco_mode == 0)	/* variant run-length-encoding */
! 	    {
! 	      csum += c;
! 	      c = readchar (remote_timeout);
! 	      csum += c;
! 	      c = c - ' ' + 3;	/* Compute repeat count */
! 
! 	      if (c > 0 && c < 255 && bp + c - 1 < buf + PBUFSIZ - 1)
! 		{
! 		  memset (bp, *(bp - 1), c);
! 		  bp += c;
! 		  continue;
! 		}
! 
! 	      *bp = '\0';
! 	      printf_filtered ("Repeat count %d too large for buffer: ", c);
! 	      puts_filtered (buf);
! 	      puts_filtered ("\n");
! 	      return 0;
! 	    }
! 	  /* else fall thru to treat like default */
  	default:
  	  if (bp < buf + PBUFSIZ - 1)
  	    {
--- 3583,3625 ----
  	    return 0;
  	  }
  	case '*':		/* Run length encoding */
!           {
! 	    int repeat;
!  	    csum += c;
! 
! 	    if (remote_cisco_mode == 0)
! 	      {
! 		c = readchar (remote_timeout);
! 		csum += c;
! 		repeat = c - ' ' + 3;	/* Compute repeat count */
! 	      }
! 	    else 
! 	      { 
! 		/* Cisco's run-length encoding variant uses two 
! 		   hex chars to represent the repeat count. */
! 
! 		c = readchar (remote_timeout);
! 		csum += c;
! 		repeat  = fromhex (c) << 4;
! 		c = readchar (remote_timeout);
! 		csum += c;
! 		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)
  	    {


-- 
J.T. Conklin
RedBack Networks

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