Welcome to mirror list, hosted at ThFree Co, Russian Federation.

test_mach_override.cp - github.com/mumble-voip/mach_override.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 77ad7480482a11e6e4ee14c26358969b95860130 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <errno.h>
#include <CoreServices/CoreServices.h>
#include "mach_override.h"

#define	assertStrEqual( EXPECTED, ACTUAL ) if( strcmp( (EXPECTED), (ACTUAL) ) != 0 ) { printf( "EXPECTED: %s\nACTUAL: %s\n", (EXPECTED), (ACTUAL)); assert( strcmp( (EXPECTED), (ACTUAL) ) == 0 ); }
#define	assertIntEqual( EXPECTED, ACTUAL ) if( (EXPECTED) != (ACTUAL) ) { printf( "EXPECTED: %d\nACTUAL: %d\n", (EXPECTED), (ACTUAL)); assert( (EXPECTED) == (ACTUAL) ); }

//------------------------------------------------------------------------------
#pragma mark Test Local Override by Pointer

const char* localFunction() {
	asm("nop;nop;nop;nop;");
	return __FUNCTION__;
}
const char* (*localOriginalPtr)() = localFunction;

void testLocalFunctionOverrideByPointer() {
	//	Test original.
	assertStrEqual( "localFunction", localOriginalPtr() );

	//	Override local function by pointer.
	kern_return_t err;
	
	MACH_OVERRIDE( const char*, localFunction, (), err ) {
		//	Test calling through the reentry island back into the original
		//	implementation.
		assertStrEqual( "localFunction", localFunction_reenter() );
		
		return "localFunctionOverride";
	} END_MACH_OVERRIDE(localFunction);
	assert( !err );
	
	//	Test override took effect.
	assertStrEqual( "localFunctionOverride", localOriginalPtr() );
}

//------------------------------------------------------------------------------
#pragma mark Test System Override by Pointer

char* (*strerrorPtr)(int) = strerror;
const char* strerrReturnValue = "Unknown error: 0";

void testSystemFunctionOverrideByPointer() {
	SInt32 sysv;
	if (Gestalt( gestaltSystemVersion, &sysv ) == noErr && sysv >= 0x1070)
		strerrReturnValue = "Undefined error: 0";

	//	Test original.
	assertStrEqual( strerrReturnValue, strerrorPtr( 0 ) );
	
	//	Override system function by pointer.
	kern_return_t err;
	MACH_OVERRIDE( char*, strerror, (int errnum), err ) {
		//	Test calling through the reentry island back into the original
		//	implementation.
		assertStrEqual( strerrReturnValue, strerror_reenter( 0 ) );
		
		return (char *)"strerrorOverride";
	} END_MACH_OVERRIDE(strerror);
	assert( !err );
	
	//	Test override took effect.
	assertStrEqual( "strerrorOverride", strerrorPtr( 0 ) );
}

//------------------------------------------------------------------------------
#pragma mark Test System Override by Name

/* The following is commented out because it does not compile.
int strerror_rOverride( int errnum, char *strerrbuf, size_t buflen );
int (*strerror_rPtr)( int, char*, size_t ) = strerror_r;
int (*gReentry_strerror_r)( int, char*, size_t );

void testSystemFunctionOverrideByName() {
	//	Test original.
	assertIntEqual( ERANGE, strerror_rPtr( 0, NULL, 0 ) );
	
	//	Override local function by pointer.
	kern_return_t err = mach_override( (char*)"_strerror_r",
									   NULL,
									   (void*)&strerror_rOverride,
									   (void**)&gReentry_strerror_r );
	
	//	Test override took effect.
	assertIntEqual( 0, strerror_rPtr( 0, NULL, 0 ) );
}

int strerror_rOverride( int errnum, char *strerrbuf, size_t buflen ) {
	assertIntEqual( ERANGE, gReentry_strerror_r( 0, NULL, 0 ) );
	
	return 0;
}
*/

//------------------------------------------------------------------------------
#pragma mark main

int main( int argc, const char *argv[] ) {
	testLocalFunctionOverrideByPointer();
	testSystemFunctionOverrideByPointer();
	//testSystemFunctionOverrideByName();
	
	printf( "success\n" );
	return 0;
}