]> git.saurik.com Git - apple/dyld.git/blob - dyld3/shared-cache/CacheBuilder.h
dyld-519.2.2.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 bool 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 bool agileSignature();
61 const std::string cdHashFirst();
62 const std::string cdHashSecond();
63
64 struct SegmentMappingInfo {
65 const void* srcSegment;
66 const char* segName;
67 uint64_t dstCacheAddress;
68 uint32_t dstCacheOffset;
69 uint32_t dstCacheSegmentSize;
70 uint32_t copySegmentSize;
71 uint32_t srcSegmentIndex;
72 };
73
74 private:
75
76 typedef std::unordered_map<const mach_header*, std::vector<SegmentMappingInfo>> SegmentMapping;
77
78 struct ArchLayout
79 {
80 uint64_t sharedMemoryStart;
81 uint64_t sharedMemorySize;
82 uint64_t sharedRegionPadding;
83 uint64_t pointerDeltaMask;
84 const char* archName;
85 uint32_t branchPoolTextSize;
86 uint32_t branchPoolLinkEditSize;
87 uint32_t branchReach;
88 uint8_t sharedRegionAlignP2;
89 bool sharedRegionsAreDiscontiguous;
90 bool is64;
91 };
92
93 static const ArchLayout _s_archLayout[];
94 static const char* const _s_neverStubEliminate[];
95
96 std::vector<DyldSharedCache::MappedMachO> makeSortedDylibs(const std::vector<DyldSharedCache::MappedMachO>& dylibs, const std::unordered_map<std::string, unsigned> sortOrder);
97
98 SegmentMapping assignSegmentAddresses(const std::vector<DyldSharedCache::MappedMachO>& dylibs, struct dyld_cache_mapping_info regions[3]);
99
100 bool cacheOverflow(const dyld_cache_mapping_info regions[3]);
101 void adjustImageForNewSegmentLocations(const std::vector<uint64_t>& segNewStartAddresses,
102 const std::vector<uint64_t>& segCacheFileOffsets,
103 const std::vector<uint64_t>& segCacheSizes, std::vector<void*>& pointersForASLR);
104
105 void fipsSign();
106 void codeSign();
107 uint64_t pathHash(const char* path);
108 void writeCacheHeader(const struct dyld_cache_mapping_info regions[3], const std::vector<DyldSharedCache::MappedMachO>& dylibs, const SegmentMapping&);
109 void copyRawSegments(const std::vector<DyldSharedCache::MappedMachO>& dylibs, const SegmentMapping& mapping);
110 void adjustAllImagesForNewSegmentLocations(const std::vector<DyldSharedCache::MappedMachO>& dylibs, const SegmentMapping& mapping);
111 void bindAllImagesInCacheFile(const dyld_cache_mapping_info regions[3]);
112 void writeSlideInfoV1();
113 void recomputeCacheUUID(void);
114 void findDylibAndSegment(const void* contentPtr, std::string& dylibName, std::string& segName);
115
116 void addCachedDylibsImageGroup(dyld3::ImageProxyGroup*);
117 void addCachedOtherDylibsImageGroup(dyld3::ImageProxyGroup*);
118 void addClosures(const std::map<std::string, const dyld3::launch_cache::binary_format::Closure*>& closures);
119
120 template <typename P> void writeSlideInfoV2();
121 template <typename P> bool makeRebaseChain(uint8_t* pageContent, uint16_t lastLocationOffset, uint16_t newOffset, const struct dyld_cache_slide_info2* info);
122 template <typename P> void addPageStarts(uint8_t* pageContent, const bool bitmap[], const struct dyld_cache_slide_info2* info,
123 std::vector<uint16_t>& pageStarts, std::vector<uint16_t>& pageExtras);
124
125
126 const DyldSharedCache::CreateOptions& _options;
127 DyldSharedCache* _buffer;
128 Diagnostics _diagnostics;
129 const ArchLayout* _archLayout;
130 uint32_t _aliasCount;
131 uint64_t _slideInfoFileOffset;
132 uint64_t _slideInfoBufferSizeAllocated;
133 uint64_t _allocatedBufferSize;
134 uint64_t _currentFileSize;
135 uint64_t _vmSize;
136 std::unordered_map<std::string, uint32_t> _dataDirtySegsOrder;
137 std::vector<void*> _pointersForASLR;
138 dyld3::ImageProxyGroup::PatchTable _patchTable;
139 std::vector<uint64_t> _branchPoolStarts;
140 uint64_t _branchPoolsLinkEditStartAddr;
141 uint8_t _cdHashFirst[20];
142 uint8_t _cdHashSecond[20];
143 };
144
145
146 // implemented in AdjustDylibSegemnts.cpp
147 void adjustDylibSegments(DyldSharedCache* cache, bool is64, mach_header* mhInCache, const std::vector<CacheBuilder::SegmentMappingInfo>& mappingInfo, std::vector<void*>& pointersForASLR, Diagnostics& diag);
148
149 // implemented in OptimizerLinkedit.cpp
150 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);
151
152 // implemented in OptimizerBranches.cpp
153 void bypassStubs(DyldSharedCache* cache, const std::vector<uint64_t>& branchPoolStartAddrs, const char* const alwaysUsesStubsTo[], Diagnostics& diag);
154
155 // implemented in OptimizerObjC.cpp
156 void optimizeObjC(DyldSharedCache* cache, bool is64, bool customerCache, std::vector<void*>& pointersForASLR, Diagnostics& diag);
157
158
159
160 inline uint64_t align(uint64_t addr, uint8_t p2)
161 {
162 uint64_t mask = (1 << p2);
163 return (addr + mask - 1) & (-mask);
164 }
165
166
167
168 #endif /* CacheBuilder_h */