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 CacheBuilder_h
26 #define CacheBuilder_h
30 #include <unordered_map>
31 #include <unordered_set>
33 #include "DyldSharedCache.h"
34 #include "Diagnostics.h"
35 #include "ImageProxy.h"
39 namespace launch_cache
{
40 namespace binary_format
{
50 CacheBuilder(const DyldSharedCache::CreateOptions
& options
);
52 bool build(const std::vector
<DyldSharedCache::MappedMachO
>& dylibsToCache
,
53 const std::vector
<DyldSharedCache::MappedMachO
>& otherOsDylibs
,
54 const std::vector
<DyldSharedCache::MappedMachO
>& osExecutables
);
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();
64 struct SegmentMappingInfo
{
65 const void* srcSegment
;
67 uint64_t dstCacheAddress
;
68 uint32_t dstCacheOffset
;
69 uint32_t dstCacheSegmentSize
;
70 uint32_t copySegmentSize
;
71 uint32_t srcSegmentIndex
;
76 typedef std::unordered_map
<const mach_header
*, std::vector
<SegmentMappingInfo
>> SegmentMapping
;
80 uint64_t sharedMemoryStart
;
81 uint64_t sharedMemorySize
;
82 uint64_t sharedRegionPadding
;
83 uint64_t pointerDeltaMask
;
85 uint32_t branchPoolTextSize
;
86 uint32_t branchPoolLinkEditSize
;
88 uint8_t sharedRegionAlignP2
;
89 bool sharedRegionsAreDiscontiguous
;
93 static const ArchLayout _s_archLayout
[];
94 static const char* const _s_neverStubEliminate
[];
96 std::vector
<DyldSharedCache::MappedMachO
> makeSortedDylibs(const std::vector
<DyldSharedCache::MappedMachO
>& dylibs
, const std::unordered_map
<std::string
, unsigned> sortOrder
);
98 SegmentMapping
assignSegmentAddresses(const std::vector
<DyldSharedCache::MappedMachO
>& dylibs
, struct dyld_cache_mapping_info regions
[3]);
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
);
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
);
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
);
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
);
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
;
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];
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
);
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
);
152 // implemented in OptimizerBranches.cpp
153 void bypassStubs(DyldSharedCache
* cache
, const std::vector
<uint64_t>& branchPoolStartAddrs
, const char* const alwaysUsesStubsTo
[], Diagnostics
& diag
);
155 // implemented in OptimizerObjC.cpp
156 void optimizeObjC(DyldSharedCache
* cache
, bool is64
, bool customerCache
, std::vector
<void*>& pointersForASLR
, Diagnostics
& diag
);
160 inline uint64_t align(uint64_t addr
, uint8_t p2
)
162 uint64_t mask
= (1 << p2
);
163 return (addr
+ mask
- 1) & (-mask
);
168 #endif /* CacheBuilder_h */