dyld-732.8.tar.gz
[apple/dyld.git] / dyld3 / shared-cache / Manifest.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 Manifest_h
26 #define Manifest_h
27
28 #include <map>
29 #include <set>
30 #include <memory>
31 #include <string>
32 #include <vector>
33
34 #include <unordered_map>
35 #include <unordered_set>
36
37 #include <assert.h>
38 #include <uuid/uuid.h>
39
40 #import <Foundation/Foundation.h>
41
42 #include "DyldSharedCache.h"
43 #include "Diagnostics.h"
44 #include "MachOAnalyzer.h"
45 #include "ClosureFileSystemPhysical.h"
46
47 extern std::string toolDir();
48
49 namespace dyld3 {
50
51 struct VIS_HIDDEN UUID {
52 UUID() {}
53 UUID(const UUID& other) { uuid_copy(_bytes, other._bytes); }
54 UUID(const uuid_t other) { uuid_copy(&_bytes[0], other); }
55 UUID(const dyld3::MachOAnalyzer* ml) { ml->getUuid(_bytes); }
56 bool operator<(const UUID& other) const { return uuid_compare(_bytes, other._bytes) < 0; }
57 bool operator==(const UUID& other) const { return uuid_compare(_bytes, other._bytes) == 0; }
58 bool operator!=(const UUID& other) const { return !(*this == other); }
59
60 size_t hash() const
61 {
62 size_t retval = 0;
63 for (size_t i = 0; i < (16 / sizeof(size_t)); ++i) {
64 retval ^= ((size_t*)(&_bytes[0]))[i];
65 }
66 return retval;
67 }
68 const unsigned char* get() const { return _bytes; };
69
70 private:
71 uuid_t _bytes;
72 };
73
74 struct BuildQueueEntry {
75 DyldSharedCache::CreateOptions options;
76 dyld3::closure::FileSystemPhysical fileSystem;
77 std::vector<DyldSharedCache::MappedMachO> dylibsForCache;
78 std::vector<DyldSharedCache::MappedMachO> otherDylibsAndBundles;
79 std::vector<DyldSharedCache::MappedMachO> mainExecutables;
80 std::string outputPath;
81 std::set<std::string> configNames;
82 };
83
84 struct Manifest {
85 struct UUIDInfo {
86 const MachOAnalyzer* mh;
87 uint64_t sliceFileOffset;
88 std::size_t size;
89 std::string runtimePath;
90 std::string buildPath;
91 std::string installName;
92 std::string arch;
93 UUID uuid;
94 UUIDInfo(const MachOAnalyzer* M, std::size_t S, uint64_t SO, UUID U, std::string A, std::string RP, std::string BP, std::string IN)
95 : mh(M), size(S), arch(A), uuid(U), runtimePath(RP), buildPath(BP), installName(IN), sliceFileOffset(SO) {}
96 UUIDInfo() : UUIDInfo(nullptr, 0, 0, UUID(), "", "", "", "") {}
97 };
98
99 struct Project {
100 std::vector<std::string> sources;
101 };
102
103
104 struct SegmentInfo {
105 std::string name;
106 uint64_t startAddr;
107 uint64_t endAddr;
108 };
109
110 struct CacheInfo {
111 std::vector<SegmentInfo> regions;
112 std::string cdHash;
113 };
114
115 struct CacheImageInfo {
116 bool included;
117 std::string exclusionInfo;
118 UUID uuid;
119 std::string installname;
120 std::vector<SegmentInfo> segments;
121 CacheImageInfo(void)
122 : included(true)
123 {
124 }
125 };
126
127 struct Results {
128 std::string failure;
129 std::map<UUID, CacheImageInfo> dylibs;
130 std::map<UUID, CacheImageInfo> bundles;
131 std::map<UUID, CacheImageInfo> executables;
132
133 std::set<std::string> warnings;
134 CacheInfo developmentCache;
135 CacheInfo productionCache;
136 CacheImageInfo& dylibForInstallname(const std::string& installname);
137 void exclude(const dyld3::MachOAnalyzer* ml, const std::string& reason);
138 void exclude(Manifest& manifest, const UUID& uuid, const std::string& reason);
139 };
140
141 struct Architecture {
142 mutable Results results;
143
144 bool operator==(const Architecture& O) const;
145 bool operator!=(const Architecture& other) const;
146 };
147
148 struct Configuration {
149 std::string platformName;
150 std::string device;
151 std::string disposition;
152 std::string metabomTag;
153 std::set<std::string> metabomTags;
154 std::set<std::string> metabomExcludeTags;
155 std::set<std::string> metabomRestrictTags;
156 std::set<std::string> restrictedInstallnames;
157 std::map<std::string, Architecture> architectures;
158
159 bool operator==(const Configuration& O) const;
160 bool operator!=(const Configuration& other) const;
161 const Architecture& architecture(const std::string& architecture) const;
162 void forEachArchitecture(std::function<void(const std::string& archName)> lambda) const;
163 };
164
165 const std::map<std::string, Project>& projects();
166 const Configuration& configuration(const std::string& configuration) const;
167 void forEachConfiguration(std::function<void(const std::string& configName)> lambda) const;
168
169 void addProjectSource(const std::string& project, const std::string& source, bool first = false);
170
171 const std::string projectPath(const std::string& projectName);
172 const bool empty(void);
173 const std::string dylibOrderFile() const;
174 void setDylibOrderFile(const std::string& dylibOrderFile);
175
176 const std::string dirtyDataOrderFile() const;
177 void setDirtyDataOrderFile(const std::string& dirtyDataOrderFile);
178
179 const std::string metabomFile() const;
180 void setMetabomFile(const std::string& metabomFile);
181
182 const Platform platform() const;
183 void setPlatform(const Platform platform);
184
185 const std::string& build() const;
186 void setBuild(const std::string& build);
187 const uint32_t version() const;
188 void setVersion(const uint32_t manifestVersion);
189 bool normalized;
190
191 Manifest(Diagnostics& D, const std::string& path, bool populateIt = true);
192 void populate(const std::set<std::string>& overlays);
193
194 BuildQueueEntry makeQueueEntry(const std::string& outputPath, const std::set<std::string>& configs, const std::string& arch, bool optimizeStubs, const std::string& prefix,
195 bool isLocallyBuiltCache, bool skipWrites, bool verbose);
196
197 void write(const std::string& path);
198 void writeJSON(const std::string& path);
199 void canonicalize(void);
200 void calculateClosure();
201 const MachOAnalyzer* machOForUUID(const UUID& uuid) const;
202 const std::string buildPathForUUID(const UUID& uuid);
203 const std::string runtimePathForUUID(const UUID& uuid);
204 const std::string& installNameForUUID(const UUID& uuid);
205 DyldSharedCache::MappedMachO machoForPathAndArch(const std::string& path, const std::string& arch) const;
206 void remove(const std::string& config, const std::string& arch);
207 void runConcurrently(dispatch_queue_t queue, dispatch_semaphore_t concurrencyLimitingSemaphore, std::function<void(const std::string configuration, const std::string architecture)> lambda);
208 bool filterForConfig(const std::string& configName);
209 std::set<std::string> resultsForConfiguration(const std::string& configName);
210
211 // These are used by MRM to support having the Manifest give us a list of files/symlinks from the BOM but we use MRM for the actual cache generation
212 void forEachMachO(std::string configuration, std::function<void(const std::string &buildPath, const std::string &runtimePath, const std::string &arch, bool shouldBeExcludedIfLeaf)> lambda);
213
214 void forEachSymlink(std::string configuration, std::function<void(const std::string &fromPath, const std::string &toPath)> lambda);
215
216 private:
217 NSDictionary* _manifestDict;
218 Diagnostics& _diags;
219 std::map<UUID, UUIDInfo> _uuidMap;
220 std::map<std::pair<std::string, std::string>, UUID> _installNameMap;
221 std::vector<std::pair<std::string, std::string>> _symlinks;
222 static dispatch_queue_t _identifierQueue;
223 uint32_t _manifestVersion;
224 std::string _build;
225 std::string _dylibOrderFile;
226 std::string _dirtyDataOrderFile;
227 std::string _metabomFile;
228 Platform _platform;
229 std::map<std::string, Project> _projects;
230 std::map<std::string, Configuration> _configurations;
231 std::map<std::string, std::set<std::string>> _metabomTagMap;
232 std::map<std::string, std::set<std::string>> _metabomSymlinkTagMap;
233 std::map<std::string, std::set<std::string>> _metabomExcludeTagMap;
234 std::map<std::string, std::set<std::string>> _metabomRestrictedTagMap;
235
236 std::vector<DyldSharedCache::MappedMachO> dylibsForCache(const std::string& configuration, const std::string& architecture);
237 std::vector<DyldSharedCache::MappedMachO> otherDylibsAndBundles(const std::string& configuration, const std::string& architecture);
238 std::vector<DyldSharedCache::MappedMachO> mainExecutables(const std::string& configuration, const std::string& architecture);
239
240 const UUIDInfo& infoForUUID(const UUID& uuid) const;
241 const UUIDInfo infoForInstallNameAndarch(const std::string& installName, const std::string arch) const;
242 void insert(std::vector<DyldSharedCache::MappedMachO>& mappedMachOs, const CacheImageInfo& imageInfo);
243 bool loadParser(const void* p, size_t sliceLength, uint64_t sliceOffset, const std::string& runtimePath, const std::string& buildPath, const std::set<std::string>& architectures);
244 bool loadParsers(const std::string& pathToMachO, const std::string& runtimePath, const std::set<std::string>& architectures);
245 void dedupeDispositions();
246 void calculateClosure(const std::string& configuration, const std::string& architecture);
247 void canonicalizeDylib(const std::string& installname);
248 template <typename P>
249 void canonicalizeDylib(const std::string& installname, const uint8_t* p);
250 void addImplicitAliases(void);
251 };
252 }
253
254 namespace std {
255 template <>
256 struct hash<dyld3::UUID> {
257 size_t operator()(const dyld3::UUID& x) const
258 {
259 return x.hash();
260 }
261 };
262 }
263
264 #endif /* Manifest_h */