dyld-625.13.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 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 dylibsImageGroupAddr; // (unslid) address of ImageGroup for dylibs in this cache
54 uint64_t dylibsImageGroupSize; // size of ImageGroup for dylibs in this cache
55 uint64_t otherImageGroupAddr; // (unslid) address of ImageGroup for other OS dylibs
56 uint64_t otherImageGroupSize; // size of oImageGroup for other OS dylibs
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 padding : 21; // TBD
67 uint64_t sharedRegionStart; // base load address of cache if not slid
68 uint64_t sharedRegionSize; // overall size of region cache can be mapped into
69 uint64_t maxSlide; // runtime slide of cache can be between zero and this value
70 uint64_t dylibsImageArrayAddr; // (unslid) address of ImageArray for dylibs in this cache
71 uint64_t dylibsImageArraySize; // size of ImageArray for dylibs in this cache
72 uint64_t dylibsTrieAddr; // (unslid) address of trie of indexes of all cached dylibs
73 uint64_t dylibsTrieSize; // size of trie of cached dylib paths
74 uint64_t otherImageArrayAddr; // (unslid) address of ImageArray for dylibs and bundles with dlopen closures
75 uint64_t otherImageArraySize; // size of ImageArray for dylibs and bundles with dlopen closures
76 uint64_t otherTrieAddr; // (unslid) address of trie of indexes of all dylibs and bundles with dlopen closures
77 uint64_t otherTrieSize; // size of trie of dylibs and bundles with dlopen closures
78 };
79
80
81 struct dyld_cache_mapping_info {
82 uint64_t address;
83 uint64_t size;
84 uint64_t fileOffset;
85 uint32_t maxProt;
86 uint32_t initProt;
87 };
88
89 struct dyld_cache_image_info
90 {
91 uint64_t address;
92 uint64_t modTime;
93 uint64_t inode;
94 uint32_t pathFileOffset;
95 uint32_t pad;
96 };
97
98 struct dyld_cache_image_info_extra
99 {
100 uint64_t exportsTrieAddr; // address of trie in unslid cache
101 uint64_t weakBindingsAddr;
102 uint32_t exportsTrieSize;
103 uint32_t weakBindingsSize;
104 uint32_t dependentsStartArrayIndex;
105 uint32_t reExportsStartArrayIndex;
106 };
107
108
109 struct dyld_cache_accelerator_info
110 {
111 uint32_t version; // currently 1
112 uint32_t imageExtrasCount; // does not include aliases
113 uint32_t imagesExtrasOffset; // offset into this chunk of first dyld_cache_image_info_extra
114 uint32_t bottomUpListOffset; // offset into this chunk to start of 16-bit array of sorted image indexes
115 uint32_t dylibTrieOffset; // offset into this chunk to start of trie containing all dylib paths
116 uint32_t dylibTrieSize; // size of trie containing all dylib paths
117 uint32_t initializersOffset; // offset into this chunk to start of initializers list
118 uint32_t initializersCount; // size of initializers list
119 uint32_t dofSectionsOffset; // offset into this chunk to start of DOF sections list
120 uint32_t dofSectionsCount; // size of initializers list
121 uint32_t reExportListOffset; // offset into this chunk to start of 16-bit array of re-exports
122 uint32_t reExportCount; // size of re-exports
123 uint32_t depListOffset; // offset into this chunk to start of 16-bit array of dependencies (0x8000 bit set if upward)
124 uint32_t depListCount; // size of dependencies
125 uint32_t rangeTableOffset; // offset into this chunk to start of ss
126 uint32_t rangeTableCount; // size of dependencies
127 uint64_t dyldSectionAddr; // address of libdyld's __dyld section in unslid cache
128 };
129
130 struct dyld_cache_accelerator_initializer
131 {
132 uint32_t functionOffset; // address offset from start of cache mapping
133 uint32_t imageIndex;
134 };
135
136 struct dyld_cache_range_entry
137 {
138 uint64_t startAddress; // unslid address of start of region
139 uint32_t size;
140 uint32_t imageIndex;
141 };
142
143 struct dyld_cache_accelerator_dof
144 {
145 uint64_t sectionAddress; // unslid address of start of region
146 uint32_t sectionSize;
147 uint32_t imageIndex;
148 };
149
150 struct dyld_cache_image_text_info
151 {
152 uuid_t uuid;
153 uint64_t loadAddress; // unslid address of start of __TEXT
154 uint32_t textSegmentSize;
155 uint32_t pathOffset; // offset from start of cache file
156 };
157
158
159 // The rebasing info is to allow the kernel to lazily rebase DATA pages of the
160 // dyld shared cache. Rebasing is adding the slide to interior pointers.
161 struct dyld_cache_slide_info
162 {
163 uint32_t version; // currently 1
164 uint32_t toc_offset;
165 uint32_t toc_count;
166 uint32_t entries_offset;
167 uint32_t entries_count;
168 uint32_t entries_size; // currently 128
169 // uint16_t toc[toc_count];
170 // entrybitmap entries[entries_count];
171 };
172
173
174 // The version 2 of the slide info uses a different compression scheme. Since
175 // only interior pointers (pointers that point within the cache) are rebased
176 // (slid), we know the possible range of the pointers and thus know there are
177 // unused bits in each pointer. We use those bits to form a linked list of
178 // locations needing rebasing in each page.
179 //
180 // Definitions:
181 //
182 // pageIndex = (pageAddress - startOfAllDataAddress)/info->page_size
183 // pageStarts[] = info + info->page_starts_offset
184 // pageExtras[] = info + info->page_extras_offset
185 // valueMask = ~(info->delta_mask)
186 // deltaShift = __builtin_ctzll(info->delta_mask) - 2
187 //
188 // There are three cases:
189 //
190 // 1) pageStarts[pageIndex] == DYLD_CACHE_SLIDE_PAGE_ATTR_NO_REBASE
191 // The page contains no values that need rebasing.
192 //
193 // 2) (pageStarts[pageIndex] & DYLD_CACHE_SLIDE_PAGE_ATTR_EXTRA) == 0
194 // All rebase locations are in one linked list. The offset of the first
195 // rebase location in the page is pageStarts[pageIndex] * 4.
196 //
197 // 3) pageStarts[pageIndex] & DYLD_CACHE_SLIDE_PAGE_ATTR_EXTRA
198 // Multiple linked lists are needed for all rebase locations in a page.
199 // The pagesExtras array contains 2 or more entries each of which is the
200 // start of a new linked list in the page. The first is at:
201 // extrasStartIndex = (pageStarts[pageIndex] & 0x3FFF)
202 // The next is at extrasStartIndex+1. The last is denoted by
203 // having the high bit (DYLD_CACHE_SLIDE_PAGE_ATTR_END) of the pageExtras[]
204 // set.
205 //
206 // For 64-bit architectures, there is always enough free bits to encode all
207 // possible deltas. The info->delta_mask field shows where the delta is located
208 // in the pointer. That value must be masked off (valueMask) before the slide
209 // is added to the pointer.
210 //
211 // For 32-bit architectures, there are only three bits free (the three most
212 // significant bits). To extract the delta, you must first subtract value_add
213 // from the pointer value, then AND with delta_mask, then shift by deltaShift.
214 // That still leaves a maximum delta to the next rebase location of 28 bytes.
215 // To reduce the number or chains needed, an optimization was added. Turns
216 // out zero is common in the DATA region. A zero can be turned into a
217 // non-rebasing entry in the linked list. The can be done because nothing
218 // in the shared cache should point out of its dylib to the start of the shared
219 // cache.
220 //
221 // The code for processing a linked list (chain) is:
222 //
223 // uint32_t delta = 1;
224 // while ( delta != 0 ) {
225 // uint8_t* loc = pageStart + pageOffset;
226 // uintptr_t rawValue = *((uintptr_t*)loc);
227 // delta = ((rawValue & deltaMask) >> deltaShift);
228 // uintptr_t newValue = (rawValue & valueMask);
229 // if ( newValue != 0 ) {
230 // newValue += valueAdd;
231 // newValue += slideAmount;
232 // }
233 // *((uintptr_t*)loc) = newValue;
234 // pageOffset += delta;
235 // }
236 //
237 //
238 struct dyld_cache_slide_info2
239 {
240 uint32_t version; // currently 2
241 uint32_t page_size; // currently 4096 (may also be 16384)
242 uint32_t page_starts_offset;
243 uint32_t page_starts_count;
244 uint32_t page_extras_offset;
245 uint32_t page_extras_count;
246 uint64_t delta_mask; // which (contiguous) set of bits contains the delta to the next rebase location
247 uint64_t value_add;
248 //uint16_t page_starts[page_starts_count];
249 //uint16_t page_extras[page_extras_count];
250 };
251 #define DYLD_CACHE_SLIDE_PAGE_ATTRS 0xC000 // high bits of uint16_t are flags
252 #define DYLD_CACHE_SLIDE_PAGE_ATTR_EXTRA 0x8000 // index is into extras array (not starts array)
253 #define DYLD_CACHE_SLIDE_PAGE_ATTR_NO_REBASE 0x4000 // page has no rebasing
254 #define DYLD_CACHE_SLIDE_PAGE_ATTR_END 0x8000 // last chain entry for page
255
256
257
258 // The version 3 of the slide info uses a different compression scheme. Since
259 // only interior pointers (pointers that point within the cache) are rebased
260 // (slid), we know the possible range of the pointers and thus know there are
261 // unused bits in each pointer. We use those bits to form a linked list of
262 // locations needing rebasing in each page.
263 //
264 // Definitions:
265 //
266 // pageIndex = (pageAddress - startOfAllDataAddress)/info->page_size
267 // pageStarts[] = info + info->page_starts_offset
268 //
269 // There are two cases:
270 //
271 // 1) pageStarts[pageIndex] == DYLD_CACHE_SLIDE_V3_PAGE_ATTR_NO_REBASE
272 // The page contains no values that need rebasing.
273 //
274 // 2) otherwise...
275 // All rebase locations are in one linked list. The offset of the first
276 // rebase location in the page is pageStarts[pageIndex].
277 //
278 // A pointer is one of of the variants in dyld_cache_slide_pointer3
279 //
280 // The code for processing a linked list (chain) is:
281 //
282 // uint32_t delta = pageStarts[pageIndex];
283 // dyld_cache_slide_pointer3* loc = pageStart;
284 // do {
285 // loc += delta;
286 // delta = loc->offsetToNextPointer;
287 // if ( loc->auth.authenticated ) {
288 // newValue = loc->offsetFromSharedCacheBase + results->slide + auth_value_add;
289 // newValue = sign_using_the_various_bits(newValue);
290 // }
291 // else {
292 // uint64_t value51 = loc->pointerValue;
293 // uint64_t top8Bits = value51 & 0x0007F80000000000ULL;
294 // uint64_t bottom43Bits = value51 & 0x000007FFFFFFFFFFULL;
295 // uint64_t targetValue = ( top8Bits << 13 ) | bottom43Bits;
296 // newValue = targetValue + results->slide;
297 // }
298 // loc->raw = newValue;
299 // } while (delta != 0);
300 //
301 //
302 struct dyld_cache_slide_info3
303 {
304 uint32_t version; // currently 3
305 uint32_t page_size; // currently 4096 (may also be 16384)
306 uint32_t page_starts_count;
307 uint64_t auth_value_add;
308 uint16_t page_starts[/* page_starts_count */];
309 };
310
311 #define DYLD_CACHE_SLIDE_V3_PAGE_ATTR_NO_REBASE 0xFFFF // page has no rebasing
312
313 union dyld_cache_slide_pointer3
314 {
315 uint64_t raw;
316 struct {
317 uint64_t pointerValue : 51,
318 offsetToNextPointer : 11,
319 unused : 2;
320 } plain;
321
322 struct {
323 uint64_t offsetFromSharedCacheBase : 32,
324 diversityData : 16,
325 hasAddressDiversity : 1,
326 key : 2,
327 offsetToNextPointer : 11,
328 unused : 1,
329 authenticated : 1; // = 1;
330 } auth;
331 };
332
333
334
335 // The version 4 of the slide info is optimized for 32-bit caches up to 1GB.
336 // Since only interior pointers (pointers that point within the cache) are rebased
337 // (slid), we know the possible range of the pointers takes 30 bits. That
338 // gives us two bits to use to chain to the next rebase.
339 //
340 // Definitions:
341 //
342 // pageIndex = (pageAddress - startOfAllDataAddress)/info->page_size
343 // pageStarts[] = info + info->page_starts_offset
344 // pageExtras[] = info + info->page_extras_offset
345 // valueMask = ~(info->delta_mask)
346 // deltaShift = __builtin_ctzll(info->delta_mask) - 2
347 //
348 // There are three cases:
349 //
350 // 1) pageStarts[pageIndex] == DYLD_CACHE_SLIDE4_PAGE_NO_REBASE
351 // The page contains no values that need rebasing.
352 //
353 // 2) (pageStarts[pageIndex] & DYLD_CACHE_SLIDE4_PAGE_USE_EXTRA) == 0
354 // All rebase locations are in one linked list. The offset of the first
355 // rebase location in the page is pageStarts[pageIndex] * 4.
356 //
357 // 3) pageStarts[pageIndex] & DYLD_CACHE_SLIDE4_PAGE_USE_EXTRA
358 // Multiple chains are needed for all rebase locations in a page.
359 // The pagesExtras array contains 2 or more entries each of which is the
360 // start of a new chain in the page. The first is at:
361 // extrasStartIndex = (pageStarts[pageIndex] & DYLD_CACHE_SLIDE4_PAGE_INDEX)
362 // The next is at extrasStartIndex+1. The last is denoted by
363 // having the high bit (DYLD_CACHE_SLIDE4_PAGE_EXTRA_END) of the pageExtras[].
364 //
365 // For 32-bit architectures, there are only two bits free (the two most
366 // significant bits). To extract the delta, you must first subtract value_add
367 // from the pointer value, then AND with delta_mask, then shift by deltaShift.
368 // That still leaves a maximum delta to the next rebase location of 12 bytes.
369 // To reduce the number or chains needed, an optimization was added. Turns
370 // most of the non-rebased data are small values and can be co-opt'ed into
371 // being used in the chain. The can be done because nothing
372 // in the shared cache should point to the first 64KB which are in the shared
373 // cache header information. So if the resulting pointer points to the
374 // start of the cache +/-32KB, then it is actually a small number that should
375 // not be rebased, but just reconstituted.
376 //
377 // The code for processing a linked list (chain) is:
378 //
379 // uint32_t delta = 1;
380 // while ( delta != 0 ) {
381 // uint8_t* loc = pageStart + pageOffset;
382 // uint32_t rawValue = *((uint32_t*)loc);
383 // delta = ((rawValue & deltaMask) >> deltaShift);
384 // uintptr_t newValue = (rawValue & valueMask);
385 // if ( (newValue & 0xFFFF8000) == 0 ) {
386 // // small positive non-pointer, use as-is
387 // }
388 // else if ( (newValue & 0x3FFF8000) == 0x3FFF8000 ) {
389 // // small negative non-pointer
390 // newValue |= 0xC0000000;
391 // }
392 // else {
393 // // pointer that needs rebasing
394 // newValue += valueAdd;
395 // newValue += slideAmount;
396 // }
397 // *((uint32_t*)loc) = newValue;
398 // pageOffset += delta;
399 // }
400 //
401 //
402 struct dyld_cache_slide_info4
403 {
404 uint32_t version; // currently 4
405 uint32_t page_size; // currently 4096 (may also be 16384)
406 uint32_t page_starts_offset;
407 uint32_t page_starts_count;
408 uint32_t page_extras_offset;
409 uint32_t page_extras_count;
410 uint64_t delta_mask; // which (contiguous) set of bits contains the delta to the next rebase location (0xC0000000)
411 uint64_t value_add; // base address of cache
412 //uint16_t page_starts[page_starts_count];
413 //uint16_t page_extras[page_extras_count];
414 };
415 #define DYLD_CACHE_SLIDE4_PAGE_NO_REBASE 0xFFFF // page has no rebasing
416 #define DYLD_CACHE_SLIDE4_PAGE_INDEX 0x7FFF // mask of page_starts[] values
417 #define DYLD_CACHE_SLIDE4_PAGE_USE_EXTRA 0x8000 // index is into extras array (not a chain start offset)
418 #define DYLD_CACHE_SLIDE4_PAGE_EXTRA_END 0x8000 // last chain entry for page
419
420
421
422
423 struct dyld_cache_local_symbols_info
424 {
425 uint32_t nlistOffset; // offset into this chunk of nlist entries
426 uint32_t nlistCount; // count of nlist entries
427 uint32_t stringsOffset; // offset into this chunk of string pool
428 uint32_t stringsSize; // byte count of string pool
429 uint32_t entriesOffset; // offset into this chunk of array of dyld_cache_local_symbols_entry
430 uint32_t entriesCount; // number of elements in dyld_cache_local_symbols_entry array
431 };
432
433 struct dyld_cache_local_symbols_entry
434 {
435 uint32_t dylibOffset; // offset in cache file of start of dylib
436 uint32_t nlistStartIndex; // start index of locals for this dylib
437 uint32_t nlistCount; // number of local symbols for this dylib
438 };
439
440
441
442 #define MACOSX_DYLD_SHARED_CACHE_DIR "/private/var/db/dyld/"
443 #define IPHONE_DYLD_SHARED_CACHE_DIR "/System/Library/Caches/com.apple.dyld/"
444 #define DYLD_SHARED_CACHE_BASE_NAME "dyld_shared_cache_"
445 #define DYLD_SHARED_CACHE_DEVELOPMENT_EXT ".development"
446
447 static const uint64_t kDyldSharedCacheTypeDevelopment = 0;
448 static const uint64_t kDyldSharedCacheTypeProduction = 1;
449
450
451
452
453 #endif // __DYLD_CACHE_FORMAT__
454
455