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 6b378f00..3db08fe5 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 9d0b2d52..d89e6f75 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 40b88a2a..f9ce5e22 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 c65cf13c..fe81325c 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 384ee61e..1fc88a92 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 9a4a2798..172224fe 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 2199e25a..06dfb4a6 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); }