kernel ext: perf improvements

This commit is contained in:
TuxSH 2022-04-05 22:23:09 +01:00
parent 3463effeae
commit c64f94bc82
8 changed files with 115 additions and 100 deletions

View File

@ -27,6 +27,7 @@
#pragma once
#include "types.h"
#include <string.h>
extern u32 kernelVersion;
@ -1161,29 +1162,37 @@ offsetof(classname##O3DSPre8x, field)))
#define KPROCESSHWINFO_GET_RVALUE(obj, field) *(KPROCESSHWINFO_GET_PTR(obj, field))
#define KPROCESSHWINFO_GET_RVALUE_TYPE(type, obj, field) *(KPROCESSHWINFO_GET_PTR_TYPE(type, obj, field))
extern u32 pidOffsetKProcess, hwInfoOffsetKProcess, codeSetOffsetKProcess, handleTableOffsetKProcess, debugOffsetKProcess;
static inline u32 idOfProcess(KProcess *process)
{
return KPROCESS_GET_RVALUE(process, processId);
u32 id;
memcpy(&id, (const u8 *)process + pidOffsetKProcess, 4);
return id;
}
static inline KProcessHwInfo *hwInfoOfProcess(KProcess *process)
{
return KPROCESS_GET_PTR_TYPE(KProcessHwInfo, process, hwInfo);
return (KProcessHwInfo *)((uintptr_t)process + hwInfoOffsetKProcess);
}
static inline KCodeSet *codeSetOfProcess(KProcess *process)
{
return KPROCESS_GET_RVALUE(process, codeSet);
KCodeSet *cs;
memcpy(&cs, (const u8 *)process + codeSetOffsetKProcess, 4);
return cs;
}
static inline KProcessHandleTable *handleTableOfProcess(KProcess *process)
{
return KPROCESS_GET_PTR(process, handleTable);
return (KProcessHandleTable *)((uintptr_t)process + handleTableOffsetKProcess);
}
static inline KDebug *debugOfProcess(KProcess *process)
{
return KPROCESS_GET_RVALUE(process, debug);
KDebug *debug;
memcpy(&debug, (const u8 *)process + debugOffsetKProcess, 4);
return debug;
}
static inline const char *classNameOfAutoObject(KAutoObject *object)

View File

@ -32,7 +32,9 @@
#include "utils.h"
extern void *officialSVCs[0x7E];
extern void *alteredSvcTable[0x100];
void buildAlteredSvcTable(void);
void postprocessSvc(void);
void svcDefaultHandler(u8 svcId);
void *svcHook(u8 *pageEnd);

View File

@ -30,5 +30,7 @@
#include "kernel.h"
#include "svc.h"
extern bool svcSignalingEnabled;
bool shouldSignalSyscallDebugEvent(KProcess *process, u8 svcId);
Result KernelSetStateHook(u32 type, u32 varg1, u32 varg2, u32 varg3);

View File

@ -113,3 +113,5 @@ u32 stolenSystemMemRegionSize;
vu32 rosalinaState;
bool hasStartedRosalinaNetworkFuncsOnce;
u32 pidOffsetKProcess, hwInfoOffsetKProcess, codeSetOffsetKProcess, handleTableOffsetKProcess, debugOffsetKProcess;

View File

@ -121,6 +121,12 @@ void configHook(vu8 *cfgPage)
*(vu32 *)(configPage + 0x44) = fcramLayout.systemSize;
*(vu32 *)(configPage + 0x48) = fcramLayout.baseSize;
*isDevUnit = true; // enable debug features
pidOffsetKProcess = KPROCESS_OFFSETOF(processId);
hwInfoOffsetKProcess = KPROCESS_OFFSETOF(hwInfo);
codeSetOffsetKProcess = KPROCESS_OFFSETOF(codeSet);
handleTableOffsetKProcess = KPROCESS_OFFSETOF(handleTable);
debugOffsetKProcess = KPROCESS_OFFSETOF(debug);
}
static void findUsefulSymbols(void)
@ -302,6 +308,7 @@ void main(FcramLayout *layout, KCoreContext *ctxs)
void **arm11SvcTable = (void**)originalHandlers[2];
while(*arm11SvcTable != NULL) arm11SvcTable++; //Look for SVC0 (NULL)
memcpy(officialSVCs, arm11SvcTable, 4 * 0x7E);
buildAlteredSvcTable();
findUsefulSymbols();

View File

