]> git.saurik.com Git - apple/dyld.git/blob - dyld3/shared-cache/DyldSharedCache.h
dyld-635.2.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 #include <uuid/uuid.h>
33
34 #include "dyld_cache_format.h"
35 #include "Diagnostics.h"
36 #include "MachOAnalyzer.h"
37 #include "Closure.h"
38
39
40 class VIS_HIDDEN DyldSharedCache
41 {
42 public:
43
44 enum CodeSigningDigestMode
45 {
46 SHA256only = 0,
47 SHA1only = 1,
48 Agile = 2
49 };
50
51 struct CreateOptions
52 {
53 std::string outputFilePath;
54 std::string outputMapFilePath;
55 std::string archName;
56 dyld3::Platform platform;
57 bool excludeLocalSymbols;
58 bool optimizeStubs;
59 bool optimizeObjC;
60 CodeSigningDigestMode codeSigningDigestMode;
61 bool dylibsRemovedDuringMastering;
62 bool inodesAreSameAsRuntime;
63 bool cacheSupportsASLR;
64 bool forSimulator;
65 bool isLocallyBuiltCache;
66 bool verbose;
67 bool evictLeafDylibsOnOverflow;
68 std::unordered_map<std::string, unsigned> dylibOrdering;
69 std::unordered_map<std::string, unsigned> dirtyDataSegmentOrdering;
70 std::vector<std::string> pathPrefixes;
71 std::string loggingPrefix;
72 };
73
74 struct MappedMachO
75 {
76 MappedMachO()
77 : mh(nullptr), length(0), isSetUID(false), protectedBySIP(false), sliceFileOffset(0), modTime(0), inode(0) { }
78 MappedMachO(const std::string& path, const dyld3::MachOAnalyzer* p, size_t l, bool isu, bool sip, uint64_t o, uint64_t m, uint64_t i)
79 : runtimePath(path), mh(p), length(l), isSetUID(isu), protectedBySIP(sip), sliceFileOffset(o), modTime(m), inode(i) { }
80
81 std::string runtimePath;
82 const dyld3::MachOAnalyzer* mh;
83 size_t length;
84 uint64_t isSetUID : 1,
85 protectedBySIP : 1,
86 sliceFileOffset : 62;
87 uint64_t modTime; // only recorded if inodesAreSameAsRuntime
88 uint64_t inode; // only recorded if inodesAreSameAsRuntime
89 };
90
91 struct CreateResults
92 {
93 std::string errorMessage;
94 std::set<std::string> warnings;
95 std::set<const dyld3::MachOAnalyzer*> evictions;
96 bool agileSignature = false;
97 std::string cdHashFirst;
98 std::string cdHashSecond;
99 };
100
101
102 struct FileAlias
103 {
104 std::string realPath;
105 std::string aliasPath;
106 };
107
108
109 // This function verifies the set of dylibs that will go into the cache are self contained. That the depend on no dylibs
110 // outset the set. It will call back the loader function to try to find any mising dylibs.
111 static bool verifySelfContained(std::vector<MappedMachO>& dylibsToCache, MappedMachO (^loader)(const std::string& runtimePath), std::vector<std::pair<DyldSharedCache::MappedMachO, std::set<std::string>>>& excluded);
112
113
114 //
115 // This function is single threaded and creates a shared cache. The cache file is created in-memory.
116 //
117 // Inputs:
118 // options: various per-platform flags
119 // dylibsToCache: a list of dylibs to include in the cache
120 // otherOsDylibs: a list of other OS dylibs and bundle which should have load info added to the cache
121 // osExecutables: a list of main executables which should have closures created in the cache
122 //
123 // Returns:
124 // On success:
125 // cacheContent: start of the allocated cache buffer which must be vm_deallocated after the caller writes out the buffer.
126 // cacheLength: size of the allocated cache buffer
127 // cdHash: hash of the code directory of the code blob of the created cache
128 // warnings: all warning messsages generated during the creation of the cache
129 //
130 // On failure:
131 // cacheContent: nullptr
132 // errorMessage: the string describing why the cache could not be created
133 // warnings: all warning messsages generated before the failure
134 //
135 static CreateResults create(const CreateOptions& options,
136 const std::vector<MappedMachO>& dylibsToCache,
137 const std::vector<MappedMachO>& otherOsDylibs,
138 const std::vector<MappedMachO>& osExecutables);
139
140
141 //
142 // Returns a text "map" file as a big string
143 //
144 std::string mapFile() const;
145
146
147 //
148 // Returns the architecture name of the shared cache, e.g. "arm64"
149 //
150 const char* archName() const;
151
152
153 //
154 // Returns the platform the cache is for
155 //
156 dyld3::Platform platform() const;
157
158
159 //
160 // Iterates over each dylib in the cache
161 //
162 void forEachImage(void (^handler)(const mach_header* mh, const char* installName)) const;
163
164
165 //
166 // Searches cache for dylib with specified path
167 //
168 bool hasImagePath(const char* dylibPath, uint32_t& imageIndex) const;
169
170
171 //
172 // Searches cache for dylib with specified mach_header
173 //
174 bool findMachHeaderImageIndex(const mach_header* mh, uint32_t& imageIndex) const;
175
176 //
177 // Iterates over each dylib in the cache
178 //
179 void forEachImageEntry(void (^handler)(const char* path, uint64_t mTime, uint64_t inode)) const;
180
181
182 //
183 // Iterates over each dylib in the cache
184 //
185 const mach_header* getIndexedImageEntry(uint32_t index, uint64_t& mTime, uint64_t& node) const;
186
187
188 //
189 // Iterates over each dylib in the cache
190 //
191 void forEachImageTextSegment(void (^handler)(uint64_t loadAddressUnslid, uint64_t textSegmentSize, const uuid_t dylibUUID, const char* installName, bool& stop)) const;
192
193
194 //
195 // Iterates over each of the three regions in the cache
196 //
197 void forEachRegion(void (^handler)(const void* content, uint64_t vmAddr, uint64_t size, uint32_t permissions)) const;
198
199
200 //
201 // Returns if an address range is in this cache, and if so if in a read-only area
202 //
203 bool inCache(const void* addr, size_t length, bool& readOnly) const;
204
205
206 //
207 // returns address the cache would load at if unslid
208 //
209 uint64_t unslidLoadAddress() const;
210
211
212 //
213 // returns UUID of cache
214 //
215 void getUUID(uuid_t uuid) const;
216
217
218 //
219 // returns the vm size required to map cache
220 //
221 uint64_t mappedSize() const;
222
223
224 //
225 // searches cache for pre-built closure for program
226 //
227 const dyld3::closure::LaunchClosure* findClosure(const char* executablePath) const;
228
229
230 //
231 // iterates all pre-built closures for program
232 //
233 void forEachLaunchClosure(void (^handler)(const char* executableRuntimePath, const dyld3::closure::LaunchClosure* closure)) const;
234
235
236 //
237 // iterates all pre-built Image* for OS dylibs/bundles not in dyld cache
238 //
239 void forEachDlopenImage(void (^handler)(const char* runtimePath, const dyld3::closure::Image* image)) const;
240
241
242 //
243 // returns the ImageArray pointer to Images in dyld shared cache
244 //
245 const dyld3::closure::ImageArray* cachedDylibsImageArray() const;
246
247
248 //
249 // returns the ImageArray pointer to Images in OS with pre-build dlopen closure
250 //
251 const dyld3::closure::ImageArray* otherOSImageArray() const;
252
253
254 //
255 // searches cache for pre-built dlopen closure for OS dylib/bundle
256 //
257 const dyld3::closure::Image* findDlopenOtherImage(const char* path) const;
258
259
260 //
261 // returns true if the offset is in the TEXT of some cached dylib and sets *index to the dylib index
262 //
263 bool addressInText(uint32_t cacheOffset, uint32_t* index) const;
264
265
266
267 dyld_cache_header header;
268 };
269
270
271
272
273
274
275
276
277 #endif /* DyldSharedCache_h */