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 88typedef 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 161typedef 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 167typedef 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. 199typedef 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 207typedef struct mkext_kext { 208 mkext_file plist; // 16 bytes 209 mkext_file module; // 16 bytes 210} mkext_kext; 211 212typedef struct mkext_header { 213 MKEXT_HEADER_CORE 214 mkext_kext kext[1]; // 32 bytes/entry 215} mkext_header; 216 217typedef 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 238u_int8_t * 239compress_lzss(u_int8_t * dst, u_int32_t dstlen, 240 u_int8_t * src, u_int32_t srclen); 241 242int 243decompress_lzss(u_int8_t * dst, u_int32_t dstlen, 244 u_int8_t * src, u_int32_t srclen); 245 246u_int32_t 247mkext_adler32(u_int8_t * src, int32_t length); 248__END_DECLS 249 250#endif /* _MKEXT_H_ */ 251