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.
This commit is contained in:
TuxSH 2017-11-26 02:18:59 +01:00
parent 9c5766f649
commit cf8696ac70
7 changed files with 34 additions and 22 deletions

View File

@ -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];

View File

@ -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);

View File

@ -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, &regs.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, &regs.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;
}

View File

@ -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);

View File

@ -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);
}

View File

@ -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];

View File

@ -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);
}