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