]> git.saurik.com Git - apple/dyld.git/blob - testing/test-cases/dlopen-RTLD_NODELETE.dtest/main.c
3fff11733ab48c57ce4081a7d6283610803f2ac2
[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
14 int main()
15 {
16 printf("[BEGIN] dlopen-RTLD_NODELETE\n");
17
18 ///
19 /// This tests that RTLD_NODELETE on first dlopen() blocks dlclose() from unloading image
20 ///
21 void* handle = dlopen(RUN_DIR "/libfoo.dylib", RTLD_NODELETE);
22 if ( handle == NULL ) {
23 printf("[FAIL] dlopen-RTLD_NODELETE: dlopen(libfoo.dylib, RTLD_NODELETE) failed but it should have worked: %s\n", dlerror());
24 return 0;
25 }
26 int* fooSym = (int*)dlsym(handle, "foo");
27 if ( fooSym == NULL ) {
28 printf("[FAIL] dlopen-RTLD_NODELETE: dlsym(handle, \"foo\") failed but it should have worked: %s\n", dlerror());
29 return 0;
30 }
31 int fooValue = *fooSym;
32 dlclose(handle);
33 Dl_info info;
34 if ( dladdr(fooSym, &info) != 0 ) {
35 printf("[FAIL] dlopen-RTLD_NODELETE: dladdr(fooSym, xx) succeeded as if libfoo.dylib was not unloaded\n");
36 return 0;
37 }
38 // dereference foo pointer. If RTLD_NODELETE worked, this will not crash
39 if ( *fooSym != fooValue ) {
40 printf("[FAIL] dlopen-RTLD_NODELETE: value at fooSym changed\n");
41 return 0;
42 }
43
44 ///
45 /// This tests that RTLD_NODELETE on later dlopen() blocks dlclose() from unloading image
46 ///
47 void* handle2 = dlopen(RUN_DIR "/libbar.dylib", RTLD_GLOBAL);
48 if ( handle2 == NULL ) {
49 printf("[FAIL] dlopen-RTLD_NODELETE: dlopen(libfoo.dylib, RTLD_GLOBAL) failed but it should have worked: %s\n", dlerror());
50 return 0;
51 }
52 int* barSym = (int*)dlsym(handle2, "bar");
53 if ( barSym == NULL ) {
54 printf("[FAIL] dlopen-RTLD_NODELETE: dlsym(handle, \"bar\") failed but it should have worked: %s\n", dlerror());
55 return 0;
56 }
57 int barValue = *barSym;
58 void* handle3 = dlopen(RUN_DIR "/libbar.dylib", RTLD_NODELETE);
59 if ( handle3 == NULL ) {
60 printf("[FAIL] dlopen-RTLD_NODELETE: dlopen(libfoo.dylib, RTLD_NODELETE) failed but it should have worked: %s\n", dlerror());
61 return 0;
62 }
63 dlclose(handle2);
64 dlclose(handle3);
65 if ( dladdr(barSym, &info) != 0 ) {
66 printf("[FAIL] dlopen-RTLD_NODELETE: dladdr(barSym, xx) succeeded as if libbar.dylib was not unloaded\n");
67 return 0;
68 }
69 // dereference foo pointer. If RTLD_NODELETE worked, this will not crash
70 if ( *barSym != barValue ) {
71 printf("[FAIL] dlopen-RTLD_NODELETE: value at barSym changed\n");
72 return 0;
73 }
74
75
76 printf("[PASS] dlopen-RTLD_NODELETE\n");
77 return 0;
78 }