thermosphere: gdb/net: reduce stack/memory usage by using memmove

This commit is contained in:
TuxSH 2020-01-23 23:43:30 +00:00
parent 779aeaa538
commit bd36796d5f
4 changed files with 46 additions and 48 deletions

View File

@ -234,31 +234,37 @@ static int GDB_DoSendPacket(GDBContext *ctx, size_t len)
int GDB_SendPacket(GDBContext *ctx, const char *packetData, size_t len)
{
memmove(ctx->buffer + 1, packetData, len);
ctx->buffer[0] = '$';
memcpy(ctx->buffer + 1, packetData, len);
char *checksumLoc = ctx->buffer + len + 1;
*checksumLoc++ = '#';
hexItoa(GDB_ComputeChecksum(packetData, len), checksumLoc, 2, false);
hexItoa(GDB_ComputeChecksum(ctx->buffer + 1, len), checksumLoc, 2, false);
return GDB_DoSendPacket(ctx, 4 + len);
}
int GDB_SendFormattedPacket(GDBContext *ctx, const char *packetDataFmt, ...)
{
// It goes without saying you shouldn't use that with user-controlled data...
char buf[GDB_BUF_LEN + 1];
va_list args;
va_start(args, packetDataFmt);
int n = vsprintf(buf, packetDataFmt, args);
int n = vsprintf(ctx->buffer + 1, packetDataFmt, args);
va_end(args);
if(n < 0) return -1;
else return GDB_SendPacket(ctx, buf, (u32)n);
if (n < 0) {
return -1;
}
ctx->buffer[0] = '$';
char *checksumLoc = ctx->buffer + n + 1;
*checksumLoc++ = '#';
hexItoa(GDB_ComputeChecksum(ctx->buffer + 1, n), checksumLoc, 2, false);
return GDB_DoSendPacket(ctx, 4 + n);
}
int GDB_SendHexPacket(GDBContext *ctx, const void *packetData, u32 len)
int GDB_SendHexPacket(GDBContext *ctx, const void *packetData, size_t len)
{
if(4 + 2 * len > GDB_BUF_LEN)
return -1;
@ -273,50 +279,26 @@ int GDB_SendHexPacket(GDBContext *ctx, const void *packetData, u32 len)
return GDB_DoSendPacket(ctx, 4 + 2 * len);
}
int GDB_SendStreamData(GDBContext *ctx, const char *streamData, u32 offset, u32 length, u32 totalSize, bool forceEmptyLast)
int GDB_SendStreamData(GDBContext *ctx, const char *streamData, size_t offset, size_t length, size_t totalSize, bool forceEmptyLast)
{
char buf[GDB_BUF_LEN];
if(length > GDB_BUF_LEN - 1)
// GDB_BUF_LEN does not include the usual %#<1-byte checksum>
if(length > GDB_BUF_LEN - 1) {
length = GDB_BUF_LEN - 1;
}
if((forceEmptyLast && offset >= totalSize) || (!forceEmptyLast && offset + length >= totalSize))
{
char letter;
if ((forceEmptyLast && offset >= totalSize) || (!forceEmptyLast && offset + length >= totalSize)) {
length = offset >= totalSize ? 0 : totalSize - offset;
buf[0] = 'l';
memcpy(buf + 1, streamData + offset, length);
return GDB_SendPacket(ctx, buf, 1 + length);
letter = 'l';
} else {
letter = 'm';
}
else
{
buf[0] = 'm';
memcpy(buf + 1, streamData + offset, length);
return GDB_SendPacket(ctx, buf, 1 + length);
}
}
int GDB_SendDebugString(GDBContext *ctx, const char *fmt, ...) // unsecure
{
/*if(ctx->state == GDB_STATE_DETACHING || !(ctx->flags & GDB_FLAG_CONTINUING))
return 0;*/
char formatted[(GDB_BUF_LEN - 1) / 2 + 1];
ctx->buffer[0] = '$';
ctx->buffer[1] = 'O';
va_list args;
va_start(args, fmt);
int n = vsprintf(formatted, fmt, args);
va_end(args);
if(n <= 0) return n;
GDB_EncodeHex(ctx->buffer + 2, formatted, 2 * n);
char *checksumLoc = ctx->buffer + 2 * n + 2;
*checksumLoc++ = '#';
hexItoa(GDB_ComputeChecksum(ctx->buffer + 1, 2 * n + 1), checksumLoc, 2, false);
return GDB_DoSendPacket(ctx, 5 + 2 * n);
// Note: ctx->buffer[0] = '$'
memmove(ctx->buffer + 2, streamData + offset, length);
ctx->buffer[1] = letter;
return GDB_SendPacket(ctx, ctx->buffer + 1, 1 + length);
}
int GDB_ReplyEmpty(GDBContext *ctx)

View File

@ -25,7 +25,6 @@ int GDB_SendPacket(GDBContext *ctx, const char *packetData, size_t len);
int GDB_SendFormattedPacket(GDBContext *ctx, const char *packetDataFmt, ...);
int GDB_SendHexPacket(GDBContext *ctx, const void *packetData, size_t len);
int GDB_SendStreamData(GDBContext *ctx, const char *streamData, size_t offset, size_t length, size_t totalSize, bool forceEmptyLast);
int GDB_SendDebugString(GDBContext *ctx, const char *fmt, ...); // unsecure
int GDB_ReplyEmpty(GDBContext *ctx);
int GDB_ReplyOk(GDBContext *ctx);
int GDB_ReplyErrno(GDBContext *ctx, int no);

View File

@ -18,6 +18,21 @@
#include "pattern_utils.h"
u32 hexItoa(u64 number, char *out, u32 digits, bool uppercase)
{
static const char hexDigits[] = "0123456789ABCDEF";
static const char hexDigitsLowercase[] = "0123456789abcdef";
u32 i = 0;
while (number > 0) {
out[digits - 1 - i++] = uppercase ? hexDigits[number & 0xF] : hexDigitsLowercase[number & 0xF];
number >>= 4;
}
while (i < digits) out[digits - 1 - i++] = '0';
return digits;
}
//Boyer-Moore Horspool algorithm, adapted from http://www-igm.univ-mlv.fr/~lecroq/string/node18.html#SECTION00180
//u32 size to limit stack usage
u8 *memsearch(u8 *startPos, const void *pattern, u32 size, u32 patternSize)

View File

@ -18,6 +18,8 @@
#include "utils.h"
u32 hexItoa(u64 number, char *out, u32 digits, bool uppercase);
// u32 size to limit stack usage
// Not sure if we need this function because we can only map one guest page at a time...
u8 *memsearch(u8 *startPos, const void *pattern, u32 size, u32 patternSize);