Implement plugin loader

This commit is contained in:
Nanquitas
2018-11-15 13:38:19 +01:00
parent 2520079536
commit 2182742708
50 changed files with 2541 additions and 89 deletions

View File

@@ -29,6 +29,7 @@
#include "csvc.h"
#include "fmt.h"
#include "gdb/breakpoints.h"
#include "utils.h"
struct
{
@@ -36,8 +37,10 @@ struct
GDBCommandHandler handler;
} remoteCommandHandlers[] =
{
{ "convertvatopa" , GDB_REMOTE_COMMAND_HANDLER(ConvertVAToPA) },
{ "syncrequestinfo" , GDB_REMOTE_COMMAND_HANDLER(SyncRequestInfo) },
{ "translatehandle" , GDB_REMOTE_COMMAND_HANDLER(TranslateHandle) },
{ "listallhandles" , GDB_REMOTE_COMMAND_HANDLER(ListAllHandles) },
{ "getmmuconfig" , GDB_REMOTE_COMMAND_HANDLER(GetMmuConfig) },
{ "getmemregions" , GDB_REMOTE_COMMAND_HANDLER(GetMemRegions) },
{ "flushcaches" , GDB_REMOTE_COMMAND_HANDLER(FlushCaches) },
@@ -51,6 +54,50 @@ static const char *GDB_SkipSpaces(const char *pos)
return nextpos;
}
GDB_DECLARE_REMOTE_COMMAND_HANDLER(ConvertVAToPA)
{
bool ok;
int n;
u32 val;
u32 pa;
char * end;
char outbuf[GDB_BUF_LEN / 2 + 1];
if(ctx->commandData[0] == 0)
return GDB_ReplyErrno(ctx, EILSEQ);
val = xstrtoul(ctx->commandData, &end, 0, true, &ok);
if(!ok)
return GDB_ReplyErrno(ctx, EILSEQ);
if (val >= 0x40000000)
pa = svcConvertVAToPA((const void *)val, false);
else
{
Handle process;
Result r = svcOpenProcess(&process, ctx->pid);
if(R_FAILED(r))
{
n = sprintf(outbuf, "Invalid process (wtf?)\n");
goto end;
}
r = svcControlProcess(process, PROCESSOP_GET_PA_FROM_VA, (u32)&pa, val);
svcCloseHandle(process);
if (R_FAILED(r))
{
n = sprintf(outbuf, "An error occured: %08X\n", r);
goto end;
}
}
n = sprintf(outbuf, "va: 0x%08X, pa: 0x%08X, b31: 0x%08X\n", val, pa, pa | (1 << 31));
end:
return GDB_SendHexPacket(ctx, outbuf, n);
}
GDB_DECLARE_REMOTE_COMMAND_HANDLER(SyncRequestInfo)
{
char outbuf[GDB_BUF_LEN / 2 + 1];
@@ -135,6 +182,29 @@ end:
return GDB_SendHexPacket(ctx, outbuf, n);
}
enum
{
TOKEN_KAUTOOBJECT = 0,
TOKEN_KSYNCHRONIZATIONOBJECT = 1,
TOKEN_KEVENT = 0x1F,
TOKEN_KSEMAPHORE = 0x2F,
TOKEN_KTIMER = 0x35,
TOKEN_KMUTEX = 0x39,
TOKEN_KDEBUG = 0x4D,
TOKEN_KSERVERPORT = 0x55,
TOKEN_KDMAOBJECT = 0x59,
TOKEN_KCLIENTPORT = 0x65,
TOKEN_KCODESET = 0x68,
TOKEN_KSESSION = 0x70,
TOKEN_KTHREAD = 0x8D,
TOKEN_KSERVERSESSION = 0x95,
TOKEN_KCLIENTSESSION = 0xA5,
TOKEN_KPORT = 0xA8,
TOKEN_KSHAREDMEMORY = 0xB0,
TOKEN_KPROCESS = 0xC5,
TOKEN_KRESOURCELIMIT = 0xC8
};
GDB_DECLARE_REMOTE_COMMAND_HANDLER(TranslateHandle)
{
bool ok;
@@ -143,10 +213,11 @@ GDB_DECLARE_REMOTE_COMMAND_HANDLER(TranslateHandle)
int n;
Result r;
u32 kernelAddr;
s64 token;
Handle handle, process;
s64 refcountRaw;
u32 refcount;
char classBuf[32], serviceBuf[12] = { 0 };
char classBuf[32], serviceBuf[12] = {0}, ownerBuf[50] = { 0 };
char outbuf[GDB_BUF_LEN / 2 + 1];
if(ctx->commandData[0] == 0)
@@ -178,12 +249,29 @@ GDB_DECLARE_REMOTE_COMMAND_HANDLER(TranslateHandle)
svcTranslateHandle(&kernelAddr, classBuf, handle);
svcGetHandleInfo(&refcountRaw, handle, 1);
svcGetHandleInfo(&token, handle, 0x10001);
svcControlService(SERVICEOP_GET_NAME, serviceBuf, handle);
refcount = (u32)(refcountRaw - 1);
if(serviceBuf[0] != 0)
n = sprintf(outbuf, "(%s *)0x%08x /* %s handle, %u %s */\n", classBuf, kernelAddr, serviceBuf, refcount, refcount == 1 ? "reference" : "references");
else if (token == TOKEN_KPROCESS)
{
svcGetProcessInfo((s64 *)serviceBuf, handle, 0x10000);
n = sprintf(outbuf, "(%s *)0x%08x /* process: %s, %u %s */\n", classBuf, kernelAddr, serviceBuf, refcount, refcount == 1 ? "reference" : "references");
}
else
n = sprintf(outbuf, "(%s *)0x%08x /* %u %s */\n", classBuf, kernelAddr, refcount, refcount == 1 ? "reference" : "references");
{
s64 owner;
if (R_SUCCEEDED(svcGetHandleInfo(&owner, handle, 0x10002)))
{
svcGetProcessInfo((s64 *)serviceBuf, (u32)owner, 0x10000);
svcCloseHandle((u32)owner);
sprintf(ownerBuf, " owner: %s", serviceBuf);
}
n = sprintf(outbuf, "(%s *)0x%08x /* %u %s%s */\n", classBuf, kernelAddr, refcount, refcount == 1 ? "reference" : "references", ownerBuf);
}
end:
svcCloseHandle(handle);
@@ -191,6 +279,68 @@ end:
return GDB_SendHexPacket(ctx, outbuf, n);
}
GDB_DECLARE_REMOTE_COMMAND_HANDLER(ListAllHandles)
{
bool ok;
u32 val;
char *end;
int n = 0;
Result r;
s32 count = 0;
Handle process, procHandles[0x100];
char outbuf[GDB_BUF_LEN / 2 + 1];
if(ctx->commandData[0] == 0)
val = 0; ///< All handles
else
{ // Get handles of specified type
val = xstrtoul(ctx->commandData, &end, 0, true, &ok);
if(!ok)
return GDB_ReplyErrno(ctx, EILSEQ);
end = (char *)GDB_SkipSpaces(end);
if(*end != 0)
return GDB_ReplyErrno(ctx, EILSEQ);
}
r = svcOpenProcess(&process, ctx->pid);
if(R_FAILED(r))
{
n = sprintf(outbuf, "Invalid process (wtf?)\n");
goto end;
}
if (R_FAILED(count = svcControlProcess(process, PROCESSOP_GET_ALL_HANDLES, (u32)procHandles, val)))
n = sprintf(outbuf, "An error occured: %08X\n", count);
else if (count == 0)
n = sprintf(outbuf, "Process has no handles ?\n");
else
{
n = sprintf(outbuf, "Found %d handles.\n", count);
const char *comma = "";
for (s32 i = 0; i < count && n < (GDB_BUF_LEN >> 1) - 20; ++i)
{
Handle handle = procHandles[i];
n += sprintf(outbuf + n, "%s0x%08X", comma, handle);
if (((i + 1) % 8) == 0)
{
outbuf[n++] = '\n';
comma = "";
}
else
comma = ", ";
}
}
end:
svcCloseHandle(process);
return GDB_SendHexPacket(ctx, outbuf, n);
}
extern bool isN3DS;
GDB_DECLARE_REMOTE_COMMAND_HANDLER(GetMmuConfig)
{