2 * Copyright (c) 2017 Apple Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
26 #ifndef LaunchCacheFormat_h
27 #define LaunchCacheFormat_h
32 #include <uuid/uuid.h>
33 #include <mach/mach.h>
35 #include "LaunchCache.h"
39 namespace launch_cache
{
40 namespace binary_format
{
43 // bump this number each time binary format changes
44 enum { kFormatVersion
= 8 };
46 union VIS_HIDDEN ImageRef
{
47 ImageRef() : val(0xFFFFFFFF) { }
48 ImageRef(uint8_t kind
, uint32_t groupNum
, uint32_t indexInGroup
) : _linkKind(kind
), _groupNum(groupNum
), _indexInGroup(indexInGroup
) {
49 assert(groupNum
< (1 << 18));
50 assert(indexInGroup
< (1 << 12));
52 uint8_t kind() const { return _linkKind
; }
53 uint32_t groupNum() const { return _groupNum
; }
54 uint32_t indexInGroup() const { return _indexInGroup
; }
55 uint16_t value() const { return val
; }
56 void clearKind() { _linkKind
= 0; }
58 bool operator==(const ImageRef
& rhs
) const {
59 return (val
== rhs
.val
);
61 bool operator!=(const ImageRef
& rhs
) const {
62 return (val
!= rhs
.val
);
64 static ImageRef
weakImportMissing();
65 static ImageRef
makeEmptyImageRef() { return ImageRef(); }
68 ImageRef(uint32_t v
) : val(v
) { }
72 uint32_t _linkKind
: 2, // Image::LinkKind
73 _groupNum
: 18, // 0 => cached dylib group, 1 => other dylib group, 2 => main closure, etc
74 _indexInGroup
: 12; // max 64K images in group
81 // In disk based images, all segments are multiples of page size
82 // This struct just tracks the size (disk and vm) of each segment.
83 // This is compact for most every image which have contiguous segments.
84 // If the image does not have contiguous segments (rare), an extra
85 // DiskSegment is inserted with the paddingNotSeg bit set.
88 uint64_t filePageCount
: 30,
95 // In cache DATA_DIRTY is not page aligned or sized
96 // This struct allows segments with any alignment and up to 256MB in size
97 struct DyldCacheSegment
99 uint64_t cacheOffset
: 32,
104 // When an Image is built on the device, the mtime and inode are recorded.
105 // When built off device, the first 16 bytes of SHA1 of CodeDirectory is recorded.
119 uint32_t isDiskImage
: 1, // images are DiskImage - not Image
120 isInvalid
: 1, // an error occurred creating the info for this image
124 mayHavePlusLoads
: 1,
125 isEncrypted
: 1, // image is DSMOS or FairPlay encrypted
128 cwdSameAsThis
: 1, // dylibs use file system relative paths, cwd must be main's dir
129 isPlatformBinary
: 1, // part of OS - can be loaded into LV process
131 overridableDylib
: 1, // only applicable to group 0
134 int32_t groupOffset
; // back pointer to containing ImageGroup (from start of Image)
135 uint32_t pathPoolOffset
;
139 uint16_t dependentsArrayStartIndex
;
140 uint16_t dependentsArrayCount
;
141 uint16_t segmentsArrayStartIndex
;
142 uint16_t segmentsArrayCount
;
143 uint16_t initBeforeArrayStartIndex
;
144 uint16_t initBeforeArrayCount
;
145 uint16_t initOffsetsArrayStartIndex
;
146 uint16_t initOffsetsArrayCount
;
147 uint16_t dofOffsetsArrayStartIndex
;
148 uint16_t dofOffsetsArrayCount
;
151 // an image in the dyld shared cache
152 struct CachedImage
: public Image
154 uint32_t patchStartIndex
;
158 // an image not in the dyld shared cache (loaded from disk at runtime)
159 struct DiskImage
: public Image
161 uint32_t totalVmPages
;
162 uint32_t sliceOffsetIn4K
;
163 uint32_t codeSignFileOffset
;
164 uint32_t codeSignFileSize
;
165 uint32_t fixupsPoolOffset
: 28, // offset in ImageGroup's pool for AllFixupsBySegment
166 fixupsPoolSegCount
: 4; // count of segments in AllFixupsBySegment for this image
167 uint32_t fairPlayTextPageCount
: 28,
168 fairPlayTextStartPage
: 4;
169 uint32_t targetsArrayStartIndex
; // index in ImageGroup's pool of OrdinalEntry
170 uint32_t targetsArrayCount
;
174 // if an Image has an alias (symlink to it), the Image does not record the alias, but the ImageGroup does
178 uint32_t imageIndexInGroup
;
179 uint32_t aliasOffsetInStringPool
;
182 // each DiskImage points to an array of these, one per segment with fixups
183 struct AllFixupsBySegment
185 uint32_t segIndex
: 4,
186 offset
: 28; // from start of AllFixupsBySegment to this seg's SegmentFixupsByPage
190 // This struct is suitable for passing into kernel when kernel supports fixups on page-in.
191 struct SegmentFixupsByPage
193 uint32_t size
; // of this struct, including fixup opcodes
194 uint32_t pageSize
; // 0x1000 or 0x4000
196 uint32_t pageInfoOffsets
[1]; // array size is pageCount
197 // each page info is a FixUpOpcode[]
200 enum class FixUpOpcode
: uint8_t {
203 rebase32
= 0x10, // add32 slide at current pageOffset, increment pageOffset by 4
204 rebase64
= 0x11, // add64 slide at current pageOffset, increment pageOffset by 8
205 bind32
= 0x12, // set 32-bit ordinal value at current pageOffset, increment pageOffset by 4
206 bind64
= 0x13, // set 64-bit ordinal value at current pageOffset, increment pageOffset by 8
207 rebaseText32
= 0x14, // add32 slide at current text pageOffset, increment pageOffset by 4
208 bindText32
= 0x15, // set 32-bit ordinal value at current text pageOffset, increment pageOffset by 4
209 bindTextRel32
= 0x16, // set delta to 32-bit ordinal value at current text pageOffset, increment pageOffset by 4 (i386 CALL to dylib)
210 bindImportJmp32
= 0x17, // set delta to 32-bit ordinal value at current text pageOffset, increment pageOffset by 4 (i386 JMP to dylib)
211 // fixupChain64 = 0x18, // current page offset is start of a chain of locations to fix up
212 // adjPageOffset = 0x20,
213 setPageOffset
= 0x20, // low 4-bits is amount to increment (1 to 15). If zero, then add next ULEB (note: can set offset for unaligned pointer)
214 incPageOffset
= 0x30, // low 4-bits *4 is amount to increment (4 to 60). If zero, then add next ULEB * 4
215 // adjOrdinal = 0x40,
216 setOrdinal
= 0x40, // low 4-bits is ordinal (1-15). If zero, then ordinal is next ULEB
217 incOrdinal
= 0x50, // low 4-bits is ordinal inc amount (1-15). If zero, then ordinal is next ULEB
218 repeat
= 0x60 // low 5-bits is how many next bytes to repeat. next ULEB is repeat count
221 // If a closure uses DYLD_LIBRARY_PATH to override an OS dylib, there is an
222 // ImageRefOverride entry to redirect uses of the OS dylib.
223 struct ImageRefOverride
225 ImageRef standardDylib
;
226 ImageRef overrideDylib
;
229 // If a closure interposes on, or has a dylib that overrides, something in the dyld shared cache,
230 // then closure's ImageGroup contains an array of these
231 struct DyldCacheOverride
233 uint64_t patchTableIndex
: 24, // index into PatchTable array of group 0
234 imageIndex
: 8, // index in this group (2) of what to replace with
235 imageOffset
: 32; // offset within image to override something in cache
239 // The ImageGroup for the dyld shared cache dylibs contains and array of these
240 // with one entry for each symbol in a cached dylib that is used by some other cached dylib.
243 uint32_t targetCacheOffset
; // delta from the base address of the cache to the address of the symbol to patch
244 uint32_t offsetsStartIndex
; // index into the PatchOffset array of first location to patch, last offset has low bit set
251 dataRegionOffset
: 30;
256 uint32_t imagesEntrySize
: 8,
257 dylibsExpectedOnDisk
: 1,
258 imageFileInfoIsCdHash
: 1,
261 uint32_t imagesPoolCount
;
262 uint32_t imagesPoolOffset
; // offset to array of Image or DiskImage
263 uint32_t imageAliasCount
;
264 uint32_t imageAliasOffset
; // offset to array of AliasEntry
265 uint32_t segmentsPoolCount
;
266 uint32_t segmentsPoolOffset
; // offset to array of Segment or DyldCacheSegment
267 uint32_t dependentsPoolCount
;
268 uint32_t dependentsPoolOffset
; // offset to array of ImageRef
269 uint32_t intializerOffsetPoolCount
;
270 uint32_t intializerOffsetPoolOffset
; // offset to array of uint32_t
271 uint32_t intializerListPoolCount
;
272 uint32_t intializerListPoolOffset
; // offset to array of ImageRef
273 uint32_t targetsPoolCount
;
274 uint32_t targetsOffset
; // offset to array of TargetSymbolValue
275 uint32_t fixupsPoolSize
;
276 uint32_t fixupsOffset
; // offset to list of AllFixupsBySegment
277 uint32_t cachePatchTableCount
;
278 uint32_t cachePatchTableOffset
; // offset to array of PatchTable (used only in group 0)
279 uint32_t cachePatchOffsetsCount
;
280 uint32_t cachePatchOffsetsOffset
; // offset to array of PatchOffset cache offsets (used only in group 0)
281 uint32_t symbolOverrideTableCount
;
282 uint32_t symbolOverrideTableOffset
; // offset to array of DyldCacheOverride (used only in group 2)
283 uint32_t imageOverrideTableCount
;
284 uint32_t imageOverrideTableOffset
; // offset to array of ImageRefOverride (used only in group 2)
285 uint32_t dofOffsetPoolCount
;
286 uint32_t dofOffsetPoolOffset
; // offset to array of uint32_t
287 uint32_t indirectGroupNumPoolCount
;
288 uint32_t indirectGroupNumPoolOffset
; // offset to array of uint32_t
289 uint32_t stringsPoolSize
;
290 uint32_t stringsPoolOffset
;
295 // Initializer offsets array
296 // Initializer ImageRef array
297 // TargetSymbolValue array
298 // AllFixupsBySegment pool
301 // DyldCacheOverride array
302 // ImageRefOverride array
310 enum { magicV1
= 0x31646c6e };
313 uint32_t usesCRT
: 1,
315 usesLibraryValidation
: 1,
317 uint32_t missingFileComponentsOffset
; // offset to array of 16-bit string pool offset of path components
318 uint32_t dyldEnvVarsOffset
;
319 uint32_t dyldEnvVarsCount
;
320 uint32_t stringPoolOffset
;
321 uint32_t stringPoolSize
;
322 ImageRef libSystemRef
;
324 uint32_t libdyldVectorOffset
;
325 uint32_t mainExecutableIndexInGroup
;
326 uint32_t mainExecutableEntryOffset
;
327 uint32_t initialImageCount
;
328 uuid_t dyldCacheUUID
; // all zero if this closure is embedded in a dyld cache
329 uint8_t mainExecutableCdHash
[20]; // or UUID if not code signed
338 } // namespace binary_format
340 } // namespace launch_cache
344 #endif // LaunchCacheFormat_h