5 // Created by Louis Gerbarg on 7/23/15.
17 #include <unordered_map>
18 #include <unordered_set>
27 std::vector
<std::string
> sources
;
33 File( MachOProxy
* P
) : proxy( P
) {}
37 std::map
<std::string
, File
> dylibs
;
38 std::map
<std::string
, File
> executables
;
42 std::string installname
;
45 Anchor( const std::string
& IN
) : installname( IN
) {}
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
);
61 std::vector
<SegmentInfo
> regions
;
67 std::string exclusionInfo
;
69 std::vector
<SegmentInfo
> segments
;
70 DylibInfo(void) : included(true) {}
71 void exclude(const std::string
& reason
) {
73 exclusionInfo
= reason
;
79 std::map
<std::string
, DylibInfo
> dylibs
;
80 std::vector
<std::string
> warnings
;
81 CacheInfo developmentCache
;
82 CacheInfo productionCache
;
86 std::vector
<Anchor
> anchors
;
87 mutable Results results
;
89 std::unordered_map
<std::string
, std::unordered_set
<std::string
>> dependents
;
91 uint64_t hash(void) const {
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]));
105 bool equivalent(const Architecture
& O
) const {
106 if (hash() != O
.hash()) {
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)
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)
130 mutable uint64_t _hash
= 0;
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
;
141 uint64_t hash( void ) const {
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();
153 bool equivalent(const Configuration
& O
) const {
154 if (hash() != O
.hash())
156 for (const auto& arch
: architectures
) {
157 if (O
.architectures
.count(arch
.first
) == 0)
159 if (!arch
.second
.equivalent(O
.architectures
.find(arch
.first
)->second
))
166 mutable uint64_t _hash
= 0;
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
;
176 // FIXME every needs to adopt platform string for v5
177 std::string platform
;
178 uint32_t manifest_version
;
183 Manifest( const std::string
& path
);
184 Manifest( const std::string
& path
, const std::set
<std::string
>& overlays
);
186 void write( const std::string
& path
);
187 void canonicalize( void );
188 void calculateClosure( bool enforeceRootless
);
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
);
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 );
208 #endif /* Manifest_h */