dyld-832.7.1.tar.gz
[apple/dyld.git] / src / ImageLoaderMegaDylib.h
1 /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-
2 *
3 * Copyright (c) 2015 Apple Inc. All rights reserved.
4 *
5 * @APPLE_LICENSE_HEADER_START@
6 *
7 * This file contains Original Code and/or Modifications of Original Code
8 * as defined in and that are subject to the Apple Public Source License
9 * Version 2.0 (the 'License'). You may not use this file except in
10 * compliance with the License. Please obtain a copy of the License at
11 * http://www.opensource.apple.com/apsl/ and read it before using this
12 * file.
13 *
14 * The Original Code and all software distributed under the License are
15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
19 * Please see the License for the specific language governing rights and
20 * limitations under the License.
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24
25
26 #ifndef __IMAGELOADER_MEGADYLIB__
27 #define __IMAGELOADER_MEGADYLIB__
28
29 #include <stdint.h>
30 #include <pthread.h>
31 #include <uuid/uuid.h>
32
33 #include "ImageLoaderMachO.h"
34 #include "dyld_cache_format.h"
35
36
37 //
38 // ImageLoaderMegaDylib is the concrete subclass of ImageLoader which represents
39 // all dylibs in the shared cache.
40 //
41 class ImageLoaderMegaDylib : public ImageLoader {
42 public:
43 static ImageLoaderMegaDylib* makeImageLoaderMegaDylib(const dyld_cache_header*, long slide, const macho_header* mainMH, const LinkContext&);
44
45
46 virtual ~ImageLoaderMegaDylib();
47
48 void appendImagesNeedingCoalescing(ImageLoader* images[], unsigned imageIndex[], unsigned& count);
49 virtual void initializeCoalIterator(CoalIterator&, unsigned int loadOrder, unsigned imageIndex);
50 virtual bool incrementCoalIterator(CoalIterator&);
51 virtual uintptr_t getAddressCoalIterator(CoalIterator&, const LinkContext& contex);
52 virtual void updateUsesCoalIterator(CoalIterator&, uintptr_t newAddr, ImageLoader* target, unsigned imageIndex, const LinkContext& context);
53
54 virtual const char* getIndexedPath(unsigned index) const;
55 virtual const char* getIndexedShortName(unsigned) const;
56 virtual const char* getInstallPath() const;
57 virtual bool inSharedCache() const { return true; }
58 virtual bool containsSymbol(const void* addr) const { unreachable(); }
59 virtual void* getEntryFromLC_MAIN() const { unreachable(); }
60 virtual void* getEntryFromLC_UNIXTHREAD() const { unreachable(); }
61 virtual const struct mach_header* machHeader() const { unreachable(); }
62 virtual uintptr_t getSlide() const { return _slide; }
63 virtual const void* getEnd() const { unreachable(); }
64 virtual bool hasCoalescedExports() const { unreachable(); }
65 virtual bool findExportedSymbolAddress(const LinkContext& context, const char* symbolName,
66 const ImageLoader* requestorImage, int requestorOrdinalOfDef,
67 bool runResolver, const ImageLoader** foundIn, uintptr_t* address) const;
68 virtual const Symbol* findExportedSymbol(const char* name, bool searchReExports, const char* thisPath, const ImageLoader** foundIn) const;
69 virtual uintptr_t getExportedSymbolAddress(const Symbol* sym, const LinkContext& context,
70 const ImageLoader* requestor, bool runResolver, const char* symbolName) const;
71 virtual DefinitionFlags getExportedSymbolInfo(const Symbol* sym) const { unreachable(); }
72 virtual const char* getExportedSymbolName(const Symbol* sym) const { unreachable(); }
73 virtual uint32_t getExportedSymbolCount() const { unreachable(); }
74 virtual const Symbol* getIndexedExportedSymbol(uint32_t index) const { unreachable(); }
75
76 virtual uint32_t getImportedSymbolCount() const { unreachable(); }
77 virtual const Symbol* getIndexedImportedSymbol(uint32_t index) const { unreachable(); }
78 virtual ReferenceFlags getImportedSymbolInfo(const Symbol* sym) const { unreachable(); }
79 virtual const char* getImportedSymbolName(const Symbol* sym) const { unreachable(); }
80 virtual const char* findClosestSymbol(const void* addr, const void** closestAddr) const { unreachable(); }
81 virtual bool isBundle() const { return false; }
82 virtual bool isDylib() const { return true; }
83 virtual bool isExecutable() const { unreachable(); }
84 virtual bool isPositionIndependentExecutable() const { unreachable(); }
85 virtual bool forceFlat() const { unreachable(); }
86 virtual uintptr_t doBindLazySymbol(uintptr_t* lazyPointer, const LinkContext& context) { unreachable(); }
87 virtual uintptr_t doBindFastLazySymbol(uint32_t lazyBindingInfoOffset, const LinkContext& context,
88 void (*lock)(), void (*unlock)()) { unreachable(); }
89 virtual void doTermination(const LinkContext& context) { unreachable(); }
90 virtual bool needsInitialization() { unreachable(); }
91 virtual bool getSectionContent(const char* segmentName, const char* sectionName, void** start, size_t* length) { unreachable(); }
92 virtual void getUnwindInfo(dyld_unwind_sections* info) { unreachable(); }
93 virtual bool findSection(const void* imageInterior, const char** segmentName, const char** sectionName, size_t* sectionOffset) { unreachable(); }
94 virtual const struct macho_section* findSection(const void* imageInterior) const { unreachable(); }
95 virtual bool isPrebindable() const { unreachable(); }
96 virtual bool usablePrebinding(const LinkContext& context) const { unreachable(); }
97 virtual void getRPaths(const LinkContext& context, std::vector<const char*>&) const { }
98 virtual bool participatesInCoalescing() const { unreachable(); }
99 virtual bool getUUID(uuid_t) const { unreachable(); }
100 virtual void dynamicInterpose(const LinkContext& context) { unreachable(); }
101 void addDynamicInterposingTuples(const struct dyld_interpose_tuple array[], size_t count) { unreachable(); }
102 virtual unsigned int segmentCount() const { unreachable(); }
103 virtual const char* segName(unsigned int) const { unreachable(); }
104 virtual uintptr_t segSize(unsigned int) const { unreachable(); }
105 virtual uintptr_t segFileSize(unsigned int) const { unreachable(); }
106 virtual bool segHasTrailingZeroFill(unsigned int) { unreachable(); }
107 virtual uintptr_t segFileOffset(unsigned int) const { unreachable(); }
108 virtual bool segReadable(unsigned int) const { unreachable(); }
109 virtual bool segWriteable(unsigned int) const { unreachable(); }
110 virtual bool segExecutable(unsigned int) const { unreachable(); }
111 virtual bool segUnaccessible(unsigned int) const { unreachable(); }
112 virtual bool segHasPreferredLoadAddress(unsigned int) const { unreachable(); }
113 virtual uintptr_t segPreferredLoadAddress(unsigned int) const { unreachable(); }
114 virtual uintptr_t segActualLoadAddress(unsigned int) const { unreachable(); }
115 virtual uintptr_t segActualEndAddress(unsigned int) const { unreachable(); }
116
117
118 // info from LC_VERSION_MIN_MACOSX or LC_VERSION_MIN_IPHONEOS
119 virtual uint32_t sdkVersion() const { unreachable(); }
120 virtual uint32_t minOSVersion() const { unreachable(); }
121
122 // if the image contains interposing functions, register them
123 virtual void registerInterposing(const LinkContext& context) { unreachable(); }
124
125 virtual ImageLoader* libImage(unsigned int) const { unreachable(); }
126 virtual bool libReExported(unsigned int) const { unreachable(); }
127 virtual bool libIsUpward(unsigned int) const { unreachable(); }
128 virtual void setLibImage(unsigned int, ImageLoader*, bool, bool) { unreachable(); }
129 virtual const char* libPath(unsigned int) const { unreachable(); }
130
131 unsigned appendImagesToNotify(dyld_image_states state, bool orLater, dyld_image_info* infos);
132 const char* notify(dyld_image_states state, bool orLater, dyld_image_state_change_handler);
133 bool dlopenFromCache(const LinkContext& context, const char* path, int mode, void** handle);
134 bool makeCacheHandle(const LinkContext& context, unsigned cacheIndex, int mode, void** result);
135 void* dlsymFromCache(const LinkContext& context, void* handle, const char* symName, unsigned index);
136 bool isCacheHandle(void* handle, unsigned* index, uint8_t* flags);
137 bool hasDylib(const char* path, unsigned* index) const;
138 bool addressInCache(const void* address, const mach_header** mh, const char** path, unsigned* index);
139 bool findUnwindSections(const void* addr, dyld_unwind_sections* info);
140 bool dladdrFromCache(const void* address, Dl_info* info);
141 uintptr_t bindLazy(uintptr_t lazyBindingInfoOffset, const LinkContext& context, const mach_header* mh, unsigned index);
142 bool flatFindSymbol(const char* name, bool onlyInCoalesced, const ImageLoader::Symbol** sym, const ImageLoader** image, ImageLoader::CoalesceNotifier);
143 void getDylibUUID(unsigned int index, uuid_t) const;
144
145 protected:
146 virtual void setDyldInfo(const dyld_info_command* dyldInfo) { unreachable(); }
147 virtual void setChainedFixups(const linkedit_data_command* fixups) { unreachable(); }
148 virtual void setExportsTrie(const linkedit_data_command*) { unreachable(); }
149 virtual void setSymbolTableInfo(const macho_nlist*, const char*, const dysymtab_command*) { unreachable(); }
150 virtual uint32_t* segmentCommandOffsets() const { unreachable(); }
151 virtual void rebase(const LinkContext& context, uintptr_t slide) { unreachable(); }
152 virtual uintptr_t exportedSymbolAddress(const LinkContext& context, const Symbol* symbol, const ImageLoader* requestor, bool runResolver) const { unreachable(); }
153 virtual bool exportedSymbolIsWeakDefintion(const Symbol* symbol) const { unreachable(); }
154 virtual const char* exportedSymbolName(const Symbol* symbol) const { unreachable(); }
155 virtual unsigned int exportedSymbolCount() const { unreachable(); }
156 virtual const ImageLoader::Symbol* exportedSymbolIndexed(unsigned int) const { unreachable(); }
157 virtual unsigned int importedSymbolCount() const { unreachable(); }
158 virtual const ImageLoader::Symbol* importedSymbolIndexed(unsigned int) const { unreachable(); }
159 virtual const char* importedSymbolName(const Symbol* symbol) const { unreachable(); }
160 #if PREBOUND_IMAGE_SUPPORT
161 virtual void resetPreboundLazyPointers(const LinkContext& context) { unreachable(); }
162 #endif
163
164 virtual void recursiveLoadLibraries(const LinkContext& context, bool preflightOnly, const RPathChain& loaderRPaths, const char* loadPath);
165 virtual unsigned updateDepth(unsigned int maxDepth);
166 virtual void recursiveRebase(const LinkContext& context) { }
167 virtual void recursiveBind(const LinkContext& context, bool forceLazysBound, bool neverUnload, const ImageLoader* parent);
168 virtual void recursiveApplyInterposing(const LinkContext& context);
169 virtual void recursiveMakeDataReadOnly(const LinkContext& context) {}
170 virtual void recursiveGetDOFSections(const LinkContext& context, std::vector<DOFInfo>& dofs) { }
171 virtual void recursiveInitialization(const LinkContext& context, mach_port_t this_thread, const char* pathToInitialize,
172 ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&);
173
174 virtual void doGetDependentLibraries(DependentLibraryInfo libs[]) { unreachable(); }
175 virtual LibraryInfo doGetLibraryInfo(const LibraryInfo& requestorInfo) { return requestorInfo; }
176 virtual void doRebase(const LinkContext& context) { unreachable(); }
177 virtual void doBind(const LinkContext& context, bool forceLazysBound, const ImageLoader* reExportParent) { unreachable(); }
178 virtual void doBindJustLazies(const LinkContext& context) { unreachable(); }
179 virtual void doGetDOFSections(const LinkContext& context, std::vector<DOFInfo>& dofs) { unreachable(); }
180 virtual void doInterpose(const LinkContext& context) { unreachable(); }
181 virtual bool doInitialization(const LinkContext& context) { unreachable(); }
182 virtual bool needsTermination() { unreachable(); }
183 virtual bool segmentsMustSlideTogether() const { unreachable(); }
184 virtual bool segmentsCanSlide() const { unreachable(); }
185 virtual void setSlide(intptr_t slide) { unreachable(); }
186 bool allDependentLibrariesAsWhenPreBound() const { unreachable(); }
187 virtual bool isSubframeworkOf(const LinkContext& context, const ImageLoader* image) const { return false; }
188 virtual bool hasSubLibrary(const LinkContext& context, const ImageLoader* child) const { return false; }
189 virtual bool weakSymbolsBound(unsigned index) const;
190 virtual void setWeakSymbolsBound(unsigned index);
191
192 private:
193 ImageLoaderMegaDylib(const dyld_cache_header*, long slide, const macho_header* mainMH, const LinkContext&);
194
195 struct UpwardIndexes
196 {
197 uint16_t count;
198 uint16_t images[1];
199 };
200
201 const macho_header* getIndexedMachHeader(unsigned index) const;
202 const uint8_t* getIndexedTrie(unsigned index, uint32_t& trieSize) const;
203 unsigned findImageIndex(const LinkContext& context, const char* path) const;
204 void recursiveMarkLoaded(const LinkContext& context, unsigned imageIndex);
205 void markAllbound(const LinkContext& context);
206 bool findInChainedTries(const LinkContext& context, const char* symbolName, unsigned definedImageIndex,
207 const ImageLoader* requestorImage, bool runResolver, uintptr_t* address) const;
208 bool findInChainedTriesAndDependents(const LinkContext& context, const char* symbolName, unsigned definedImageIndex,
209 const ImageLoader* requestorImage, bool runResolver, uintptr_t* address) const;
210 bool findInChainedTriesAndDependentsExcept(const LinkContext& context, const char* symbolName, unsigned imageIndex,
211 const ImageLoader* requestorImage, bool runResolver, bool alreadyVisited[], uintptr_t* address) const;
212 bool exportTrieHasNodeRecursive(const char* symbolName, unsigned index,
213 const uint8_t** exportNode, const uint8_t** exportTrieEnd,
214 unsigned* foundinIndex) const;
215 bool exportTrieHasNode(const char* symbolName, unsigned index,
216 const uint8_t** exportNode, const uint8_t** exportTrieEnd) const;
217
218 void initAllLoaded(const LinkContext& context, InitializerTimingList& timingInfo);
219 void printSegments(const macho_header* mh) const;
220 void* makeCacheHandle(unsigned index, int mode);
221 uint8_t flagsFromCacheHandle(void* handle);
222 void processExportNode(const LinkContext& context, const char* symbolName, unsigned definedImageIndex,
223 const uint8_t* exportNode, const uint8_t* exportTrieEnd,
224 const ImageLoader* requestorImage, bool runResolver, uintptr_t* address) const;
225 static uint8_t dyldStateToCacheState(dyld_image_states state);
226 void recursiveInitialization(const LinkContext& context, mach_port_t this_thread, unsigned int imageIndex,
227 InitializerTimingList& timingInfo, UpwardIndexes&);
228 void recursiveSpinLockAcquire(unsigned int imageIndex, mach_port_t thisThread);
229 void recursiveSpinLockRelease(unsigned int imageIndex, mach_port_t thisThread);
230
231 __attribute__((noreturn))
232 void unreachable() const;
233
234 enum { kStateUnused=0, kStateLoaded=1, kStateFlagBound=2, kStateFlagWeakBound=3, kStateFlagInitialized=4 };
235
236
237 const dyld_cache_header* _header;
238 const void* _endOfCacheInMemory;
239 const uint8_t* _linkEditBias;
240 const dyld_cache_image_info* _images;
241 const dyld_cache_image_info_extra* _imageExtras;
242 long _slide;
243 const dyld_cache_accelerator_initializer* _initializers;
244 const dyld_cache_range_entry* _rangeTable;
245 const uint16_t* _reExportsArray;
246 const uint16_t* _dependenciesArray;
247 const uint16_t* _bottomUpArray;
248 const uint8_t* _dylibsTrieStart;
249 const uint8_t* _dylibsTrieEnd;
250 const dyld_cache_image_text_info* _imageTextInfo;
251 uint8_t* _stateFlags;
252 uint32_t _imageCount;
253 uint32_t _initializerCount;
254 uint32_t _rangeTableCount;
255 pthread_mutex_t _lockArrayGuard;
256 ImageLoader::recursive_lock* _lockArray;
257 unsigned int _lockArrayInUseCount;
258 };
259
260
261
262 #endif // __IMAGELOADER_MEGADYLIB__
263
264
265
266