Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / third_party / mach_override / mach_override.h
blobecd319c1cd7a899032e084fc34f32f93cd1d39f7
1 // mach_override.h semver:1.2.0
2 // Copyright (c) 2003-2012 Jonathan 'Wolf' Rentzsch: http://rentzsch.com
3 // Some rights reserved: http://opensource.org/licenses/mit
4 // https://github.com/rentzsch/mach_override
6 #ifndef _mach_override_
7 #define _mach_override_
9 #include <sys/types.h>
10 #include <mach/error.h>
12 #define err_cannot_override (err_local|1)
14 __BEGIN_DECLS
16 /****************************************************************************************
17 Dynamically overrides the function implementation referenced by
18 originalFunctionAddress with the implentation pointed to by overrideFunctionAddress.
19 Optionally returns a pointer to a "reentry island" which, if jumped to, will resume
20 the original implementation.
22 @param originalFunctionAddress -> Required address of the function to
23 override (with overrideFunctionAddress).
24 @param overrideFunctionAddress -> Required address to the overriding
25 function.
26 @param originalFunctionReentryIsland <- Optional pointer to pointer to the
27 reentry island. Can be NULL.
28 @result <- err_cannot_override if the original
29 function's implementation begins with
30 the 'mfctr' instruction.
32 ************************************************************************************/
34 mach_error_t
35 mach_override_ptr(
36 void *originalFunctionAddress,
37 const void *overrideFunctionAddress,
38 void **originalFunctionReentryIsland );
40 __END_DECLS
42 /****************************************************************************************
43 If you're using C++ this macro will ease the tedium of typedef'ing, naming, keeping
44 track of reentry islands and defining your override code. See test_mach_override.cp
45 for example usage.
47 ************************************************************************************/
49 #ifdef __cplusplus
50 #define MACH_OVERRIDE( ORIGINAL_FUNCTION_RETURN_TYPE, ORIGINAL_FUNCTION_NAME, ORIGINAL_FUNCTION_ARGS, ERR ) \
51 { \
52 static ORIGINAL_FUNCTION_RETURN_TYPE (*ORIGINAL_FUNCTION_NAME##_reenter)ORIGINAL_FUNCTION_ARGS; \
53 static bool ORIGINAL_FUNCTION_NAME##_overriden = false; \
54 class mach_override_class__##ORIGINAL_FUNCTION_NAME { \
55 public: \
56 static kern_return_t override(void *originalFunctionPtr) { \
57 kern_return_t result = err_none; \
58 if (!ORIGINAL_FUNCTION_NAME##_overriden) { \
59 ORIGINAL_FUNCTION_NAME##_overriden = true; \
60 result = mach_override_ptr( (void*)originalFunctionPtr, \
61 (void*)mach_override_class__##ORIGINAL_FUNCTION_NAME::replacement, \
62 (void**)&ORIGINAL_FUNCTION_NAME##_reenter ); \
63 } \
64 return result; \
65 } \
66 static ORIGINAL_FUNCTION_RETURN_TYPE replacement ORIGINAL_FUNCTION_ARGS {
68 #define END_MACH_OVERRIDE( ORIGINAL_FUNCTION_NAME ) \
69 } \
70 }; \
72 err = mach_override_class__##ORIGINAL_FUNCTION_NAME::override((void*)ORIGINAL_FUNCTION_NAME); \
74 #endif
76 #endif // _mach_override_