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