@@ -146,22 +146,48 @@ int register_callback(void *func)
146
146
return 0 ;
147
147
}
148
148
149
+ #define SENTINEL_VALUE 0x5AFEC0DE
150
+ /* These values should hang around if IGR in OPL is activated */
151
+ extern u32 Uninitialized ;
152
+ static u32 * pOldSetupThread = & Uninitialized ;
153
+ static u32 * pSentinel = & Uninitialized + 1 ;
154
+
155
+ void InstallHook ()
156
+ {
157
+ * pOldSetupThread = GetSyscallHandler (__NR_SetupThread );
158
+ SetSyscall (__NR_SetupThread , KSEG0 (HookSetupThread ));
159
+ * pSentinel = SENTINEL_VALUE ;
160
+ }
161
+
162
+ void RemoveHook ()
163
+ {
164
+ SetSyscall (__NR_SetupThread , * pOldSetupThread );
165
+ }
166
+
149
167
int __attribute__((section (".init" ))) _init (void )
150
168
{
151
169
#ifdef _HOOK_9
152
170
/* hook syscall */
153
- OldSetupThread = GetSyscallHandler (__NR_SetupThread );
154
- j_SetupThread = MAKE_J (OldSetupThread );
155
- SetSyscall (__NR_SetupThread , KSEG0 (HookSetupThread ));
171
+ if (* pSentinel == SENTINEL_VALUE && * pOldSetupThread )
172
+ {
173
+ /* When the engine is installed it hooks SetupThread and keeps the
174
+ * address to the original callback in an uninitialized area that should
175
+ * be retained if IGR is activated in OPL. The sentinel value signals
176
+ * that the engine has already been installed, so we need to temporarily
177
+ * restore the original SetupThread callback before "installing" it
178
+ * again.
179
+ */
180
+ RemoveHook ();
181
+ }
182
+ InstallHook ();
156
183
#endif
157
184
return 0 ;
158
185
}
159
186
160
187
int __attribute__((section (".fini" ))) _fini (void )
161
188
{
162
189
#ifdef _HOOK_9
163
- /* unhook syscall */
164
- SetSyscall (__NR_SetupThread , OldSetupThread );
190
+ RemoveHook ();
165
191
#endif
166
192
return 0 ;
167
193
}
0 commit comments