]> git.saurik.com Git - apple/dyld.git/blob - interlinked-dylibs/Manifest.h
dyld-421.2.tar.gz
[apple/dyld.git] / interlinked-dylibs / Manifest.h
1 //
2 // Manifest.h
3 // dyld
4 //
5 // Created by Louis Gerbarg on 7/23/15.
6 //
7 //
8
9 #ifndef Manifest_h
10 #define Manifest_h
11
12 #include <map>
13 #include <set>
14 #include <string>
15 #include <vector>
16
17 #include <unordered_map>
18 #include <unordered_set>
19
20
21 struct SharedCache;
22 struct MachOProxy;
23 struct Manifest;
24
25 struct Manifest {
26 struct Project {
27 std::vector<std::string> sources;
28 };
29
30 struct File {
31 MachOProxy* proxy;
32
33 File( MachOProxy* P ) : proxy( P ) {}
34 };
35
36 struct FileSet {
37 std::map<std::string, File> dylibs;
38 std::map<std::string, File> executables;
39 };
40
41 struct Anchor {
42 std::string installname;
43 bool required;
44
45 Anchor( const std::string& IN ) : installname( IN ) {}
46 };
47
48 struct SegmentInfo {
49 std::string name;
50 uint64_t startAddr;
51 uint64_t endAddr;
52 };
53
54 struct SegmentInfoHasher {
55 std::size_t operator()(const SegmentInfo &x) const {
56 return std::hash<std::string>()(x.name) ^ std::hash<uint64_t>()(x.startAddr) ^ std::hash<uint64_t>()(x.endAddr);
57 }
58 };
59
60 struct CacheInfo {
61 std::vector<SegmentInfo> regions;
62 std::string cdHash;
63 };
64
65 struct DylibInfo {
66 bool included;
67 std::string exclusionInfo;
68 uuid_t uuid;
69 std::vector<SegmentInfo> segments;
70 DylibInfo(void) : included(true) {}
71 void exclude(const std::string& reason) {
72 included = false;
73 exclusionInfo = reason;
74 }
75 };
76
77 struct Results {
78 std::string failure;
79 std::map<std::string, DylibInfo> dylibs;
80 std::vector<std::string> warnings;
81 CacheInfo developmentCache;
82 CacheInfo productionCache;
83 };
84
85 struct Architecture {
86 std::vector<Anchor> anchors;
87 mutable Results results;
88 //FIXME: Gross
89 std::unordered_map<std::string, std::unordered_set<std::string>> dependents;
90
91 uint64_t hash(void) const {
92 if (!_hash) {
93 for (auto& dylib : results.dylibs) {
94 if (dylib.second.included) {
95 _hash ^= std::hash<std::string>()(dylib.first);
96 //HACK to get some of the UUID into the hash
97 _hash ^= std::hash<uint64_t>()(*(uint64_t *)(&dylib.second.uuid[0]));
98 }
99 };
100 }
101
102 return _hash;
103 }
104
105 bool equivalent(const Architecture& O) const {
106 if (hash() != O.hash()) {
107 return false;
108 }
109 for (auto& dylib : results.dylibs) {
110 if (dylib.second.included) {
111 auto Odylib = O.results.dylibs.find(dylib.first);
112 if (Odylib == O.results.dylibs.end()
113 || Odylib->second.included == false
114 || memcmp(&Odylib->second.uuid[0], &dylib.second.uuid[0], sizeof(uuid_t)) != 0)
115 return false;
116 }
117 }
118 //Iterate over O.results to make sure we included all the same things
119 for (auto Odylib : O.results.dylibs) {
120 if (Odylib.second.included) {
121 auto dylib = results.dylibs.find(Odylib.first);
122 if (dylib == results.dylibs.end()
123 || dylib->second.included == false)
124 return false;
125 }
126 }
127 return true;
128 }
129 private:
130 mutable uint64_t _hash = 0;
131 };
132
133 struct Configuration {
134 std::string platformName;
135 std::string metabomTag;
136 std::set<std::string> metabomExcludeTags;
137 std::set<std::string> metabomRestrictTags;
138 std::set<std::string> restrictedInstallnames;
139 std::map<std::string, Architecture> architectures;
140
141 uint64_t hash( void ) const {
142 if (!_hash) {
143 _hash ^= std::hash<size_t>()(architectures.size());
144 // We want the preliminary info here to make dedupe decisions
145 for (auto& arch : architectures) {
146 _hash ^= arch.second.hash();
147 };
148 }
149 return _hash;
150 }
151
152 //Used for dedupe
153 bool equivalent(const Configuration& O) const {
154 if (hash() != O.hash())
155 return false;
156 for (const auto& arch : architectures) {
157 if (O.architectures.count(arch.first) == 0)
158 return false;
159 if (!arch.second.equivalent(O.architectures.find(arch.first)->second))
160 return false;
161 }
162
163 return true;
164 }
165 private:
166 mutable uint64_t _hash = 0;
167 };
168
169 std::map<std::string, FileSet> architectureFiles;
170 std::map<std::string, Project> projects;
171 std::map<std::string, Configuration> configurations;
172 std::string dylibOrderFile;
173 std::string dirtyDataOrderFile;
174 std::string metabomFile;
175 std::string build;
176 // FIXME every needs to adopt platform string for v5
177 std::string platform;
178 uint32_t manifest_version;
179 bool normalized;
180
181 Manifest( void ) {}
182 #if BOM_SUPPORT
183 Manifest( const std::string& path );
184 Manifest( const std::string& path, const std::set<std::string>& overlays );
185 #endif
186 void write( const std::string& path );
187 void canonicalize( void );
188 void calculateClosure( bool enforeceRootless );
189 void pruneClosure();
190 bool sameContentsAsCacheAtPath( const std::string& configuration, const std::string& architecture,
191 const std::string& path ) const;
192 MachOProxy* dylibProxy( const std::string& installname, const std::string& arch );
193 MachOProxy* removeLargestLeafDylib( const std::string& configuration, const std::string& architecture );
194
195 private:
196 void removeDylib( MachOProxy* proxy, const std::string& reason, const std::string& configuration, const std::string& architecture,
197 std::unordered_set<std::string>& processedInstallnames );
198 File* dylibForInstallName( const std::string& installname, const std::string& arch );
199 void calculateClosure( const std::string& configuration, const std::string& architecture);
200 void pruneClosure(const std::string& configuration, const std::string& architecture);
201 void canonicalizeDylib( const std::string& installname );
202 template <typename P>
203 void canonicalizeDylib( const std::string& installname, const uint8_t* p );
204 void addImplicitAliases( void );
205 };
206
207
208 #endif /* Manifest_h */