]> git.saurik.com Git - apple/dyld.git/blobdiff - src/ImageLoaderMachO.h
dyld-433.5.tar.gz
[apple/dyld.git] / src / ImageLoaderMachO.h
index 8665c9676c992c438144f0646f410d85911b454e..5c485892fe101ee9bfd853a5efc457c50b125344 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-
  *
- * Copyright (c) 2004-2005 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2004-2009 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
 #define __IMAGELOADERMACHO__
 
 #include <stdint.h> 
+#include <mach-o/loader.h> 
+#include <mach-o/nlist.h> 
 
 #include "ImageLoader.h"
+#include "mach-o/dyld_images.h"
 
-struct sf_mapping;
-struct _shared_region_mapping_np;
 
 //
-// ImageLoaderMachO is the concrete subclass of ImageLoader which loads mach-o format files.
-// The class is written to be 64-bit clean and support both 32-bit and 64-bit executables in
-// mach-o.
+// ImageLoaderMachO is a subclass of ImageLoader which loads mach-o format files.
 //
 //
 class ImageLoaderMachO : public ImageLoader {
 public:
-                                                                               ImageLoaderMachO(const char* path, int fd, const uint8_t firstPage[4096], uint64_t offset, uint64_t len, const struct stat& info, const LinkContext& context);
-                                                                               ImageLoaderMachO(const char* moduleName, const struct mach_header* mh, uint64_t len, const LinkContext& context);
-       virtual                                                         ~ImageLoaderMachO()  {}
+       static ImageLoader*                                     instantiateMainExecutable(const macho_header* mh, uintptr_t slide, const char* path, const LinkContext& context);
+       static ImageLoader*                                     instantiateFromFile(const char* path, int fd, const uint8_t firstPages[], size_t firstPagesSize, uint64_t offsetInFat,
+                                                                                                                       uint64_t lenInFat, const struct stat& info, const LinkContext& context);
+       static ImageLoader*                                     instantiateFromCache(const macho_header* mh, const char* path, long slide, const struct stat& info, const LinkContext& context);
+       static ImageLoader*                                     instantiateFromMemory(const char* moduleName, const macho_header* mh, uint64_t len, const LinkContext& context);
+
+
+       bool                                                            inSharedCache() const { return fInSharedCache; }
+       void                                                            disableCoverageCheck() { fCoveredCodeLength = UINT64_MAX; }
 
        const char*                                                     getInstallPath() const;
        virtual void*                                           getMain() const;
+       virtual void*                                           getThreadPC() const;
        virtual const struct mach_header*   machHeader() const;
        virtual uintptr_t                                       getSlide() const;
-       virtual const void*                                     getBaseAddress() const;
+       virtual const void*                                     getEnd() const;
        virtual bool                                            hasCoalescedExports() const;
-       virtual const Symbol*                           findExportedSymbol(const char* name, const void* hint, bool searchReExports, ImageLoader** foundIn) const;
-       virtual uintptr_t                                       getExportedSymbolAddress(const Symbol* sym) 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*) const;
        virtual DefinitionFlags                         getExportedSymbolInfo(const Symbol* sym) const;
        virtual const char*                                     getExportedSymbolName(const Symbol* sym) const;
        virtual uint32_t                                        getExportedSymbolCount() const;
        virtual const Symbol*                           getIndexedExportedSymbol(uint32_t index) const;
        virtual uint32_t                                        getImportedSymbolCount() const;
        virtual const Symbol*                           getIndexedImportedSymbol(uint32_t index) const;
-       virtual ReferenceFlags                          geImportedSymbolInfo(const Symbol* sym) const;
+       virtual ReferenceFlags                          getImportedSymbolInfo(const Symbol* sym) const;
        virtual const char*                                     getImportedSymbolName(const Symbol* sym) const;
        virtual bool                                            isBundle() const;
        virtual bool                                            isDylib() const;
+       virtual bool                                            isExecutable() const;
+       virtual bool                                            isPositionIndependentExecutable() const;
        virtual bool                                            forceFlat() const;
-       virtual uintptr_t                                       doBindLazySymbol(uintptr_t* lazyPointer, const LinkContext& context);
+       virtual bool                                            participatesInCoalescing() const;
+       virtual const char*                                     findClosestSymbol(const void* addr, const void** closestAddr) const = 0;
+       virtual void                                            initializeCoalIterator(CoalIterator&, unsigned int loadOrder, unsigned) = 0;
+       virtual bool                                            incrementCoalIterator(CoalIterator&) = 0;
+       virtual uintptr_t                                       getAddressCoalIterator(CoalIterator&, const LinkContext& contex) = 0;
+       virtual void                                            updateUsesCoalIterator(CoalIterator&, uintptr_t newAddr, ImageLoader* target, unsigned targetIndex, const LinkContext& context) = 0;
+       virtual uintptr_t                                       doBindLazySymbol(uintptr_t* lazyPointer, const LinkContext& context) = 0;
+       virtual uintptr_t                                       doBindFastLazySymbol(uint32_t lazyBindingInfoOffset, const LinkContext& context, void (*lock)(), void (*unlock)()) = 0;
        virtual void                                            doTermination(const LinkContext& context);
