dyld-45.1.tar.gz
[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
33 struct sf_mapping;
34 struct _shared_region_mapping_np;
35
36 //
37 // ImageLoaderMachO is the concrete subclass of ImageLoader which loads mach-o format files.
38 // The class is written to be 64-bit clean and support both 32-bit and 64-bit executables in
39 // mach-o.
40 //
41 //
42 class ImageLoaderMachO : public ImageLoader {
43 public:
44 ImageLoaderMachO(const char* path, int fd, const uint8_t firstPage[4096], uint64_t offset, uint64_t len, const struct stat& info, const LinkContext& context);
45 ImageLoaderMachO(const char* moduleName, const struct mach_header* mh, uint64_t len, const LinkContext& context);
46 virtual ~ImageLoaderMachO();
47
48 const char* getInstallPath() const;
49 virtual void* getMain() const;
50 virtual const struct mach_header* machHeader() const;
51 virtual uintptr_t getSlide() const;
52 virtual const void* getBaseAddress() const;
53 virtual bool hasCoalescedExports() const;
54 virtual const Symbol* findExportedSymbol(const char* name, const void* hint, bool searchReExports, ImageLoader** foundIn) const;
55 virtual uintptr_t getExportedSymbolAddress(const Symbol* sym) const;
56 virtual DefinitionFlags getExportedSymbolInfo(const Symbol* sym) const;
57 virtual const char* getExportedSymbolName(const Symbol* sym) const;
58 virtual uint32_t getExportedSymbolCount() const;
59 virtual const Symbol* getIndexedExportedSymbol(uint32_t index) const;
60 virtual uint32_t getImportedSymbolCount() const;
61 virtual const Symbol* getIndexedImportedSymbol(uint32_t index) const;
62 virtual ReferenceFlags geImportedSymbolInfo(const Symbol* sym) const;
63 virtual const char* getImportedSymbolName(const Symbol* sym) const;
64 virtual bool isBundle() const;
65 virtual bool isDylib() const;
66 virtual bool forceFlat() const;
67 virtual uintptr_t doBindLazySymbol(uintptr_t* lazyPointer, const LinkContext& context);
68 virtual void doTermination(const LinkContext& context);
69 virtual void doNotification(enum dyld_image_mode mode, uint32_t infoCount, const struct dyld_image_info info[]);
70 virtual bool needsInitialization();
71 virtual bool hasImageNotification();
72 virtual bool getSectionContent(const char* segmentName, const char* sectionName, void** start, size_t* length);
73 virtual bool findSection(const void* imageInterior, const char** segmentName, const char** sectionName, size_t* sectionOffset);
74 virtual bool usablePrebinding(const LinkContext& context) const;
75
76
77 static void printStatistics(unsigned int imageCount);
78
79 protected:
80 ImageLoaderMachO(const ImageLoaderMachO&);
81 void operator=(const ImageLoaderMachO&);
82
83 virtual uint32_t doGetDependentLibraryCount();
84 virtual void doGetDependentLibraries(DependentLibrary libs[]);
85 virtual LibraryInfo doGetLibraryInfo();
86 virtual void doRebase(const LinkContext& context);
87 virtual void doBind(const LinkContext& context, BindingLaziness bindness);
88 virtual void doInitialization(const LinkContext& context);
89 virtual void doPrebinding(const LinkContext& context, time_t timestamp, uint8_t* fileToPrebind);
90 virtual bool needsTermination();
91 virtual void instantiateSegments(const uint8_t* fileData);
92 virtual bool segmentsMustSlideTogether() const;
93 virtual bool segmentsCanSlide() const;
94 virtual void setSlide(intptr_t slide);
95 virtual bool usesTwoLevelNameSpace() const;
96 virtual bool isSubframeworkOf(const LinkContext& context, const ImageLoader* image) const;
97 virtual bool hasSubLibrary(const LinkContext& context, const ImageLoader* child) const;
98 virtual bool isPrebindable() const;
99 virtual void prebindUnmap(const LinkContext& context);
100
101 #if !__LP64__ // split segs not supported for 64-bits
102 virtual void mapSegments(int fd, uint64_t offsetInFat, uint64_t lenInFat, uint64_t fileLen, const LinkContext& context);
103 #endif
104
105 private:
106 friend class SegmentMachO;
107
108 void init();
109 void parseLoadCmds();
110 uintptr_t bindIndirectSymbol(uintptr_t* ptrToBind, const struct macho_section* sect, const char* symbolName, uintptr_t targetAddr, ImageLoader* targetImage, const LinkContext& context);
111 void doBindIndirectSymbolPointers(const LinkContext& context, BindingLaziness bindness, bool onlyCoalescedSymbols);
112 void doBindExternalRelocations(const LinkContext& context, bool onlyCoalescedSymbols);
113 uintptr_t resolveUndefined(const LinkContext& context, const struct macho_nlist* symbol, bool twoLevel, ImageLoader **foundIn);
114 uintptr_t getRelocBase();
115 uintptr_t getFirstWritableSegmentAddress();
116 void doImageInit(const LinkContext& context);
117 void doModInitFunctions(const LinkContext& context);
118 void setupLazyPointerHandler(const LinkContext& context);
119 void applyPrebindingToDATA(uint8_t* fileToPrebind);
120 void applyPrebindingToLoadCommands(const LinkContext& context, uint8_t* fileToPrebind, time_t timestamp);
121 void applyPrebindingToLinkEdit(const LinkContext& context, uint8_t* fileToPrebind);
122 #if !__LP64__ // split segs not supported for 64-bits
123 unsigned int getExtraZeroFillEntriesCount();
124 int sharedRegionLoadFile(int fd, uint64_t offsetInFat, uint64_t lenInFat, uint64_t fileLen, const LinkContext& context);
125 int sharedRegionMapFile(int fd, uint64_t offsetInFat, uint64_t lenInFat, uint64_t fileLen, const LinkContext& context);
126 int sharedRegionMakePrivate(const LinkContext& context);
127 int sharedRegionMapFilePrivate(int fd, uint64_t offsetInFat, uint64_t lenInFat, uint64_t fileLen, const LinkContext& context, bool usemmap);
128 int sharedRegionMapFilePrivateOutside(int fd, uint64_t offsetInFat, uint64_t lenInFat, uint64_t fileLen, const LinkContext& context);
129 void initMappingTable(uint64_t offsetInFat, sf_mapping *mappingTable, uintptr_t baseAddress);
130 void initMappingTable(uint64_t offsetInFat, _shared_region_mapping_np *mappingTable);
131 #endif
132 bool needsCoalescing() const;
133 bool isAddrInSection(uintptr_t addr, uint8_t sectionIndex);
134
135 static bool symbolRequiresCoalescing(const struct macho_nlist* symbol);
136 static uintptr_t bindLazySymbol(const mach_header*, uintptr_t* lazyPointer);
137 static const struct macho_nlist* binarySearch(const char* key, const char stringPool[], const struct macho_nlist symbols[], uint32_t symbolCount);
138 static const struct macho_nlist* binarySearchWithToc(const char* key, const char stringPool[], const struct macho_nlist symbols[],
139 const struct dylib_table_of_contents toc[], uint32_t symbolCount, uint32_t hintIndex);
140
141 const uint8_t* fMachOData;
142 const uint8_t* fLinkEditBase; // add any internal "offset" to this to get actual address
143 const struct macho_nlist* fSymbolTable;
144 const char* fStrings;
145 const struct dysymtab_command* fDynamicInfo;
146 uintptr_t fSlide;
147 bool fIsSplitSeg;
148 bool fHasSubLibraries;
149 bool fHasSubUmbrella;
150 bool fTextSegmentHasFixups;
151 const struct macho_routines_command* fDashInit;
152 const struct macho_section* fModInitSection;
153 const struct macho_section* fModTermSection;
154 const struct macho_section* fDATAdyld;
155 const struct macho_section* fImageNotifySection;
156 const struct twolevel_hints_command* fTwoLevelHints;
157 const struct dylib_command* fDylibID;
158 const char* fReExportThruFramework;
159 class SegmentMachO* fTextSegmentWithFixups; // NULL unless __TEXT segment has fixups
160
161 static uint32_t fgHintedBinaryTreeSearchs;
162 static uint32_t fgUnhintedBinaryTreeSearchs;
163 static uint32_t fgCountOfImagesWithWeakExports;
164 };
165
166
167 class SegmentMachO : public Segment
168 {
169 public:
170 SegmentMachO(const struct macho_segment_command* cmd, ImageLoaderMachO*, const uint8_t* fileData);
171 virtual ~SegmentMachO();
172
173 virtual const ImageLoader* getImage();
174 virtual const char* getName();
175 virtual uintptr_t getSize();
176 virtual uintptr_t getFileSize();
177 virtual uintptr_t getFileOffset();
178 virtual bool readable();
179 virtual bool writeable();
180 virtual bool executable();
181 virtual bool unaccessible();
182 virtual bool hasFixUps();
183 virtual uintptr_t getActualLoadAddress();
184 virtual uintptr_t getPreferredLoadAddress();
185 virtual void setUnMapWhenDestructed(bool unmap);
186 virtual uint32_t crc32();
187
188 protected:
189 virtual bool hasPreferredLoadAddress();
190
191 private:
192 SegmentMachO(const SegmentMachO&);
193 void operator=(const SegmentMachO&);
194
195 friend class ImageLoaderMachO;
196
197
198 ImageLoaderMachO* const fImage;
199 char fName[18];
200 const uintptr_t fSize;
201 const uintptr_t fFileSize;
202 const uintptr_t fFileOffset;
203 const uintptr_t fPreferredLoadAddress;
204 const uint16_t fVMProtection;
205 bool fHasFixUps;
206 bool fUnMapOnDestruction;
207 };
208
209
210 #endif // __IMAGELOADERMACHO__
211
212
213
214