dyld-551.3.tar.gz
[apple/dyld.git] / dyld3 / shared-cache / CacheBuilder.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 CacheBuilder_h
26 #define CacheBuilder_h
27
28 #include <string>
29 #include <vector>
30 #include <unordered_map>
31 #include <unordered_set>
32
33 #include "DyldSharedCache.h"
34 #include "Diagnostics.h"
35 #include "ImageProxy.h"
36
37
38 namespace dyld3 {
39 namespace launch_cache {
40 namespace binary_format {
41 struct ImageGroup;
42 struct Closure;
43 }
44 }
45 }
46
47
48 struct CacheBuilder {
49
50 CacheBuilder(const DyldSharedCache::CreateOptions& options);
51
52 void build(const std::vector<DyldSharedCache::MappedMachO>& dylibsToCache,
53 const std::vector<DyldSharedCache::MappedMachO>& otherOsDylibs,
54 const std::vector<DyldSharedCache::MappedMachO>& osExecutables);
55 void deleteBuffer();
56 const DyldSharedCache* buffer() { return _buffer; }
57 size_t bufferSize() { return (size_t)_allocatedBufferSize; }
58 std::string errorMessage();
59 const std::set<std::string> warnings();
60 const std::set<const mach_header*> evictions();
61 const bool agileSignature();
62 const std::string cdHashFirst();
63 const std::string cdHashSecond();
64
65 struct SegmentMappingInfo {
66 const void* srcSegment;
67 const char* segName;
68 uint64_t dstCacheAddress;
69 uint32_t dstCacheOffset;
70 uint32_t dstCacheSegmentSize;
71 uint32_t copySegmentSize;
72 uint32_t srcSegmentIndex;
73 };
74
75 private:
76
77 typedef std::unordered_map<const mach_header*, std::vector<SegmentMappingInfo>> SegmentMapping;
78
79 struct ArchLayout
80 {
81 uint64_t sharedMemoryStart;
82 uint64_t sharedMemorySize;
83 uint64_t sharedRegionPadding;
84 uint64_t pointerDeltaMask;
85 const char* archName;
86 uint32_t branchPoolTextSize;
87 uint32_t branchPoolLinkEditSize;
88 uint32_t branchReach;
89 uint8_t sharedRegionAlignP2;
90 bool sharedRegionsAreDiscontiguous;
91 bool is64;
92 };
93
94 static const ArchLayout _s_archLayout[];
95 static const char* const _s_neverStubEliminate[];
96
97 std::vector<DyldSharedCache::MappedMachO> makeSortedDylibs(const std::vector<DyldSharedCache::MappedMachO>& dylibs, const std::unordered_map<std::string, unsigned> sortOrder);
98
99 SegmentMapping assignSegmentAddresses(const std::vector<DyldSharedCache::MappedMachO>& dylibs, struct dyld_cache_mapping_info regions[3]);
100
101 bool cacheOverflow(const dyld_cache_mapping_info regions[3]);
102 void adjustImageForNewSegmentLocations(const std::vector<uint64_t>& segNewStartAddresses,
103 const std::vector<uint64_t>& segCacheFileOffsets,
104 const std::vector<uint64_t>& segCacheSizes, std::vector<void*>& pointersForASLR);
105
106 void fipsSign();
107 void codeSign();
108 uint64_t pathHash(const char* path);
109 void writeCacheHeader(const struct dyld_cache_mapping_info regions[3], const std::vector<DyldSharedCache::MappedMachO>& dylibs, const SegmentMapping&);
110 void copyRawSegments(const std::vector<DyldSharedCache::MappedMachO>& dylibs, const SegmentMapping& mapping);
111 void adjustAllImagesForNewSegmentLocations(const std::vector<DyldSharedCache::MappedMachO>& dylibs, const SegmentMapping& mapping);
112 void bindAllImagesInCacheFile(const dyld_cache_mapping_info regions[3]);
113 void writeSlideInfoV1();
114 void recomputeCacheUUID(void);
115 void findDylibAndSegment(const void* contentPtr, std::string& dylibName, std::string& segName);
116
117 void addCachedDylibsImageGroup(dyld3::ImageProxyGroup*);
118 void addCachedOtherDylibsImageGroup(dyld3::ImageProxyGroup*);
119 void addClosures(const std::map<std::string, const dyld3::launch_cache::binary_format::Closure*>& closures);
120
121 template <typename P> void writeSlideInfoV2();
122 template <typename P> bool makeRebaseChain(uint8_t* pageContent, uint16_t lastLocationOffset, uint16_t newOffset, const struct dyld_cache_slide_info2* info);
123 template <typename P> void addPageStarts(uint8_t* pageContent, const bool bitmap[], const struct dyld_cache_slide_info2* info,
124 std::vector<uint16_t>& pageStarts, std::vector<uint16_t>& pageExtras);
125
126
127 const DyldSharedCache::CreateOptions& _options;
128 DyldSharedCache* _buffer;
129 Diagnostics _diagnostics;
130 std::set<const mach_header*> _evictions;
131 const ArchLayout* _archLayout;
132 uint32_t _aliasCount;
133 uint64_t _slideInfoFileOffset;
134 uint64_t _slideInfoBufferSizeAllocated;
135 uint64_t _allocatedBufferSize;
136 uint64_t _currentFileSize;
137 uint64_t _vmSize;
138 std::unordered_map<std::string, uint32_t> _dataDirtySegsOrder;
139 std::vector<void*> _pointersForASLR;
140 dyld3::ImageProxyGroup::PatchTable _patchTable;
141 std::vector<uint64_t> _branchPoolStarts;
142 uint64_t _branchPoolsLinkEditStartAddr;
143 uint8_t _cdHashFirst[20];
144 uint8_t _cdHashSecond[20];
145 };
146
147
148 // implemented in AdjustDylibSegemnts.cpp
149 void adjustDylibSegments(DyldSharedCache* cache, bool is64, mach_header* mhInCache, const std::vector<CacheBuilder::SegmentMappingInfo>& mappingInfo, std::vector<void*>& pointersForASLR, Diagnostics& diag);
150
151 // implemented in OptimizerLinkedit.cpp
152 uint64_t optimizeLinkedit(DyldSharedCache* cache, bool is64, bool dontMapLocalSymbols, bool addAcceleratorTables, const std::vector<uint64_t>& branchPoolOffsets, Diagnostics& diag, dyld_cache_local_symbols_info** localsInfo);
153
154 // implemented in OptimizerBranches.cpp
155 void bypassStubs(DyldSharedCache* cache, const std::vector<uint64_t>& branchPoolStartAddrs, const char* const alwaysUsesStubsTo[], Diagnostics& diag);
156
157 // implemented in OptimizerObjC.cpp
158 void optimizeObjC(DyldSharedCache* cache, bool is64, bool customerCache, std::vector<void*>& pointersForASLR, Diagnostics& diag);
159
160
161
162 inline uint64_t align(uint64_t addr, uint8_t p2)
163 {
164 uint64_t mask = (1 << p2);
165 return (addr + mask - 1) & (-mask);
166 }
167
168
169
170 #endif /* CacheBuilder_h */