]> git.saurik.com Git - apple/dyld.git/blob - testing/test-cases/dlopen-RTLD_LOCAL-coalesce.dtest/main.c
8c91cb585060bd05703feeb9a6da9bcd3fcc4bc9
[apple/dyld.git] / testing / test-cases / dlopen-RTLD_LOCAL-coalesce.dtest / main.c
1
2 // BUILD: $CC foo1.c -dynamiclib -install_name $RUN_DIR/libfoo1.dylib -o $BUILD_DIR/libfoo1.dylib
3 // BUILD: $CC foo2.c -dynamiclib -install_name $RUN_DIR/libfoo2.dylib -o $BUILD_DIR/libfoo2.dylib
4 // BUILD: $CC foo3.c -dynamiclib -install_name $RUN_DIR/libfoo3.dylib -o $BUILD_DIR/libfoo3.dylib
5 // BUILD: $CC main.c -o $BUILD_DIR/dlopen-RTLD_LOCAL-coalesce.exe -DRUN_DIR="$RUN_DIR"
6
7 // RUN: ./dlopen-RTLD_LOCAL-coalesce.exe
8
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <dlfcn.h>
13
14
15 ///
16 /// This tests the interaction of RTLD_LOCAL and weak-def coalescing.
17 ///
18 /// Normally, (for correct C++ ODR), dyld coalesces all weak-def symbols
19 /// across all images, so that only one copy of each weak symbol name
20 /// is in use. But, dlopen with RTLD_LOCAL means to "hide" the symbols in
21 /// that one (top) image being loaded.
22 ///
23 ///
24
25 // main *coalA
26 // libfoo1.dylib coalA *coalB
27 // libfoo2.dylib coalA coalB coalC // loaded with RTLD_LOCAL
28 // libfoo3.dylib coalA coalB *coalC
29 //
30
31 typedef int (*IntProc)(void);
32
33 int __attribute__((weak)) coalA = 0;
34
35 int main()
36 {
37 printf("[BEGIN] dlopen-RTLD_LOCAL-coalesce\n");
38
39 ///
40 /// Load three foo dylibs in order
41 ///
42 void* handle1 = dlopen(RUN_DIR "/libfoo1.dylib", RTLD_GLOBAL);
43 void* handle2 = dlopen(RUN_DIR "/libfoo2.dylib", RTLD_LOCAL);
44 void* handle3 = dlopen(RUN_DIR "/libfoo3.dylib", RTLD_GLOBAL);
45 if ( handle1 == NULL ) {
46 printf("[FAIL] dlopen-RTLD_LOCAL-coalesce: dlopen(libfoo1.dylib, RTLD_GLOBAL) failed but it should have worked: %s\n", dlerror());
47 return 0;
48 }
49 if ( handle2 == NULL ) {
50 printf("[FAIL] dlopen-RTLD_LOCAL-coalesce: dlopen(libfoo2.dylib, RTLD_LOCAL) failed but it should have worked: %s\n", dlerror());
51 return 0;
52 }
53 if ( handle3 == NULL ) {
54 printf("[FAIL] dlopen-RTLD_LOCAL-coalesce: dlopen(libfoo3.dylib, RTLD_GLOBAL) failed but it should have worked: %s\n", dlerror());
55 return 0;
56 }
57
58
59 ///
60 /// Get accessor functions
61 ///
62 IntProc foo1_coalA = (IntProc)dlsym(handle1, "foo1_coalA");
63 IntProc foo1_coalB = (IntProc)dlsym(handle1, "foo1_coalB");
64 IntProc foo2_coalA = (IntProc)dlsym(handle2, "foo2_coalA");
65 IntProc foo2_coalB = (IntProc)dlsym(handle2, "foo2_coalB");
66 IntProc foo2_coalC = (IntProc)dlsym(handle2, "foo2_coalC");
67 IntProc foo3_coalA = (IntProc)dlsym(handle3, "foo3_coalA");
68 IntProc foo3_coalB = (IntProc)dlsym(handle3, "foo3_coalB");
69 IntProc foo3_coalC = (IntProc)dlsym(handle3, "foo3_coalC");
70 if ( !foo1_coalA || !foo1_coalB ||
71 !foo2_coalA || !foo2_coalB || !foo2_coalC ||
72 !foo3_coalA || !foo3_coalB || !foo3_coalC ) {
73 printf("[FAIL] dlopen-RTLD_LOCAL-coalesce: dlsym() failed\n");
74 return 0;
75 }
76
77 ///
78 /// Get values for each coal[ABC] seen in each image
79 ///
80 int foo1A = (*foo1_coalA)();
81 int foo1B = (*foo1_coalB)();
82 int foo2A = (*foo2_coalA)();
83 int foo2B = (*foo2_coalB)();
84 int foo2C = (*foo2_coalC)();
85 int foo3A = (*foo3_coalA)();
86 int foo3B = (*foo3_coalB)();
87 int foo3C = (*foo3_coalC)();
88 printf("coalA in main: %d\n", coalA);
89 printf("coalA in libfoo1: %d\n", foo1A);
90 printf("coalA in libfoo2: %d\n", foo2A);
91 printf("coalA in libfoo3: %d\n", foo3A);
92
93 printf("coalB in libfoo1: %d\n", foo1B);
94 printf("coalB in libfoo2: %d\n", foo2B);
95 printf("coalB in libfoo3: %d\n", foo3B);
96
97 printf("coalC in libfoo2: %d\n", foo2C);
98 printf("coalC in libfoo3: %d\n", foo3C);
99
100
101
102 ///
103 /// Verify coalescing was done properly (foo2 was skipped because of RTLD_LOCAL)
104 ///
105 if ( (foo1A != 0) || (foo2A != 0) || (foo3A != 0) || (coalA != 0) ) {
106 printf("[FAIL] dlopen-RTLD_LOCAL-coalesce: coalA was not coalesced properly\n");
107 return 0;
108 }
109 if ( (foo1B != 1) || (foo2B != 1) || (foo3B != 1) ) {
110 printf("[FAIL] dlopen-RTLD_LOCAL-coalesce: coalB was not coalesced properly\n");
111 return 0;
112 }
113 if ( (foo2C != 2) || (foo3C != 3) ) {
114 printf("[FAIL] dlopen-RTLD_LOCAL-coalesce: coalC was not coalesced properly\n");
115 return 0;
116 }
117
118
119
120 printf("[PASS] dlopen-RTLD_LOCAL-coalesce\n");
121 return 0;
122 }