1 /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*- 
   3  * Copyright (c) 2018 Apple Inc. All rights reserved. 
   5  * @APPLE_LICENSE_HEADER_START@ 
   7  * This file contains Original Code and/or Modifications of Original Code 
   8  * as defined in and that are subject to the Apple Public Source License 
   9  * Version 2.0 (the 'License'). You may not use this file except in 
  10  * compliance with the License. Please obtain a copy of the License at 
  11  * http://www.opensource.apple.com/apsl/ and read it before using this 
  14  * The Original Code and all software distributed under the License are 
  15  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  16  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  17  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 
  18  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  19  * Please see the License for the specific language governing rights and 
  20  * limitations under the License. 
  22  * @APPLE_LICENSE_HEADER_END@ 
  25 #ifndef __MACH_O_FIXUP_CHAINS__ 
  26 #define __MACH_O_FIXUP_CHAINS__ 4 
  32 //#define LC_DYLD_EXPORTS_TRIE   0x80000033 // used with linkedit_data_command 
  33 //#define LC_DYLD_CHAINED_FIXUPS 0x80000034 // used with linkedit_data_command, payload is dyld_chained_fixups_header 
  36 // header of the LC_DYLD_CHAINED_FIXUPS payload 
  37 struct dyld_chained_fixups_header
 
  39     uint32_t    fixups_version
;    // 0 
  40     uint32_t    starts_offset
;     // offset of dyld_chained_starts_in_image in chain_data 
  41     uint32_t    imports_offset
;    // offset of imports table in chain_data 
  42     uint32_t    symbols_offset
;    // offset of symbol strings in chain_data 
  43     uint32_t    imports_count
;     // number of imported symbol names 
  44     uint32_t    imports_format
;    // DYLD_CHAINED_IMPORT* 
  45     uint32_t    symbols_format
;    // 0 => uncompressed, 1 => zlib compressed 
  48 // This struct is embedded in LC_DYLD_CHAINED_FIXUPS payload 
  49 struct dyld_chained_starts_in_image
 
  52     uint32_t    seg_info_offset
[1];  // each entry is offset into this struct for that segment 
  53     // followed by pool of dyld_chain_starts_in_segment data 
  56 // This struct is embedded in dyld_chain_starts_in_image 
  57 // and passed down to the kernel for page-in linking 
  58 struct dyld_chained_starts_in_segment
 
  60     uint32_t    size
;               // size of this (amount kernel needs to copy) 
  61     uint16_t    page_size
;          // 0x1000 or 0x4000 
  62     uint16_t    pointer_format
;     // DYLD_CHAINED_PTR_* 
  63     uint64_t    segment_offset
;     // offset in memory to start of segment 
  64     uint32_t    max_valid_pointer
;  // for 32-bit OS, any value beyond this is not a pointer 
  65     uint16_t    page_count
;         // how many pages are in array 
  66     uint16_t    page_start
[1];      // each entry is offset in each page of first element in chain 
  67                                     // or DYLD_CHAINED_PTR_START_NONE if no fixups on page 
  68  // uint16_t    chain_starts[1];    // some 32-bit formats may require multiple starts per page. 
  69                                     // for those, if high bit is set in page_starts[], then it 
  70                                     // is index into chain_starts[] which is a list of starts 
  71                                     // the last of which has the high bit set 
  75     DYLD_CHAINED_PTR_START_NONE   
= 0xFFFF, // used in page_start[] to denote a page with no fixups 
  76     DYLD_CHAINED_PTR_START_MULTI  
= 0x8000, // used in page_start[] to denote a page which has multiple starts 
  77     DYLD_CHAINED_PTR_START_LAST   
= 0x8000, // used in chain_starts[] to denote last start in list for page 
  80 // This struct is embedded in __TEXT,__chain_starts section in firmware 
  81 struct dyld_chained_starts_offsets
 
  83     uint32_t    pointer_format
;     // DYLD_CHAINED_PTR_32_FIRMWARE 
  84     uint32_t    starts_count
;       // number of starts in array 
  85     uint32_t    chain_starts
[1];    // array chain start offsets 
  89 // values for dyld_chained_starts_in_segment.pointer_format 
  91     DYLD_CHAINED_PTR_ARM64E             
=  1,    // stride 8, unauth target is vmaddr 
  92     DYLD_CHAINED_PTR_64                 
=  2,    // target is vmaddr 
  93     DYLD_CHAINED_PTR_32                 
=  3, 
  94     DYLD_CHAINED_PTR_32_CACHE           
=  4, 
  95     DYLD_CHAINED_PTR_32_FIRMWARE        
=  5, 
  96     DYLD_CHAINED_PTR_64_OFFSET          
=  6,    // target is vm offset 
  97     DYLD_CHAINED_PTR_ARM64E_OFFSET      
=  7,    // old name 
  98     DYLD_CHAINED_PTR_ARM64E_KERNEL      
=  7,    // stride 4, unauth target is vm offset 
  99     DYLD_CHAINED_PTR_64_KERNEL_CACHE    
=  8, 
 100     DYLD_CHAINED_PTR_ARM64E_USERLAND    
