1 /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-
3 * Copyright (c) 2006-2015 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@
24 #ifndef __DYLD_CACHE_FORMAT__
25 #define __DYLD_CACHE_FORMAT__
28 #include <uuid/uuid.h>
31 struct dyld_cache_header
33 char magic
[16]; // e.g. "dyld_v0 i386"
34 uint32_t mappingOffset
; // file offset to first dyld_cache_mapping_info
35 uint32_t mappingCount
; // number of dyld_cache_mapping_info entries
36 uint32_t imagesOffset
; // file offset to first dyld_cache_image_info
37 uint32_t imagesCount
; // number of dyld_cache_image_info entries
38 uint64_t dyldBaseAddress
; // base address of dyld when cache was built
39 uint64_t codeSignatureOffset
; // file offset of code signature blob
40 uint64_t codeSignatureSize
; // size of code signature blob (zero means to end of file)
41 uint64_t slideInfoOffset
; // file offset of kernel slid info
42 uint64_t slideInfoSize
; // size of kernel slid info
43 uint64_t localSymbolsOffset
; // file offset of where local symbols are stored
44 uint64_t localSymbolsSize
; // size of local symbols information
45 uint8_t uuid
[16]; // unique value for each shared cache file
46 uint64_t cacheType
; // 0 for development, 1 for production
47 uint32_t branchPoolsOffset
; // file offset to table of uint64_t pool addresses
48 uint32_t branchPoolsCount
; // number of uint64_t entries
49 uint64_t accelerateInfoAddr
; // (unslid) address of optimization info
50 uint64_t accelerateInfoSize
; // size of optimization info
51 uint64_t imagesTextOffset
; // file offset to first dyld_cache_image_text_info
52 uint64_t imagesTextCount
; // number of dyld_cache_image_text_info entries
53 uint64_t patchInfoAddr
; // (unslid) address of dyld_cache_patch_info
54 uint64_t patchInfoSize
; // Size of all of the patch information pointed to via the dyld_cache_patch_info
55 uint64_t otherImageGroupAddrUnused
; // unused
56 uint64_t otherImageGroupSizeUnused
; // unused
57 uint64_t progClosuresAddr
; // (unslid) address of list of program launch closures
58 uint64_t progClosuresSize
; // size of list of program launch closures
59 uint64_t progClosuresTrieAddr
; // (unslid) address of trie of indexes into program launch closures
60 uint64_t progClosuresTrieSize
; // size of trie of indexes into program launch closures
61 uint32_t platform
; // platform number (macOS=1, etc)
62 uint32_t formatVersion
: 8, // dyld3::closure::kFormatVersion
63 dylibsExpectedOnDisk
: 1, // dyld should expect the dylib exists on disk and to compare inode/mtime to see if cache is valid
64 simulator
: 1, // for simulator of specified platform
65 locallyBuiltCache
: 1, // 0 for B&I built cache, 1 for locally built cache
66 builtFromChainedFixups
: 1, // some dylib in cache was built using chained fixups, so patch tables must be used for overrides
68 uint64_t sharedRegionStart
; // base load address of cache if not slid
69 uint64_t sharedRegionSize
; // overall size of region cache can be mapped into
70 uint64_t maxSlide
; // runtime slide of cache can be between zero and this value
71 uint64_t dylibsImageArrayAddr
; // (unslid) address of ImageArray for dylibs in this cache
72 uint64_t dylibsImageArraySize
; // size of ImageArray for dylibs in this cache
73 uint64_t dylibsTrieAddr
; // (unslid) address of trie of indexes of all cached dylibs
74 uint64_t dylibsTrieSize
; // size of trie of cached dylib paths
75 uint64_t otherImageArrayAddr
; // (unslid) address of ImageArray for dylibs and bundles with dlopen closures
76 uint64_t otherImageArraySize
; // size of ImageArray for dylibs and bundles with dlopen closures
77 uint64_t otherTrieAddr
; // (unslid) address of trie of indexes of all dylibs and bundles with dlopen closures
78 uint64_t otherTrieSize
; // size of trie of dylibs and bundles with dlopen closures
81 // Uncomment this and check the build errors for the current mapping offset to check against when adding new fields.
82 // template<size_t size> class A { int x[-size]; }; A<sizeof(dyld_cache_header)> a;
85 struct dyld_cache_mapping_info
{
93 struct dyld_cache_image_info
98 uint32_t pathFileOffset
;
102 struct dyld_cache_image_info_extra
104 uint64_t exportsTrieAddr
; // address of trie in unslid cache
105 uint64_t weakBindingsAddr
;
106 uint32_t exportsTrieSize
;
107 uint32_t weakBindingsSize
;
108 uint32_t dependentsStartArrayIndex
;
109 uint32_t reExportsStartArrayIndex
;
113 struct dyld_cache_accelerator_info
115 uint32_t version
; // currently 1
116 uint32_t imageExtrasCount
; // does not include aliases
117 uint32_t imagesExtrasOffset
; // offset into this chunk of first dyld_cache_image_info_extra
118 uint32_t bottomUpListOffset
; // offset into this chunk to start of 16-bit array of sorted image indexes
119 uint32_t dylibTrieOffset
; // offset into this chunk to start of trie containing all dylib paths
120 uint32_t dylibTrieSize
; // size of trie containing all dylib paths
121 uint32_t initializersOffset
; // offset into this chunk to start of initializers list
122 uint32_t initializersCount
; // size of initializers list
123 uint32_t dofSectionsOffset
; // offset into this chunk to start of DOF sections list
124 uint32_t dofSectionsCount
; // size of initializers list
125 uint32_t reExportListOffset
; // offset into this chunk to start of 16-bit array of re-exports
126 uint32_t reExportCount
; // size of re-exports
127 uint32_t depListOffset
; // offset into this chunk to start of 16-bit array of dependencies (0x8000 bit set if upward)
128 uint32_t depListCount
; // size of dependencies
129 uint32_t rangeTableOffset
; // offset into this chunk to start of ss
130 uint32_t rangeTableCount
; // size of dependencies
131 uint64_t dyldSectionAddr
; // address of libdyld's __dyld section in unslid cache
134 struct dyld_cache_accelerator_initializer
136 uint32_t functionOffset
; // address offset from start of cache mapping
140 struct dyld_cache_range_entry
142 uint64_t startAddress
; // unslid address of start of region
147 struct dyld_cache_accelerator_dof
149 uint64_t sectionAddress
; // unslid address of start of region
150 uint32_t sectionSize
;
154 struct dyld_cache_image_text_info
157 uint64_t loadAddress
; // unslid address of start of __TEXT
158 uint32_t textSegmentSize
;
159 uint32_t pathOffset
; // offset from start of cache file
163 // The rebasing info is to allow the kernel to lazily rebase DATA pages of the
164 // dyld shared cache. Rebasing is adding the slide to interior pointers.
165 struct dyld_cache_slide_info
167 uint32_t version
; // currently 1
170 uint32_t entries_offset
;
171 uint32_t entries_count
;
172 uint32_t entries_size
; // currently 128
173 // uint16_t toc[toc_count];
174 // entrybitmap entries[entries_count];
177 struct dyld_cache_slide_info_entry
{
178 uint8_t bits
[4096/(8*4)]; // 128-byte bitmap
182 // The version 2 of the slide info uses a different compression scheme. Since
183 // only interior pointers (pointers that point within the cache) are rebased
184 // (slid), we know the possible range of the pointers and thus know there are
185 // unused bits in each pointer. We use those bits to form a linked list of
186 // locations needing rebasing in each page.
190 // pageIndex = (pageAddress - startOfAllDataAddress)/info->page_size
191 // pageStarts[] = info + info->page_starts_offset
192 // pageExtras[] = info + info->page_extras_offset
193 // valueMask = ~(info->delta_mask)
194 // deltaShift = __builtin_ctzll(info->delta_mask) - 2
196 // There are three cases:
198 // 1) pageStarts[pageIndex] == DYLD_CACHE_SLIDE_PAGE_ATTR_NO_REBASE
199 // The page contains no values that need rebasing.
201 // 2) (pageStarts[pageIndex] & DYLD_CACHE_SLIDE_PAGE_ATTR_EXTRA) == 0
202 // All rebase locations are in one linked list. The offset of the first
203 // rebase location in the page is pageStarts[pageIndex] * 4.
205 // 3) pageStarts[pageIndex] & DYLD_CACHE_SLIDE_PAGE_ATTR_EXTRA
206 // Multiple linked lists are needed for all rebase locations in a page.
207 // The pagesExtras array contains 2 or more entries each of which is the
208 // start of a new linked list in the page. The first is at:
209 // extrasStartIndex = (pageStarts[pageIndex] & 0x3FFF)
210 // The next is at extrasStartIndex+1. The last is denoted by
211 // having the high bit (DYLD_CACHE_SLIDE_PAGE_ATTR_END) of the pageExtras[]
214 // For 64-bit architectures, there is always enough free bits to encode all
215 // possible deltas. The info->delta_mask field shows where the delta is located
216 // in the pointer. That value must be masked off (valueMask) before the slide
217 // is added to the pointer.
219 // For 32-bit architectures, there are only three bits free (the three most
220 // significant bits). To extract the delta, you must first subtract value_add
221 // from the pointer value, then AND with delta_mask, then shift by deltaShift.
222 // That still leaves a maximum delta to the next rebase location of 28 bytes.
223 // To reduce the number or chains needed, an optimization was added. Turns
224 // out zero is common in the DATA region. A zero can be turned into a
225 // non-rebasing entry in the linked list. The can be done because nothing
226 // in the shared cache should point out of its dylib to the start of the shared
229 // The code for processing a linked list (chain) is:
231 // uint32_t delta = 1;
232 // while ( delta != 0 ) {
233 // uint8_t* loc = pageStart + pageOffset;
234 // uintptr_t rawValue = *((uintptr_t*)loc);
235 // delta = ((rawValue & deltaMask) >> deltaShift);
236 // uintptr_t newValue = (rawValue & valueMask);
237 // if ( newValue != 0 ) {
238 // newValue += valueAdd;
239 // newValue += slideAmount;
241 // *((uintptr_t*)loc) = newValue;
242 // pageOffset += delta;
246 struct dyld_cache_slide_info2
248 uint32_t version
; // currently 2
249 uint32_t page_size
; // currently 4096 (may also be 16384)
250 uint32_t page_starts_offset
;
251 uint32_t page_starts_count
;
252 uint32_t page_extras_offset
;
253 uint32_t page_extras_count
;
254 uint64_t delta_mask
; // which (contiguous) set of bits contains the delta to the next rebase location
256 //uint16_t page_starts[page_starts_count];
257 //uint16_t page_extras[page_extras_count];
259 #define DYLD_CACHE_SLIDE_PAGE_ATTRS 0xC000 // high bits of uint16_t are flags
260 #define DYLD_CACHE_SLIDE_PAGE_ATTR_EXTRA 0x8000 // index is into extras array (not starts array)
261 #define DYLD_CACHE_SLIDE_PAGE_ATTR_NO_REBASE 0x4000 // page has no rebasing
262 #define DYLD_CACHE_SLIDE_PAGE_ATTR_END 0x8000 // last chain entry for page
266 // The version 3 of the slide info uses a different compression scheme. Since
267 // only interior pointers (pointers that point within the cache) are rebased
268 // (slid), we know the possible range of the pointers and thus know there are
269 // unused bits in each pointer. We use those bits to form a linked list of
270 // locations needing rebasing in each page.
274 // pageIndex = (pageAddress - startOfAllDataAddress)/info->page_size
275 // pageStarts[] = info + info->page_starts_offset
277 // There are two cases:
279 // 1) pageStarts[pageIndex] == DYLD_CACHE_SLIDE_V3_PAGE_ATTR_NO_REBASE
280 // The page contains no values that need rebasing.
283 // All rebase locations are in one linked list. The offset of the first
284 // rebase location in the page is pageStarts[pageIndex].
286 // A pointer is one of of the variants in dyld_cache_slide_pointer3
288 // The code for processing a linked list (chain) is:
290 // uint32_t delta = pageStarts[pageIndex];
291 // dyld_cache_slide_pointer3* loc = pageStart;
294 // delta = loc->offsetToNextPointer;
295 // if ( loc->auth.authenticated ) {
296 // newValue = loc->offsetFromSharedCacheBase + results->slide + auth_value_add;
297 // newValue = sign_using_the_various_bits(newValue);
300 // uint64_t value51 = loc->pointerValue;
301 // uint64_t top8Bits = value51 & 0x0007F80000000000ULL;
302 // uint64_t bottom43Bits = value51 & 0x000007FFFFFFFFFFULL;
303 // uint64_t targetValue = ( top8Bits << 13 ) | bottom43Bits;
304 // newValue = targetValue + results->slide;
306 // loc->raw = newValue;
307 // } while (delta != 0);
310 struct dyld_cache_slide_info3
312 uint32_t version
; // currently 3
313 uint32_t page_size
; // currently 4096 (may also be 16384)
314 uint32_t page_starts_count
;
315 uint64_t auth_value_add
;
316 uint16_t page_starts
[/* page_starts_count */];
319 #define DYLD_CACHE_SLIDE_V3_PAGE_ATTR_NO_REBASE 0xFFFF // page has no rebasing
321 union dyld_cache_slide_pointer3
325 uint64_t pointerValue
: 51,
326 offsetToNextPointer
: 11,
331 uint64_t offsetFromSharedCacheBase
: 32,
333 hasAddressDiversity
: 1,
335 offsetToNextPointer
: 11,
337 authenticated
: 1; // = 1;
343 // The version 4 of the slide info is optimized for 32-bit caches up to 1GB.
344 // Since only interior pointers (pointers that point within the cache) are rebased
345 // (slid), we know the possible range of the pointers takes 30 bits. That
346 // gives us two bits to use to chain to the next rebase.
350 // pageIndex = (pageAddress - startOfAllDataAddress)/info->page_size
351 // pageStarts[] = info + info->page_starts_offset
352 // pageExtras[] = info + info->page_extras_offset
353 // valueMask = ~(info->delta_mask)
354 // deltaShift = __builtin_ctzll(info->delta_mask) - 2
356 // There are three cases:
358 // 1) pageStarts[pageIndex] == DYLD_CACHE_SLIDE4_PAGE_NO_REBASE
359 // The page contains no values that need rebasing.
361 // 2) (pageStarts[pageIndex] & DYLD_CACHE_SLIDE4_PAGE_USE_EXTRA) == 0
362 // All rebase locations are in one linked list. The offset of the first
363 // rebase location in the page is pageStarts[pageIndex] * 4.
365 // 3) pageStarts[pageIndex] & DYLD_CACHE_SLIDE4_PAGE_USE_EXTRA
366 // Multiple chains are needed for all rebase locations in a page.
367 // The pagesExtras array contains 2 or more entries each of which is the
368 // start of a new chain in the page. The first is at:
369 // extrasStartIndex = (pageStarts[pageIndex] & DYLD_CACHE_SLIDE4_PAGE_INDEX)
370 // The next is at extrasStartIndex+1. The last is denoted by
371 // having the high bit (DYLD_CACHE_SLIDE4_PAGE_EXTRA_END) of the pageExtras[].
373 // For 32-bit architectures, there are only two bits free (the two most
374 // significant bits). To extract the delta, you must first subtract value_add
375 // from the pointer value, then AND with delta_mask, then shift by deltaShift.
376 // That still leaves a maximum delta to the next rebase location of 12 bytes.
377 // To reduce the number or chains needed, an optimization was added. Turns
378 // most of the non-rebased data are small values and can be co-opt'ed into
379 // being used in the chain. The can be done because nothing
380 // in the shared cache should point to the first 64KB which are in the shared
381 // cache header information. So if the resulting pointer points to the
382 // start of the cache +/-32KB, then it is actually a small number that should
383 // not be rebased, but just reconstituted.
385 // The code for processing a linked list (chain) is:
387 // uint32_t delta = 1;
388 // while ( delta != 0 ) {
389 // uint8_t* loc = pageStart + pageOffset;
390 // uint32_t rawValue = *((uint32_t*)loc);
391 // delta = ((rawValue & deltaMask) >> deltaShift);
392 // uintptr_t newValue = (rawValue & valueMask);
393 // if ( (newValue & 0xFFFF8000) == 0 ) {
394 // // small positive non-pointer, use as-is
396 // else if ( (newValue & 0x3FFF8000) == 0x3FFF8000 ) {
397 // // small negative non-pointer
398 // newValue |= 0xC0000000;
401 // // pointer that needs rebasing
402 // newValue += valueAdd;
403 // newValue += slideAmount;
405 // *((uint32_t*)loc) = newValue;
406 // pageOffset += delta;
410 struct dyld_cache_slide_info4
412 uint32_t version
; // currently 4
413 uint32_t page_size
; // currently 4096 (may also be 16384)
414 uint32_t page_starts_offset
;
415 uint32_t page_starts_count
;
416 uint32_t page_extras_offset
;
417 uint32_t page_extras_count
;
418 uint64_t delta_mask
; // which (contiguous) set of bits contains the delta to the next rebase location (0xC0000000)
419 uint64_t value_add
; // base address of cache
420 //uint16_t page_starts[page_starts_count];
421 //uint16_t page_extras[page_extras_count];
423 #define DYLD_CACHE_SLIDE4_PAGE_NO_REBASE 0xFFFF // page has no rebasing
424 #define DYLD_CACHE_SLIDE4_PAGE_INDEX 0x7FFF // mask of page_starts[] values
425 #define DYLD_CACHE_SLIDE4_PAGE_USE_EXTRA 0x8000 // index is into extras array (not a chain start offset)
426 #define DYLD_CACHE_SLIDE4_PAGE_EXTRA_END 0x8000 // last chain entry for page
431 struct dyld_cache_local_symbols_info
433 uint32_t nlistOffset
; // offset into this chunk of nlist entries
434 uint32_t nlistCount
; // count of nlist entries
435 uint32_t stringsOffset
; // offset into this chunk of string pool
436 uint32_t stringsSize
; // byte count of string pool
437 uint32_t entriesOffset
; // offset into this chunk of array of dyld_cache_local_symbols_entry
438 uint32_t entriesCount
; // number of elements in dyld_cache_local_symbols_entry array
441 struct dyld_cache_local_symbols_entry
443 uint32_t dylibOffset
; // offset in cache file of start of dylib
444 uint32_t nlistStartIndex
; // start index of locals for this dylib
445 uint32_t nlistCount
; // number of local symbols for this dylib
448 struct dyld_cache_patch_info
450 uint64_t patchTableArrayAddr
; // (unslid) address of array for dyld_cache_image_patches for each image
451 uint64_t patchTableArrayCount
; // count of patch table entries
452 uint64_t patchExportArrayAddr
; // (unslid) address of array for patch exports for each image
453 uint64_t patchExportArrayCount
; // count of patch exports entries
454 uint64_t patchLocationArrayAddr
; // (unslid) address of array for patch locations for each patch
455 uint64_t patchLocationArrayCount
;// count of patch location entries
456 uint64_t patchExportNamesAddr
; // blob of strings of export names for patches
457 uint64_t patchExportNamesSize
; // size of string blob of export names for patches
460 struct dyld_cache_image_patches
462 uint32_t patchExportsStartIndex
;
463 uint32_t patchExportsCount
;
466 struct dyld_cache_patchable_export
468 uint32_t cacheOffsetOfImpl
;
469 uint32_t patchLocationsStartIndex
;
470 uint32_t patchLocationsCount
;
471 uint32_t exportNameOffset
;
474 struct dyld_cache_patchable_location
476 uint64_t cacheOffset
: 32,
477 addend
: 12, // +/- 2048
479 usesAddressDiversity
: 1,
486 #define MACOSX_DYLD_SHARED_CACHE_DIR "/private/var/db/dyld/"
487 #define IPHONE_DYLD_SHARED_CACHE_DIR "/System/Library/Caches/com.apple.dyld/"
488 #if !TARGET_OS_SIMULATOR
489 #define DYLD_SHARED_CACHE_BASE_NAME "dyld_shared_cache_"
491 #define DYLD_SHARED_CACHE_BASE_NAME "dyld_sim_shared_cache_"
493 #define DYLD_SHARED_CACHE_DEVELOPMENT_EXT ".development"
495 static const uint64_t kDyldSharedCacheTypeDevelopment
= 0;
496 static const uint64_t kDyldSharedCacheTypeProduction
= 1;
501 #endif // __DYLD_CACHE_FORMAT__