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 LaunchCacheWriter_h
26 #define LaunchCacheWriter_h
33 #include <unordered_map>
36 #include "LaunchCacheFormat.h"
37 #include "LaunchCache.h"
38 #include "MachOParser.h"
39 #include "shared-cache/DyldSharedCache.h"
43 namespace launch_cache
{
49 std::vector
<uint8_t> _data
;
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()]; }
57 void append_uleb128(uint64_t value
) {
64 _data
.push_back(byte
);
66 } while( byte
>= 0x80 );
69 void append_byte(uint8_t byte
) {
70 _data
.push_back(byte
);
73 void append_uint32(uint32_t value
) {
74 for (int i
=0; i
< 4; ++i
) {
75 _data
.push_back(value
& 0xFF);
80 void append_uint64(uint64_t value
) {
81 for (int i
=0; i
< 8; ++i
) {
82 _data
.push_back(value
& 0xFF);
87 void append_buffer(const ContentBuffer
& value
) {
88 _data
.insert(_data
.end(), value
.start(), value
.end());
91 static unsigned int uleb128_size(uint64_t value
) {
96 } while ( value
!= 0 );
100 void pad_to_size(unsigned int alignment
) {
101 while ( (_data
.size() % alignment
) != 0 )
106 class ImageGroupWriter
109 ImageGroupWriter(uint32_t groupNum
, bool pages16KB
, bool is64
, bool dylibsExpectedOnDisk
, bool mtimeAndInodeAreValid
);
111 enum class FixupType
{ rebase
, pointerBind
, pointerLazyBind
, bindText
, bindTextRel
, rebaseText
, bindImportJmpRel
, ignore
};
116 TargetSymbolValue target
;
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;
123 bool isInvalid(uint32_t imageIndex
) const;
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
);
156 uint32_t addIndirectGroupNum(uint32_t groupNum
);
158 uint32_t addString(const char* str
);
159 void alignStringPool();
161 uint32_t imageDependentsCount(uint32_t imageIndex
) const;
162 binary_format::ImageRef
imageDependent(uint32_t imageIndex
, uint32_t depIndex
) const;
165 struct InitializerInfo
{
166 std::vector
<uint32_t> offsetsInImage
;
167 std::vector
<binary_format::ImageRef
> initBeforeImages
;
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;
179 const bool _isDiskImage
;
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
;
207 } // namespace launch_cache
211 #endif // LaunchCacheWriter_h