1/* 2 * Copyright (c) 2005 Apple Computer, 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 <stdbool.h> // fprintf(), NULL 24#include <stdio.h> // fprintf(), NULL 25#include <stdlib.h> // exit(), EXIT_SUCCESS 26#include <stdbool.h> 27#include <string.h> 28#include <mach-o/dyld.h> 29#include <mach-o/dyld_priv.h> 30#include <dlfcn.h> 31 32#include "test.h" // PASS(), FAIL(), XPASS(), XFAIL() 33 34static bool doneRegistering = false; 35 36 37// 38// By returning a string, we prevent that image from loading. 39// We just prevent any image with "bar" in its name from loading. 40// 41 42static const char* batchMappedHandler(enum dyld_image_states state, uint32_t infoCount, const struct dyld_image_info info[]) 43{ 44 for (uint32_t i=0; i < infoCount; ++i) { 45 //fprintf(stderr, "batch mapped: %d %s\n", i, info[i].imageFilePath); 46 if ( strstr(info[i].imageFilePath, "bar") != NULL ) 47 return "can't load bar"; 48 } 49 return NULL; 50} 51 52static const char* singleMappedHandler(enum dyld_image_states state, uint32_t infoCount, const struct dyld_image_info info[]) 53{ 54 //fprintf(stderr, "single mapped: %s\n", info[0].imageFilePath); 55 if ( strstr(info[0].imageFilePath, "bar") != NULL ) 56 return "can't load bar"; 57 return NULL; 58} 59 60 61 62static const char* singleInitializedHandler(enum dyld_image_states state, uint32_t infoCount, const struct dyld_image_info info[]) 63{ 64 //fprintf(stderr, "singleInitializedHandler(%s)\n", info[0].imageFilePath); 65 if ( doneRegistering ) { 66 FAIL("image-state-deny something loaded"); 67 exit(0); 68 } 69 return NULL; 70} 71 72//static const char* batchBoundHandler(enum dyld_image_states state, uint32_t infoCount, const struct dyld_image_info info[]) 73//{ 74// //for (uint32_t i=0; i < infoCount; ++i) 75// // fprintf(stderr, "bound: %u %s\n", i, info[i].imageFilePath); 76// return NULL; 77//} 78 79static void load(const char* name) 80{ 81 void* handle = dlopen(name, RTLD_LAZY); 82 if ( handle != NULL ) { 83 FAIL("image-state-deny: dlopen(%s) should have failed", name); 84 exit(0); 85 } 86} 87 88 89int main(int argc, const char* argv[]) 90{ 91 // tell dyld we want to know when images successfully loaded 92 dyld_register_image_state_change_handler(dyld_image_state_initialized, false, singleInitializedHandler); 93 doneRegistering = true; 94 95 // tell dyld we want to know when images successfully loaded 96 //dyld_register_image_state_change_handler(dyld_image_state_bound, true, batchBoundHandler); 97 98 // tell dyld we want to know when images are mapped 99 if ( argc > 1 ) 100 dyld_register_image_state_change_handler(dyld_image_state_dependents_mapped, true, batchMappedHandler); 101 else 102 dyld_register_image_state_change_handler(dyld_image_state_mapped, false, singleMappedHandler); 103 104 load("foo.bundle"); 105 106 load("bar.bundle"); 107 108 //dlopen("/usr/lib/libz.1.2.3.dylib", RTLD_LAZY); 109 110 PASS("image-state-deny"); 111 112 return EXIT_SUCCESS; 113} 114