summaryrefslogtreecommitdiff
path: root/togl/linuxwin/mach_override.h
diff options
context:
space:
mode:
Diffstat (limited to 'togl/linuxwin/mach_override.h')
-rw-r--r--togl/linuxwin/mach_override.h76
1 files changed, 76 insertions, 0 deletions
diff --git a/togl/linuxwin/mach_override.h b/togl/linuxwin/mach_override.h
new file mode 100644
index 0000000..ecd319c
--- /dev/null
+++ b/togl/linuxwin/mach_override.h
@@ -0,0 +1,76 @@
+// mach_override.h semver:1.2.0
+// Copyright (c) 2003-2012 Jonathan 'Wolf' Rentzsch: http://rentzsch.com
+// Some rights reserved: http://opensource.org/licenses/mit
+// https://github.com/rentzsch/mach_override
+
+#ifndef _mach_override_
+#define _mach_override_
+
+#include <sys/types.h>
+#include <mach/error.h>
+
+#define err_cannot_override (err_local|1)
+
+__BEGIN_DECLS
+
+/****************************************************************************************
+ Dynamically overrides the function implementation referenced by
+ originalFunctionAddress with the implentation pointed to by overrideFunctionAddress.
+ Optionally returns a pointer to a "reentry island" which, if jumped to, will resume
+ the original implementation.
+
+ @param originalFunctionAddress -> Required address of the function to
+ override (with overrideFunctionAddress).
+ @param overrideFunctionAddress -> Required address to the overriding
+ function.
+ @param originalFunctionReentryIsland <- Optional pointer to pointer to the
+ reentry island. Can be NULL.
+ @result <- err_cannot_override if the original
+ function's implementation begins with
+ the 'mfctr' instruction.
+
+ ************************************************************************************/
+
+ mach_error_t
+mach_override_ptr(
+ void *originalFunctionAddress,
+ const void *overrideFunctionAddress,
+ void **originalFunctionReentryIsland );
+
+__END_DECLS
+
+/****************************************************************************************
+ If you're using C++ this macro will ease the tedium of typedef'ing, naming, keeping
+ track of reentry islands and defining your override code. See test_mach_override.cp
+ for example usage.
+
+ ************************************************************************************/
+
+#ifdef __cplusplus
+#define MACH_OVERRIDE( ORIGINAL_FUNCTION_RETURN_TYPE, ORIGINAL_FUNCTION_NAME, ORIGINAL_FUNCTION_ARGS, ERR ) \
+{ \
+ static ORIGINAL_FUNCTION_RETURN_TYPE (*ORIGINAL_FUNCTION_NAME##_reenter)ORIGINAL_FUNCTION_ARGS; \
+ static bool ORIGINAL_FUNCTION_NAME##_overriden = false; \
+ class mach_override_class__##ORIGINAL_FUNCTION_NAME { \
+ public: \
+ static kern_return_t override(void *originalFunctionPtr) { \
+ kern_return_t result = err_none; \
+ if (!ORIGINAL_FUNCTION_NAME##_overriden) { \
+ ORIGINAL_FUNCTION_NAME##_overriden = true; \
+ result = mach_override_ptr( (void*)originalFunctionPtr, \
+ (void*)mach_override_class__##ORIGINAL_FUNCTION_NAME::replacement, \
+ (void**)&ORIGINAL_FUNCTION_NAME##_reenter ); \
+ } \
+ return result; \
+ } \
+ static ORIGINAL_FUNCTION_RETURN_TYPE replacement ORIGINAL_FUNCTION_ARGS {
+
+#define END_MACH_OVERRIDE( ORIGINAL_FUNCTION_NAME ) \
+ } \
+ }; \
+ \
+ err = mach_override_class__##ORIGINAL_FUNCTION_NAME::override((void*)ORIGINAL_FUNCTION_NAME); \
+}
+#endif
+
+#endif // _mach_override_