From 5ffff7c1d1d2db595e4c23a8c388d3a51d5bb357 Mon Sep 17 00:00:00 2001 From: Daniel Jacobowitz Date: Thu, 21 Sep 2006 16:09:54 +0000 Subject: [PATCH] * remote-utils.c (try_rle): New function. (putpkt_binary): Use it. --- gdb/gdbserver/ChangeLog | 5 ++++ gdb/gdbserver/remote-utils.c | 52 ++++++++++++++++++++++++++++++++---- 2 files changed, 52 insertions(+), 5 deletions(-) diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog index 25b7ed55619..737f9cd0040 100644 --- a/gdb/gdbserver/ChangeLog +++ b/gdb/gdbserver/ChangeLog @@ -1,3 +1,8 @@ +2006-09-21 Daniel Jacobowitz + + * remote-utils.c (try_rle): New function. + (putpkt_binary): Use it. + 2006-08-19 Daniel Jacobowitz * Makefile.in (clean): Clean reg-x86-64-linux.c. diff --git a/gdb/gdbserver/remote-utils.c b/gdb/gdbserver/remote-utils.c index 8da223f7e3b..a6726d578c5 100644 --- a/gdb/gdbserver/remote-utils.c +++ b/gdb/gdbserver/remote-utils.c @@ -406,6 +406,50 @@ remote_unescape_input (const gdb_byte *buffer, int len, return output_index; } +/* Look for a sequence of characters which can be run-length encoded. + If there are any, update *CSUM and *P. Otherwise, output the + single character. Return the number of characters consumed. */ + +static int +try_rle (char *buf, int remaining, unsigned char *csum, char **p) +{ + int n; + + /* Always output the character. */ + *csum += buf[0]; + *(*p)++ = buf[0]; + + /* Don't go past '~'. */ + if (remaining > 97) + remaining = 97; + + for (n = 1; n < remaining; n++) + if (buf[n] != buf[0]) + break; + + /* N is the index of the first character not the same as buf[0]. + buf[0] is counted twice, so by decrementing N, we get the number + of characters the RLE sequence will replace. */ + n--; + + if (n < 3) + return 1; + + /* Skip the frame characters. The manual says to skip '+' and '-' + also, but there's no reason to. Unfortunately these two unusable + characters double the encoded length of a four byte zero + value. */ + while (n + 29 == '$' || n + 29 == '#') + n--; + + *csum += '*'; + *(*p)++ = '*'; + *csum += n + 29; + *(*p)++ = n + 29; + + return n + 1; +} + /* Send a packet to the remote machine, with error checking. The data of the packet is in BUF, and the length of the packet is in CNT. Returns >= 0 on success, -1 otherwise. */ @@ -427,11 +471,9 @@ putpkt_binary (char *buf, int cnt) p = buf2; *p++ = '$'; - for (i = 0; i < cnt; i++) - { - csum += buf[i]; - *p++ = buf[i]; - } + for (i = 0; i < cnt;) + i += try_rle (buf + i, cnt - i, &csum, &p); + *p++ = '#'; *p++ = tohex ((csum >> 4) & 0xf); *p++ = tohex (csum & 0xf); -- 2.30.2