dyld-832.7.1.tar.gz
[apple/dyld.git] / dyld3 / shared-cache / dyld_cache_format.h
1 /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-
2 *
3 * Copyright (c) 2006-2015 Apple Inc. All rights reserved.
4 *
5 * @APPLE_LICENSE_HEADER_START@
6 *
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
12 * file.
13 *
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.
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24 #ifndef __DYLD_CACHE_FORMAT__
25 #define __DYLD_CACHE_FORMAT__
26
27 #include <stdint.h>
28 #include <uuid/uuid.h>
29
30
31 struct dyld_cache_header
32 {
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 slideInfoOffsetUnused; // unused. Used to be file offset of kernel slid info
42 uint64_t slideInfoSizeUnused; // unused. Used to be 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
67 padding : 20; // TBD
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
79 uint32_t mappingWithSlideOffset; // file offset to first dyld_cache_mapping_and_slide_info
80 uint32_t mappingWithSlideCount; // number of dyld_cache_mapping_and_slide_info entries
81 };
82
83 // Uncomment this and check the build errors for the current mapping offset to check against when adding new fields.
84 // template<size_t size> class A { int x[-size]; }; A<sizeof(dyld_cache_header)> a;
85
86
87 struct dyld_cache_mapping_info {
88 uint64_t address;
89 uint64_t size;
90 uint64_t fileOffset;
91 uint32_t maxProt;
92 uint32_t initProt;
93 };
94
95 // Contains the flags for the dyld_cache_mapping_and_slide_info flgs field
96 enum {
97 DYLD_CACHE_MAPPING_AUTH_DATA = 1 << 0U,
98 DYLD_CACHE_MAPPING_DIRTY_DATA = 1 << 1U,
99 DYLD_CACHE_MAPPING_CONST_DATA = 1 << 2U,
100 };
101
102 struct dyld_cache_mapping_and_slide_info {
103 uint64_t address;
104 uint64_t size;
105 uint64_t fileOffset;
106 uint64_t slideInfoFileOffset;
107 uint64_t slideInfoFileSize;
108 uint64_t flags;
109 uint32_t maxProt;
110 uint32_t initProt;
111 };
112
113 struct dyld_cache_image_info
114 {
115 uint64_t address;
116 uint64_t modTime;
117 uint64_t inode;
118 uint32_t pathFileOffset;
119 uint32_t pad;
120 };
121
122 struct dyld_cache_image_info_extra
123 {
124 uint64_t exportsTrieAddr; // address of trie in unslid cache
125 uint64_t weakBindingsAddr;
126 uint32_t exportsTrieSize;
127 uint32_t weakBindingsSize;
128 uint32_t dependentsStartArrayIndex;
129 uint32_t reExportsStartArrayIndex;
130 };
131
132
133 struct dyld_cache_accelerator_info
134 {
135 uint32_t version; // currently 1
136 uint32_t imageExtrasCount; // does not include aliases
137 uint32_t imagesExtrasOffset; // offset into this chunk of first dyld_cache_image_info_extra
138 uint32_t bottomUpListOffset; // offset into this chunk to start of 16-bit array of sorted image indexes
139 uint32_t dylibTrieOffset; // offset into this chunk to start of trie containing all dylib paths
140 uint32_t dylibTrieSize; // size of trie containing all dylib paths
141 uint32_t initializersOffset; // offset into this chunk to start of initializers list
142 uint32_t initializersCount; // size of initializers list
143 uint32_t dofSectionsOffset; // offset into this chunk to start of DOF sections list
144 uint32_t dofSectionsCount; // size of initializers list
145 uint32_t reExportListOffset; // offset into this chunk to start of 16-bit array of re-exports
146 uint32_t reExportCount; // size of re-exports
147 uint32_t depListOffset; // offset into this chunk to start of 16-bit array of dependencies (0x8000 bit set if upward)
148 uint32_t depListCount; // size of dependencies
149 uint32_t rangeTableOffset; // offset into this chunk to start of ss
150 uint32_t rangeTableCount; // size of dependencies
151 uint64_t dyldSectionAddr; // address of libdyld's __dyld section in unslid cache
152 };
153
154 struct dyld_cache_accelerator_initializer
155 {
156 uint32_t functionOffset; // address offset from start of cache mapping
157 uint32_t imageIndex;
158 };
159
160 struct dyld_cache_range_entry
161 {
162 uint64_t startAddress; // unslid address of start of region
163 uint32_t size;
164 uint32_t imageIndex;
165 };
166
167 struct dyld_cache_accelerator_dof
168 {
169 uint64_t sectionAddress; // unslid address of start of region
170 uint32_t sectionSize;
171 uint32_t imageIndex;
172 };
173
174 struct dyld_cache_image_text_info
175 {
176 uuid_t uuid;
177 uint64_t loadAddress; // unslid address of start of __TEXT
178 uint32_t textSegmentSize;
179 uint32_t pathOffset; // offset from start of cache file
180 };
181
182
183 // The rebasing info is to allow the kernel to lazily rebase DATA pages of the
184 // dyld shared cache. Rebasing is adding the slide to interior pointers.
185 struct dyld_cache_slide_info
186 {
187 uint32_t version; // currently 1
188 uint32_t toc_offset;
189 uint32_t toc_count;
190 uint32_t entries_offset;
191 uint32_t entries_count;
192 uint32_t entries_size; // currently 128
193 // uint16_t toc[toc_count];
194 // entrybitmap entries[entries_count];
195 };
196
197 struct dyld_cache_slide_info_entry {
198 uint8_t bits[4096/(8*4)]; // 128-byte bitmap
199 };
200
201
202 // The version 2 of the slide info uses a different compression scheme. Since
203 // only interior pointers (pointers that point within the cache) are rebased
204 // (slid), we know the possible range of the pointers and thus know there are
205 // unused bits in each pointer. We use those bits to form a linked list of
206 // locations needing rebasing in each page.
207 //
208 // Definitions:
209 //
210 // pageIndex = (pageAddress - startOfAllDataAddress)/info->page_size
211 // pageStarts[] = info + info->page_starts_offset
212 // pageExtras[] = info + info->page_extras_offset
213 // valueMask = ~(info->delta_mask)
214 // deltaShift = __builtin_ctzll(info->delta_mask) - 2
215 //
216 // There are three cases:
217 //
218 // 1) pageStarts[pageIndex] == DYLD_CACHE_SLIDE_PAGE_ATTR_NO_REBASE
219 // The page contains no values that need rebasing.
220 //
221 // 2) (pageStarts[pageIndex] & DYLD_CACHE_SLIDE_PAGE_ATTR_EXTRA) == 0
222 // All rebase locations are in one linked list. The offset of the first
223 // rebase location in the page is pageStarts[pageIndex] * 4.
224 //
225 // 3) pageStarts[pageIndex] & DYLD_CACHE_SLIDE_PAGE_ATTR_EXTRA
226 // Multiple linked lists are needed for all rebase locations in a page.
227 // The pagesExtras array contains 2 or more entries each of which is the
228 // start of a new linked list in the page. The first is at:
229 // extrasStartIndex = (pageStarts[pageIndex] & 0x3FFF)
230 // The next is at extrasStartIndex+1. The last is denoted by
231 // having the high bit (DYLD_CACHE_SLIDE_PAGE_ATTR_END) of the pageExtras[]
232 // set.
233 //
234 // For 64-bit architectures, there is always enough free bits to encode all
235 // possible deltas. The info->delta_mask field shows where the delta is located
236 // in the pointer. That value must be masked off (valueMask) before the slide
237 // is added to the pointer.
238 //
239 // For 32-bit architectures, there are only three bits free (the three most
240 // significant bits). To extract the delta, you must first subtract value_add
241 // from the pointer value, then AND with delta_mask, then shift by deltaShift.
242 // That still leaves a maximum delta to the next rebase location of 28 bytes.
243 // To reduce the number or chains needed, an optimization was added. Turns
244 // out zero is common in the DATA region. A zero can be turned into a
245 // non-rebasing entry in the linked list. The can be done because nothing
246 // in the shared cache should point out of its dylib to the start of the shared
247 // cache.
248 //
249 // The code for processing a linked list (chain) is:
250 //
251 // uint32_t delta = 1;
252 // while ( delta != 0 ) {
253 // uint8_t* loc = pageStart + pageOffset;
254 // uintptr_t rawValue = *((uintptr_t*)loc);
255 // delta = ((rawValue & deltaMask) >> deltaShift);
256 // uintptr_t newValue = (rawValue & valueMask);
257 // if ( newValue != 0 ) {
258 // newValue += valueAdd;
259 // newValue += slideAmount;
260 // }
261 // *((uintptr_t*)loc) = newValue;
262 // pageOffset += delta;
263 // }
264 //
265 //
266 struct dyld_cache_slide_info2
267 {
268 uint32_t version; // currently 2
269 uint32_t page_size; // currently 4096 (may also be 16384)
270 uint32_t page_starts_offset;
271 uint32_t page_starts_count;
272 uint32_t page_extras_offset;
273 uint32_t page_extras_count;
274 uint64_t delta_mask; // which (contiguous) set of bits contains the delta to the next rebase location
275 uint64_t value_add;
276 //uint16_t page_starts[page_starts_count];
277 //uint16_t page_extras[page_extras_count];
278 };
279 #define DYLD_CACHE_SLIDE_PAGE_ATTRS 0xC000 // high bits of uint16_t are flags
280 #define DYLD_CACHE_SLIDE_PAGE_ATTR_EXTRA 0x8000 // index is into extras array (not starts array)
281 #define DYLD_CACHE_SLIDE_PAGE_ATTR_NO_REBASE 0x4000 // page has no rebasing
282 #define DYLD_CACHE_SLIDE_PAGE_ATTR_END 0x8000 // last chain entry for page
283
284
285
286 // The version 3 of the slide info uses a different compression scheme. Since
287 // only interior pointers (pointers that point within the cache) are rebased
288 // (slid), we know the possible range of the pointers and thus know there are
289 // unused bits in each pointer. We use those bits to form a linked list of
290 // locations needing rebasing in each page.
291 //
292 // Definitions:
293 //
294 // pageIndex = (pageAddress - startOfAllDataAddress)/info->page_size
295 // pageStarts[] = info + info->page_starts_offset
296 //
297 // There are two cases:
298 //
299 // 1) pageStarts[pageIndex] == DYLD_CACHE_SLIDE_V3_PAGE_ATTR_NO_REBASE
300 // The page contains no values that need rebasing.
301 //
302 // 2) otherwise...
303 // All rebase locations are in one linked list. The offset of the first
304 // rebase location in the page is pageStarts[pageIndex].
305 //
306 // A pointer is one of of the variants in dyld_cache_slide_pointer3
307 //
308 // The code for processing a linked list (chain) is:
309 //
310 // uint32_t delta = pageStarts[pageIndex];
311 // dyld_cache_slide_pointer3* loc = pageStart;
312 // do {
313 // loc += delta;
314 // delta = loc->offsetToNextPointer;
315 // if ( loc->auth.authenticated ) {
316 // newValue = loc->offsetFromSharedCacheBase + results->slide + auth_value_add;
317 // newValue = sign_using_the_various_bits(newValue);
318 // }
319 // else {
320 // uint64_t value51 = loc->pointerValue;
321 // uint64_t top8Bits = value51 & 0x0007F80000000000ULL;
322 // uint64_t bottom43Bits = value51 & 0x000007FFFFFFFFFFULL;
323 // uint64_t targetValue = ( top8Bits << 13 ) | bottom43Bits;
324 // newValue = targetValue + results->slide;
325 // }
326 // loc->raw = newValue;
327 // } while (delta != 0);
328 //
329 //
330 struct dyld_cache_slide_info3
331 {
332 uint32_t version; // currently 3
333 uint32_t page_size; // currently 4096 (may also be 16384)
334 uint32_t page_starts_count;
335 uint64_t auth_value_add;
336 uint16_t page_starts[/* page_starts_count */];
337 };
338
339 #define DYLD_CACHE_SLIDE_V3_PAGE_ATTR_NO_REBASE 0xFFFF // page has no rebasing
340
341 union dyld_cache_slide_pointer3
342 {
343 uint64_t raw;
344 struct {
345 uint64_t pointerValue : 51,
346 offsetToNextPointer : 11,
347 unused : 2;
348 } plain;
349
350 struct {
351 uint64_t offsetFromSharedCacheBase : 32,
352 diversityData : 16,
353 hasAddressDiversity : 1,
354 key : 2,
355 offsetToNextPointer : 11,
356 unused : 1,
357 authenticated : 1; // = 1;
358 } auth;
359 };
360
361
362
363 // The version 4 of the slide info is optimized for 32-bit caches up to 1GB.
364 // Since only interior pointers (pointers that point within the cache) are rebased
365 // (slid), we know the possible range of the pointers takes 30 bits. That
366 // gives us two bits to use to chain to the next rebase.
367 //
368 // Definitions:
369 //
370 // pageIndex = (pageAddress - startOfAllDataAddress)/info->page_size
371 // pageStarts[] = info + info->page_starts_offset
372 // pageExtras[] = info + info->page_extras_offset
373 // valueMask = ~(info->delta_mask)
374 // deltaShift = __builtin_ctzll(info->delta_mask) - 2
375 //
376 // There are three cases:
377 //
378 // 1) pageStarts[pageIndex] == DYLD_CACHE_SLIDE4_PAGE_NO_REBASE
379 // The page contains no values that need rebasing.
380 //
381 // 2) (pageStarts[pageIndex] & DYLD_CACHE_SLIDE4_PAGE_USE_EXTRA) == 0
382 // All rebase locations are in one linked list. The offset of the first
383 // rebase location in the page is pageStarts[pageIndex] * 4.
384 //
385 // 3) pageStarts[pageIndex] & DYLD_CACHE_SLIDE4_PAGE_USE_EXTRA
386 // Multiple chains are needed for all rebase locations in a page.
387 // The pagesExtras array contains 2 or more entries each of which is the
388 // start of a new chain in the page. The first is at:
389 // extrasStartIndex = (pageStarts[pageIndex] & DYLD_CACHE_SLIDE4_PAGE_INDEX)
390 // The next is at extrasStartIndex+1. The last is denoted by
391 // having the high bit (DYLD_CACHE_SLIDE4_PAGE_EXTRA_END) of the pageExtras[].
392 //
393 // For 32-bit architectures, there are only two bits free (the two most
394 // significant bits). To extract the delta, you must first subtract value_add
395 // from the pointer value, then AND with delta_mask, then shift by deltaShift.
396 // That still leaves a maximum delta to the next rebase location of 12 bytes.
397 // To reduce the number or chains needed, an optimization was added. Turns
398 // most of the non-rebased data are small values and can be co-opt'ed into
399 // being used in the chain. The can be done because nothing
400 // in the shared cache should point to the first 64KB which are in the shared
401 // cache header information. So if the resulting pointer points to the
402 // start of the cache +/-32KB, then it is actually a small number that should
403 // not be rebased, but just reconstituted.
404 //
405 // The code for processing a linked list (chain) is:
406 //
407 // uint32_t delta = 1;
408 // while ( delta != 0 ) {
409 // uint8_t* loc = pageStart + pageOffset;
410 // uint32_t rawValue = *((uint32_t*)loc);
411 // delta = ((rawValue & deltaMask) >> deltaShift);
412 // uintptr_t newValue = (rawValue & valueMask);
413 // if ( (newValue & 0xFFFF8000) == 0 ) {
414 // // small positive non-pointer, use as-is
415 // }
416 // else if ( (newValue & 0x3FFF8000) == 0x3FFF8000 ) {
417 // // small negative non-pointer
418 // newValue |= 0xC0000000;
419 // }
420 // else {
421 // // pointer that needs rebasing
422 // newValue += valueAdd;
423 // newValue += slideAmount;
424 // }
425 // *((uint32_t*)loc) = newValue;
426 // pageOffset += delta;
427 // }
428 //
429 //
430 struct dyld_cache_slide_info4
431 {
432 uint32_t version; // currently 4
433 uint32_t page_size; // currently 4096 (may also be 16384)
434 uint32_t page_starts_offset;
435 uint32_t page_starts_count;
436 uint32_t page_extras_offset;
437 uint32_t page_extras_count;
438 uint64_t delta_mask; // which (contiguous) set of bits contains the delta to the next rebase location (0xC0000000)
439 uint64_t value_add; // base address of cache
440 //uint16_t page_starts[page_starts_count];
441 //uint16_t page_extras[page_extras_count];
442 };
443 #define DYLD_CACHE_SLIDE4_PAGE_NO_REBASE 0xFFFF // page has no rebasing
444 #define DYLD_CACHE_SLIDE4_PAGE_INDEX 0x7FFF // mask of page_starts[] values
445 #define DYLD_CACHE_SLIDE4_PAGE_USE_EXTRA 0x8000 // index is into extras array (not a chain start offset)
446 #define DYLD_CACHE_SLIDE4_PAGE_EXTRA_END 0x8000 // last chain entry for page
447
448
449
450
451 struct dyld_cache_local_symbols_info
452 {
453 uint32_t nlistOffset; // offset into this chunk of nlist entries
454 uint32_t nlistCount; // count of nlist entries
455 uint32_t stringsOffset; // offset into this chunk of string pool
456 uint32_t stringsSize; // byte count of string pool
457 uint32_t entriesOffset; // offset into this chunk of array of dyld_cache_local_symbols_entry
458 uint32_t entriesCount; // number of elements in dyld_cache_local_symbols_entry array
459 };
460
461 struct dyld_cache_local_symbols_entry
462 {
463 uint32_t dylibOffset; // offset in cache file of start of dylib
464 uint32_t nlistStartIndex; // start index of locals for this dylib
465 uint32_t nlistCount; // number of local symbols for this dylib
466 };
467
468 struct dyld_cache_patch_info
469 {
470 uint64_t patchTableArrayAddr; // (unslid) address of array for dyld_cache_image_patches for each image
471 uint64_t patchTableArrayCount; // count of patch table entries
472 uint64_t patchExportArrayAddr; // (unslid) address of array for patch exports for each image
473 uint64_t patchExportArrayCount; // count of patch exports entries
474 uint64_t patchLocationArrayAddr; // (unslid) address of array for patch locations for each patch
475 uint64_t patchLocationArrayCount;// count of patch location entries
476 uint64_t patchExportNamesAddr; // blob of strings of export names for patches
477 uint64_t patchExportNamesSize; // size of string blob of export names for patches
478 };
479
480 struct dyld_cache_image_patches
481 {
482 uint32_t patchExportsStartIndex;
483 uint32_t patchExportsCount;
484 };
485
486 struct dyld_cache_patchable_export
487 {
488 uint32_t cacheOffsetOfImpl;
489 uint32_t patchLocationsStartIndex;
490 uint32_t patchLocationsCount;
491 uint32_t exportNameOffset;
492 };
493
494 struct dyld_cache_patchable_location
495 {
496 uint64_t cacheOffset : 32,
497 high7 : 7,
498 addend : 5, // 0..31
499 authenticated : 1,
500 usesAddressDiversity : 1,
501 key : 2,
502 discriminator : 16;
503 };
504
505
506 // This is the location of the macOS shared cache on macOS 11.0 and later
507 #define MACOSX_MRM_DYLD_SHARED_CACHE_DIR "/System/Library/dyld/"
508
509 // This is old define for the old location of the dyld cache
510 #define MACOSX_DYLD_SHARED_CACHE_DIR MACOSX_MRM_DYLD_SHARED_CACHE_DIR
511
512 #define IPHONE_DYLD_SHARED_CACHE_DIR "/System/Library/Caches/com.apple.dyld/"
513 #if !TARGET_OS_SIMULATOR
514 #define DYLD_SHARED_CACHE_BASE_NAME "dyld_shared_cache_"
515 #else
516 #define DYLD_SHARED_CACHE_BASE_NAME "dyld_sim_shared_cache_"
517 #endif
518 #define DYLD_SHARED_CACHE_DEVELOPMENT_EXT ".development"
519
520 static const uint64_t kDyldSharedCacheTypeDevelopment = 0;
521 static const uint64_t kDyldSharedCacheTypeProduction = 1;
522
523
524
525
526 #endif // __DYLD_CACHE_FORMAT__
527
528