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"
45 #include "ClosureFileSystemPhysical.h"
47 extern std::string
toolDir();
51 struct VIS_HIDDEN 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
); }
63 for (size_t i
= 0; i
< (16 / sizeof(size_t)); ++i
) {
64 retval
^= ((size_t*)(&_bytes
[0]))[i
];
68 const unsigned char* get() const { return _bytes
; };
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
;
86 const MachOAnalyzer
* mh
;
87 uint64_t sliceFileOffset
;
89 std::string runtimePath
;
90 std::string buildPath
;
91 std::string installName
;
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(), "", "", "", "") {}
100 std::vector
<std::string
> sources
;
111 std::vector
<SegmentInfo
> regions
;
115 struct CacheImageInfo
{
117 std::string exclusionInfo
;
119 std::string installname
;
120 std::vector
<SegmentInfo
> segments
;
129 std::map
<UUID
, CacheImageInfo
> dylibs
;
130 std::map
<UUID
, CacheImageInfo
> bundles
;
131 std::map
<UUID
, CacheImageInfo
> executables
;
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
);
141 struct Architecture
{
142 mutable Results results
;
144 bool operator==(const Architecture
& O
) const;
145 bool operator!=(const Architecture
& other
) const;
148 struct Configuration
{
149 std::string platformName
;
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
;
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;
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;
169 void addProjectSource(const std::string
& project
, const std::string
& source
, bool first
= false);
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
);
176 const std::string
dirtyDataOrderFile() const;
177 void setDirtyDataOrderFile(const std::string
& dirtyDataOrderFile
);
179 const std::string
metabomFile() const;
180 void setMetabomFile(const std::string
& metabomFile
);
182 const Platform
platform() const;
183 void setPlatform(const Platform platform
);
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
);
191 Manifest(Diagnostics
& D
, const std::string
& path
, bool populateIt
= true);
192 void populate(const std::set
<std::string
>& overlays
);
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
);
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
);
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
);
214 void forEachSymlink(std::string configuration
, std::function
<void(const std::string
&fromPath
, const std::string
&toPath
)> lambda
);
217 NSDictionary
* _manifestDict
;
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
;
225 std::string _dylibOrderFile
;
226 std::string _dirtyDataOrderFile
;
227 std::string _metabomFile
;
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
;
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
);
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);
256 struct hash
<dyld3::UUID
> {
257 size_t operator()(const dyld3::UUID
& x
) const
264 #endif /* Manifest_h */