1 /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*- 
   3  * Copyright (c) 2015 Apple Inc. All rights reserved. 
   5  * @APPLE_LICENSE_HEADER_START@ 
   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 
  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. 
  22  * @APPLE_LICENSE_HEADER_END@ 
  26 #ifndef __IMAGELOADER_MEGADYLIB__ 
  27 #define __IMAGELOADER_MEGADYLIB__ 
  31 #include <uuid/uuid.h> 
  33 #include "ImageLoaderMachO.h" 
  34 #include "dyld_cache_format.h" 
  38 // ImageLoaderMegaDylib is the concrete subclass of ImageLoader which represents 
  39 // all dylibs in the shared cache. 
  41 class ImageLoaderMegaDylib 
: public ImageLoader 
{ 
  43         static ImageLoaderMegaDylib
*            makeImageLoaderMegaDylib(const dyld_cache_header
*, long slide
, const macho_header
* mainMH
, const LinkContext
&); 
  46         virtual                                                         ~ImageLoaderMegaDylib(); 
  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
); 
  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(); } 
  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(); } 
 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(); } 
 122                                                                                 // if the image contains interposing functions, register them 
 123         virtual void                                            registerInterposing(const LinkContext
& context
) { unreachable(); } 
 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(); } 
 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; 
 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(); } 
 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
&); 
 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
); 
 193                                                                                 ImageLoaderMegaDylib(const dyld_cache_header
*, long slide
, const macho_header
* mainMH
, const LinkContext
&); 
 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; 
 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
); 
 231         __attribute__((noreturn
)) 
 232         void                                                            unreachable() const; 
 234         enum { kStateUnused
=0, kStateLoaded
=1, kStateFlagBound
=2, kStateFlagWeakBound
=3, kStateFlagInitialized
=4 }; 
 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
; 
 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
; 
 262 #endif // __IMAGELOADER_MEGADYLIB__