mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2024-12-02 19:27:31 +01:00
thermosphere: gdb/net: reduce stack/memory usage by using memmove
This commit is contained in:
parent
779aeaa538
commit
bd36796d5f
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user