#include <stdio.h>
#include <stdbool.h>
#include <mach-o/dyld.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <unistd.h>
#include <fcntl.h>
#include <Availability.h>
#include "test.h" // PASS(), FAIL()
typedef bool (*CheckFunc)();
int main()
{
#if __MAC_OS_X_VERSION_MIN_REQUIRED
int fd = open("test.bundle", O_RDONLY, 0);
if ( fd == -1 ) {
FAIL("open() failed");
return 1;
}
struct stat stat_buf;
if ( fstat(fd, &stat_buf) == -1) {
FAIL("fstat() failed");
return 1;
}
void* loadAddress = mmap(NULL, stat_buf.st_size, PROT_READ, MAP_FILE | MAP_PRIVATE, fd, 0);
if ( loadAddress == ((void*)(-1)) ) {
FAIL("mmap() failed");
return 1;
}
close(fd);
NSObjectFileImage ofi;
if ( NSCreateObjectFileImageFromMemory(loadAddress, stat_buf.st_size, &ofi) != NSObjectFileImageSuccess ) {
FAIL("NSCreateObjectFileImageFromMemory failed");
return 1;
}
NSModule mod = NSLinkModule(ofi, "he_he", NSLINKMODULE_OPTION_NONE);
if ( mod == NULL ) {
FAIL("NSLinkModule failed");
return 1;
}
NSSymbol sym = NSLookupSymbolInModule(mod, "_checkdata");
if ( sym == NULL ) {
FAIL("NSLookupSymbolInModule failed");
return 1;
}
CheckFunc func = NSAddressOfSymbol(sym);
if ( !func() ) {
FAIL("NSAddressOfSymbol failed");
return 1;
}
if ( !NSUnLinkModule(mod, NSUNLINKMODULE_OPTION_NONE) ) {
FAIL("NSUnLinkModule failed");
return 1;
}
if ( !NSDestroyObjectFileImage(ofi) ) {
FAIL("NSDestroyObjectFileImage failed");
return 1;
}
#endif
PASS("bundle-memory-load");
return 0;
}