]> git.saurik.com Git - apple/dyld.git/blob - dyld3/LaunchCacheWriter.h
dyld-551.4.tar.gz
[apple/dyld.git] / dyld3 / LaunchCacheWriter.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 LaunchCacheWriter_h
26 #define LaunchCacheWriter_h
27
28
29 #include <stdint.h>
30
31 #include <vector>
32 #include <list>
33 #include <unordered_map>
34 #include <map>
35
36 #include "LaunchCacheFormat.h"
37 #include "LaunchCache.h"
38 #include "MachOParser.h"
39 #include "shared-cache/DyldSharedCache.h"
40
41
42 namespace dyld3 {
43 namespace launch_cache {
44
45
46
47 class ContentBuffer {
48 private:
49 std::vector<uint8_t> _data;
50 public:
51 std::vector<uint8_t>& bytes() { return _data; }
52 unsigned long size() const { return _data.size(); }
53 void reserve(unsigned long l) { _data.reserve(l); }
54 const uint8_t* start() const { return &_data[0]; }
55 const uint8_t* end() const { return &_data[_data.size()]; }
56
57 void append_uleb128(uint64_t value) {
58 uint8_t byte;
59 do {
60 byte = value & 0x7F;
61 value &= ~0x7F;
62 if ( value != 0 )
63 byte |= 0x80;
64 _data.push_back(byte);
65 value = value >> 7;
66 } while( byte >= 0x80 );
67 }
68
69 void append_byte(uint8_t byte) {
70 _data.push_back(byte);
71 }
72
73 void append_uint32(uint32_t value) {
74 for (int i=0; i < 4; ++i) {
75 _data.push_back(value & 0xFF);
76 value = (value >> 8);
77 }
78 }
79
80 void append_uint64(uint64_t value) {
81 for (int i=0; i < 8; ++i) {
82 _data.push_back(value & 0xFF);
83 value = (value >> 8);
84 }
85 }
86
87 void append_buffer(const ContentBuffer& value) {
88 _data.insert(_data.end(), value.start(), value.end());
89 }
90
91 static unsigned int uleb128_size(uint64_t value) {
92 uint32_t result = 0;
93 do {
94 value = value >> 7;
95 ++result;
96 } while ( value != 0 );
97 return result;
98 }
99
100 void pad_to_size(unsigned int alignment) {
101 while ( (_data.size() % alignment) != 0 )
102 _data.push_back(0);
103 }
104 };
105
106 class ImageGroupWriter
107 {
108 public:
109 ImageGroupWriter(uint32_t groupNum, bool pages16KB, bool is64, bool dylibsExpectedOnDisk, bool mtimeAndInodeAreValid);
110
111 enum class FixupType { rebase, pointerBind, pointerLazyBind, bindText, bindTextRel, rebaseText, bindImportJmpRel, ignore };
112 struct FixUp {
113 uint32_t segIndex;
114 uint64_t segOffset;
115 FixupType type;
116 TargetSymbolValue target;
117 };
118
119 uint32_t size() const;
120 void finalizeTo(Diagnostics& diag, const std::vector<const BinaryImageGroupData*>&, binary_format::ImageGroup* buffer) const;
121 uint32_t maxLoadCount(Diagnostics& diag, const std::vector<const BinaryImageGroupData*>&, binary_format::ImageGroup* buffer) const;
122
123 bool isInvalid(uint32_t imageIndex) const;
124
125 void setImageCount(uint32_t);
126 void setImageInvalid(uint32_t imageIndex);
127 void setImagePath(uint32_t imageIndex, const char* path);
128 void setImageUUID(uint32_t imageIndex, const uuid_t uuid);
129 void setImageHasObjC(uint32_t imageIndex, bool value);
130 void setImageIsBundle(uint32_t imageIndex, bool value);
131 void setImageHasWeakDefs(uint32_t imageIndex, bool value);
132 void setImageMayHavePlusLoads(uint32_t imageIndex, bool value);
133 void setImageNeverUnload(uint32_t imageIndex, bool);
134 void setImageMustBeThisDir(uint32_t imageIndex, bool value);
135 void setImageIsPlatformBinary(uint32_t imageIndex, bool value);
136 void setImageOverridableDylib(uint32_t imageIndex, bool value);
137 void setImageIsEncrypted(uint32_t imageIndex, bool value);
138 void setImageMaxLoadCount(uint32_t imageIndex, uint32_t count);
139 void setImageFairPlayRange(uint32_t imageIndex, uint32_t offset, uint32_t size);
140 void setImageInitializerOffsets(uint32_t imageIndex, const std::vector<uint32_t>& offsets);
141 void setImageDOFOffsets(uint32_t imageIndex, const std::vector<uint32_t>& offsets);
142 void setImageInitBefore(uint32_t imageIndex, const std::vector<binary_format::ImageRef>&);
143 void setImageSliceOffset(uint32_t imageIndex, uint64_t fileOffset);
144 void setImageFileMtimeAndInode(uint32_t imageIndex, uint64_t mTime, uint64_t inode);
145 void setImageCdHash(uint32_t imageIndex, uint8_t cdHash[20]);
146 void setImageCodeSignatureLocation(uint32_t imageIndex, uint32_t fileOffset, uint32_t size);
147 void setImageDependentsCount(uint32_t imageIndex, uint32_t count);
148 void setImageDependent(uint32_t imageIndex, uint32_t depIndex, binary_format::ImageRef dependent);
149 void setImageSegments(uint32_t imageIndex, MachOParser& imageParser, uint64_t cacheUnslideBaseAddress);
150 void setImageFixups(Diagnostics& diag, uint32_t imageIndex, std::vector<FixUp>& fixups, bool hasTextRelocs);
151 void addImageAliasPath(uint32_t imageIndex, const char* anAlias);
152 void setImagePatchLocations(uint32_t imageIndex, uint32_t funcOffset, const std::unordered_set<uint32_t>& patchLocations);
153 void setGroupCacheOverrides(const std::vector<binary_format::DyldCacheOverride>& cacheOverrides);
154 void addImageIsOverride(binary_format::ImageRef replacer, binary_format::ImageRef replacee);
155
156 uint32_t addIndirectGroupNum(uint32_t groupNum);
157
158 uint32_t addString(const char* str);
159 void alignStringPool();
160
161 uint32_t imageDependentsCount(uint32_t imageIndex) const;
162 binary_format::ImageRef imageDependent(uint32_t imageIndex, uint32_t depIndex) const;
163
164 private:
165 struct InitializerInfo {
166 std::vector<uint32_t> offsetsInImage;
167 std::vector<binary_format::ImageRef> initBeforeImages;
168 };
169
170 uint32_t imageCount() const;
171 binary_format::Image& imageByIndex(uint32_t);
172 const binary_format::Image& imageByIndex(uint32_t) const;
173 std::vector<uint8_t> makeFixupOpcodes(const FixUp* start, const FixUp* end, uint32_t pageStartSegmentOffset, std::map<uint32_t, TargetSymbolValue>&);
174 void makeDataFixupMapAndOrdinalTable(std::vector<uint8_t>& fixupMap, std::vector<TargetSymbolValue>& ordinalTable);
175 void computeInitializerOrdering(uint32_t imageIndex);
176 uint32_t addUniqueInitList(const std::vector<binary_format::ImageRef>& initBefore);
177 void layoutBinary(binary_format::ImageGroup* grp) const;
178
179 const bool _isDiskImage;
180 const bool _is64;
181 const uint16_t _groupNum;
182 const uint32_t _pageSize;
183 bool _dylibsExpectedOnDisk;
184 bool _imageFileInfoIsCdHash;
185 std::vector<binary_format::CachedImage> _images;
186 std::vector<binary_format::DiskImage> _diskImages;
187 std::vector<binary_format::AliasEntry> _aliases;
188 std::vector<uint64_t> _segmentPool;
189 std::vector<binary_format::ImageRef> _dependentsPool;
190 std::vector<uint32_t> _initializerOffsets;
191 std::vector<binary_format::ImageRef> _initializerBeforeLists;
192 std::vector<uint32_t> _dofOffsets;
193 std::vector<TargetSymbolValue> _targetsPool;
194 ContentBuffer _fixupsPool;
195 std::vector<binary_format::PatchTable> _patchPool;
196 std::vector<binary_format::PatchOffset> _patchLocationPool;
197 std::vector<binary_format::DyldCacheOverride>_dyldCacheSymbolOverridePool;
198 std::vector<binary_format::ImageRefOverride> _imageOverridePool;
199 std::vector<uint32_t> _indirectGroupNumPool;
200 std::unordered_map<uint32_t, uint32_t> _indirectGroupNumPoolExisting;
201 std::vector<char> _stringPool;
202 std::unordered_map<std::string, uint32_t> _stringPoolExisting;
203 };
204
205
206
207 } // namespace launch_cache
208 } // namespace dyld3
209
210
211 #endif // LaunchCacheWriter_h
212
213