-       virtual void                                            doNotification(enum dyld_image_mode mode, uint32_t infoCount, const struct dyld_image_info info[]);
        virtual bool                                            needsInitialization();
-       virtual bool                                            hasImageNotification();
        virtual bool                                            getSectionContent(const char* segmentName, const char* sectionName, void** start, size_t* length);
+       virtual void                                            getUnwindInfo(dyld_unwind_sections* info);
        virtual bool                                            findSection(const void* imageInterior, const char** segmentName, const char** sectionName, size_t* sectionOffset);
        virtual bool                                            usablePrebinding(const LinkContext& context) const;
-                       
-       
-       static void                                                     printStatistics(unsigned int imageCount);
-       
+       virtual unsigned int                            segmentCount() const;
+       virtual const char*                                     segName(unsigned int) const;
+       virtual uintptr_t                                       segSize(unsigned int) const;
+       virtual uintptr_t                                       segFileSize(unsigned int) const;
+       virtual bool                                            segHasTrailingZeroFill(unsigned int);
+       virtual uintptr_t                                       segFileOffset(unsigned int) const;
+       virtual bool                                            segReadable(unsigned int) const;
+       virtual bool                                            segWriteable(unsigned int) const;
+       virtual bool                                            segExecutable(unsigned int) const;
+       virtual bool                                            segUnaccessible(unsigned int) const;
+       virtual bool                                            segHasPreferredLoadAddress(unsigned int) const;
+       virtual uintptr_t                                       segActualLoadAddress(unsigned int) const;
+       virtual uintptr_t                                       segPreferredLoadAddress(unsigned int) const;
+       virtual uintptr_t                                       segActualEndAddress(unsigned int) const;
+       virtual void                                            registerInterposing();
+       virtual uint32_t                                        sdkVersion() const;
+       virtual uint32_t                                        minOSVersion() const;
+       virtual const char*                                     libPath(unsigned int) const;
+       virtual bool                                            notifyObjC() const { return fNotifyObjC; }
+
+       static void                                                     printStatisticsDetails(unsigned int imageCount, const InitializerTimingList&);
+       static uint32_t                                         minOSVersion(const mach_header*);
+       static uint32_t                                         sdkVersion(const mach_header* mh);
+       static intptr_t                                         computeSlide(const mach_header* mh);
+       static bool                                                     findSection(const mach_header* mh, const char* segmentName, const char* sectionName, void** sectAddress, uintptr_t* sectSize);
+       static const dyld_info_command*         findDyldInfoLoadCommand(const mach_header* mh);
+       static const char*                                      findClosestSymbol(const mach_header* mh, const void* addr, const void** closestAddr);
+       static bool                                                     getLazyBindingInfo(uint32_t& lazyBindingInfoOffset, const uint8_t* lazyInfoStart, const uint8_t* lazyInfoEnd,
+                                                                                                                 uint8_t* segIndex, uintptr_t* segOffset, int* ordinal, const char** symbolName, bool* doneAfterBind);
+       static uintptr_t                                        segPreferredAddress(const mach_header* mh, unsigned segIndex);
+       static uintptr_t                                        bindLocation(const LinkContext& context, uintptr_t location, uintptr_t value, 
+                                                                                                       uint8_t type, const char* symbolName,
+                                                                                                       intptr_t addend, const char* inPath, const char* toPath, const char* msg);
+       virtual void                                            rebase(const LinkContext& context, uintptr_t slide) = 0;
+
+
+
 protected:
                                                ImageLoaderMachO(const ImageLoaderMachO&);
+                                               ImageLoaderMachO(const macho_header* mh, const char* path, unsigned int segCount,
+                                                                                                                                       uint32_t segOffsets[], unsigned int libCount);
+       virtual                         ~ImageLoaderMachO() {}
+
        void                            operator=(const ImageLoaderMachO&);
 
