1/*
2 * Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23#include <stdio.h>
24#include <mach-o/dyld.h>
25#include <Availability.h>
26
27#include "test.h" // PASS(), FAIL()
28
29///
30/// The point of this test is to load the same bundle file multiple times and
31/// verify each time it is linked is a new instantiations (new globals, etc)
32///
33
34int main()
35{
36// NSCreateObjectFileImageFromMemory is only available on Mac OS X - not iPhone OS
37#if __MAC_OS_X_VERSION_MIN_REQUIRED
38	NSObjectFileImage ofi;
39	if ( NSCreateObjectFileImageFromFile("test.bundle", &ofi) != NSObjectFileImageSuccess ) {
40		FAIL("NSCreateObjectFileImageFromFile failed");
41		return 0;
42	}
43
44	NSModule mod = NSLinkModule(ofi, "test.bundle", NSLINKMODULE_OPTION_NONE);
45	if ( mod == NULL ) {
46		FAIL("NSLinkModule failed");
47		return 0;
48	}
49
50	NSSymbol sym = NSLookupSymbolInModule(mod, "_foo");
51	if ( sym == NULL ) {
52		FAIL("NSLookupSymbolInModule failed");
53		return 0;
54	}
55
56	void* func = NSAddressOfSymbol(sym);
57	//fprintf(stderr, "1st address of foo() = %p in module %p in OFI %p\n", func, mod, ofi);
58
59
60	NSObjectFileImage ofi2;
61	if ( NSCreateObjectFileImageFromFile("test.bundle", &ofi2) != NSObjectFileImageSuccess ) {
62		FAIL("2nd NSCreateObjectFileImageFromFile failed");
63		return 0;
64	}
65
66	NSModule mod2 = NSLinkModule(ofi2, "test2.bundle", NSLINKMODULE_OPTION_NONE);
67	if ( mod2 == NULL ) {
68		FAIL("2nd NSLookupSymbolInModule failed");
69		return 0;
70	}
71	if ( mod == mod2 ) {
72		FAIL("2nd NSLinkModule return same function address as first\n");
73		return 0;
74	}
75
76	NSSymbol sym2 = NSLookupSymbolInModule(mod2, "_foo");
77	if ( sym2 == NULL ) {
78		FAIL("2nd NSLookupSymbolInModule failed\n");
79		return 0;
80	}
81
82	void* func2 = NSAddressOfSymbol(sym2);
83	//fprintf(stderr, "2nd address of foo() = %p in module %p in OFI %p\n", func2, mod2, ofi2);
84	if ( func == func2 ) {
85		FAIL("2nd NSAddressOfSymbol return same function address as 1st\n");
86		return 0;
87	}
88
89
90	NSObjectFileImage ofi3;
91	if ( NSCreateObjectFileImageFromFile("test.bundle", &ofi3) != NSObjectFileImageSuccess ) {
92		FAIL("3rd NSCreateObjectFileImageFromFile failed");
93		return 0;
94	}
95	NSModule mod3 = NSLinkModule(ofi3, "test3.bundle", NSLINKMODULE_OPTION_NONE);
96	if ( mod3 == NULL ) {
97		FAIL("3rd NSLinkModule failed\n");
98		return 0;
99	}
100	if ( mod3 == mod ) {
101		FAIL("3rd NSLinkModule return same function address as 1st\n");
102		return 0;
103	}
104	if ( mod3 == mod2 ) {
105		FAIL("3rd NSLinkModule return same function address as 2nd\n");
106		return 0;
107	}
108
109   NSSymbol sym3 = NSLookupSymbolInModule(mod3, "_foo");
110	if ( sym3 == NULL ) {
111		FAIL("3rd NSLookupSymbolInModule failed\n");
112		return 0;
113	}
114	void* func3 = NSAddressOfSymbol(sym3);
115	//fprintf(stderr, "3rd address of foo() = %p in module %p in OFI %p\n", func3, mod3, ofi3);
116	if ( func3 == func ) {
117		FAIL("3rd NSAddressOfSymbol return same function address as 1st\n");
118		return 0;
119	}
120	if ( func3 == func2 ) {
121		FAIL("3rd NSAddressOfSymbol return same function address as 2nd\n");
122		return 0;
123	}
124
125	if ( !NSUnLinkModule(mod, NSUNLINKMODULE_OPTION_NONE) ) {
126		FAIL("NSUnLinkModule failed");
127		return 0;
128	}
129
130	if ( !NSUnLinkModule(mod3, NSUNLINKMODULE_OPTION_NONE) ) {
131		FAIL("3rd NSUnLinkModule failed");
132		return 0;
133	}
134
135	// note, we are calling NSDestroyObjectFileImage() before NSUnLinkModule()
136	if ( !NSDestroyObjectFileImage(ofi2) ) {
137		FAIL("2nd NSDestroyObjectFileImage failed");
138		return 0;
139	}
140	if ( !NSUnLinkModule(mod2, NSUNLINKMODULE_OPTION_NONE) ) {
141		FAIL("2nd NSUnLinkModule failed");
142		return 0;
143	}
144
145	if ( !NSDestroyObjectFileImage(ofi) ) {
146		FAIL("1st NSDestroyObjectFileImage failed");
147		return 0;
148	}
149	if ( !NSDestroyObjectFileImage(ofi3) ) {
150		FAIL("3rd NSDestroyObjectFileImage failed");
151		return 0;
152	}
153#endif
154	PASS("bundle-multi-load");
155	return 0;
156}
157
158