#include <stdio.h> // fprintf(), NULL
#include <stdlib.h> // exit(), EXIT_SUCCESS
#include <dlfcn.h>
#include <string.h>
#include "test.h" // PASS(), FAIL(), XPASS(), XFAIL()
static void* openWithModeGetSymbol(const char* path, int mode, const char* symbol)
{
void* handle = dlopen(path, mode);
if ( handle == NULL ) {
const char* msg = dlerror();
if ( ((mode & RTLD_LOCAL) != 0) && (strstr(msg, "RTLD_LOCAL") != NULL) )
XFAIL("dlopen(\"%s\") failed: %s", path, msg);
else
FAIL("dlopen(\"%s\") failed: %s", path, msg);
exit(0);
}
void* sym = dlsym(handle, symbol);
if ( sym == NULL ) {
FAIL("dlsym(handle, \"%s\") failed", symbol);
exit(0);
}
return sym;
}
static void trySO(const char* path)
{
#if LOCAL_FIRST
void* symLocal = openWithModeGetSymbol(path, RTLD_LOCAL, "foo");
void* symGlobal = openWithModeGetSymbol(path, RTLD_GLOBAL, "foo");
#else
void* symGlobal = openWithModeGetSymbol(path, RTLD_GLOBAL, "foo");
void* symLocal = openWithModeGetSymbol(path, RTLD_LOCAL, "foo");
#endif
if ( symLocal != symGlobal ) {
FAIL("global load after local load failed");
exit(0);
}
}
int main(int argc, const char* argv[])
{
trySO("foo.bundle");
trySO("foo.dylib");
PASS("dlopen-local-and-global");
return EXIT_SUCCESS;
}