1 /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-
3 * Copyright (c) 2004-2005 Apple Computer, 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 __IMAGELOADERMACHO__
27 #define __IMAGELOADERMACHO__
31 #include "ImageLoader.h"
32 #include "mach-o/dyld_images.h"
35 struct _shared_region_mapping_np
;
39 // ImageLoaderMachO is the concrete subclass of ImageLoader which loads mach-o format files.
40 // The class is written to be 64-bit clean and support both 32-bit and 64-bit executables in
44 class ImageLoaderMachO
: public ImageLoader
{
46 ImageLoaderMachO(const char* path
, int fd
, const uint8_t firstPage
[4096], uint64_t offset
, uint64_t len
, const struct stat
& info
, const LinkContext
& context
);
47 ImageLoaderMachO(const char* moduleName
, const struct mach_header
* mh
, uint64_t len
, const LinkContext
& context
);
48 ImageLoaderMachO(const struct mach_header
* mh
, const char* path
, const struct stat
& info
, const LinkContext
& context
);
49 ImageLoaderMachO(const struct mach_header
* executableHeader
, uintptr_t executableSlide
, const char* path
, const LinkContext
& context
);
50 virtual ~ImageLoaderMachO();
52 const char* getInstallPath() const;
53 virtual void* getMain() const;
54 virtual const struct mach_header
* machHeader() const;
55 virtual uintptr_t getSlide() const;
56 virtual const void* getEnd() const;
57 virtual bool hasCoalescedExports() const;
58 virtual const Symbol
* findExportedSymbol(const char* name
, const void* hint
, bool searchReExports
, const ImageLoader
** foundIn
) const;
59 virtual uintptr_t getExportedSymbolAddress(const Symbol
* sym
, const LinkContext
& context
, const ImageLoader
* requestor
) const;
60 virtual DefinitionFlags
getExportedSymbolInfo(const Symbol
* sym
) const;
61 virtual const char* getExportedSymbolName(const Symbol
* sym
) const;
62 virtual uint32_t getExportedSymbolCount() const;
63 virtual const Symbol
* getIndexedExportedSymbol(uint32_t index
) const;
64 virtual uint32_t getImportedSymbolCount() const;
65 virtual const Symbol
* getIndexedImportedSymbol(uint32_t index
) const;
66 virtual ReferenceFlags
geImportedSymbolInfo(const Symbol
* sym
) const;
67 virtual const char* getImportedSymbolName(const Symbol
* sym
) const;
68 virtual bool isBundle() const;
69 virtual bool isDylib() const;
70 virtual bool forceFlat() const;
71 virtual uintptr_t doBindLazySymbol(uintptr_t* lazyPointer
, const LinkContext
& context
);
72 virtual void doTermination(const LinkContext
& context
);
73 #if IMAGE_NOTIFY_SUPPORT
74 virtual void doNotification(enum dyld_image_mode mode
, uint32_t infoCount
, const struct dyld_image_info info
[]);
76 virtual bool needsInitialization();
77 #if IMAGE_NOTIFY_SUPPORT
78 virtual bool hasImageNotification();
80 virtual bool getSectionContent(const char* segmentName
, const char* sectionName
, void** start
, size_t* length
);
81 virtual bool findSection(const void* imageInterior
, const char** segmentName
, const char** sectionName
, size_t* sectionOffset
);
82 virtual bool usablePrebinding(const LinkContext
& context
) const;
85 static void printStatistics(unsigned int imageCount
);
88 ImageLoaderMachO(const ImageLoaderMachO
&);
89 void operator=(const ImageLoaderMachO
&);
91 virtual uint32_t doGetDependentLibraryCount();
92 virtual void doGetDependentLibraries(DependentLibraryInfo libs
[]);
93 virtual LibraryInfo
doGetLibraryInfo();
94 virtual void getRPaths(const LinkContext
& context
, std::vector
<const char*>&) const;
95 virtual void doRebase(const LinkContext
& context
);
96 virtual void doBind(const LinkContext
& context
, bool forceLazysBound
);
97 virtual void doBindJustLazies(const LinkContext
& context
);
98 virtual void doUpdateMappingPermissions(const LinkContext
& context
);
99 virtual void doInitialization(const LinkContext
& context
);
100 virtual void doGetDOFSections(const LinkContext
& context
, std::vector
<ImageLoader::DOFInfo
>& dofs
);
101 virtual bool needsTermination();
102 virtual void instantiateSegments(const uint8_t* fileData
);
103 virtual bool segmentsMustSlideTogether() const;
104 virtual bool segmentsCanSlide() const;
105 virtual void setSlide(intptr_t slide
);
106 virtual bool usesTwoLevelNameSpace() const;
107 virtual bool isSubframeworkOf(const LinkContext
& context
, const ImageLoader
* image
) const;
108 virtual bool hasSubLibrary(const LinkContext
& context
, const ImageLoader
* child
) const;
109 virtual bool isPrebindable() const;
110 virtual SegmentIterator
beginSegments() const;
111 virtual SegmentIterator
endSegments() const;
113 #if SPLIT_SEG_DYLIB_SUPPORT
114 virtual void mapSegments(int fd
, uint64_t offsetInFat
, uint64_t lenInFat
, uint64_t fileLen
, const LinkContext
& context
);
118 friend class SegmentMachO
;
121 void parseLoadCmds();
122 uintptr_t bindIndirectSymbol(uintptr_t* ptrToBind
, const struct macho_section
* sect
, const char* symbolName
, uintptr_t targetAddr
, const ImageLoader
* targetImage
, const LinkContext
& context
);
123 void doBindIndirectSymbolPointers(const LinkContext
& context
, bool bindNonLazys
, bool bindLazys
, bool onlyCoalescedSymbols
);
124 void doBindExternalRelocations(const LinkContext
& context
, bool onlyCoalescedSymbols
);
125 uintptr_t resolveUndefined(const LinkContext
& context
, const struct macho_nlist
* symbol
, bool twoLevel
, const ImageLoader
**foundIn
);
126 uintptr_t getRelocBase();
127 uintptr_t getFirstWritableSegmentAddress();
128 void resetPreboundLazyPointers(const LinkContext
& context
, uintptr_t relocBase
);
129 void doImageInit(const LinkContext
& context
);
130 void doModInitFunctions(const LinkContext
& context
);
131 void setupLazyPointerHandler(const LinkContext
& context
);
132 void lookupProgramVars(const LinkContext
& context
) const;
133 #if SPLIT_SEG_DYLIB_SUPPORT
134 unsigned int getExtraZeroFillEntriesCount();
135 void initMappingTable(uint64_t offsetInFat
, _shared_region_mapping_np
*mappingTable
);
136 int sharedRegionMapFilePrivateOutside(int fd
, uint64_t offsetInFat
, uint64_t lenInFat
, uint64_t fileLen
, const LinkContext
& context
);
138 #if SPLIT_SEG_SHARED_REGION_SUPPORT
139 int sharedRegionLoadFile(int fd
, uint64_t offsetInFat
, uint64_t lenInFat
, uint64_t fileLen
, const LinkContext
& context
);
140 int sharedRegionMapFile(int fd
, uint64_t offsetInFat
, uint64_t lenInFat
, uint64_t fileLen
, const LinkContext
& context
);
141 int sharedRegionMakePrivate(const LinkContext
& context
);
142 int sharedRegionMapFilePrivate(int fd
, uint64_t offsetInFat
, uint64_t lenInFat
, uint64_t fileLen
, const LinkContext
& context
, bool usemmap
);
143 void initMappingTable(uint64_t offsetInFat
, sf_mapping
*mappingTable
, uintptr_t baseAddress
);
145 bool needsCoalescing() const;
146 bool isAddrInSection(uintptr_t addr
, uint8_t sectionIndex
);
147 void adjustSegments();
148 uintptr_t getSymbolAddress(const struct macho_nlist
* sym
, const ImageLoader
* requestor
, const LinkContext
& context
) const;
149 void preFetch(int fd
, uint64_t offsetInFat
, const LinkContext
& context
);
151 void makeImportSegmentWritable(const LinkContext
& context
);
152 void makeImportSegmentReadOnly(const LinkContext
& context
);
155 static bool symbolRequiresCoalescing(const struct macho_nlist
* symbol
);
156 static uintptr_t bindLazySymbol(const mach_header
*, uintptr_t* lazyPointer
);
157 const struct macho_nlist
* binarySearch(const char* key
, const char stringPool
[], const struct macho_nlist symbols
[], uint32_t symbolCount
) const;
158 const struct macho_nlist
* binarySearchWithToc(const char* key
, const char stringPool
[], const struct macho_nlist symbols
[],
159 const struct dylib_table_of_contents toc
[], uint32_t symbolCount
, uint32_t hintIndex
) const;
161 const uint8_t* fMachOData
;
162 const uint8_t* fLinkEditBase
; // add any internal "offset" to this to get actual address
163 const struct macho_nlist
* fSymbolTable
;
164 const char* fStrings
;
165 const struct dysymtab_command
* fDynamicInfo
;
167 const struct twolevel_hints_command
* fTwoLevelHints
;
168 const struct dylib_command
* fDylibID
;
169 class SegmentMachO
* fSegmentsArray
;
170 #if TEXT_RELOC_SUPPORT
171 class SegmentMachO
* fTextSegmentWithFixups
; // NULL unless __TEXT segment has fixups
174 class SegmentMachO
* fReadOnlyImportSegment
; // NULL unless __IMPORT segment built with -read_only_stubs
175 static uint32_t fgReadOnlyImportSpinLock
;
177 uint32_t fSegmentsArrayCount
: 8,
183 fHasSubLibraries
: 1,
188 fHasInitializers
: 1,
189 #if IMAGE_NOTIFY_SUPPORT
190 fHasImageNotifySection
: 1,
193 static uint32_t fgHintedBinaryTreeSearchs
;
194 static uint32_t fgUnhintedBinaryTreeSearchs
;
195 static uint32_t fgCountOfImagesWithWeakExports
;
199 class SegmentMachO
: public Segment
202 SegmentMachO(const struct macho_segment_command
* cmd
);
203 virtual ~SegmentMachO();
205 virtual const char* getName();
206 virtual uintptr_t getSize();
207 virtual uintptr_t getFileSize();
208 virtual uintptr_t getFileOffset();
209 virtual bool readable();
210 virtual bool writeable();
211 virtual bool executable();
212 virtual bool unaccessible();
213 virtual uintptr_t getActualLoadAddress(const ImageLoader
*);
214 virtual uintptr_t getPreferredLoadAddress();
215 virtual void unmap(const ImageLoader
*);
216 virtual Segment
* next(Segment
*);
217 #if TEXT_RELOC_SUPPORT
218 virtual bool hasFixUps();
221 virtual bool readOnlyImportStubs();
224 virtual bool hasPreferredLoadAddress();
227 SegmentMachO(const SegmentMachO
&);
228 void operator=(const SegmentMachO
&);
229 void adjust(const struct macho_segment_command
* cmd
);
231 friend class ImageLoaderMachO
;
233 const struct macho_segment_command
* fSegmentLoadCommand
;
237 #endif // __IMAGELOADERMACHO__