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@
34 #include <unordered_map>
35 #include <unordered_set>
38 #include <uuid/uuid.h>
40 #import <Foundation/Foundation.h>
42 #include "DyldSharedCache.h"
43 #include "Diagnostics.h"
44 #include "MachOAnalyzer.h"
46 extern std::string
toolDir();
50 struct VIS_HIDDEN UUID
{
52 UUID(const UUID
& other
) { uuid_copy(_bytes
, other
._bytes
); }
53 UUID(const uuid_t other
) { uuid_copy(&_bytes
[0], other
); }
54 UUID(const dyld3::MachOAnalyzer
* ml
) { ml
->getUuid(_bytes
); }
55 bool operator<(const UUID
& other
) const { return uuid_compare(_bytes
, other
._bytes
) < 0; }
56 bool operator==(const UUID
& other
) const { return uuid_compare(_bytes
, other
._bytes
) == 0; }
57 bool operator!=(const UUID
& other
) const { return !(*this == other
); }
62 for (size_t i
= 0; i
< (16 / sizeof(size_t)); ++i
) {
63 retval
^= ((size_t*)(&_bytes
[0]))[i
];
67 const unsigned char* get() const { return _bytes
; };
73 struct BuildQueueEntry
{
74 DyldSharedCache::CreateOptions options
;
75 std::vector
<DyldSharedCache::MappedMachO
> dylibsForCache
;
76 std::vector
<DyldSharedCache::MappedMachO
> otherDylibsAndBundles
;
77 std::vector
<DyldSharedCache::MappedMachO
> mainExecutables
;
78 std::string outputPath
;
79 std::set
<std::string
> configNames
;
84 const MachOAnalyzer
* mh
;
85 uint64_t sliceFileOffset
;
87 std::string runtimePath
;
88 std::string buildPath
;
89 std::string installName
;
92 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
)
93 : mh(M
), size(S
), arch(A
), uuid(U
), runtimePath(RP
), buildPath(BP
), installName(IN
), sliceFileOffset(SO
) {}
94 UUIDInfo() : UUIDInfo(nullptr, 0, 0, UUID(), "", "", "", "") {}
98 std::vector
<std::string
> sources
;
109 std::vector
<SegmentInfo
> regions
;
113 struct CacheImageInfo
{
115 std::string exclusionInfo
;
117 std::string installname
;
118 std::vector
<SegmentInfo
> segments
;
127 std::map
<UUID
, CacheImageInfo
> dylibs
;
128 std::map
<UUID
, CacheImageInfo
> bundles
;
129 std::map
<UUID
, CacheImageInfo
> executables
;
131 std::set
<std::string
> warnings
;
132 CacheInfo developmentCache
;
133 CacheInfo productionCache
;
134 CacheImageInfo
& dylibForInstallname(const std::string
& installname
);
135 void exclude(const dyld3::MachOAnalyzer
* ml
, const std::string
& reason
);
136 void exclude(Manifest
& manifest
, const UUID
& uuid
, const std::string
& reason
);
139 struct Architecture
{
140 mutable Results results
;
142 bool operator==(const Architecture
& O
) const;
143 bool operator!=(const Architecture
& other
) const;
146 struct Configuration
{
147 std::string platformName
;
149 std::string disposition
;
150 std::string metabomTag
;
151 std::set
<std::string
> metabomTags
;
152 std::set
<std::string
> metabomExcludeTags
;
153 std::set
<std::string
> metabomRestrictTags
;
154 std::set
<std::string
> restrictedInstallnames
;
155 std::map
<std::string
, Architecture
> architectures
;
157 bool operator==(const Configuration
& O
) const;
158 bool operator!=(const Configuration
& other
) const;
159 const Architecture
& architecture(const std::string
& architecture
) const;
160 void forEachArchitecture(std::function
<void(const std::string
& archName
)> lambda
) const;
163 const std::map
<std::string
, Project
>& projects();
164 const Configuration
& configuration(const std::string
& configuration
) const;
165 void forEachConfiguration(std::function
<void(const std::string
& configName
)> lambda
) const;
167 void addProjectSource(const std::string
& project
, const std::string
& source
, bool first
= false);
169 const std::string
projectPath(const std::string
& projectName
);
170 const bool empty(void);
171 const std::string
dylibOrderFile() const;
172 void setDylibOrderFile(const std::string
& dylibOrderFile
);
174 const std::string
dirtyDataOrderFile() const;
175 void setDirtyDataOrderFile(const std::string
& dirtyDataOrderFile
);
177 const std::string
metabomFile() const;
178 void setMetabomFile(const std::string
& metabomFile
);
180 const Platform
platform() const;
181 void setPlatform(const Platform platform
);
183 const std::string
& build() const;
184 void setBuild(const std::string
& build
);
185 const uint32_t version() const;
186 void setVersion(const uint32_t manifestVersion
);
189 Manifest(Diagnostics
& D
, const std::string
& path
, bool onlyParseManifest
= false);
190 Manifest(Diagnostics
& D
, const std::string
& path
, const std::set
<std::string
>& overlays
, bool onlyParseManifest
= false);
192 BuildQueueEntry
makeQueueEntry(const std::string
& outputPath
, const std::set
<std::string
>& configs
, const std::string
& arch
, bool optimizeStubs
, const std::string
& prefix
,
193 bool isLocallyBuiltCache
, bool skipWrites
, bool verbose
);
195 void write(const std::string
& path
);
196 void writeJSON(const std::string
& path
);
197 void canonicalize(void);
198 void calculateClosure();
199 const MachOAnalyzer
* machOForUUID(const UUID
& uuid
) const;
200 const std::string
buildPathForUUID(const UUID
& uuid
);
201 const std::string
runtimePathForUUID(const UUID
& uuid
);
202 const std::string
& installNameForUUID(const UUID
& uuid
);
203 DyldSharedCache::MappedMachO
machoForPathAndArch(const std::string
& path
, const std::string
& arch
) const;
204 void remove(const std::string
& config
, const std::string
& arch
);
205 void runConcurrently(dispatch_queue_t queue
, dispatch_semaphore_t concurrencyLimitingSemaphore
, std::function
<void(const std::string configuration
, const std::string architecture
)> lambda
);
206 bool filterForConfig(const std::string
& configName
);
207 std::set
<std::string
> resultsForConfiguration(const std::string
& configName
);
209 // 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
210 void forEachMachO(std::string configuration
, std::function
<void(const std::string
&buildPath
, const std::string
&runtimePath
, const std::string
&arch
, bool shouldBeExcludedIfLeaf
)> lambda
);
212 void forEachSymlink(std::string configuration
, std::function
<void(const std::string
&fromPath
, const std::string
&toPath
)> lambda
);
215 NSDictionary
* _manifestDict
;
217 std::map
<UUID
, UUIDInfo
> _uuidMap
;
218 std::map
<std::pair
<std::string
, std::string
>, UUID
> _installNameMap
;
219 std::vector
<std::pair
<std::string
, std::string
>> _symlinks
;
220 static dispatch_queue_t _identifierQueue
;
221 uint32_t _manifestVersion
;
223 std::string _dylibOrderFile
;
224 std::string _dirtyDataOrderFile
;
225 std::string _metabomFile
;
227 std::map
<std::string
, Project
> _projects
;
228 std::map
<std::string
, Configuration
> _configurations
;
229 std::map
<std::string
, std::set
<std::string
>> _metabomTagMap
;
230 std::map
<std::string
, std::set
<std::string
>> _metabomSymlinkTagMap
;
231 std::map
<std::string
, std::set
<std::string
>> _metabomExcludeTagMap
;
232 std::map
<std::string
, std::set
<std::string
>> _metabomRestrictedTagMap
;
234 std::vector
<DyldSharedCache::MappedMachO
> dylibsForCache(const std::string
& configuration
, const std::string
& architecture
);
235 std::vector
<DyldSharedCache::MappedMachO
> otherDylibsAndBundles(const std::string
& configuration
, const std::string
& architecture
);
236 std::vector
<DyldSharedCache::MappedMachO
> mainExecutables(const std::string
& configuration
, const std::string
& architecture
);
238 const UUIDInfo
& infoForUUID(const UUID
& uuid
) const;
239 const UUIDInfo
infoForInstallNameAndarch(const std::string
& installName
, const std::string arch
) const;
240 void insert(std::vector
<DyldSharedCache::MappedMachO
>& mappedMachOs
, const CacheImageInfo
& imageInfo
);
241 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
);
242 bool loadParsers(const std::string
& pathToMachO
, const std::string
& runtimePath
, const std::set
<std::string
>& architectures
);
243 void dedupeDispositions();
244 void calculateClosure(const std::string
& configuration
, const std::string
& architecture
);
245 void canonicalizeDylib(const std::string
& installname
);
246 template <typename P
>
247 void canonicalizeDylib(const std::string
& installname
, const uint8_t* p
);
248 void addImplicitAliases(void);
254 struct hash
<dyld3::UUID
> {
255 size_t operator()(const dyld3::UUID
& x
) const
262 #endif /* Manifest_h */