diff --git a/engine/engine.c b/engine/engine.c index 4ede77a..1a02bbe 100644 --- a/engine/engine.c +++ b/engine/engine.c @@ -146,13 +146,40 @@ int register_callback(void *func) return 0; } +#define SENTINEL_VALUE 0x5AFEC0DE +/* These values should hang around if IGR in OPL is activated */ +extern u32 Uninitialized; +static u32 *pOldSetupThread = &Uninitialized; +static u32 *pSentinel = &Uninitialized + 1; + +void InstallHook() +{ + *pOldSetupThread = GetSyscallHandler(__NR_SetupThread); + SetSyscall(__NR_SetupThread, KSEG0(HookSetupThread)); + *pSentinel = SENTINEL_VALUE; +} + +void RemoveHook() +{ + SetSyscall(__NR_SetupThread, *pOldSetupThread); +} + int __attribute__((section(".init"))) _init(void) { #ifdef _HOOK_9 /* hook syscall */ - OldSetupThread = GetSyscallHandler(__NR_SetupThread); - j_SetupThread = MAKE_J(OldSetupThread); - SetSyscall(__NR_SetupThread, KSEG0(HookSetupThread)); + if(*pSentinel == SENTINEL_VALUE && *pOldSetupThread) + { + /* When the engine is installed it hooks SetupThread and keeps the + * address to the original callback in an uninitialized area that should + * be retained if IGR is activated in OPL. The sentinel value signals + * that the engine has already been installed, so we need to temporarily + * restore the original SetupThread callback before "installing" it + * again. + */ + RemoveHook(); + } + InstallHook(); #endif return 0; } @@ -160,8 +187,7 @@ int __attribute__((section(".init"))) _init(void) int __attribute__((section(".fini"))) _fini(void) { #ifdef _HOOK_9 - /* unhook syscall */ - SetSyscall(__NR_SetupThread, OldSetupThread); + RemoveHook(); #endif return 0; } diff --git a/engine/engine_asm.S b/engine/engine_asm.S index 44c299e..08c5624 100644 --- a/engine/engine_asm.S +++ b/engine/engine_asm.S @@ -57,6 +57,7 @@ .globl eh_backup .globl CodeHandler .globl BootCodeHandler + .globl Uninitialized #ifdef _HOOK_9 .globl HookSetupThread @@ -798,8 +799,8 @@ HookSetupThread: addiu $sp, 0x10 /* jump to original SetupThread() */ -j_SetupThread: - j 0 + lw $t1, Uninitialized + j $t1 nop .end HookSetupThread #endif @@ -860,6 +861,9 @@ numcodes: codelist: .space (MAX_CODES*8) +Uninitialized: + .space /* Anything after this address should be retained when activating IGR in OPL. */ + .set pop /* EOF */