dyld-750.5.tar.gz
[apple/dyld.git] / testing / test-cases / dlopen-RTLD_NODELETE.dtest / main.c
1
2 // BUILD: $CC foo.c -dynamiclib -install_name $RUN_DIR/libfoo.dylib -o $BUILD_DIR/libfoo.dylib
3 // BUILD: $CC bar.c -dynamiclib -install_name $RUN_DIR/libbar.dylib -o $BUILD_DIR/libbar.dylib
4 // BUILD: $CC main.c -o $BUILD_DIR/dlopen-RTLD_NODELETE.exe -DRUN_DIR="$RUN_DIR"
5
6 // RUN: ./dlopen-RTLD_NODELETE.exe
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <dlfcn.h>
12
13 #include "test_support.h"
14
15 int main(int argc, const char* argv[], const char* envp[], const char* apple[]) {
16 ///
17 /// This tests that RTLD_NODELETE on first dlopen() blocks dlclose() from unloading image
18 ///
19 void* handle = dlopen(RUN_DIR "/libfoo.dylib", RTLD_NODELETE);
20 if ( handle == NULL ) {
21 FAIL("dlopen(libfoo.dylib, RTLD_NODELETE) failed but it should have worked: %s", dlerror());
22 }
23 int* fooSym = (int*)dlsym(handle, "foo");
24 if ( fooSym == NULL ) {
25 FAIL("dlsym(handle, \"foo\") failed but it should have worked: %s", dlerror());
26 }
27 int fooValue = *fooSym;
28 dlclose(handle);
29 Dl_info info;
30 if ( dladdr(fooSym, &info) != 0 ) {
31 FAIL("dladdr(fooSym, xx) succeeded as if libfoo.dylib was not unloaded");
32 }
33 // dereference foo pointer. If RTLD_NODELETE worked, this will not crash
34 if ( *fooSym != fooValue ) {
35 FAIL("value at fooSym changed");
36 }
37
38 ///
39 /// This tests that RTLD_NODELETE on later dlopen() blocks dlclose() from unloading image
40 ///
41 void* handle2 = dlopen(RUN_DIR "/libbar.dylib", RTLD_GLOBAL);
42 if ( handle2 == NULL ) {
43 FAIL("dlopen(libfoo.dylib, RTLD_GLOBAL) failed but it should have worked: %s", dlerror());
44 }
45 int* barSym = (int*)dlsym(handle2, "bar");
46 if ( barSym == NULL ) {
47 FAIL("dlsym(handle, \"bar\") failed but it should have worked: %s", dlerror());
48 }
49 int barValue = *barSym;
50 void* handle3 = dlopen(RUN_DIR "/libbar.dylib", RTLD_NODELETE);
51 if ( handle3 == NULL ) {
52 FAIL("dlopen(libfoo.dylib, RTLD_NODELETE) failed but it should have worked: %s", dlerror());
53 }
54 dlclose(handle2);
55 dlclose(handle3);
56 if ( dladdr(barSym, &info) != 0 ) {
57 FAIL("dladdr(barSym, xx) succeeded as if libbar.dylib was not unloaded");
58 }
59 // dereference foo pointer. If RTLD_NODELETE worked, this will not crash
60 if ( *barSym != barValue ) {
61 FAIL("value at barSym changed");
62 }
63
64 PASS("Success");
65 }