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