This is the mail archive of the
gdb-patches@sourceware.cygnus.com
mailing list for the GDB project.
remote.c run-length encoding patch
- To: gdb-patches@sourceware.cygnus.com
- Subject: remote.c run-length encoding patch
- From: jtc@redback.com (J.T. Conklin)
- Date: 20 Aug 1999 16:37:40 -0700
- Reply-To: jtc@redback.com
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