dyld-551.3.tar.gz
[apple/dyld.git] / dyld3 / shared-cache / DyldSharedCache.h
1 /*
2 * Copyright (c) 2017 Apple Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
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
11 * file.
12 *
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.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24
25 #ifndef DyldSharedCache_h
26 #define DyldSharedCache_h
27
28 #include <set>
29 #include <string>
30 #include <vector>
31 #include <unordered_map>
32
33 #include "dyld_cache_format.h"
34 #include "Diagnostics.h"
35 #include "MachOParser.h"
36
37
38 namespace dyld3 {
39 namespace launch_cache {
40 namespace binary_format {
41 struct Closure;
42 struct ImageGroup;
43 struct Image;
44 }
45 }
46 }
47
48
49 class VIS_HIDDEN DyldSharedCache
50 {
51 public:
52
53 enum CodeSigningDigestMode
54 {
55 SHA256only = 0,
56 SHA1only = 1,
57 Agile = 2
58 };
59
60 struct CreateOptions
61 {
62 std::string archName;
63 dyld3::Platform platform;
64 bool excludeLocalSymbols;
65 bool optimizeStubs;
66 bool optimizeObjC;
67 CodeSigningDigestMode codeSigningDigestMode;
68 bool agileSignatureChooseSHA256CdHash;
69 bool dylibsRemovedDuringMastering;
70 bool inodesAreSameAsRuntime;
71 bool cacheSupportsASLR;
72 bool forSimulator;
73 bool verbose;
74 bool evictLeafDylibsOnOverflow;
75 std::unordered_map<std::string, unsigned> dylibOrdering;
76 std::unordered_map<std::string, unsigned> dirtyDataSegmentOrdering;
77 std::vector<std::string> pathPrefixes;
78 std::string loggingPrefix;
79 };
80
81 struct MappedMachO
82 {
83 MappedMachO()
84 : mh(nullptr), length(0), isSetUID(false), protectedBySIP(false), sliceFileOffset(0), modTime(0), inode(0) { }
85 MappedMachO(const std::string& path, const mach_header* p, size_t l, bool isu, bool sip, uint64_t o, uint64_t m, uint64_t i)
86 : runtimePath(path), mh(p), length(l), isSetUID(isu), protectedBySIP(sip), sliceFileOffset(o), modTime(m), inode(i) { }
87
88 std::string runtimePath;
89 const mach_header* mh;
90 size_t length;
91 uint64_t isSetUID : 1,
92 protectedBySIP : 1,
93 sliceFileOffset : 62;
94 uint64_t modTime; // only recorded if inodesAreSameAsRuntime
95 uint64_t inode; // only recorded if inodesAreSameAsRuntime
96 };
97
98 struct CreateResults
99 {
100 const DyldSharedCache* cacheContent = nullptr; // caller needs to vm_deallocate() when done
101 size_t cacheLength = 0;
102 std::string errorMessage;
103 std::set<std::string> warnings;
104 std::set<const mach_header*> evictions;
105 bool agileSignature = false;
106 std::string cdHashFirst;
107 std::string cdHashSecond;
108 };
109
110
111 // This function verifies the set of dylibs that will go into the cache are self contained. That the depend on no dylibs
112 // outset the set. It will call back the loader function to try to find any mising dylibs.
113 static bool verifySelfContained(std::vector<MappedMachO>& dylibsToCache, MappedMachO (^loader)(const std::string& runtimePath), std::vector<std::pair<DyldSharedCache::MappedMachO, std::set<std::string>>>& excluded);
114
115
116 //
117 // This function is single threaded and creates a shared cache. The cache file is created in-memory.
118 //
119 // Inputs:
120 // options: various per-platform flags
121 // dylibsToCache: a list of dylibs to include in the cache
122 // otherOsDylibs: a list of other OS dylibs and bundle which should have load info added to the cache
123 // osExecutables: a list of main executables which should have closures created in the cache
124 //
125 // Returns:
126 // On success:
127 // cacheContent: start of the allocated cache buffer which must be vm_deallocated after the caller writes out the buffer.
128 // cacheLength: size of the allocated cache buffer
129 // cdHash: hash of the code directory of the code blob of the created cache
130 // warnings: all warning messsages generated during the creation of the cache
131 //
132 // On failure:
133 // cacheContent: nullptr
134 // errorMessage: the string describing why the cache could not be created
135 // warnings: all warning messsages generated before the failure
136 //
137 static CreateResults create(const CreateOptions& options,
138 const std::vector<MappedMachO>& dylibsToCache,
139 const std::vector<MappedMachO>& otherOsDylibs,
140 const std::vector<MappedMachO>& osExecutables);
141
142
143 //
144 // Returns a text "map" file as a big string
145 //
146 std::string mapFile() const;
147
148
149 //
150 // Returns the architecture name of the shared cache, e.g. "arm64"
151 //
152 std::string archName() const;
153
154
155 //
156 // Returns the platform the cache is for
157 //
158 uint32_t platform() const;
159
160
161 //
162 // Iterates over each dylib in the cache
163 //
164 void forEachImage(void (^handler)(const mach_header* mh, const char* installName)) const;
165
166
167 //
168 // Iterates over each dylib in the cache
169 //
170 void forEachImageEntry(void (^handler)(const char* path, uint64_t mTime, uint64_t inode)) const;
171
172
173 //
174 // Iterates over each dylib in the cache
175 //
176 void forEachImageTextSegment(void (^handler)(uint64_t loadAddressUnslid, uint64_t textSegmentSize, const uuid_t dylibUUID, const char* installName)) const;
177
178
179 //
180 // Iterates over each of the three regions in the cache
181 //
182 void forEachRegion(void (^handler)(const void* content, uint64_t vmAddr, uint64_t size, uint32_t permissions)) const;
183
184
185 //
186 // returns address the cache would load at if unslid
187 //
188 uint64_t unslidLoadAddress() const;
189
190
191 //
192 // returns UUID of cache
193 //
194 void getUUID(uuid_t uuid) const;
195
196
197 //
198 // returns the vm size required to map cache
199 //
200 uint64_t mappedSize() const;
201
202
203 dyld_cache_header header;
204 };
205
206
207
208
209
210
211
212
213 #endif /* DyldSharedCache_h */