-       virtual uint32_t        doGetDependentLibraryCount();
-       virtual void            doGetDependentLibraries(DependentLibrary libs[]);
-       virtual LibraryInfo doGetLibraryInfo();
+       virtual void                                            setDyldInfo(const struct dyld_info_command*) = 0;
+       virtual void                                            setSymbolTableInfo(const macho_nlist*, const char*, const dysymtab_command*) = 0;
+       virtual bool                                            isSubframeworkOf(const LinkContext& context, const ImageLoader* image) const = 0;
+       virtual bool                                            hasSubLibrary(const LinkContext& context, const ImageLoader* child) const = 0;
+       virtual uint32_t*                                       segmentCommandOffsets() const = 0;
+       virtual const ImageLoader::Symbol*      findShallowExportedSymbol(const char* name, const ImageLoader** foundIn) const = 0;
+       virtual bool                                            containsSymbol(const void* addr) const = 0;
+       virtual uintptr_t                                       exportedSymbolAddress(const LinkContext& context, const Symbol* symbol, const ImageLoader* requestor, bool runResolver) const = 0;
+       virtual bool                                            exportedSymbolIsWeakDefintion(const Symbol* symbol) const = 0;
+       virtual const char*                                     exportedSymbolName(const Symbol* symbol) const = 0;
+       virtual unsigned int                            exportedSymbolCount() const = 0;
+       virtual const ImageLoader::Symbol*      exportedSymbolIndexed(unsigned int) const = 0;
+       virtual unsigned int                            importedSymbolCount() const = 0;
+       virtual const ImageLoader::Symbol*      importedSymbolIndexed(unsigned int) const = 0;
+       virtual const char*                                     importedSymbolName(const Symbol* symbol) const = 0;
+#if PREBOUND_IMAGE_SUPPORT
+       virtual void                                            resetPreboundLazyPointers(const LinkContext& context) = 0;
+#endif
+
+
+       virtual void            doGetDependentLibraries(DependentLibraryInfo libs[]);
+       virtual LibraryInfo doGetLibraryInfo(const LibraryInfo& requestorInfo);
+       virtual void            getRPaths(const LinkContext& context, std::vector<const char*>&) const;
+       virtual bool            getUUID(uuid_t) const;
        virtual void            doRebase(const LinkContext& context);
-       virtual void            doBind(const LinkContext& context, BindingLaziness bindness);
-       virtual void            doInitialization(const LinkContext& context);
-       virtual void            doPrebinding(const LinkContext& context, time_t timestamp, uint8_t* fileToPrebind);
+       virtual void            doBind(const LinkContext& context, bool forceLazysBound) = 0;
+       virtual void            doBindJustLazies(const LinkContext& context) = 0;
+       virtual bool            doInitialization(const LinkContext& context);
+       virtual void            doGetDOFSections(const LinkContext& context, std::vector<ImageLoader::DOFInfo>& dofs);
        virtual bool            needsTermination();
-       virtual void            instantiateSegments(const uint8_t* fileData);
        virtual bool            segmentsMustSlideTogether() const;      
        virtual bool            segmentsCanSlide() const;                       
        virtual void            setSlide(intptr_t slide);               
        virtual bool            usesTwoLevelNameSpace() const;
-       virtual bool            isSubframeworkOf(const LinkContext& context, const ImageLoader* image) const;
-       virtual bool            hasSubLibrary(const LinkContext& context, const ImageLoader* child) const;
        virtual bool            isPrebindable() const;
