#include <stdio.h> // fprintf(), NULL
#include <stdlib.h> // exit(), EXIT_SUCCESS
#include <stdbool.h>
#include <mach-o/dyld.h>
#include <dlfcn.h>
#include "test.h" // PASS(), FAIL(), XPASS(), XFAIL()
static void* sExpectedBundleBaseAddress = 0;
static bool sNotified = false;
static void removeNotification(const struct mach_header *mh, intptr_t vmaddr_slide)
{
if ( mh == sExpectedBundleBaseAddress )
sNotified = true;
}
int main(int argc, const char* argv[])
{
_dyld_register_func_for_remove_image(removeNotification);
void* handle = dlopen("foo.bundle", RTLD_LAZY);
if ( handle == NULL ) {
FAIL("image-remove-notification: dlopen(foo.bundle) failed: %s", dlerror());
exit(0);
}
void* sym = dlsym(handle, "foo");
if ( sym == NULL ) {
FAIL("image-remove-notification: dlsym(handle, \"foo\") failed: %s", dlerror());
exit(0);
}
Dl_info info;
if ( dladdr(sym, &info) == 0 ) {
FAIL("image-remove-notification: dladdr() failed");
exit(0);
}
sExpectedBundleBaseAddress = info.dli_fbase;
int result = dlclose(handle);
if ( result != 0 ) {
FAIL("image-remove-notification: dlclose(handle) returned %d, %s", result, dlerror());
exit(0);
}
if ( sNotified )
PASS("image-remove-notification");
else
FAIL("image-remove-notification");
return EXIT_SUCCESS;
}