]>
git.saurik.com Git - apple/dyld.git/blob - testing/test-cases/dlopen-RTLD_LOCAL-coalesce.dtest/main.c
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"
7 // RUN: ./dlopen-RTLD_LOCAL-coalesce.exe
16 /// This tests the interaction of RTLD_LOCAL and weak-def coalescing.
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.
26 // libfoo1.dylib coalA *coalB
27 // libfoo2.dylib coalA coalB coalC // loaded with RTLD_LOCAL
28 // libfoo3.dylib coalA coalB *coalC
31 typedef int (*IntProc
)(void);
33 int __attribute__((weak
)) coalA
= 0;
37 printf("[BEGIN] dlopen-RTLD_LOCAL-coalesce\n");
40 /// Load three foo dylibs in order
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());
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());
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());
60 /// Get accessor functions
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");
78 /// Get values for each coal[ABC] seen in each image
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
);
93 printf("coalB in libfoo1: %d\n", foo1B
);
94 printf("coalB in libfoo2: %d\n", foo2B
);
95 printf("coalB in libfoo3: %d\n", foo3B
);
97 printf("coalC in libfoo2: %d\n", foo2C
);
98 printf("coalC in libfoo3: %d\n", foo3C
);
103 /// Verify coalescing was done properly (foo2 was skipped because of RTLD_LOCAL)
105 if ( (foo1A
!= 0) || (foo2A
!= 0) || (foo3A
!= 0) || (coalA
!= 0) ) {
106 printf("[FAIL] dlopen-RTLD_LOCAL-coalesce: coalA was not coalesced properly\n");
109 if ( (foo1B
!= 1) || (foo2B
!= 1) || (foo3B
!= 1) ) {
110 printf("[FAIL] dlopen-RTLD_LOCAL-coalesce: coalB was not coalesced properly\n");
113 if ( (foo2C
!= 2) || (foo3C
!= 3) ) {
114 printf("[FAIL] dlopen-RTLD_LOCAL-coalesce: coalC was not coalesced properly\n");
120 printf("[PASS] dlopen-RTLD_LOCAL-coalesce\n");