-       virtual void            prebindUnmap(const LinkContext& context);
-
-#if !__LP64__   // split segs not supported for 64-bits
-       virtual void            mapSegments(int fd, uint64_t offsetInFat, uint64_t lenInFat, uint64_t fileLen, const LinkContext& context);
-#endif 
-               
-private:
-       friend class SegmentMachO;
-
-                       void            init();
-                       void            parseLoadCmds();
-                       void            doBindIndirectSymbolPointers(const LinkContext& context, BindingLaziness bindness, bool onlyCoalescedSymbols);
-                       void            doBindExternalRelocations(const LinkContext& context, bool onlyCoalescedSymbols);
-                       uintptr_t       resolveUndefined(const LinkContext& context, const struct macho_nlist* symbol, bool twoLevel, ImageLoader **foundIn);
-                       uintptr_t       getRelocBase();
+
+protected:
+
+                       void            destroy();
+       static void                     sniffLoadCommands(const macho_header* mh, const char* path, bool inCache, bool* compressed,
+                                                                                       unsigned int* segCount, unsigned int* libCount, const LinkContext& context,
+                                                                                       const linkedit_data_command** codeSigCmd,
+                                                                                       const encryption_info_command** encryptCmd);
+       static bool                     needsAddedLibSystemDepency(unsigned int libCount, const macho_header* mh);
+                       void            loadCodeSignature(const struct linkedit_data_command* codeSigCmd, int fd, uint64_t offsetInFatFile, const LinkContext& context);
+                       void            validateFirstPages(const struct linkedit_data_command* codeSigCmd, int fd, const uint8_t *fileData, size_t lenFileData, off_t offsetInFat, const LinkContext& context);
+                       const struct macho_segment_command* segLoadCommand(unsigned int segIndex) const;
+                       void            parseLoadCmds(const ImageLoader::LinkContext& context);
+                       int             crashIfInvalidCodeSignature();
+                       bool            segHasRebaseFixUps(unsigned int) const;
+                       bool            segHasBindFixUps(unsigned int) const;
+                       void            segProtect(unsigned int segIndex, const ImageLoader::LinkContext& context);
+                       void            segMakeWritable(unsigned int segIndex, const ImageLoader::LinkContext& context);
+#if __i386__
+                       bool            segIsReadOnlyImport(unsigned int) const;
+#endif
+                       intptr_t        assignSegmentAddresses(const LinkContext& context);
+                       uintptr_t       reserveAnAddressRange(size_t length, const ImageLoader::LinkContext& context);
+                       bool            reserveAddressRange(uintptr_t start, size_t length);
+                       void            mapSegments(int fd, uint64_t offsetInFat, uint64_t lenInFat, uint64_t fileLen, const LinkContext& context);
+                       void            mapSegments(const void* memoryImage, uint64_t imageLen, const LinkContext& context);
+                       void            UnmapSegments();
+                       void            __attribute__((noreturn)) throwSymbolNotFound(const LinkContext& context, const char* symbol, 
+                                                                                                                                       const char* referencedFrom, const char* fromVersMismatch,
+                                                                                                                                       const char* expectedIn);
                        void            doImageInit(const LinkContext& context);
                        void            doModInitFunctions(const LinkContext& context);
-                       void            setupLazyPointerHandler();
-                       void            applyPrebindingToDATA(uint8_t* fileToPrebind);
-                       void            applyPrebindingToLoadCommands(const LinkContext& context, uint8_t* fileToPrebind, time_t timestamp);
-                       void            applyPrebindingToLinkEdit(const LinkContext& context, uint8_t* fileToPrebind);
-#if !__LP64__   // split segs not supported for 64-bits
-                       unsigned int getExtraZeroFillEntriesCount();
-                       int                     sharedRegionLoadFile(int fd, uint64_t offsetInFat, uint64_t lenInFat, uint64_t fileLen, const LinkContext& context);
-                       int                     sharedRegionMapFile(int fd, uint64_t offsetInFat, uint64_t lenInFat, uint64_t fileLen, const LinkContext& context);
-                       int                     sharedRegionMakePrivate(const LinkContext& context);
-                       int                     sharedRegionMapFilePrivate(int fd, uint64_t offsetInFat, uint64_t lenInFat, uint64_t fileLen, const LinkContext& context, bool usemmap);
-                       int                     sharedRegionMapFilePrivateOutside(int fd, uint64_t offsetInFat, uint64_t lenInFat, uint64_t fileLen, const LinkContext& context);
-                       void            initMappingTable(uint64_t offsetInFat, sf_mapping *mappingTable, uintptr_t baseAddress);
-                       void            initMappingTable(uint64_t offsetInFat, _shared_region_mapping_np *mappingTable);
-#endif
-                       bool            needsCoalescing() const;
-                       
-       static  bool                            symbolRequiresCoalescing(const struct macho_nlist* symbol); 
-       static uintptr_t                        bindLazySymbol(const mach_header*, uintptr_t* lazyPointer);
-       static const struct macho_nlist*  binarySearch(const char* key, const char stringPool[], const struct macho_nlist symbols[], uint32_t symbolCount);
-       static const struct macho_nlist*  binarySearchWithToc(const char* key, const char stringPool[], const struct macho_nlist symbols[], 
-                                                                                               const struct dylib_table_of_contents toc[], uint32_t symbolCount, uint32_t hintIndex);
-                       
-       const uint8_t*                                                  fMachOData;
-       const uint8_t*                                                  fLinkEditBase; // add any internal "offset" to this to get actual address
-       const struct macho_nlist*                               fSymbolTable;
-       const char*                                                             fStrings;
-       const struct dysymtab_command*                  fDynamicInfo;
-       uintptr_t                                                               fSlide;
-       bool                                                                    fIsSplitSeg;
-       bool                                                                    fHasSubLibraries;
-       bool                                                                    fHasSubUmbrella;
-       bool                                                                    fTextSegmentHasFixups;
-       const struct macho_routines_command*    fDashInit;
-       const struct macho_section*                             fModInitSection;
-       const struct macho_section*                             fModTermSection;
-       const struct macho_section*                             fDATAdyld;
-       const struct macho_section*                             fImageNotifySection;
-       const struct twolevel_hints_command*    fTwoLevelHints;
-       const struct dylib_command*                             fDylibID;
-       const char*                                                             fReExportThruFramework;
-       SegmentMachO*                                                   fTextSegmentWithFixups; // NULL unless __TEXT segment has fixups
-
-       static uint32_t                                 fgHintedBinaryTreeSearchs;
-       static uint32_t                                 fgUnhintedBinaryTreeSearchs;
-};
+                       void            setupLazyPointerHandler(const LinkContext& context);
+                       void            lookupProgramVars(const LinkContext& context) const;
 
