#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dlfcn.h>
int main()
{
printf("[BEGIN] dlopen-RTLD_NODELETE\n");
void* handle = dlopen(RUN_DIR "/libfoo.dylib", RTLD_NODELETE);
if ( handle == NULL ) {
printf("[FAIL] dlopen-RTLD_NODELETE: dlopen(libfoo.dylib, RTLD_NODELETE) failed but it should have worked: %s\n", dlerror());
return 0;
}
int* fooSym = (int*)dlsym(handle, "foo");
if ( fooSym == NULL ) {
printf("[FAIL] dlopen-RTLD_NODELETE: dlsym(handle, \"foo\") failed but it should have worked: %s\n", dlerror());
return 0;
}
int fooValue = *fooSym;
dlclose(handle);
Dl_info info;
if ( dladdr(fooSym, &info) != 0 ) {
printf("[FAIL] dlopen-RTLD_NODELETE: dladdr(fooSym, xx) succeeded as if libfoo.dylib was not unloaded\n");
return 0;
}
if ( *fooSym != fooValue ) {
printf("[FAIL] dlopen-RTLD_NODELETE: value at fooSym changed\n");
return 0;
}
void* handle2 = dlopen(RUN_DIR "/libbar.dylib", RTLD_GLOBAL);
if ( handle2 == NULL ) {
printf("[FAIL] dlopen-RTLD_NODELETE: dlopen(libfoo.dylib, RTLD_GLOBAL) failed but it should have worked: %s\n", dlerror());
return 0;
}
int* barSym = (int*)dlsym(handle2, "bar");
if ( barSym == NULL ) {
printf("[FAIL] dlopen-RTLD_NODELETE: dlsym(handle, \"bar\") failed but it should have worked: %s\n", dlerror());
return 0;
}
int barValue = *barSym;
void* handle3 = dlopen(RUN_DIR "/libbar.dylib", RTLD_NODELETE);
if ( handle3 == NULL ) {
printf("[FAIL] dlopen-RTLD_NODELETE: dlopen(libfoo.dylib, RTLD_NODELETE) failed but it should have worked: %s\n", dlerror());
return 0;
}
dlclose(handle2);
dlclose(handle3);
if ( dladdr(barSym, &info) != 0 ) {
printf("[FAIL] dlopen-RTLD_NODELETE: dladdr(barSym, xx) succeeded as if libbar.dylib was not unloaded\n");
return 0;
}
if ( *barSym != barValue ) {
printf("[FAIL] dlopen-RTLD_NODELETE: value at barSym changed\n");
return 0;
}
printf("[PASS] dlopen-RTLD_NODELETE\n");
return 0;
}