]>
git.saurik.com Git - apple/dyld.git/blob - testing/test-cases/dlopen-RTLD_NODELETE.dtest/main.c
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"
6 // RUN: ./dlopen-RTLD_NODELETE.exe
13 #include "test_support.h"
15 int main(int argc
, const char* argv
[], const char* envp
[], const char* apple
[]) {
17 /// This tests that RTLD_NODELETE on first dlopen() blocks dlclose() from unloading image
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());
23 int* fooSym
= (int*)dlsym(handle
, "foo");
24 if ( fooSym
== NULL
) {
25 FAIL("dlsym(handle, \"foo\") failed but it should have worked: %s", dlerror());
27 int fooValue
= *fooSym
;
30 if ( dladdr(fooSym
, &info
) != 0 ) {
31 FAIL("dladdr(fooSym, xx) succeeded as if libfoo.dylib was not unloaded");
33 // dereference foo pointer. If RTLD_NODELETE worked, this will not crash
34 if ( *fooSym
!= fooValue
) {
35 FAIL("value at fooSym changed");
39 /// This tests that RTLD_NODELETE on later dlopen() blocks dlclose() from unloading image
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());
45 int* barSym
= (int*)dlsym(handle2
, "bar");
46 if ( barSym
== NULL
) {
47 FAIL("dlsym(handle, \"bar\") failed but it should have worked: %s", dlerror());
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());
56 if ( dladdr(barSym
, &info
) != 0 ) {
57 FAIL("dladdr(barSym, xx) succeeded as if libbar.dylib was not unloaded");
59 // dereference foo pointer. If RTLD_NODELETE worked, this will not crash
60 if ( *barSym
!= barValue
) {
61 FAIL("value at barSym changed");