#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <mach-o/dyld.h>
#include <mach-o/dyld_images.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()
struct dyld_all_image_infos* getImageInfosFromKernel()
{
task_dyld_info_data_t task_dyld_info;
mach_msg_type_number_t count = TASK_DYLD_INFO_COUNT;
if ( task_info(mach_task_self(), TASK_DYLD_INFO, (task_info_t)&task_dyld_info, &count) ) {
FAIL("all_image_infos: task_info() failed");
exit(0);
}
return (struct dyld_all_image_infos*)(uintptr_t)task_dyld_info.all_image_info_addr;
}
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 0;
}
void* loadAddress = mmap(NULL, stat_buf.st_size, PROT_READ, MAP_FILE | MAP_PRIVATE, fd, 0);
if ( loadAddress == ((void*)(-1)) ) {
FAIL("mmap() failed");
return 0;
}
close(fd);
NSObjectFileImage ofi;
if ( NSCreateObjectFileImageFromMemory(loadAddress, stat_buf.st_size, &ofi) != NSObjectFileImageSuccess ) {
FAIL("NSCreateObjectFileImageFromMemory failed");
return 0;
}
NSModule mod = NSLinkModule(ofi, "he_he", NSLINKMODULE_OPTION_NONE);
if ( mod == NULL ) {
FAIL("NSLinkModule failed");
return 0;
}
struct dyld_all_image_infos* infos = getImageInfosFromKernel();
if ( infos->infoArrayCount < 2 ) {
FAIL("bundle-memory-load-all-images: dyld_all_image_infos.infoArrayCount is < 2");
return 0;
}
bool found = false;
for( int i=0; i < infos->infoArrayCount; ++i) {
if ( infos->infoArray[i].imageFilePath == NULL ) {
FAIL("bundle-memory-load-all-images: NULL image path found");
exit(0);
}
if ( strcmp(infos->infoArray[i].imageFilePath, "he_he") == 0 )
found = true;
}
if ( !found ) {
FAIL("bundle-memory-load-all-images: loaded memory bundle 'he_he' nout found");
return 0;
}
if ( !NSUnLinkModule(mod, NSUNLINKMODULE_OPTION_NONE) ) {
FAIL("NSUnLinkModule failed");
return 0;
}
if ( !NSDestroyObjectFileImage(ofi) ) {
FAIL("NSDestroyObjectFileImage failed");
return 0;
}
#endif
PASS("bundle-memory-load-all-images");
return 0;
}