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