1/* 2 * Copyright (c) 2007 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 24#include <stdbool.h> // fprintf(), NULL 25#include <stdio.h> // fprintf(), NULL 26#include <stdlib.h> // exit(), EXIT_SUCCESS 27#include <string.h> 28#include <stdbool.h> 29#include <mach-o/dyld.h> 30#include <mach-o/dyld_priv.h> 31#include <dlfcn.h> 32 33#include "test.h" // PASS(), FAIL(), XPASS(), XFAIL() 34 35 36 37static enum { start, barDeps, bar, fooDeps, foo, mainDeps, main } step = start; 38 39 40static const char* depInitHandler(enum dyld_image_states state, uint32_t infoCount, const struct dyld_image_info info[]) 41{ 42 if ( infoCount != 1 ) { 43 FAIL("image-state-dependents-initialized: depInitHandler infoCount != 1\n"); 44 exit(0); 45 } 46 47 //fprintf(stderr, "depInitHandler(%s), state=%d\n", info[0].imageFilePath, step); 48 49 if ( (step == start) && (strstr(info[0].imageFilePath, "libbar.dylib") != NULL) ) 50 step = barDeps; 51 else if ( (step == bar) && (strstr(info[0].imageFilePath, "libfoo.dylib") != NULL) ) 52 step = fooDeps; 53 else if ( (step == foo) && (strstr(info[0].imageFilePath, "/main") != NULL) ) 54 step = mainDeps; 55 else { 56 fprintf(stderr, "out of order depInitHandler\n"); 57 exit(0); 58 } 59 60 61 return NULL; 62} 63 64static const char* initHandler(enum dyld_image_states state, uint32_t infoCount, const struct dyld_image_info info[]) 65{ 66 if ( infoCount != 1 ) { 67 FAIL("image-state-dependents-initialized: initHandler infoCount != 1\n"); 68 exit(0); 69 } 70 71 //fprintf(stderr, "initHandler(%s), state=%d\n", info[0].imageFilePath, step); 72 bool isBar = (strstr(info[0].imageFilePath, "libbar.dylib") != NULL); 73 bool isFoo = (strstr(info[0].imageFilePath, "libfoo.dylib") != NULL); 74 bool isMain= (strstr(info[0].imageFilePath, "/main") != NULL); 75 76 if ( isBar ) { 77 if ( step == barDeps ) { 78 step = bar; 79 } 80 else { 81 fprintf(stderr, "out of order initHandler bar\n"); 82 exit(0); 83 } 84 } 85 else if ( isFoo ) { 86 if ( step == fooDeps ) { 87 step = foo; 88 } 89 else { 90 fprintf(stderr, "out of order initHandler foo\n"); 91 exit(0); 92 } 93 } 94 else if ( isMain ) { 95 if ( step == mainDeps ) { 96 step = main; 97 } 98 else { 99 fprintf(stderr, "out of order initHandler main\n"); 100 exit(0); 101 } 102 } 103 104 105 return NULL; 106} 107 108 109 110 111void __attribute__((constructor)) setup_bar() 112{ 113 // tell dyld we want to know when images are mapped 114 dyld_register_image_state_change_handler(dyld_image_state_dependents_initialized, false, depInitHandler); 115 dyld_register_image_state_change_handler(dyld_image_state_initialized, false, initHandler); 116} 117 118 119 120