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@
25 #ifndef SharedCacheBuilder_h
26 #define SharedCacheBuilder_h
28 #include "CacheBuilder.h"
29 #include "DyldSharedCache.h"
30 #include "ClosureFileSystem.h"
31 #include "IMPCachesBuilder.hpp"
33 class SharedCacheBuilder
: public CacheBuilder
{
35 SharedCacheBuilder(const DyldSharedCache::CreateOptions
& options
, const dyld3::closure::FileSystem
& fileSystem
);
37 void build(std::vector
<InputFile
>& inputFiles
,
38 std::vector
<DyldSharedCache::FileAlias
>& aliases
);
39 void build(const std::vector
<LoadedMachO
>& dylibs
,
40 const std::vector
<LoadedMachO
>& otherOsDylibsInput
,
41 const std::vector
<LoadedMachO
>& osExecutables
,
42 std::vector
<DyldSharedCache::FileAlias
>& aliases
);
43 void build(const std::vector
<DyldSharedCache::MappedMachO
>& dylibsToCache
,
44 const std::vector
<DyldSharedCache::MappedMachO
>& otherOsDylibs
,
45 const std::vector
<DyldSharedCache::MappedMachO
>& osExecutables
,
46 std::vector
<DyldSharedCache::FileAlias
>& aliases
);
48 void writeFile(const std::string
& path
);
49 void writeBuffer(uint8_t*& buffer
, uint64_t& size
);
50 void writeMapFile(const std::string
& path
);
51 std::string
getMapFileBuffer() const;
52 std::string
getMapFileJSONBuffer(const std::string
& cacheDisposition
) const;
54 const std::set
<std::string
> warnings();
55 const std::set
<const dyld3::MachOAnalyzer
*> evictions();
56 const bool agileSignature();
57 const std::string
cdHashFirst();
58 const std::string
cdHashSecond();
59 const std::string
uuid() const;
61 void forEachCacheDylib(void (^callback
)(const std::string
& path
));
62 void forEachCacheSymlink(void (^callback
)(const std::string
& path
));
64 void forEachDylibInfo(void (^callback
)(const DylibInfo
& dylib
, Diagnostics
& dylibDiag
)) override final
;
68 void writeSlideInfoV1();
70 template <typename P
> void writeSlideInfoV2(const bool bitmap
[], unsigned dataPageCount
);
71 template <typename P
> bool makeRebaseChainV2(uint8_t* pageContent
, uint16_t lastLocationOffset
, uint16_t newOffset
, const struct dyld_cache_slide_info2
* info
);
72 template <typename P
> void addPageStartsV2(uint8_t* pageContent
, const bool bitmap
[], const struct dyld_cache_slide_info2
* info
,
73 std::vector
<uint16_t>& pageStarts
, std::vector
<uint16_t>& pageExtras
);
75 void writeSlideInfoV3(const bool bitmap
[], unsigned dataPageCoun
);
76 uint16_t pageStartV3(uint8_t* pageContent
, uint32_t pageSize
, const bool bitmap
[]);
77 void setPointerContentV3(dyld3::MachOLoaded::ChainedFixupPointerOnDisk
* loc
, uint64_t targetVMAddr
, size_t next
);
79 template <typename P
> void writeSlideInfoV4(const bool bitmap
[], unsigned dataPageCount
);
80 template <typename P
> bool makeRebaseChainV4(uint8_t* pageContent
, uint16_t lastLocationOffset
, uint16_t newOffset
, const struct dyld_cache_slide_info4
* info
);
81 template <typename P
> void addPageStartsV4(uint8_t* pageContent
, const bool bitmap
[], const struct dyld_cache_slide_info4
* info
,
82 std::vector
<uint16_t>& pageStarts
, std::vector
<uint16_t>& pageExtras
);
86 uint64_t sharedMemoryStart
;
87 uint64_t sharedMemorySize
;
88 uint64_t sharedRegionPadding
;
89 uint64_t pointerDeltaMask
;
92 uint8_t sharedRegionAlignP2
;
93 uint8_t slideInfoBytesPerPage
;
94 bool sharedRegionsAreDiscontiguous
;
99 static const ArchLayout _s_archLayout
[];
100 static const char* const _s_neverStubEliminateSymbols
[];
102 void makeSortedDylibs(const std::vector
<LoadedMachO
>& dylibs
, const std::unordered_map
<std::string
, unsigned> sortOrder
);
103 void processSelectorStrings(const std::vector
<LoadedMachO
>& executables
, IMPCaches::HoleMap
& selectorsHoleMap
);
104 void parseCoalescableSegments(IMPCaches::SelectorMap
& selectorMap
, IMPCaches::HoleMap
& selectorsHoleMap
);
105 void assignSegmentAddresses();
106 void assignMultipleDataSegmentAddresses(uint64_t& addr
, uint32_t totalProtocolDefCount
);
108 uint64_t dataRegionsTotalSize() const;
109 uint64_t dataRegionsSizeInUse() const;
111 // Return the earliest data region by address
112 const Region
* firstDataRegion() const;
114 // Return the lateset data region by address
115 const Region
* lastDataRegion() const;
117 uint64_t cacheOverflowAmount();
118 size_t evictLeafDylibs(uint64_t reductionTarget
, std::vector
<const LoadedMachO
*>& overflowDylibs
);
122 uint64_t pathHash(const char* path
);
123 void writeCacheHeader();
124 void findDylibAndSegment(const void* contentPtr
, std::string
& dylibName
, std::string
& segName
);
125 void addImageArray();
126 void buildImageArray(std::vector
<DyldSharedCache::FileAlias
>& aliases
);
127 void addOtherImageArray(const std::vector
<LoadedMachO
>&, std::vector
<const LoadedMachO
*>& overflowDylibs
);
128 void addClosures(const std::vector
<LoadedMachO
>&);
129 void markPaddingInaccessible();
131 bool writeCache(void (^cacheSizeCallback
)(uint64_t size
), bool (^copyCallback
)(const uint8_t* src
, uint64_t size
, uint64_t dstOffset
));
133 // implemented in OptimizerObjC.cpp
134 void optimizeObjC(bool impCachesSuccess
, const std::vector
<const IMPCaches::Selector
*> & inlinedSelectors
);
135 uint32_t computeReadOnlyObjC(uint32_t selRefCount
, uint32_t classDefCount
, uint32_t protocolDefCount
);
136 uint32_t computeReadWriteObjC(uint32_t imageCount
, uint32_t protocolDefCount
);
138 void emitContantObjects();
140 typedef std::unordered_map
<std::string
, const dyld3::MachOAnalyzer
*> InstallNameToMA
;
142 typedef uint64_t CacheOffset
;
144 std::vector
<DylibInfo
> _sortedDylibs
;
145 std::vector
<Region
> _dataRegions
; // 1 or more __DATA regions.
146 UnmappedRegion _codeSignatureRegion
;
147 std::set
<const dyld3::MachOAnalyzer
*> _evictions
;
148 const ArchLayout
* _archLayout
= nullptr;
149 uint32_t _aliasCount
= 0;
150 uint8_t* _objcReadOnlyBuffer
= nullptr;
151 uint64_t _objcReadOnlyBufferSizeUsed
= 0;
152 uint64_t _objcReadOnlyBufferSizeAllocated
= 0;
153 uint8_t* _objcReadWriteBuffer
= nullptr;
154 uint64_t _objcReadWriteBufferSizeAllocated
= 0;
155 uint64_t _objcReadWriteFileOffset
= 0;
156 uint64_t _selectorStringsFromExecutables
= 0;
157 InstallNameToMA _installNameToCacheDylib
;
158 std::unordered_map
<std::string
, uint32_t> _dataDirtySegsOrder
;
159 std::map
<void*, std::string
> _missingWeakImports
;
160 const dyld3::closure::ImageArray
* _imageArray
= nullptr;
161 uint8_t _cdHashFirst
[20];
162 uint8_t _cdHashSecond
[20];
163 bool _someDylibsUsedChainedFixups
= false;
164 std::unordered_map
<const dyld3::MachOLoaded
*, std::set
<CacheOffset
>> _dylibToItsExports
;
165 std::set
<std::pair
<const dyld3::MachOLoaded
*, CacheOffset
>> _dylibWeakExports
;
166 std::unordered_map
<CacheOffset
, std::vector
<dyld_cache_patchable_location
>> _exportsToUses
;
167 std::unordered_map
<CacheOffset
, std::string
> _exportsToName
;
168 IMPCaches::IMPCachesBuilder
* _impCachesBuilder
;
173 #endif /* SharedCacheBuilder_h */