@ -47,28 +47,68 @@
#include "svc/TranslateHandle.h"
void *officialSVCs[0x7E] = {NULL};
void *alteredSvcTable[0x100] = {NULL};
void signalSvcEntry(u8 *pageEnd)
static Result BreakHook(UserBreakType breakReason, const void* croInfo, u32 croInfoSize)
{
u32 svcId = (u32) *(u8 *)(pageEnd - 0xB5);
KProcess *currentProcess = currentCoreContext->objectContext.currentProcess;
if(svcId == 0xFE)
svcId = *(u32 *)(pageEnd - 0x110 + 8 * 4); // r12 ; note: max theortical SVC atm: 0x3FFFFFFF. We don't support catching svcIds >= 0x100 atm either
void *funptr = (debugOfProcess(currentProcess) != NULL) ? officialSVCs[0x3C] : (void *)Break;
return ((Result (*)(UserBreakType, const void *, u32))funptr)(breakReason, croInfo, croInfoSize);
}
void buildAlteredSvcTable(void)
{
memcpy(alteredSvcTable, officialSVCs, 4 * 0x7E);
alteredSvcTable[0x01] = ControlMemoryHookWrapper;
alteredSvcTable[0x29] = GetHandleInfoHookWrapper;
alteredSvcTable[0x2A] = GetSystemInfoHookWrapper;
alteredSvcTable[0x2B] = GetProcessInfoHookWrapper;
alteredSvcTable[0x2C] = GetThreadInfoHookWrapper;
alteredSvcTable[0x2D] = ConnectToPortHookWrapper;
alteredSvcTable[0x32] = SendSyncRequestHook;
alteredSvcTable[0x3C] = BreakHook;
alteredSvcTable[0x59] = SetGpuProt;
alteredSvcTable[0x5A] = SetWifiEnabled;
alteredSvcTable[0x7B] = Backdoor;
alteredSvcTable[0x7C] = KernelSetStateHook;
// Custom SVCs past that point
alteredSvcTable[0x80] = CustomBackdoor;
alteredSvcTable[0x90] = convertVAToPA;
alteredSvcTable[0x91] = flushDataCacheRange;
alteredSvcTable[0x92] = flushEntireDataCache;
alteredSvcTable[0x93] = invalidateInstructionCacheRange;
alteredSvcTable[0x94] = invalidateEntireInstructionCache;
alteredSvcTable[0xA0] = MapProcessMemoryEx;
alteredSvcTable[0xA1] = UnmapProcessMemoryEx;
alteredSvcTable[0xA2] = ControlMemoryEx;
alteredSvcTable[0xB0] = ControlService;
alteredSvcTable[0xB1] = CopyHandleWrapper;
alteredSvcTable[0xB2] = TranslateHandleWrapper;
}
void signalSvcEntry(u32 svcId)
{
KProcess *currentProcess = currentCoreContext->objectContext.currentProcess;
// Since DBGEVENT_SYSCALL_ENTRY is non blocking, we'll cheat using EXCEVENT_UNDEFINED_SYSCALL (debug->svcId is fortunately an u16!)
if(debugOfProcess(currentProcess) != NULL && shouldSignalSyscallDebugEvent(currentProcess, svcId))
SignalDebugEvent(DBGEVENT_OUTPUT_STRING, 0xFFFFFFFE, svcId);
}
void signalSvcReturn(u8 *pageEnd)
void signalSvcReturn(u32 svcId)
{
u32 svcId = (u32) *(u8 *)(pageEnd - 0xB5);
KProcess *currentProcess = currentCoreContext->objectContext.currentProcess;
if(svcId == 0xFE)
svcId = *(u32 *)(pageEnd - 0x110 + 8 * 4); // r12 ; note: max theortical SVC atm: 0x1FFFFFFF. We don't support catching svcIds >= 0x100 atm either
// Since DBGEVENT_SYSCALL_RETURN is non blocking, we'll cheat using EXCEVENT_UNDEFINED_SYSCALL (debug->svcId is fortunately an u16!)
if(debugOfProcess(currentProcess) != NULL && shouldSignalSyscallDebugEvent(currentProcess, svcId))
SignalDebugEvent(DBGEVENT_OUTPUT_STRING, 0xFFFFFFFF, svcId);
@ -82,71 +122,3 @@ void postprocessSvc(void)
officialPostProcessSvc();
}
void *svcHook(u8 *pageEnd)
{
KProcess *currentProcess = currentCoreContext->objectContext.currentProcess;
u32 svcId = *(u8 *)(pageEnd - 0xB5);
if(svcId == 0xFE)
svcId = *(u32 *)(pageEnd - 0x110 + 8 * 4); // r12 ; note: max theortical SVC atm: 0x3FFFFFFF. We don't support catching svcIds >= 0x100 atm either
switch(svcId)
{
case 0x01:
return ControlMemoryHookWrapper;
case 0x29:
return GetHandleInfoHookWrapper;
case 0x2A:
return GetSystemInfoHookWrapper;
case 0x2B:
return GetProcessInfoHookWrapper;
case 0x2C:
return GetThreadInfoHookWrapper;
case 0x2D:
return ConnectToPortHookWrapper;
case 0x32:
return SendSyncRequestHook;
case 0x3C:
return (debugOfProcess(currentProcess) != NULL) ? officialSVCs[0x3C] : (void *)Break;
case 0x59:
return SetGpuProt;
case 0x5A:
return SetWifiEnabled;
case 0x7B:
return Backdoor;
case 0x7C:
return KernelSetStateHook;
case 0x80:
return CustomBackdoor;
case 0x90:
return convertVAToPA;
case 0x91:
return flushDataCacheRange;
case 0x92:
return flushEntireDataCache;
case 0x93:
return invalidateInstructionCacheRange;
case 0x94:
return invalidateEntireInstructionCache;
case 0xA0:
return MapProcessMemoryEx;
case 0xA1:
return UnmapProcessMemoryEx;
case 0xA2:
return ControlMemoryEx;
case 0xB0:
return ControlService;
case 0xB1:
return CopyHandleWrapper;
case 0xB2:
return TranslateHandleWrapper;
default:
return (svcId <= 0x7D) ? officialSVCs[svcId] : NULL;
}
}

