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 MKEXT_HEADER_CORE \ 79 uint32_t magic; \ 80 uint32_t signature; \ 81 uint32_t length; \ 82 uint32_t adler32; \ 83 uint32_t version; \ 84 uint32_t numkexts; \ 85 cpu_type_t cputype; \ 86 cpu_subtype_t cpusubtype; 87 88 typedef struct mkext_basic_header { 89 MKEXT_HEADER_CORE 90 } mkext_basic_header; 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 mkext2_header { 168 MKEXT_HEADER_CORE 169 uint32_t plist_offset; 170 uint32_t plist_compressed_size; 171 uint32_t plist_full_size; 172 } mkext2_header; 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 mkext_header { 213 MKEXT_HEADER_CORE 214 mkext_kext kext[1]; // 32 bytes/entry 215 } mkext_header; 216 217 typedef mkext_header mkext1_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