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:
parent
9c5766f649
commit
cf8696ac70
@ -111,7 +111,7 @@ typedef struct GDBContext
|
|||||||
u32 nbWatchpoints;
|
u32 nbWatchpoints;
|
||||||
u32 watchpoints[2];
|
u32 watchpoints[2];
|
||||||
|
|
||||||
bool isGDB;
|
bool enableExternalMemoryAccess;
|
||||||
char *commandData, *commandEnd;
|
char *commandData, *commandEnd;
|
||||||
int latestSentPacketSize;
|
int latestSentPacketSize;
|
||||||
char buffer[GDB_BUF_LEN + 4];
|
char buffer[GDB_BUF_LEN + 4];
|
||||||
|
@ -35,5 +35,6 @@ GDB_DECLARE_REMOTE_COMMAND_HANDLER(SyncRequestInfo);
|
|||||||
GDB_DECLARE_REMOTE_COMMAND_HANDLER(TranslateHandle);
|
GDB_DECLARE_REMOTE_COMMAND_HANDLER(TranslateHandle);
|
||||||
GDB_DECLARE_REMOTE_COMMAND_HANDLER(GetMmuConfig);
|
GDB_DECLARE_REMOTE_COMMAND_HANDLER(GetMmuConfig);
|
||||||
GDB_DECLARE_REMOTE_COMMAND_HANDLER(FlushCaches);
|
GDB_DECLARE_REMOTE_COMMAND_HANDLER(FlushCaches);
|
||||||
|
GDB_DECLARE_REMOTE_COMMAND_HANDLER(ToggleExternalMemoryAccess);
|
||||||
|
|
||||||
GDB_DECLARE_QUERY_HANDLER(Rcmd);
|
GDB_DECLARE_QUERY_HANDLER(Rcmd);
|
||||||
|
@ -173,17 +173,13 @@ static int GDB_ParseCommonThreadInfo(char *out, GDBContext *ctx, int sig)
|
|||||||
if(R_SUCCEEDED(r))
|
if(R_SUCCEEDED(r))
|
||||||
n += sprintf(out + n, "core:%x;", core);
|
n += sprintf(out + n, "core:%x;", core);
|
||||||
|
|
||||||
if(ctx->isGDB)
|
|
||||||
{
|
|
||||||
for(u32 i = 0; i <= 12; 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, "%x:%08x;", i, __builtin_bswap32(regs.cpu_registers.r[i]));
|
||||||
}
|
|
||||||
n += sprintf(out + n, "d:%08x;e:%08x;f:%08x;19:%08x;",
|
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.sp), __builtin_bswap32(regs.cpu_registers.lr), __builtin_bswap32(regs.cpu_registers.pc),
|
||||||
__builtin_bswap32(regs.cpu_registers.cpsr));
|
__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;
|
u64 val;
|
||||||
@ -192,7 +188,7 @@ static int GDB_ParseCommonThreadInfo(char *out, GDBContext *ctx, int sig)
|
|||||||
}
|
}
|
||||||
|
|
||||||
n += sprintf(out + n, "2a:%08x;2b:%08x;", __builtin_bswap32(regs.fpu_registers.fpscr), __builtin_bswap32(regs.fpu_registers.fpexc));
|
n += sprintf(out + n, "2a:%08x;2b:%08x;", __builtin_bswap32(regs.fpu_registers.fpscr), __builtin_bswap32(regs.fpu_registers.fpexc));
|
||||||
}
|
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,6 +41,8 @@ Result GDB_ReadMemoryInPage(void *out, GDBContext *ctx, u32 addr, u32 len)
|
|||||||
|
|
||||||
if(addr < (1u << (32 - (u32)TTBCR)))
|
if(addr < (1u << (32 - (u32)TTBCR)))
|
||||||
return svcReadProcessMemory(out, ctx->debug, addr, len);
|
return svcReadProcessMemory(out, ctx->debug, addr, len);
|
||||||
|
else if(!ctx->enableExternalMemoryAccess)
|
||||||
|
return -1;
|
||||||
else if(addr >= 0x80000000 && addr < 0xB0000000)
|
else if(addr >= 0x80000000 && addr < 0xB0000000)
|
||||||
{
|
{
|
||||||
memcpy(out, (const void *)addr, len);
|
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)))
|
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
|
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)
|
else if(addr >= 0x80000000 && addr < 0xB0000000)
|
||||||
{
|
{
|
||||||
memcpy((void *)addr, in, len);
|
memcpy((void *)addr, in, len);
|
||||||
|
@ -120,7 +120,6 @@ GDB_DECLARE_QUERY_HANDLER(Supported)
|
|||||||
|
|
||||||
GDB_DECLARE_QUERY_HANDLER(StartNoAckMode)
|
GDB_DECLARE_QUERY_HANDLER(StartNoAckMode)
|
||||||
{
|
{
|
||||||
ctx->isGDB = true;
|
|
||||||
ctx->state = GDB_STATE_NOACK_SENT;
|
ctx->state = GDB_STATE_NOACK_SENT;
|
||||||
return GDB_ReplyOk(ctx);
|
return GDB_ReplyOk(ctx);
|
||||||
}
|
}
|
||||||
|
@ -36,10 +36,11 @@ struct
|
|||||||
GDBCommandHandler handler;
|
GDBCommandHandler handler;
|
||||||
} remoteCommandHandlers[] =
|
} remoteCommandHandlers[] =
|
||||||
{
|
{
|
||||||
{ "syncrequestinfo", GDB_REMOTE_COMMAND_HANDLER(SyncRequestInfo) },
|
{ "syncrequestinfo" , GDB_REMOTE_COMMAND_HANDLER(SyncRequestInfo) },
|
||||||
{ "translatehandle", GDB_REMOTE_COMMAND_HANDLER(TranslateHandle) },
|
{ "translatehandle" , GDB_REMOTE_COMMAND_HANDLER(TranslateHandle) },
|
||||||
{ "getmmuconfig" , GDB_REMOTE_COMMAND_HANDLER(GetMmuConfig) },
|
{ "getmmuconfig" , GDB_REMOTE_COMMAND_HANDLER(GetMmuConfig) },
|
||||||
{ "flushcaches" , GDB_REMOTE_COMMAND_HANDLER(FlushCaches) },
|
{ "flushcaches" , GDB_REMOTE_COMMAND_HANDLER(FlushCaches) },
|
||||||
|
{ "toggleextmemaccess", GDB_REMOTE_COMMAND_HANDLER(ToggleExternalMemoryAccess) },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *GDB_SkipSpaces(const char *pos)
|
static const char *GDB_SkipSpaces(const char *pos)
|
||||||
@ -236,6 +237,18 @@ GDB_DECLARE_REMOTE_COMMAND_HANDLER(FlushCaches)
|
|||||||
return GDB_ReplyOk(ctx);
|
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)
|
GDB_DECLARE_QUERY_HANDLER(Rcmd)
|
||||||
{
|
{
|
||||||
char commandData[GDB_BUF_LEN / 2 + 1];
|
char commandData[GDB_BUF_LEN / 2 + 1];
|
||||||
|
@ -211,7 +211,7 @@ void GDB_ReleaseClient(GDBServer *server, GDBContext *ctx)
|
|||||||
ctx->nbThreads = 0;
|
ctx->nbThreads = 0;
|
||||||
memset(ctx->threadInfos, 0, sizeof(ctx->threadInfos));
|
memset(ctx->threadInfos, 0, sizeof(ctx->threadInfos));
|
||||||
ctx->catchThreadEvents = false;
|
ctx->catchThreadEvents = false;
|
||||||
ctx->isGDB = false;
|
ctx->enableExternalMemoryAccess = false;
|
||||||
RecursiveLock_Unlock(&ctx->lock);
|
RecursiveLock_Unlock(&ctx->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user