View File

@ -36,6 +36,8 @@ static u32 nbEnabled = 0;
static u32 maskedPids[MAX_DEBUG];
static u32 masks[MAX_DEBUG][8] = {0};
bool svcSignalingEnabled = false;
bool shouldSignalSyscallDebugEvent(KProcess *process, u8 svcId)
{
u32 pid = idOfProcess(process);
@ -65,6 +67,7 @@ Result SetSyscallDebugEventMask(u32 pid, bool enable, const u32 *mask)
{
maskedPids[nbEnabled] = pid;
memcpy(&masks[nbEnabled++], tmpMask, 32);
svcSignalingEnabled = true;
}
else
{
@ -84,6 +87,7 @@ Result SetSyscallDebugEventMask(u32 pid, bool enable, const u32 *mask)
}
maskedPids[--nbEnabled] = 0;
memset(&masks[nbEnabled], 0, 32);
svcSignalingEnabled = false;
}
KRecursiveLock__Unlock(&syscallDebugEventMaskLock);

View File

@ -43,22 +43,24 @@ svcHandler:
strb r9, [sp, #0x58+3] @ page end - 0xb8 + 3: svc being handled
strb r10, [sp, #0x58+1] @ page end - 0xb8 + 1: "allow debug" flag
@ sp = page end - 0x110
ldr r8, =alteredSvcTable
ldr r8, [r8, r9,lsl#2]
/*@ sp = page end - 0x110
add r0, sp, #0x110 @ page end
bl svcHook
cpsid i
mov r8, r0
ldmfd sp, {r0-r7, r12, lr}
*/
cmp r8, #0
beq _fallback @ invalid svc, or svc 0xff (stop point)
_handled_svc: @ unused label, just here for formatting
push {r0-r12, lr}
add r0, sp, #0x148
cpsie i
bl signalSvcEntry
cpsid i
pop {r0-r12, lr}
ldr r10, =svcSignalingEnabled @ should work, I guess
ldrb r10, [r10]
cmp r10, #0
bne _call_svc_debugged @ returns to _fallback_end*/
cpsie i
blx r8
@ -82,16 +84,10 @@ svcHandler:
popne {r0-r7, r12}
add sp, #4
cmp r9, #0xff
beq _no_signal_return
push {r0-r7, r12, lr}
add r0, sp, #0x110 @ page end
cpsie i
bl signalSvcReturn
cpsid i
pop {r0-r7, r12}
add sp, #4
ldr r10, =svcSignalingEnabled @ should work, I guess
ldr r10, [r10]
cmp r10, #0
bne _signal_svc_end @ returns to _no_signal_return
_no_signal_return:
@ -123,3 +119,24 @@ svcHandler:
popne {r0-r7, r12}
add sp, #4
b _svc_finished
_call_svc_debugged:
push {r0-r3, r12, lr}
mov r0, r9
cpsie i
bl signalSvcEntry
pop {r0-r3, r12, lr}
blx r8
cpsid i
ldrb lr, [sp, #0x58+0] @ page end - 0xb8 + 0: scheduling flags
b _fallback_end
_signal_svc_end:
push {r0-r3, r12, lr}
mov r0, r9
cpsie i
bl signalSvcReturn
cpsid i
pop {r0-r3, r12, lr}
b _no_signal_return