From cf8696ac70afc8f206c757783c79c3d5ff848a60 Mon Sep 17 00:00:00 2001 From: TuxSH Date: Sun, 26 Nov 2017 02:18:59 +0100 Subject: [PATCH] Disable non-process memory access by default (see below), remove IDA 6.8 support... The physical memory access "bit31" mapping (0--0x30000000 => 0x80000000--0xB0000000) as well as privileged (kernel) mappings confuse debugger clients like IDA's which interpret the value of the registers. Access to those mappings can be toggled using "monitor toggleextmemaccess" instead (issue reported by @Nanquitas). Closes #943. Additionally, support for the buggy IDA 6.8's buggy gdb client was removed. Please use IDA 7.0 or higher. P.S: IDA 7.0 added client support for no-ack mode (Debugging options > Set specific options), which should be enabled to make debugging twice as smooth. "Use stepping support" should be unchecked. --- sysmodules/rosalina/include/gdb.h | 2 +- .../rosalina/include/gdb/remote_command.h | 1 + sysmodules/rosalina/source/gdb/debug.c | 24 ++++++++----------- sysmodules/rosalina/source/gdb/mem.c | 5 +++- sysmodules/rosalina/source/gdb/query.c | 1 - .../rosalina/source/gdb/remote_command.c | 21 ++++++++++++---- sysmodules/rosalina/source/gdb/server.c | 2 +- 7 files changed, 34 insertions(+), 22 deletions(-) diff --git a/sysmodules/rosalina/include/gdb.h b/sysmodules/rosalina/include/gdb.h index 6b378f0..3db08fe 100644 --- a/sysmodules/rosalina/include/gdb.h +++ b/sysmodules/rosalina/include/gdb.h @@ -111,7 +111,7 @@ typedef struct GDBContext u32 nbWatchpoints; u32 watchpoints[2]; - bool isGDB; + bool enableExternalMemoryAccess; char *commandData, *commandEnd; int latestSentPacketSize; char buffer[GDB_BUF_LEN + 4]; diff --git a/sysmodules/rosalina/include/gdb/remote_command.h b/sysmodules/rosalina/include/gdb/remote_command.h index 9d0b2d5..d89e6f7 100644 --- a/sysmodules/rosalina/include/gdb/remote_command.h +++ b/sysmodules/rosalina/include/gdb/remote_command.h @@ -35,5 +35,6 @@ GDB_DECLARE_REMOTE_COMMAND_HANDLER(SyncRequestInfo); GDB_DECLARE_REMOTE_COMMAND_HANDLER(TranslateHandle); GDB_DECLARE_REMOTE_COMMAND_HANDLER(GetMmuConfig); GDB_DECLARE_REMOTE_COMMAND_HANDLER(FlushCaches); +GDB_DECLARE_REMOTE_COMMAND_HANDLER(ToggleExternalMemoryAccess); GDB_DECLARE_QUERY_HANDLER(Rcmd); diff --git a/sysmodules/rosalina/source/gdb/debug.c b/sysmodules/rosalina/source/gdb/debug.c index 40b88a2..f9ce5e2 100644 --- a/sysmodules/rosalina/source/gdb/debug.c +++ b/sysmodules/rosalina/source/gdb/debug.c @@ -173,26 +173,22 @@ static int GDB_ParseCommonThreadInfo(char *out, GDBContext *ctx, int sig) if(R_SUCCEEDED(r)) n += sprintf(out + n, "core:%x;", core); - if(ctx->isGDB) - { - for(u32 i = 0; i <= 12; i++) - n += sprintf(out + n, "%x:%08x;", i, __builtin_bswap32(regs.cpu_registers.r[i])); - } + for(u32 i = 0; i <= 12; i++) + n += sprintf(out + n, "%x:%08x;", i, __builtin_bswap32(regs.cpu_registers.r[i])); + n += sprintf(out + n, "d:%08x;e:%08x;f:%08x;19:%08x;", __builtin_bswap32(regs.cpu_registers.sp), __builtin_bswap32(regs.cpu_registers.lr), __builtin_bswap32(regs.cpu_registers.pc), __builtin_bswap32(regs.cpu_registers.cpsr)); - if(ctx->isGDB) + for(u32 i = 0; i < 16; i++) { - for(u32 i = 0; i < 16; i++) - { - u64 val; - memcpy(&val, ®s.fpu_registers.d[i], 8); - n += sprintf(out + n, "%x:%016llx;", 26 + i, __builtin_bswap64(val)); - } - - n += sprintf(out + n, "2a:%08x;2b:%08x;", __builtin_bswap32(regs.fpu_registers.fpscr), __builtin_bswap32(regs.fpu_registers.fpexc)); + u64 val; + memcpy(&val, ®s.fpu_registers.d[i], 8); + n += sprintf(out + n, "%x:%016llx;", 26 + i, __builtin_bswap64(val)); } + + n += sprintf(out + n, "2a:%08x;2b:%08x;", __builtin_bswap32(regs.fpu_registers.fpscr), __builtin_bswap32(regs.fpu_registers.fpexc)); + return n; } diff --git a/sysmodules/rosalina/source/gdb/mem.c b/sysmodules/rosalina/source/gdb/mem.c index c65cf13..fe81325 100644 --- a/sysmodules/rosalina/source/gdb/mem.c +++ b/sysmodules/rosalina/source/gdb/mem.c @@ -41,6 +41,8 @@ Result GDB_ReadMemoryInPage(void *out, GDBContext *ctx, u32 addr, u32 len) if(addr < (1u << (32 - (u32)TTBCR))) return svcReadProcessMemory(out, ctx->debug, addr, len); + else if(!ctx->enableExternalMemoryAccess) + return -1; else if(addr >= 0x80000000 && addr < 0xB0000000) { memcpy(out, (const void *)addr, len); @@ -67,7 +69,8 @@ Result GDB_WriteMemoryInPage(GDBContext *ctx, const void *in, u32 addr, u32 len) if(addr < (1u << (32 - (u32)TTBCR))) return svcWriteProcessMemory(ctx->debug, in, addr, len); // not sure if it checks if it's IO or not. It probably does - + else if(!ctx->enableExternalMemoryAccess) + return -1; else if(addr >= 0x80000000 && addr < 0xB0000000) { memcpy((void *)addr, in, len); diff --git a/sysmodules/rosalina/source/gdb/query.c b/sysmodules/rosalina/source/gdb/query.c index 384ee61..1fc88a9 100644 --- a/sysmodules/rosalina/source/gdb/query.c +++ b/sysmodules/rosalina/source/gdb/query.c @@ -120,7 +120,6 @@ GDB_DECLARE_QUERY_HANDLER(Supported) GDB_DECLARE_QUERY_HANDLER(StartNoAckMode) { - ctx->isGDB = true; ctx->state = GDB_STATE_NOACK_SENT; return GDB_ReplyOk(ctx); } diff --git a/sysmodules/rosalina/source/gdb/remote_command.c b/sysmodules/rosalina/source/gdb/remote_command.c index 9a4a279..172224f 100644 --- a/sysmodules/rosalina/source/gdb/remote_command.c +++ b/sysmodules/rosalina/source/gdb/remote_command.c @@ -36,10 +36,11 @@ struct GDBCommandHandler handler; } remoteCommandHandlers[] = { - { "syncrequestinfo", GDB_REMOTE_COMMAND_HANDLER(SyncRequestInfo) }, - { "translatehandle", GDB_REMOTE_COMMAND_HANDLER(TranslateHandle) }, - { "getmmuconfig" , GDB_REMOTE_COMMAND_HANDLER(GetMmuConfig) }, - { "flushcaches" , GDB_REMOTE_COMMAND_HANDLER(FlushCaches) }, + { "syncrequestinfo" , GDB_REMOTE_COMMAND_HANDLER(SyncRequestInfo) }, + { "translatehandle" , GDB_REMOTE_COMMAND_HANDLER(TranslateHandle) }, + { "getmmuconfig" , GDB_REMOTE_COMMAND_HANDLER(GetMmuConfig) }, + { "flushcaches" , GDB_REMOTE_COMMAND_HANDLER(FlushCaches) }, + { "toggleextmemaccess", GDB_REMOTE_COMMAND_HANDLER(ToggleExternalMemoryAccess) }, }; static const char *GDB_SkipSpaces(const char *pos) @@ -236,6 +237,18 @@ GDB_DECLARE_REMOTE_COMMAND_HANDLER(FlushCaches) return GDB_ReplyOk(ctx); } +GDB_DECLARE_REMOTE_COMMAND_HANDLER(ToggleExternalMemoryAccess) +{ + int n; + char outbuf[GDB_BUF_LEN / 2 + 1]; + + ctx->enableExternalMemoryAccess = !ctx->enableExternalMemoryAccess; + + n = sprintf(outbuf, "External memory access %s successfully.\n", ctx->enableExternalMemoryAccess ? "enabled" : "disabled"); + + return GDB_SendHexPacket(ctx, outbuf, n); +} + GDB_DECLARE_QUERY_HANDLER(Rcmd) { char commandData[GDB_BUF_LEN / 2 + 1]; diff --git a/sysmodules/rosalina/source/gdb/server.c b/sysmodules/rosalina/source/gdb/server.c index 2199e25..06dfb4a 100644 --- a/sysmodules/rosalina/source/gdb/server.c +++ b/sysmodules/rosalina/source/gdb/server.c @@ -211,7 +211,7 @@ void GDB_ReleaseClient(GDBServer *server, GDBContext *ctx) ctx->nbThreads = 0; memset(ctx->threadInfos, 0, sizeof(ctx->threadInfos)); ctx->catchThreadEvents = false; - ctx->isGDB = false; + ctx->enableExternalMemoryAccess = false; RecursiveLock_Unlock(&ctx->lock); }