Skip to content

Commit

Permalink
gdbstub: add RLE compression
Browse files Browse the repository at this point in the history
Refer to
https://sourceware.org/gdb/current/onlinedocs/gdb.html/Overview.html

w/o compression, nxgcore command took 41seconds.
w compression, 28second.

If we enable `set trust-readonly-sections on` to read from elf whenever
possible, it furture reduces to 14.9seconds.

Signed-off-by: xuxingliang <[email protected]>
  • Loading branch information
XuNeo authored and anjiahao1 committed Oct 8, 2024
1 parent c8416d9 commit 36aba9e
Showing 1 changed file with 99 additions and 0 deletions.
99 changes: 99 additions & 0 deletions libs/libc/gdbstub/lib_gdbstub.c
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ static ssize_t gdb_hex2bin(FAR void *buf, size_t buf_len,
FAR const void *data, size_t data_len);
static ssize_t gdb_bin2bin(FAR void *buf, size_t buf_len,
FAR const void *data, size_t data_len);
static size_t gdb_encode_rle(FAR void *data, size_t data_len);

/* Packet creation helpers */

Expand Down Expand Up @@ -355,6 +356,8 @@ static int gdb_send_packet(FAR struct gdb_state_s *state)
}
#endif

state->pkt_len = gdb_encode_rle(state->pkt_buf, state->pkt_len);

/* Send packet data */

ret = state->send(state->priv, state->pkt_buf, state->pkt_len);
Expand Down Expand Up @@ -714,6 +717,102 @@ static ssize_t gdb_bin2bin(FAR void *buf, size_t buf_len,
return out_pos;
}

/****************************************************************************
* Name: gdb_count_repeat
*
* Description:
* Get how many bytes are repeated in coming data.
*
* Input Parameters:
* data - The buffer containing the encoded data.
* data_len - The length of the data to decode.
*
* Returned Value:
* The number of bytes repeated.
*
****************************************************************************/

static size_t gdb_count_repeat(FAR const char *data, size_t data_len)
{
char c = data[0];
size_t i = 1;

while (i < data_len && data[i] == c)
{
i++;
}

return i;
}

/****************************************************************************
* Name: gdb_encode_rle
*
* Description:
* Encode data in place using GDB RLE encoding.
*
* Input Parameters:
* data - The buffer containing the encoded data.
* data_len - The length of the data to decode.
*
* Returned Value:
* The number of bytes written to data on success.
*
****************************************************************************/

static size_t gdb_encode_rle(FAR void *data, size_t data_len)
{
static const int max_count = 127 - 29;
FAR char *buf = data;
size_t widx = 0;
size_t ridx = 0;

while (ridx < data_len)
{
size_t count = gdb_count_repeat(buf + ridx, data_len - ridx);
char c = buf[ridx];

ridx += count;
while (count >= max_count)
{
buf[widx++] = c;
buf[widx++] = '*';
buf[widx++] = max_count - 1 + 29;
count -= max_count;
}

if (count <= 3)
{
while (count > 0)
{
buf[widx++] = c;
count--;
}

continue;
}

buf[widx++] = c;
count--;
if (count + 29 == '$')
{
buf[widx++] = c;
buf[widx++] = c;
count -= 2;
}
else if (count + 29 == '#')
{
buf[widx++] = c;
count -= 1;
}

buf[widx++] = '*';
buf[widx++] = count + 29;
}

return widx;
}

/****************************************************************************
* Name: gdb_is_valid_region
* Description:
Expand Down

0 comments on commit 36aba9e

Please sign in to comment.