+                       void            makeTextSegmentWritable(const LinkContext& context, bool writeable);
+                       void            preFetchDATA(int fd, uint64_t offsetInFat, const LinkContext& context);
 
-class SegmentMachO : public Segment
-{
-public:        
-                                                               SegmentMachO(const struct macho_segment_command* cmd, ImageLoaderMachO*, const uint8_t* fileData);
-       virtual                                         ~SegmentMachO();
-                                                               
-       virtual const ImageLoader*      getImage();
-       virtual const char*                     getName();
-       virtual uintptr_t                       getSize();
-       virtual uintptr_t                       getFileSize();
-       virtual uintptr_t                       getFileOffset();
-       virtual bool                            readable();
-       virtual bool                            writeable();
-       virtual bool                            executable();
-       virtual bool                            unaccessible();
-       virtual bool                            hasFixUps();
-       virtual uintptr_t                       getActualLoadAddress();
-       virtual uintptr_t                       getPreferredLoadAddress();
-       virtual void                            setUnMapWhenDestructed(bool unmap);
-       virtual uint32_t                        crc32();
 
+                       void            doInterpose(const LinkContext& context) = 0;
+                       bool            hasReferencesToWeakSymbols() const;
+                       uintptr_t       getSymbolAddress(const Symbol* sym, const ImageLoader* requestor, 
+                                                                               const LinkContext& context, bool runResolver) const;
+                       
+       static uintptr_t                        bindLazySymbol(const mach_header*, uintptr_t* lazyPointer);
 protected:
-       virtual bool                            hasPreferredLoadAddress();
-       
-private:
-                                               SegmentMachO(const SegmentMachO&);
-       void                            operator=(const SegmentMachO&);
-
-       friend class ImageLoaderMachO;
-       
-
-       ImageLoaderMachO* const fImage;
-       char                                    fName[18];
-       const uintptr_t                 fSize;
-       const uintptr_t                 fFileSize;
-       const uintptr_t                 fFileOffset;
-       const uintptr_t                 fPreferredLoadAddress;
-       const uint16_t                  fVMProtection;
-       bool                                    fHasFixUps;
-       bool                                    fUnMapOnDestruction;
+       uint64_t                                                                fCoveredCodeLength;
+       const uint8_t*                                                  fMachOData;
+       const uint8_t*                                                  fLinkEditBase; // add any internal "offset" to this to get mapped address
+       uintptr_t                                                               fSlide;
+       uint32_t                                                                fEHFrameSectionOffset;
+       uint32_t                                                                fUnwindInfoSectionOffset;
+       uint32_t                                                                fDylibIDOffset;
+       uint32_t                                                                fSegmentsCount : 8,
+                                                                                       fIsSplitSeg : 1,
+                                                                                       fInSharedCache : 1,
+#if TEXT_RELOC_SUPPORT
+                                                                                       fTextSegmentRebases : 1, 
+                                                                                       fTextSegmentBinds : 1, 
+#endif
+#if __i386__
+                                                                                       fReadOnlyImportSegment : 1,
+#endif
+                                                                                       fHasSubLibraries : 1,
+                                                                                       fHasSubUmbrella : 1,
+                                                                                       fInUmbrella : 1,
+                                                                                       fHasDOFSections : 1,
+                                                                                       fHasDashInit : 1,
+                                                                                       fHasInitializers : 1,
+                                                                                       fHasTerminators : 1,
+                                                                                       fNotifyObjC : 1,
+                                                                                       fRetainForObjC : 1,
+                                                                                       fRegisteredAsRequiresCoalescing : 1;    // <rdar://problem/7886402> Loading MH_DYLIB_STUB causing coalescable miscount
+
+                                                                                       
+       static uint32_t                                 fgSymbolTableBinarySearchs;
 };