1/* 2 * Copyright (c) 2010 Apple Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23#include <stdio.h> 24#include <stdlib.h> 25#include <stdbool.h> 26#include <mach-o/dyld.h> 27#include <mach-o/dyld_images.h> 28#include <sys/types.h> 29#include <sys/stat.h> 30#include <sys/mman.h> 31#include <unistd.h> 32#include <fcntl.h> 33#include <Availability.h> 34 35#include "test.h" // PASS(), FAIL() 36 37 38struct dyld_all_image_infos* getImageInfosFromKernel() 39{ 40 task_dyld_info_data_t task_dyld_info; 41 mach_msg_type_number_t count = TASK_DYLD_INFO_COUNT; 42 43 if ( task_info(mach_task_self(), TASK_DYLD_INFO, (task_info_t)&task_dyld_info, &count) ) { 44 FAIL("all_image_infos: task_info() failed"); 45 exit(0); 46 } 47 return (struct dyld_all_image_infos*)(uintptr_t)task_dyld_info.all_image_info_addr; 48} 49 50 51int main() 52{ 53// NSObjectFileImage APIs are only available on Mac OS X - not iPhone OS 54#if __MAC_OS_X_VERSION_MIN_REQUIRED 55 int fd = open("test.bundle", O_RDONLY, 0); 56 if ( fd == -1 ) { 57 FAIL("open() failed"); 58 return 1; 59 } 60 61 struct stat stat_buf; 62 if ( fstat(fd, &stat_buf) == -1) { 63 FAIL("fstat() failed"); 64 return 0; 65 } 66 67 void* loadAddress = mmap(NULL, stat_buf.st_size, PROT_READ, MAP_FILE | MAP_PRIVATE, fd, 0); 68 if ( loadAddress == ((void*)(-1)) ) { 69 FAIL("mmap() failed"); 70 return 0; 71 } 72 73 close(fd); 74 75 NSObjectFileImage ofi; 76 if ( NSCreateObjectFileImageFromMemory(loadAddress, stat_buf.st_size, &ofi) != NSObjectFileImageSuccess ) { 77 FAIL("NSCreateObjectFileImageFromMemory failed"); 78 return 0; 79 } 80 81 NSModule mod = NSLinkModule(ofi, "he_he", NSLINKMODULE_OPTION_NONE); 82 if ( mod == NULL ) { 83 FAIL("NSLinkModule failed"); 84 return 0; 85 } 86 87 // look for he_he string in list of images loaded 88 struct dyld_all_image_infos* infos = getImageInfosFromKernel(); 89 90 if ( infos->infoArrayCount < 2 ) { 91 FAIL("bundle-memory-load-all-images: dyld_all_image_infos.infoArrayCount is < 2"); 92 return 0; 93 } 94 95 bool found = false; 96 for( int i=0; i < infos->infoArrayCount; ++i) { 97 //fprintf(stderr, "infos->infoArray[%d].imageLoadAddress=%p %s\n", i, infos->infoArray[i].imageLoadAddress, infos->infoArray[i].imageFilePath); 98 if ( infos->infoArray[i].imageFilePath == NULL ) { 99 FAIL("bundle-memory-load-all-images: NULL image path found"); 100 exit(0); 101 } 102 if ( strcmp(infos->infoArray[i].imageFilePath, "he_he") == 0 ) 103 found = true; 104 } 105 106 if ( !found ) { 107 FAIL("bundle-memory-load-all-images: loaded memory bundle 'he_he' nout found"); 108 return 0; 109 } 110 111 if ( !NSUnLinkModule(mod, NSUNLINKMODULE_OPTION_NONE) ) { 112 FAIL("NSUnLinkModule failed"); 113 return 0; 114 } 115 116 if ( !NSDestroyObjectFileImage(ofi) ) { 117 FAIL("NSDestroyObjectFileImage failed"); 118 return 0; 119 } 120 121 // Should check that loadAddress is unmmaped now (by call to NSDestroyObjectFileImage) 122#endif 123 124 PASS("bundle-memory-load-all-images"); 125 return 0; 126}