]>
Commit | Line | Data |
---|---|---|
0959b6d4 A |
1 | /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*- |
2 | * | |
412ebb8e | 3 | * Copyright (c) 2004-2009 Apple Inc. All rights reserved. |
0959b6d4 A |
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> | |
39a8cd10 A |
30 | #include <mach-o/loader.h> |
31 | #include <mach-o/nlist.h> | |
0959b6d4 A |
32 | |
33 | #include "ImageLoader.h" | |
bac542e6 | 34 | #include "mach-o/dyld_images.h" |
0959b6d4 | 35 | |
bac542e6 | 36 | |
0959b6d4 | 37 | // |
39a8cd10 | 38 | // ImageLoaderMachO is a subclass of ImageLoader which loads mach-o format files. |
0959b6d4 A |
39 | // |
40 | // | |
41 | class ImageLoaderMachO : public ImageLoader { | |
42 | public: | |
39a8cd10 | 43 | static ImageLoader* instantiateMainExecutable(const macho_header* mh, uintptr_t slide, const char* path, const LinkContext& context); |
df9d6cf7 | 44 | static ImageLoader* instantiateFromFile(const char* path, int fd, const uint8_t firstPages[4096], uint64_t offsetInFat, |
39a8cd10 | 45 | uint64_t lenInFat, const struct stat& info, const LinkContext& context); |
412ebb8e | 46 | static ImageLoader* instantiateFromCache(const macho_header* mh, const char* path, long slide, const struct stat& info, const LinkContext& context); |
39a8cd10 A |
47 | static ImageLoader* instantiateFromMemory(const char* moduleName, const macho_header* mh, uint64_t len, const LinkContext& context); |
48 | ||
0959b6d4 | 49 | |
412ebb8e | 50 | bool inSharedCache() const { return fInSharedCache; } |
df9d6cf7 A |
51 | void disableCoverageCheck() { fCoveredCodeLength = UINT64_MAX; } |
52 | ||
0959b6d4 A |
53 | const char* getInstallPath() const; |
54 | virtual void* getMain() const; | |
832b6fce | 55 | virtual void* getThreadPC() const; |
0959b6d4 A |
56 | virtual const struct mach_header* machHeader() const; |
57 | virtual uintptr_t getSlide() const; | |
bac542e6 | 58 | virtual const void* getEnd() const; |
0959b6d4 | 59 | virtual bool hasCoalescedExports() const; |
39a8cd10 | 60 | virtual const Symbol* findExportedSymbol(const char* name, bool searchReExports, const ImageLoader** foundIn) const; |
412ebb8e A |
61 | virtual uintptr_t getExportedSymbolAddress(const Symbol* sym, const LinkContext& context, |
62 | const ImageLoader* requestor, bool runResolver) const; | |
0959b6d4 A |
63 | virtual DefinitionFlags getExportedSymbolInfo(const Symbol* sym) const; |
64 | virtual const char* getExportedSymbolName(const Symbol* sym) const; | |
65 | virtual uint32_t getExportedSymbolCount() const; | |
66 | virtual const Symbol* getIndexedExportedSymbol(uint32_t index) const; | |
67 | virtual uint32_t getImportedSymbolCount() const; | |
68 | virtual const Symbol* getIndexedImportedSymbol(uint32_t index) const; | |
39a8cd10 | 69 | virtual ReferenceFlags getImportedSymbolInfo(const Symbol* sym) const; |
0959b6d4 A |
70 | virtual const char* getImportedSymbolName(const Symbol* sym) const; |
71 | virtual bool isBundle() const; | |
72 | virtual bool isDylib() const; | |
39a8cd10 A |
73 | virtual bool isExecutable() const; |
74 | virtual bool isPositionIndependentExecutable() const; | |
0959b6d4 | 75 | virtual bool forceFlat() const; |
39a8cd10 A |
76 | virtual bool participatesInCoalescing() const; |
77 | virtual const char* findClosestSymbol(const void* addr, const void** closestAddr) const = 0; | |
78 | virtual void initializeCoalIterator(CoalIterator&, unsigned int loadOrder) = 0; | |
79 | virtual bool incrementCoalIterator(CoalIterator&) = 0; | |
80 | virtual uintptr_t getAddressCoalIterator(CoalIterator&, const LinkContext& contex) = 0; | |
81 | virtual void updateUsesCoalIterator(CoalIterator&, uintptr_t newAddr, ImageLoader* target, const LinkContext& context) = 0; | |
82 | virtual uintptr_t doBindLazySymbol(uintptr_t* lazyPointer, const LinkContext& context) = 0; | |
412ebb8e | 83 | virtual uintptr_t doBindFastLazySymbol(uint32_t lazyBindingInfoOffset, const LinkContext& context, void (*lock)(), void (*unlock)()) = 0; |
0959b6d4 | 84 | virtual void doTermination(const LinkContext& context); |
0959b6d4 | 85 | virtual bool needsInitialization(); |
0959b6d4 | 86 | virtual bool getSectionContent(const char* segmentName, const char* sectionName, void** start, size_t* length); |
39a8cd10 | 87 | virtual void getUnwindInfo(dyld_unwind_sections* info); |
0959b6d4 A |
88 | virtual bool findSection(const void* imageInterior, const char** segmentName, const char** sectionName, size_t* sectionOffset); |
89 | virtual bool usablePrebinding(const LinkContext& context) const; | |
39a8cd10 A |
90 | virtual unsigned int segmentCount() const; |
91 | virtual const char* segName(unsigned int) const; | |
92 | virtual uintptr_t segSize(unsigned int) const; | |
93 | virtual uintptr_t segFileSize(unsigned int) const; | |
94 | virtual bool segHasTrailingZeroFill(unsigned int); | |
95 | virtual uintptr_t segFileOffset(unsigned int) const; | |
96 | virtual bool segReadable(unsigned int) const; | |
97 | virtual bool segWriteable(unsigned int) const; | |
98 | virtual bool segExecutable(unsigned int) const; | |
99 | virtual bool segUnaccessible(unsigned int) const; | |
100 | virtual bool segHasPreferredLoadAddress(unsigned int) const; | |
101 | virtual uintptr_t segActualLoadAddress(unsigned int) const; | |
102 | virtual uintptr_t segPreferredLoadAddress(unsigned int) const; | |
103 | virtual uintptr_t segActualEndAddress(unsigned int) const; | |
412ebb8e | 104 | virtual void registerInterposing(); |
2fd3f4e8 | 105 | virtual uint32_t sdkVersion() const; |
19894a12 | 106 | virtual uint32_t minOSVersion() const; |
0959b6d4 A |
107 | |
108 | ||
412ebb8e | 109 | static void printStatistics(unsigned int imageCount, const InitializerTimingList&); |
19894a12 | 110 | static uint32_t minOSVersion(const mach_header*); |
0959b6d4 A |
111 | |
112 | protected: | |
113 | ImageLoaderMachO(const ImageLoaderMachO&); | |
39a8cd10 A |
114 | ImageLoaderMachO(const macho_header* mh, const char* path, unsigned int segCount, |
115 | uint32_t segOffsets[], unsigned int libCount); | |
116 | virtual ~ImageLoaderMachO() {} | |
117 | ||
0959b6d4 A |
118 | void operator=(const ImageLoaderMachO&); |
119 | ||
412ebb8e | 120 | virtual void setDyldInfo(const struct dyld_info_command*) = 0; |
39a8cd10 A |
121 | virtual void setSymbolTableInfo(const macho_nlist*, const char*, const dysymtab_command*) = 0; |
122 | virtual bool isSubframeworkOf(const LinkContext& context, const ImageLoader* image) const = 0; | |
123 | virtual bool hasSubLibrary(const LinkContext& context, const ImageLoader* child) const = 0; | |
124 | virtual uint32_t* segmentCommandOffsets() const = 0; | |
125 | virtual void rebase(const LinkContext& context) = 0; | |
126 | virtual const ImageLoader::Symbol* findExportedSymbol(const char* name, const ImageLoader** foundIn) const = 0; | |
127 | virtual bool containsSymbol(const void* addr) const = 0; | |
2fd3f4e8 | 128 | virtual uintptr_t exportedSymbolAddress(const LinkContext& context, const Symbol* symbol, const ImageLoader* requestor, bool runResolver) const = 0; |
39a8cd10 A |
129 | virtual bool exportedSymbolIsWeakDefintion(const Symbol* symbol) const = 0; |
130 | virtual const char* exportedSymbolName(const Symbol* symbol) const = 0; | |
131 | virtual unsigned int exportedSymbolCount() const = 0; | |
132 | virtual const ImageLoader::Symbol* exportedSymbolIndexed(unsigned int) const = 0; | |
133 | virtual unsigned int importedSymbolCount() const = 0; | |
134 | virtual const ImageLoader::Symbol* importedSymbolIndexed(unsigned int) const = 0; | |
135 | virtual const char* importedSymbolName(const Symbol* symbol) const = 0; | |
136 | #if PREBOUND_IMAGE_SUPPORT | |
137 | virtual void resetPreboundLazyPointers(const LinkContext& context) = 0; | |
138 | #endif | |
139 | ||
140 | ||
bac542e6 | 141 | virtual void doGetDependentLibraries(DependentLibraryInfo libs[]); |
0959b6d4 | 142 | virtual LibraryInfo doGetLibraryInfo(); |
bac542e6 | 143 | virtual void getRPaths(const LinkContext& context, std::vector<const char*>&) const; |
39a8cd10 | 144 | virtual bool getUUID(uuid_t) const; |
0959b6d4 | 145 | virtual void doRebase(const LinkContext& context); |
39a8cd10 A |
146 | virtual void doBind(const LinkContext& context, bool forceLazysBound) = 0; |
147 | virtual void doBindJustLazies(const LinkContext& context) = 0; | |
412ebb8e | 148 | virtual bool doInitialization(const LinkContext& context); |
bac542e6 | 149 | virtual void doGetDOFSections(const LinkContext& context, std::vector<ImageLoader::DOFInfo>& dofs); |
0959b6d4 | 150 | virtual bool needsTermination(); |
0959b6d4 A |
151 | virtual bool segmentsMustSlideTogether() const; |
152 | virtual bool segmentsCanSlide() const; | |
153 | virtual void setSlide(intptr_t slide); | |
154 | virtual bool usesTwoLevelNameSpace() const; | |
0959b6d4 A |
155 | virtual bool isPrebindable() const; |
156 | ||
0959b6d4 | 157 | |
39a8cd10 | 158 | protected: |
0959b6d4 | 159 | |
39a8cd10 | 160 | void destroy(); |
df9d6cf7 | 161 | static void sniffLoadCommands(const macho_header* mh, const char* path, bool inCache, bool* compressed, |
2fd3f4e8 | 162 | unsigned int* segCount, unsigned int* libCount, const LinkContext& context, |
df9d6cf7 A |
163 | const linkedit_data_command** codeSigCmd, |
164 | const encryption_info_command** encryptCmd); | |
39a8cd10 | 165 | static bool needsAddedLibSystemDepency(unsigned int libCount, const macho_header* mh); |
2fd3f4e8 | 166 | void loadCodeSignature(const struct linkedit_data_command* codeSigCmd, int fd, uint64_t offsetInFatFile, const LinkContext& context); |
df9d6cf7 | 167 | void validateFirstPages(const struct linkedit_data_command* codeSigCmd, int fd, const uint8_t *fileData, size_t lenFileData, off_t offsetInFat, const LinkContext& context); |
39a8cd10 | 168 | const struct macho_segment_command* segLoadCommand(unsigned int segIndex) const; |
df9d6cf7 | 169 | void parseLoadCmds(const ImageLoader::LinkContext& context); |
2fd3f4e8 | 170 | int crashIfInvalidCodeSignature(); |
39a8cd10 A |
171 | bool segHasRebaseFixUps(unsigned int) const; |
172 | bool segHasBindFixUps(unsigned int) const; | |
173 | void segProtect(unsigned int segIndex, const ImageLoader::LinkContext& context); | |
174 | void segMakeWritable(unsigned int segIndex, const ImageLoader::LinkContext& context); | |
175 | #if __i386__ | |
176 | bool segIsReadOnlyImport(unsigned int) const; | |
177 | #endif | |
178 | intptr_t assignSegmentAddresses(const LinkContext& context); | |
179 | uintptr_t reserveAnAddressRange(size_t length, const ImageLoader::LinkContext& context); | |
180 | bool reserveAddressRange(uintptr_t start, size_t length); | |
181 | void mapSegments(int fd, uint64_t offsetInFat, uint64_t lenInFat, uint64_t fileLen, const LinkContext& context); | |
182 | void mapSegments(const void* memoryImage, uint64_t imageLen, const LinkContext& context); | |
183 | void UnmapSegments(); | |
412ebb8e | 184 | void __attribute__((noreturn)) throwSymbolNotFound(const LinkContext& context, const char* symbol, |
19894a12 A |
185 | const char* referencedFrom, const char* fromVersMismatch, |
186 | const char* expectedIn); | |
0959b6d4 A |
187 | void doImageInit(const LinkContext& context); |
188 | void doModInitFunctions(const LinkContext& context); | |
a3afc008 | 189 | void setupLazyPointerHandler(const LinkContext& context); |
bac542e6 | 190 | void lookupProgramVars(const LinkContext& context) const; |
39a8cd10 A |
191 | uintptr_t bindLocation(const LinkContext& context, uintptr_t location, uintptr_t value, |
192 | const ImageLoader* targetImage, uint8_t type, const char* symbolName, | |
193 | intptr_t addend, const char* msg); | |
0959b6d4 | 194 | |
39a8cd10 A |
195 | void makeTextSegmentWritable(const LinkContext& context, bool writeable); |
196 | void preFetchDATA(int fd, uint64_t offsetInFat, const LinkContext& context); | |
197 | ||
198 | ||
412ebb8e | 199 | void doInterpose(const LinkContext& context) = 0; |
39a8cd10 | 200 | bool hasReferencesToWeakSymbols() const; |
412ebb8e A |
201 | uintptr_t getSymbolAddress(const Symbol* sym, const ImageLoader* requestor, |
202 | const LinkContext& context, bool runResolver) const; | |
0959b6d4 | 203 | |
39a8cd10 | 204 | static uintptr_t bindLazySymbol(const mach_header*, uintptr_t* lazyPointer); |
df9d6cf7 A |
205 | protected: |
206 | uint64_t fCoveredCodeLength; | |
0959b6d4 | 207 | const uint8_t* fMachOData; |
39a8cd10 | 208 | const uint8_t* fLinkEditBase; // add any internal "offset" to this to get mapped address |
0959b6d4 | 209 | uintptr_t fSlide; |
39a8cd10 A |
210 | uint32_t fEHFrameSectionOffset; |
211 | uint32_t fUnwindInfoSectionOffset; | |
212 | uint32_t fDylibIDOffset; | |
213 | uint32_t fSegmentsCount : 8, | |
214 | fIsSplitSeg : 1, | |
215 | fInSharedCache : 1, | |
bac542e6 | 216 | #if TEXT_RELOC_SUPPORT |
39a8cd10 A |
217 | fTextSegmentRebases : 1, |
218 | fTextSegmentBinds : 1, | |
bac542e6 A |
219 | #endif |
220 | #if __i386__ | |
39a8cd10 | 221 | fReadOnlyImportSegment : 1, |
bac542e6 A |
222 | #endif |
223 | fHasSubLibraries : 1, | |
224 | fHasSubUmbrella : 1, | |
225 | fInUmbrella : 1, | |
226 | fHasDOFSections : 1, | |
227 | fHasDashInit : 1, | |
228 | fHasInitializers : 1, | |
412ebb8e | 229 | fHasTerminators : 1, |
412ebb8e | 230 | fRegisteredAsRequiresCoalescing : 1; // <rdar://problem/7886402> Loading MH_DYLIB_STUB causing coalescable miscount |
39a8cd10 A |
231 | |
232 | ||
233 | static uint32_t fgSymbolTableBinarySearchs; | |
234 | static uint32_t fgSymbolTrieSearchs; | |
0959b6d4 A |
235 | }; |
236 | ||
237 | ||
238 | #endif // __IMAGELOADERMACHO__ | |
239 | ||
240 | ||
241 | ||
242 |