1/* 2 * Copyright (c) 2006-2008 Apple Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_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. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28#ifndef __FAT_UTIL_H__ 29#define __FAT_UTIL_H__ 30 31#include <mach-o/fat.h> 32 33/*! 34 * @define MAGIC32 35 * @abstract Get the 32-bit magic number from a file data pointer. 36 * @param ptr A pointer to a file whose magic number you want to get. 37 * @result Returns an unsigned 32-bit integer containing 38 * the first four bytes of the file data. 39 */ 40#define MAGIC32(ptr) (*((uint32_t *)(ptr))) 41 42#define ISFAT(magic) ((magic) == OSSwapHostToBigInt32(FAT_MAGIC)) 43 44/*! 45 * @typedef fat_iterator 46 * @abstract An opaque type for iterating architectures 47 * in a Mach-O or universal binary file. 48 * @discussion A fat_iterator allows you to access every architecture in a 49 * Macho-O or universal binary file. Initialized with either kind, 50 * you use the fat_iterator_next_arch function to scan through each 51 * architecture (which will be one for a Mach-O file, and one or more 52 * for a universal binary file). 53 */ 54typedef struct __fat_iterator * fat_iterator; 55 56 57/*! 58 * @function fat_iterator_open 59 * @abstract Create an iterator for a Mach-O or universal binary file. 60 * @discussion 61 * The fat_iterator_open function opens and maps the named file, 62 * creates a fat_iterator for it, and returns the iterator. 63 * When finished with the iterator, use fat_iterator_close and the 64 * file will be unmapped. 65 * @param path The pathname of the file to open. 66 * @param macho_only Pass true to require the file data be either fat or a 67 * thin Mach-O file or 68 * false to allow a non-fat file to contain any kind of data. 69 * @result Returns a fat_iterator you can use to access the architectures 70 * in the named file. 71 * Returns NULL if the file can't be opened, 72 * if macho_only is true and the file is neither fat nor a Mach-O file, 73 * or if the iterator can't be created. 74 */ 75fat_iterator fat_iterator_open(const char * path, int macho_only); 76 77/*! 78 * @function fat_iterator_for_data 79 * @abstract Create an iterator for in-memory Mach-O or universal binary data. 80 * @discussion 81 * The fat_iterator_for_data function creates and returns an iterator 82 * for in-memory Mach-O or universal binary data, which must be complete. 83 * The iterator does not own the data, so be sure not to free or unmap 84 * it before you close the iterator. 85 * @param file_data A pointer to the start of the file data. 86 * @param file_end A pointer to the end of the file data, which the iterator 87 * uses for bounds checking. 88 * @param macho_only Pass true to require the file data be either fat or a 89 * thin Mach-O file or 90 * false to allow a non-fat file to contain any kind of data. 91 * @result Returns a fat_iterator you can use to access the architectures 92 * in the file data. 93 * Returns NULL if the file can't be opened, 94 * if macho_only is true and the file is neither fat nor a Mach-O file, 95 * or if the iterator can't be created. 96 */ 97fat_iterator fat_iterator_for_data( 98 const void * file_data, 99 const void * file_end, 100 int macho_only); 101 102/*! 103 * @function fat_iterator_close 104 * @abstract Close and free a fat_iterator. 105 * @discussion 106 * The fat_iterator_close function unmaps a fat_iterator's file data 107 * if necessary and frees the iterator. 108 * @param iter The fat_iterator to close. 109 */ 110void fat_iterator_close(fat_iterator iter); 111 112/*! 113 * @function fat_iterator_num_arches 114 * @abstract Return how many arches are in the data of a fat iterator. 115 * @param iter The fat_iterator to check. 116 * @result Returns the number of arches that will be iterated over, total. 117 */ 118int fat_iterator_num_arches( 119 fat_iterator iter); 120 121/*! 122 * @function fat_iterator_is_iterable 123 * @abstract Return whether a fat_iterator can actually iterate. 124 * @discussion 125 * The fat_iterator_is_iterable function returns true if it represents 126 * a fat file or a thin Mach-O file, false otherwise. 127 * @param iter The fat_iterator to check. 128 * @result Returns true if the iterator represents 129 * a fat file or a thin Mach-O file, false otherwise. 130 */ 131int fat_iterator_is_iterable( 132 fat_iterator iter); 133 134/*! 135 * @function fat_iterator_next_arch 136 * @abstract Return the next architecture in a fat_iterator. 137 * @discussion 138 * The fat_iterator_next_arch function returns a pointer to the start 139 * of the data for the next architecture in the iterator's file, or NULL if the 140 * architectures have been fully traversed (or if the iterator is not valid). 141 * @param iter The fat_iterator to iterate. 142 * @param file_end If provided, this indirect pointer is filled 143 * with the address of the end of the data for the architecture returned. 144 * Other macho utility functions use this for bounds checking. 145 * @result Returns a pointer to the mach_header 146 * struct for the next architecture in the iterator's file, or NULL if the 147 * architectures have been fully traversed (or if the iterator is not valid). 148 */ 149void * fat_iterator_next_arch( 150 fat_iterator iter, 151 void ** arch_end); 152 153/*! 154 * @function fat_iterator_reset 155 * @abstract Rewinds a fat_iterator. 156 * @discussion 157 * The fat_iterator_reset function sets the iterator to start from 158 * the beginning of the file so that you can iterate it again. 159 * @param iter The fat_iterator to reset. 160 */ 161void fat_iterator_reset(fat_iterator iter); 162 163/*! 164 * @function fat_iterator_find_fat_arch 165 * @abstract Find the specified fat_arch entry in a fat_iterator, 166 * if present. 167 * @discussion 168 * The fat_iterator_find_arch function fills in a provided 169 * fat_arch struct for the specified architecture 170 * in the iterator's file, or NULL if that architecture is not represented. 171 * @param iter The fat_iterator to get the arch data from. 172 * @param cputype The CPU type code requested (see <mach/machine.h> for a list). 173 * @param cpusubtype The CPU subtype requested. 174 * Use CPU_SUBTYPE_MULTIPLE for a generic processor family request. 175 * @param fat_arch A pointer to the fat_arch struct to fill in. 176 * All fields filled in are in host byte order. 177 * @result Returns 1 if the 178 * specified architecture is found in the iterator's file, 179 * or 0 if the specified architecture is not represented. 180 */ 181int fat_iterator_find_fat_arch( 182 fat_iterator iter, 183 cpu_type_t cputype, 184 cpu_subtype_t cpusubtype, 185 struct fat_arch * fat_arch); 186 187/*! 188 * @function fat_iterator_find_arch 189 * @abstract Return the specified architecture in a fat_iterator, if present. 190 * @discussion 191 * The fat_iterator_find_arch function returns a pointer 192 * to the start of the data for the specified architecture 193 * in the iterator's file, or NULL if that architecture is not represented. 194 * @param iter The fat_iterator to get the arch data from. 195 * @param cputype The CPU type code specified (see <mach/machine.h> for a list). 196 * @param cpusubtype The CPU subtype specified. 197 * Use CPU_SUBTYPE_MULTIPLE for a generic processor family request. 198 * @param file_end If provided, this indirect pointer is filled 199 * with the address of the end of the data for the architecture returned. 200 * Other macho utility functions use this for bounds checking. 201 * @result Returns a pointer to the file data 202 * for the specified architecture in the iterator's file, 203 * or NULL if the specified architecture is not represented. 204 */ 205void * fat_iterator_find_arch( 206 fat_iterator iter, 207 cpu_type_t cputype, 208 cpu_subtype_t cpusubtype, 209 void ** arch_end_ptr); 210 211/*! 212 * @function fat_iterator_find_host_arch 213 * @abstract Return the host architecture in a fat_iterator, if present. 214 * @discussion 215 * The fat_iterator_find_host_arch function returns a pointer 216 * to the start of the data for the host architecture in the iterator's file, 217 * or NULL if the host architecture is not represented. 218 * @param iter The fat_iterator to get the host arch data from. 219 * @param file_end If provided, this indirect pointer is filled 220 * with the address of the end of the data for the architecture returned. 221 * Other macho utility functions use this for bounds checking. 222 * @result Returns a pointer to the file data 223 * for the host architecture in the iterator's file, 224 * or NULL if the host architecture is not represented. 225 */ 226void * fat_iterator_find_host_arch( 227 fat_iterator iter, 228 void ** arch_end_ptr); 229 230/*! 231 * @function fat_iterator_file_start 232 * @abstract Returns a pointer to the start of a fat_iterator's file. 233 * @discussion 234 * The fat_iterator_reset returns a pointer to the start 235 * of a fat_iterator's file, so that you can access it directly. 236 * @param iter The fat_iterator to get the file start for. 237 * @result Returns a pointer to the beginning of the file accessed 238 * by the fat_iterator. 239 */ 240const void * fat_iterator_file_start(fat_iterator iter); 241 242/*! 243 * @function fat_iterator_file_end 244 * @abstract Returns a pointer to the end of a fat_iterator's file. 245 * @discussion 246 * The fat_iterator_reset returns a pointer to the end 247 * of a fat_iterator's file, so that you can do bounds checking. 248 * @param iter The fat_iterator to get the file end for. 249 * @result Returns a pointer to the end of the file accessed 250 * by the fat_iterator. 251 */ 252const void * fat_iterator_file_end(fat_iterator iter); 253 254 255#endif /* __FAT_UTIL_H__ */ 256