]> git.saurik.com Git - apple/dyld.git/blob - src/ImageLoaderMachO.h
a7f2c413f8861092ac607d9b1980722a80a84a3b
[apple/dyld.git] / src / ImageLoaderMachO.h
1 /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-
2 *
3 * Copyright (c) 2004-2005 Apple Computer, 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 __IMAGELOADERMACHO__
27 #define __IMAGELOADERMACHO__
28
29 #include <stdint.h>
30
31 #include "ImageLoader.h"
32 #include "mach-o/dyld_images.h"
33
34 struct sf_mapping;
35 struct _shared_region_mapping_np;
36
37
38 //
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
41 // mach-o.
42 //
43 //
44 class ImageLoaderMachO : public ImageLoader {
45 public:
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();
51
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[]);
75 #endif
76 virtual bool needsInitialization();
77 #if IMAGE_NOTIFY_SUPPORT
78 virtual bool hasImageNotification();
79 #endif
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;
83
84
85 static void printStatistics(unsigned int imageCount);
86
87 protected:
88 ImageLoaderMachO(const ImageLoaderMachO&);
89 void operator=(const ImageLoaderMachO&);
90
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 doUpdateMappingPermissions(const LinkContext& context);
98 virtual void doInitialization(const LinkContext& context);
99 virtual void doGetDOFSections(const LinkContext& context, std::vector<ImageLoader::DOFInfo>& dofs);
100 virtual bool needsTermination();
101 virtual void instantiateSegments(const uint8_t* fileData);
102 virtual bool segmentsMustSlideTogether() const;
103 virtual bool segmentsCanSlide() const;
104 virtual void setSlide(intptr_t slide);
105 virtual bool usesTwoLevelNameSpace() const;
106 virtual bool isSubframeworkOf(const LinkContext& context, const ImageLoader* image) const;
107 virtual bool hasSubLibrary(const LinkContext& context, const ImageLoader* child) const;
108 virtual bool isPrebindable() const;
109 virtual SegmentIterator beginSegments() const;
110 virtual SegmentIterator endSegments() const;
111
112 #if SPLIT_SEG_DYLIB_SUPPORT
113 virtual void mapSegments(int fd, uint64_t offsetInFat, uint64_t lenInFat, uint64_t fileLen, const LinkContext& context);
114 #endif
115
116 private:
117 friend class SegmentMachO;
118
119 void init();
120 void parseLoadCmds();
121 uintptr_t bindIndirectSymbol(uintptr_t* ptrToBind, const struct macho_section* sect, const char* symbolName, uintptr_t targetAddr, const ImageLoader* targetImage, const LinkContext& context);
122 void doBindIndirectSymbolPointers(const LinkContext& context, bool bindNonLazys, bool bindLazys, bool onlyCoalescedSymbols);
123 void doBindExternalRelocations(const LinkContext& context, bool onlyCoalescedSymbols);
124 uintptr_t resolveUndefined(const LinkContext& context, const struct macho_nlist* symbol, bool twoLevel, const ImageLoader **foundIn);
125 uintptr_t getRelocBase();
126 uintptr_t getFirstWritableSegmentAddress();
127 void resetPreboundLazyPointers(const LinkContext& context, uintptr_t relocBase);
128 void doImageInit(const LinkContext& context);
129 void doModInitFunctions(const LinkContext& context);
130 void setupLazyPointerHandler(const LinkContext& context);
131 void lookupProgramVars(const LinkContext& context) const;
132 #if SPLIT_SEG_DYLIB_SUPPORT
133 unsigned int getExtraZeroFillEntriesCount();
134 void initMappingTable(uint64_t offsetInFat, _shared_region_mapping_np *mappingTable);
135 int sharedRegionMapFilePrivateOutside(int fd, uint64_t offsetInFat, uint64_t lenInFat, uint64_t fileLen, const LinkContext& context);
136 #endif
137 #if SPLIT_SEG_SHARED_REGION_SUPPORT
138 int sharedRegionLoadFile(int fd, uint64_t offsetInFat, uint64_t lenInFat, uint64_t fileLen, const LinkContext& context);
139 int sharedRegionMapFile(int fd, uint64_t offsetInFat, uint64_t lenInFat, uint64_t fileLen, const LinkContext& context);
140 int sharedRegionMakePrivate(const LinkContext& context);
141 int sharedRegionMapFilePrivate(int fd, uint64_t offsetInFat, uint64_t lenInFat, uint64_t fileLen, const LinkContext& context, bool usemmap);
142 void initMappingTable(uint64_t offsetInFat, sf_mapping *mappingTable, uintptr_t baseAddress);
143 #endif
144 bool needsCoalescing() const;
145 bool isAddrInSection(uintptr_t addr, uint8_t sectionIndex);
146 void adjustSegments();
147 uintptr_t getSymbolAddress(const struct macho_nlist* sym, const ImageLoader* requestor, const LinkContext& context) const;
148 void preFetch(int fd, uint64_t offsetInFat, const LinkContext& context);
149 #if __i386__
150 void makeImportSegmentWritable(const LinkContext& context);
151 void makeImportSegmentReadOnly(const LinkContext& context);
152 #endif
153
154 static bool symbolRequiresCoalescing(const struct macho_nlist* symbol);
155 static uintptr_t bindLazySymbol(const mach_header*, uintptr_t* lazyPointer);
156 const struct macho_nlist* binarySearch(const char* key, const char stringPool[], const struct macho_nlist symbols[], uint32_t symbolCount) const;
157 const struct macho_nlist* binarySearchWithToc(const char* key, const char stringPool[], const struct macho_nlist symbols[],
158 const struct dylib_table_of_contents toc[], uint32_t symbolCount, uint32_t hintIndex) const;
159
160 const uint8_t* fMachOData;
161 const uint8_t* fLinkEditBase; // add any internal "offset" to this to get actual address
162 const struct macho_nlist* fSymbolTable;
163 const char* fStrings;
164 const struct dysymtab_command* fDynamicInfo;
165 uintptr_t fSlide;
166 const struct twolevel_hints_command* fTwoLevelHints;
167 const struct dylib_command* fDylibID;
168 class SegmentMachO* fSegmentsArray;
169 #if TEXT_RELOC_SUPPORT
170 class SegmentMachO* fTextSegmentWithFixups; // NULL unless __TEXT segment has fixups
171 #endif
172 #if __i386__
173 class SegmentMachO* fReadOnlyImportSegment; // NULL unless __IMPORT segment built with -read_only_stubs
174 static uint32_t fgReadOnlyImportSpinLock;
175 #endif
176 uint32_t fSegmentsArrayCount : 8,
177 fIsSplitSeg : 1,
178 fInSharedCache : 1,
179 #if __ppc64__
180 f4GBWritable : 1,
181 #endif
182 fHasSubLibraries : 1,
183 fHasSubUmbrella : 1,
184 fInUmbrella : 1,
185 fHasDOFSections : 1,
186 fHasDashInit : 1,
187 fHasInitializers : 1,
188 #if IMAGE_NOTIFY_SUPPORT
189 fHasImageNotifySection : 1,
190 #endif
191 fHasTerminators : 1;
192 static uint32_t fgHintedBinaryTreeSearchs;
193 static uint32_t fgUnhintedBinaryTreeSearchs;
194 static uint32_t fgCountOfImagesWithWeakExports;
195 };
196
197
198 class SegmentMachO : public Segment
199 {
200 public:
201 SegmentMachO(const struct macho_segment_command* cmd);
202 virtual ~SegmentMachO();
203
204 virtual const char* getName();
205 virtual uintptr_t getSize();
206 virtual uintptr_t getFileSize();
207 virtual uintptr_t getFileOffset();
208 virtual bool readable();
209 virtual bool writeable();
210 virtual bool executable();
211 virtual bool unaccessible();
212 virtual uintptr_t getActualLoadAddress(const ImageLoader*);
213 virtual uintptr_t getPreferredLoadAddress();
214 virtual void unmap(const ImageLoader*);
215 virtual Segment* next(Segment*);
216 #if TEXT_RELOC_SUPPORT
217 virtual bool hasFixUps();
218 #endif
219 #if __i386__
220 virtual bool readOnlyImportStubs();
221 #endif
222 protected:
223 virtual bool hasPreferredLoadAddress();
224
225 private:
226 SegmentMachO(const SegmentMachO&);
227 void operator=(const SegmentMachO&);
228 void adjust(const struct macho_segment_command* cmd);
229
230 friend class ImageLoaderMachO;
231
232 const struct macho_segment_command* fSegmentLoadCommand;
233 };
234
235
236 #endif // __IMAGELOADERMACHO__
237
238
239
240