dyld-832.7.1.tar.gz
[apple/dyld.git] / dyld3 / shared-cache / SharedCacheBuilder.h
1 /*
2 * Copyright (c) 2017 Apple Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
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
11 * file.
12 *
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.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24
25 #ifndef SharedCacheBuilder_h
26 #define SharedCacheBuilder_h
27
28 #include "CacheBuilder.h"
29 #include "DyldSharedCache.h"
30 #include "ClosureFileSystem.h"
31 #include "IMPCachesBuilder.hpp"
32
33 class SharedCacheBuilder : public CacheBuilder {
34 public:
35 SharedCacheBuilder(const DyldSharedCache::CreateOptions& options, const dyld3::closure::FileSystem& fileSystem);
36
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);
47
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;
53 void deleteBuffer();
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;
60
61 void forEachCacheDylib(void (^callback)(const std::string& path));
62 void forEachCacheSymlink(void (^callback)(const std::string& path));
63
64 void forEachDylibInfo(void (^callback)(const DylibInfo& dylib, Diagnostics& dylibDiag)) override final;
65
66 private:
67
68 void writeSlideInfoV1();
69
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);
74
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);
78
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);
83
84 struct ArchLayout
85 {
86 uint64_t sharedMemoryStart;
87 uint64_t sharedMemorySize;
88 uint64_t sharedRegionPadding;
89 uint64_t pointerDeltaMask;
90 const char* archName;
91 uint16_t csPageSize;
92 uint8_t sharedRegionAlignP2;
93 uint8_t slideInfoBytesPerPage;
94 bool sharedRegionsAreDiscontiguous;
95 bool is64;
96 bool useValueAdd;
97 };
98
99 static const ArchLayout _s_archLayout[];
100 static const char* const _s_neverStubEliminateSymbols[];
101
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);
107
108 uint64_t dataRegionsTotalSize() const;
109 uint64_t dataRegionsSizeInUse() const;
110
111 // Return the earliest data region by address
112 const Region* firstDataRegion() const;
113
114 // Return the lateset data region by address
115 const Region* lastDataRegion() const;
116
117 uint64_t cacheOverflowAmount();
118 size_t evictLeafDylibs(uint64_t reductionTarget, std::vector<const LoadedMachO*>& overflowDylibs);
119
120 void fipsSign();
121 void codeSign();
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();
130
131 bool writeCache(void (^cacheSizeCallback)(uint64_t size), bool (^copyCallback)(const uint8_t* src, uint64_t size, uint64_t dstOffset));
132
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);
137
138 void emitContantObjects();
139
140 typedef std::unordered_map<std::string, const dyld3::MachOAnalyzer*> InstallNameToMA;
141
142 typedef uint64_t CacheOffset;
143
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 _selectorStringsFromExecutables = 0;
156 InstallNameToMA _installNameToCacheDylib;
157 std::unordered_map<std::string, uint32_t> _dataDirtySegsOrder;
158 std::map<void*, std::string> _missingWeakImports;
159 const dyld3::closure::ImageArray* _imageArray = nullptr;
160 uint8_t _cdHashFirst[20];
161 uint8_t _cdHashSecond[20];
162 bool _someDylibsUsedChainedFixups = false;
163 std::unordered_map<const dyld3::MachOLoaded*, std::set<CacheOffset>> _dylibToItsExports;
164 std::set<std::pair<const dyld3::MachOLoaded*, CacheOffset>> _dylibWeakExports;
165 std::unordered_map<CacheOffset, std::vector<dyld_cache_patchable_location>> _exportsToUses;
166 std::unordered_map<CacheOffset, std::string> _exportsToName;
167 IMPCaches::IMPCachesBuilder* _impCachesBuilder;
168 };
169
170
171
172 #endif /* SharedCacheBuilder_h */