=  9,    // stride 8, unauth target is vm offset 
 101     DYLD_CHAINED_PTR_ARM64E_FIRMWARE    
= 10,    // stride 4, unauth target is vmaddr 
 105 // DYLD_CHAINED_PTR_ARM64E 
 106 struct dyld_chained_ptr_arm64e_rebase
 
 108     uint64_t    target   
: 43, 
 110                 next     
: 11,    // 4 or 8-byte stide 
 115 // DYLD_CHAINED_PTR_ARM64E 
 116 struct dyld_chained_ptr_arm64e_bind
 
 118     uint64_t    ordinal   
: 16, 
 120                 addend    
: 19,    // +/-256K 
 121                 next      
: 11,    // 4 or 8-byte stide 
 126 // DYLD_CHAINED_PTR_ARM64E 
 127 struct dyld_chained_ptr_arm64e_auth_rebase
 
 129     uint64_t    target    
: 32,   // runtimeOffset 
 133                 next      
: 11,    // 4 or 8-byte stide 
 138 // DYLD_CHAINED_PTR_ARM64E 
 139 struct dyld_chained_ptr_arm64e_auth_bind
 
 141     uint64_t    ordinal   
: 16, 
 146                 next      
: 11,    // 4 or 8-byte stide 
 151 // DYLD_CHAINED_PTR_64/DYLD_CHAINED_PTR_64_OFFSET 
 152 struct dyld_chained_ptr_64_rebase
 
 154     uint64_t    target    
: 36,    // 64GB max image size (DYLD_CHAINED_PTR_64 => vmAddr, DYLD_CHAINED_PTR_64_OFFSET => runtimeOffset) 
 155                 high8     
:  8,    // top 8 bits set to this (DYLD_CHAINED_PTR_64 => after slide added, DYLD_CHAINED_PTR_64_OFFSET => before slide added) 
 156                 reserved  
:  7,    // all zeros 
 157                 next      
: 12,    // 4-byte stride 
 161 // DYLD_CHAINED_PTR_64 
 162 struct dyld_chained_ptr_64_bind
 
 164     uint64_t    ordinal   
: 24, 
 165                 addend    
:  8,   // 0 thru 255 
 166                 reserved  
: 19,   // all zeros 
 167                 next      
: 12,   // 4-byte stride 
 171 // DYLD_CHAINED_PTR_64_KERNEL_CACHE 
 172 struct dyld_chained_ptr_64_kernel_cache_rebase
 
 174     uint64_t    target     
: 30,   // basePointers[cacheLevel] + target 
 175                 cacheLevel 
:  2,   // what level of cache to bind to (indexes a mach_header array) 
 179                 next       
: 12,    // 4-byte stide 
 180                 isAuth     
:  1;    // 0 -> not authenticated.  1 -> authenticated 
 183 // DYLD_CHAINED_PTR_32 
 184 // Note: for DYLD_CHAINED_PTR_32 some non-pointer values are co-opted into the chain 
 185 // as out of range rebases.  If an entry in the chain is > max_valid_pointer, then it 
 186 // is not a pointer.  To restore the value, subtract off the bias, which is 
 187 // (64MB+max_valid_pointer)/2. 
 188 struct dyld_chained_ptr_32_rebase
 
 190     uint32_t    target    
: 26,   // vmaddr, 64MB max image size 
 191                 next      
:  5,   // 4-byte stride 
 195 // DYLD_CHAINED_PTR_32 
 196 struct dyld_chained_ptr_32_bind
 
 198     uint32_t    ordinal   
: 20, 
 199                 addend    
:  6,   // 0 thru 63 
 200                 next      
:  5,   // 4-byte stride 
 204 // DYLD_CHAINED_PTR_32_CACHE 
 205 struct dyld_chained_ptr_32_cache_rebase
 
 207     uint32_t    target    
: 30,   // 1GB max dyld cache TEXT and DATA 
 208                 next      
:  2;   // 4-byte stride 
 212 // DYLD_CHAINED_PTR_32_FIRMWARE 
 213 struct dyld_chained_ptr_32_firmware_rebase
 
 215     uint32_t    target   
: 26,   // 64MB max firmware TEXT and DATA 
 216                 next     
:  6;   // 4-byte stride 
 221 // values for dyld_chained_fixups_header.imports_format 
 223     DYLD_CHAINED_IMPORT          
= 1, 
 224     DYLD_CHAINED_IMPORT_ADDEND   
= 2, 
 225     DYLD_CHAINED_IMPORT_ADDEND64 
= 3, 
 228 // DYLD_CHAINED_IMPORT 
 229 struct dyld_chained_import
 
 231     uint32_t    lib_ordinal 
:  8, 
 236 // DYLD_CHAINED_IMPORT_ADDEND 
 237 struct dyld_chained_import_addend
 
 239     uint32_t    lib_ordinal 
:  8, 
 245 // DYLD_CHAINED_IMPORT_ADDEND64 
 246 struct dyld_chained_import_addend64
 
 248     uint64_t    lib_ordinal 
: 16, 
 255 #endif // __MACH_O_FIXUP_CHAINS__