1 | /* |
2 | * Copyright (c) 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 | |
29 | #ifndef _MKEXT_H_ |
30 | #define _MKEXT_H_ 1 |
31 | |
32 | #include <sys/cdefs.h> |
33 | #include <sys/types.h> |
34 | |
35 | #include <mach/machine.h> |
36 | |
37 | /********************************************************************* |
38 | * Mkext File Format |
39 | * |
40 | * ALL BINARY VALUES ARE BIG-ENDIAN. |
41 | *********************************************************************/ |
42 | #if PRAGMA_MARK |
43 | #pragma mark Constants |
44 | #endif |
45 | |
46 | #define MKEXT_MAGIC 0x4D4B5854 /* 'MKXT' */ |
47 | #define MKEXT_SIGN 0x4D4F5358 /* 'MOSX' */ |
48 | |
49 | #define MKEXT_EXTN ".mkext" |
50 | |
51 | #define MKEXT_VERS_1 (0x01008000) |
52 | |
53 | // Used during development/bringup: v 2.0d1 |
54 | #define MKEXT_VERS_2 (0x02002001) |
55 | // xxx - Will use this when format is final |
56 | // #define MKEXT_VERS_2 (0x02008000) |
57 | |
58 | #if PRAGMA_MARK |
59 | #pragma mark Core Header |
60 | #endif |
61 | /********************************************************************* |
62 | * Core Header |
63 | * |
64 | * All versions of mkext files have this basic header: |
65 | * |
66 | * - magic & signature - always 'MKXT' and 'MOSX' as defined above. |
67 | * - length - the length of the whole file |
68 | * - adler32 - checksum from &version to end of file |
69 | * - version - a 'vers' style value |
70 | * - numkexts - how many kexts are in the archive (only needed in v.1) |
71 | * - cputype & cpusubtype - in version 1 could be CPU_TYPE_ANY |
72 | * and CPU_SUBTYPE_MULTIPLE if the archive contained fat kexts; |
73 | * version 2 does not allow this and all kexts must be of a single |
74 | * arch. For either version, mkexts of specific arches can be |
75 | * embedded in a fat Mach-O file to combine them. |
76 | *********************************************************************/ |
77 | |
78 | #define \ |
79 | uint32_t ; \ |
80 | uint32_t ; \ |
81 | uint32_t ; \ |
82 | uint32_t ; \ |
83 | uint32_t ; \ |
84 | uint32_t ; \ |
85 | cpu_type_t ; \ |
86 | cpu_subtype_t ; |
87 | |
88 | typedef struct { |
89 | MKEXT_HEADER_CORE |
90 | } ; |
91 | |
92 | #define MKEXT_HDR_CAST(hdr) ((mkext_basic_header *)(hdr)) |
93 | |
94 | #define MKEXT_SWAP(num) OSSwapBigToHostInt32((uint32_t)(num)) |
95 | |
96 | #define MKEXT_GET_MAGIC(hdr) (MKEXT_SWAP(MKEXT_HDR_CAST(hdr)->magic)) |
97 | #define MKEXT_GET_SIGNATURE(hdr) (MKEXT_SWAP(MKEXT_HDR_CAST(hdr)->signature)) |
98 | #define MKEXT_GET_LENGTH(hdr) (MKEXT_SWAP(MKEXT_HDR_CAST(hdr)->length)) |
99 | #define MKEXT_GET_CHECKSUM(hdr) (MKEXT_SWAP(MKEXT_HDR_CAST(hdr)->adler32)) |
100 | #define MKEXT_GET_VERSION(hdr) (MKEXT_SWAP(MKEXT_HDR_CAST(hdr)->version)) |
101 | #define MKEXT_GET_COUNT(hdr) (MKEXT_SWAP(MKEXT_HDR_CAST(hdr)->numkexts)) |
102 | #define MKEXT_GET_CPUTYPE(hdr) (MKEXT_SWAP(MKEXT_HDR_CAST(hdr)->cputype)) |
103 | #define MKEXT_GET_CPUSUBTYPE(hdr) (MKEXT_SWAP(MKEXT_HDR_CAST(hdr)->cpusubtype)) |
104 | |
105 | #if PRAGMA_MARK |
106 | #pragma mark Mkext Version 2 Format Definitions |
107 | #endif |
108 | /********************************************************************* |
109 | * Mkext Version 2 Format Definitions |
110 | * |
111 | * The version field here will be some variant of 0x0200....; that is |
112 | * the major version byte will be 0x02. |
113 | * |
114 | * Version 2 uses zlib for compression, not the lzss compressor used |
115 | * by version 1. |
116 | * |
117 | * In version 2, all executable & resource files are stored in sequence |
118 | * followed by the combined info dictionaries of all kexts at the end. |
119 | * This XML plist should be nul-terminated and stored at a page-aligned |
120 | * offset in the file so that kernel code can unmap it as soon as it's |
121 | * parsed. |
122 | * |
123 | * The info dict for each kext will have inserted into it these |
124 | * additional properties: |
125 | * |
126 | * - _MKEXTBundlePath (string) - full path to the original bundle, |
127 | * relative to volume. |
128 | * - _MKEXTExecutable (integer) - offset to the executable entry. |
129 | * - _MKEXTResources (dict) - keyed by filename, values integer offsets |
130 | * to file entries. |
131 | * |
132 | * Mkext2 buffers are used to send load requests to the kernel. When |
133 | * this is done, the plist will contain an _MKEXTLoadRequest dictionary |
134 | * whose keys are the bundle IDs to load, and whose values are |
135 | * dictionaries of flags: |
136 | * |
137 | * - "Load Kext" - boolean, whether to load the kext or not (default true). |
138 | * May be used to send just personalities for already-loaded kexts, |
139 | * but we do have a mechanism to do that from userland already. |
140 | * - "Start Kext" - boolean, whether to start the kext or not |
141 | * (used when debugging). Defaults to true. |
142 | * - "Add Personalities" - boolean, whether to send personalities to |
143 | * the IOCatalogue (used when debugging). Defaults to true. |
144 | * - "Disable Autounload" - boolean, whether to prevent the reaper |
145 | * thread from unloading the kext, so the dev. has time to set up |
146 | * the debug session. (Predefined window, or maybe this will be a |
147 | * number of seconds to wait.) Defaults to false. |
148 | *********************************************************************/ |
149 | #define kMKEXTInfoDictionariesKey "_MKEXTInfoDictionaries" |
150 | |
151 | #define kMKEXTBundlePathKey "_MKEXTBundlePath" |
152 | #define kMKEXTExecutableRelativePathKey "_MKEXTExecutableRelativePath" |
153 | #define kMKEXTExecutableKey "_MKEXTExecutable" |
154 | |
155 | #define kMKEXTLoadRequestKey "_MKEXTLoadRequest" |
156 | #define kMKEXTLoadRequestLoadKey "Load Kext" |
157 | #define kMKEXTLoadRequestStartKey "Start Kext" |
158 | #define kMKEXTLoadRequestAddPersonalitiesKey "Add Personalities" |
159 | #define kMKEXTLoadRequestDisableAutounloadKey "Disable Autounload" |
160 | |
161 | typedef struct mkext2_file_entry { |
162 | uint32_t compressed_size; // if zero, file is not compressed |
163 | uint32_t full_size; // full size of data w/o this struct |
164 | uint8_t data[0]; // data is inline to this struct |
165 | } mkext2_file_entry; |
166 | |
167 | typedef struct { |
168 | MKEXT_HEADER_CORE |
169 | uint32_t ; |
170 | uint32_t ; |
171 | uint32_t ; |
172 | } ; |
173 | |
174 | #define MKEXT2_GET_ENTRY_COMPSIZE(ptr) MKEXT_SWAP((ptr)->compressed_size) |
175 | #define MKEXT2_GET_ENTRY_FULLSIZE(ptr) MKEXT_SWAP((ptr)->full_size) |
176 | #define MKEXT2_GET_ENTRY_DATA(ptr) ((ptr)->data) |
177 | |
178 | #define MKEXT2_HDR_CAST(hdr) ((mkext2_header *)(hdr)) |
179 | #define MKEXT2_GET_PLIST(hdr) MKEXT_SWAP(MKEXT2_HDR_CAST(hdr)->plist_offset) |
180 | #define MKEXT2_GET_PLIST_COMPSIZE(hdr) MKEXT_SWAP(MKEXT2_HDR_CAST(hdr)->plist_compressed_size) |
181 | #define MKEXT2_GET_PLIST_FULLSIZE(hdr) MKEXT_SWAP(MKEXT2_HDR_CAST(hdr)->plist_full_size) |
182 | |
183 | #if PRAGMA_MARK |
184 | #pragma mark Mkext Version 1 Format Definitions |
185 | #endif |
186 | /********************************************************************* |
187 | * Mkext Version 1 Format Definitions |
188 | * |
189 | * The original mkext format has version 0x01008000 ("1.0"). |
190 | * |
191 | * In version 1, plists were not nul-terminated, so it's up to the |
192 | * reader to add that '\0' on the end if it's needed. |
193 | * |
194 | * Original bad names preserved for source compatibility. |
195 | *********************************************************************/ |
196 | |
197 | // If all fields are 0 then this file slot is empty |
198 | // If compsize is zero then the file isn't compressed. |
199 | typedef struct mkext_file { |
200 | uint32_t offset; // 4 bytes |
201 | uint32_t compsize; // 4 bytes |
202 | uint32_t realsize; // 4 bytes |
203 | uint32_t modifiedsecs; // 4 bytes; cast to time_t to use |
204 | } mkext_file; |
205 | |
206 | // The plist file entry is mandatory, but module may be empty |
207 | typedef struct mkext_kext { |
208 | mkext_file plist; // 16 bytes |
209 | mkext_file module; // 16 bytes |
210 | } mkext_kext; |
211 | |
212 | typedef struct { |
213 | MKEXT_HEADER_CORE |
214 | mkext_kext [1]; // 32 bytes/entry |
215 | } ; |
216 | |
217 | typedef mkext_header ; |
218 | |
219 | #define MKEXT1_ENTRY_CAST(ptr) ((mkext_file *)(ptr)) |
220 | #define MKEXT1_GET_ENTRY_OFFSET(ptr) (MKEXT_SWAP(MKEXT1_ENTRY_CAST(ptr)->offset)) |
221 | #define MKEXT1_GET_ENTRY_COMPSIZE(ptr) (MKEXT_SWAP(MKEXT1_ENTRY_CAST(ptr)->compsize)) |
222 | #define MKEXT1_GET_ENTRY_FULLSIZE(ptr) (MKEXT_SWAP(MKEXT1_ENTRY_CAST(ptr)->realsize)) |
223 | #define MKEXT1_GET_ENTRY_MODTIME(ptr) ((time_t)MKEXT_SWAP(MKEXT1_ENTRY_CAST(ptr)->modifiedsecs)) |
224 | #define MKEXT1_ENTRY_EXISTS(ptr) (MKEXT1_GET_ENTRY_OFFSET(ptr) || \ |
225 | MKEXT1_GET_ENTRY_FULLSIZE(ptr) || \ |
226 | MKEXT_GET_ENTRY_COMPSIZE(ptr) || \ |
227 | MKEXT_GET_ENTRY_COMPSIZE(ptr)) |
228 | |
229 | #define MKEXT1_GET_KEXT(hdr, i) ((mkext_kext *)&(MKEXT1_HDR_CAST(hdr)->kext[(i)])) |
230 | #define MKEXT1_GET_KEXT_PLIST(hdr, i) (MKEXT1_ENTRY_CAST(&(MKEXT1_GET_KEXT((hdr), (i))->plist))) |
231 | #define MKEXT1_GET_KEXT_EXEC(hdr, i) (MKEXT1_ENTRY_CAST(&(MKEXT1_GET_KEXT((hdr), (i))->module) |
232 | |
233 | #define MKEXT1_HDR_CAST(hdr) ((mkext1_header *)(hdr)) |
234 | |
235 | /* These functions are only used for version 1 mkexts. |
236 | */ |
237 | __BEGIN_DECLS |
238 | u_int8_t * |
239 | compress_lzss(u_int8_t * dst, u_int32_t dstlen, |
240 | u_int8_t * src, u_int32_t srclen); |
241 | |
242 | int |
243 | decompress_lzss(u_int8_t * dst, u_int32_t dstlen, |
244 | u_int8_t * src, u_int32_t srclen); |
245 | |
246 | u_int32_t |
247 | mkext_adler32(u_int8_t * src, int32_t length); |
248 | __END_DECLS |
249 | |
250 | #endif /* _MKEXT_H_ */ |
251 | |