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__
30 #include <mach-o/loader.h>
31 #include <mach-o/nlist.h>
33 #include "ImageLoader.h"
34 #include "mach-o/dyld_images.h"
38 // ImageLoaderMachO is a subclass of ImageLoader which loads mach-o format files.
41 class ImageLoaderMachO
: public ImageLoader
{
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
, const struct stat
& info
, const LinkContext
& context
);
47 static ImageLoader
* instantiateFromMemory(const char* moduleName
, const macho_header
* mh
, uint64_t len
, const LinkContext
& context
);
50 const char* getInstallPath() const;
51 virtual void* getMain() const;
52 virtual const struct mach_header
* machHeader() const;
53 virtual uintptr_t getSlide() const;
54 virtual const void* getEnd() const;
55 virtual bool hasCoalescedExports() const;
56 virtual const Symbol
* findExportedSymbol(const char* name
, bool searchReExports
, const ImageLoader
** foundIn
) const;
57 virtual uintptr_t getExportedSymbolAddress(const Symbol
* sym
, const LinkContext
& context
, const ImageLoader
* requestor
) const;
58 virtual DefinitionFlags
getExportedSymbolInfo(const Symbol
* sym
) const;
59 virtual const char* getExportedSymbolName(const Symbol
* sym
) const;
60 virtual uint32_t getExportedSymbolCount() const;
61 virtual const Symbol
* getIndexedExportedSymbol(uint32_t index
) const;
62 virtual uint32_t getImportedSymbolCount() const;
63 virtual const Symbol
* getIndexedImportedSymbol(uint32_t index
) const;
64 virtual ReferenceFlags
getImportedSymbolInfo(const Symbol
* sym
) const;
65 virtual const char* getImportedSymbolName(const Symbol
* sym
) const;
66 virtual bool isBundle() const;
67 virtual bool isDylib() const;
68 virtual bool isExecutable() const;
69 virtual bool isPositionIndependentExecutable() const;
70 virtual bool forceFlat() const;
71 virtual bool participatesInCoalescing() const;
72 virtual const char* findClosestSymbol(const void* addr
, const void** closestAddr
) const = 0;
73 virtual void initializeCoalIterator(CoalIterator
&, unsigned int loadOrder
) = 0;
74 virtual bool incrementCoalIterator(CoalIterator
&) = 0;
75 virtual uintptr_t getAddressCoalIterator(CoalIterator
&, const LinkContext
& contex
) = 0;
76 virtual void updateUsesCoalIterator(CoalIterator
&, uintptr_t newAddr
, ImageLoader
* target
, const LinkContext
& context
) = 0;
77 virtual uintptr_t doBindLazySymbol(uintptr_t* lazyPointer
, const LinkContext
& context
) = 0;
78 virtual uintptr_t doBindFastLazySymbol(uint32_t lazyBindingInfoOffset
, const LinkContext
& context
) = 0;
79 virtual void doTermination(const LinkContext
& context
);
80 virtual bool needsInitialization();
81 virtual bool getSectionContent(const char* segmentName
, const char* sectionName
, void** start
, size_t* length
);
82 virtual void getUnwindInfo(dyld_unwind_sections
* info
);
83 virtual bool findSection(const void* imageInterior
, const char** segmentName
, const char** sectionName
, size_t* sectionOffset
);
84 virtual bool usablePrebinding(const LinkContext
& context
) const;
85 virtual unsigned int segmentCount() const;
86 virtual const char* segName(unsigned int) const;
87 virtual uintptr_t segSize(unsigned int) const;
88 virtual uintptr_t segFileSize(unsigned int) const;
89 virtual bool segHasTrailingZeroFill(unsigned int);
90 virtual uintptr_t segFileOffset(unsigned int) const;
91 virtual bool segReadable(unsigned int) const;
92 virtual bool segWriteable(unsigned int) const;
93 virtual bool segExecutable(unsigned int) const;
94 virtual bool segUnaccessible(unsigned int) const;
95 virtual bool segHasPreferredLoadAddress(unsigned int) const;
96 virtual uintptr_t segActualLoadAddress(unsigned int) const;
97 virtual uintptr_t segPreferredLoadAddress(unsigned int) const;
98 virtual uintptr_t segActualEndAddress(unsigned int) const;
101 static void printStatistics(unsigned int imageCount
);
104 ImageLoaderMachO(const ImageLoaderMachO
&);
105 ImageLoaderMachO(const macho_header
* mh
, const char* path
, unsigned int segCount
,
106 uint32_t segOffsets
[], unsigned int libCount
);
107 virtual ~ImageLoaderMachO() {}
109 void operator=(const ImageLoaderMachO
&);
111 virtual void setDyldInfo(const dyld_info_command
*) = 0;
112 virtual void setSymbolTableInfo(const macho_nlist
*, const char*, const dysymtab_command
*) = 0;
113 virtual bool isSubframeworkOf(const LinkContext
& context
, const ImageLoader
* image
) const = 0;
114 virtual bool hasSubLibrary(const LinkContext
& context
, const ImageLoader
* child
) const = 0;
115 virtual uint32_t* segmentCommandOffsets() const = 0;
116 virtual void rebase(const LinkContext
& context
) = 0;
117 virtual const ImageLoader::Symbol
* findExportedSymbol(const char* name
, const ImageLoader
** foundIn
) const = 0;
118 virtual bool containsSymbol(const void* addr
) const = 0;
119 virtual uintptr_t exportedSymbolAddress(const Symbol
* symbol
) const = 0;
120 virtual bool exportedSymbolIsWeakDefintion(const Symbol
* symbol
) const = 0;
121 virtual const char* exportedSymbolName(const Symbol
* symbol
) const = 0;
122 virtual unsigned int exportedSymbolCount() const = 0;
123 virtual const ImageLoader::Symbol
* exportedSymbolIndexed(unsigned int) const = 0;
124 virtual unsigned int importedSymbolCount() const = 0;
125 virtual const ImageLoader::Symbol
* importedSymbolIndexed(unsigned int) const = 0;
126 virtual const char* importedSymbolName(const Symbol
* symbol
) const = 0;
127 #if PREBOUND_IMAGE_SUPPORT
128 virtual void resetPreboundLazyPointers(const LinkContext
& context
) = 0;
132 virtual void doGetDependentLibraries(DependentLibraryInfo libs
[]);
133 virtual LibraryInfo
doGetLibraryInfo();
134 virtual void getRPaths(const LinkContext
& context
, std::vector
<const char*>&) const;
135 virtual bool getUUID(uuid_t
) const;
136 virtual void doRebase(const LinkContext
& context
);
137 virtual void doBind(const LinkContext
& context
, bool forceLazysBound
) = 0;
138 virtual void doBindJustLazies(const LinkContext
& context
) = 0;
139 virtual void doInitialization(const LinkContext
& context
);
140 virtual void doGetDOFSections(const LinkContext
& context
, std::vector
<ImageLoader::DOFInfo
>& dofs
);
141 virtual bool needsTermination();
142 virtual bool segmentsMustSlideTogether() const;
143 virtual bool segmentsCanSlide() const;
144 virtual void setSlide(intptr_t slide
);
145 virtual bool usesTwoLevelNameSpace() const;
146 virtual bool isPrebindable() const;
152 static void sniffLoadCommands(const macho_header
* mh
, const char* path
, bool* compressed
,
153 unsigned int* segCount
, unsigned int* libCount
);
154 static bool needsAddedLibSystemDepency(unsigned int libCount
, const macho_header
* mh
);
155 #if CODESIGNING_SUPPORT
156 void loadCodeSignature(const uint8_t* fileData
, int fd
, uint64_t offsetInFatFile
);
158 const struct macho_segment_command
* segLoadCommand(unsigned int segIndex
) const;
159 void parseLoadCmds();
160 bool segHasRebaseFixUps(unsigned int) const;
161 bool segHasBindFixUps(unsigned int) const;
162 void segProtect(unsigned int segIndex
, const ImageLoader::LinkContext
& context
);
163 void segMakeWritable(unsigned int segIndex
, const ImageLoader::LinkContext
& context
);
165 bool segIsReadOnlyImport(unsigned int) const;
167 intptr_t assignSegmentAddresses(const LinkContext
& context
);
168 uintptr_t reserveAnAddressRange(size_t length
, const ImageLoader::LinkContext
& context
);
169 bool reserveAddressRange(uintptr_t start
, size_t length
);
170 void mapSegments(int fd
, uint64_t offsetInFat
, uint64_t lenInFat
, uint64_t fileLen
, const LinkContext
& context
);
171 void mapSegments(const void* memoryImage
, uint64_t imageLen
, const LinkContext
& context
);
172 void UnmapSegments();
173 void __attribute__((noreturn
)) throwSymbolNotFound(const char* symbol
, const char* referencedFrom
, const char* expectedIn
);
174 void doImageInit(const LinkContext
& context
);
175 void doModInitFunctions(const LinkContext
& context
);
176 void setupLazyPointerHandler(const LinkContext
& context
);
177 void lookupProgramVars(const LinkContext
& context
) const;
178 uintptr_t bindLocation(const LinkContext
& context
, uintptr_t location
, uintptr_t value
,
179 const ImageLoader
* targetImage
, uint8_t type
, const char* symbolName
,
180 intptr_t addend
, const char* msg
);
182 void makeTextSegmentWritable(const LinkContext
& context
, bool writeable
);
183 void preFetchDATA(int fd
, uint64_t offsetInFat
, const LinkContext
& context
);
186 bool hasReferencesToWeakSymbols() const;
187 uintptr_t getSymbolAddress(const Symbol
* sym
, const ImageLoader
* requestor
, const LinkContext
& context
) const;
189 static uintptr_t bindLazySymbol(const mach_header
*, uintptr_t* lazyPointer
);
191 const uint8_t* fMachOData
;
192 const uint8_t* fLinkEditBase
; // add any internal "offset" to this to get mapped address
194 uint32_t fEHFrameSectionOffset
;
195 uint32_t fUnwindInfoSectionOffset
;
196 uint32_t fDylibIDOffset
;
197 uint32_t fSegmentsCount
: 8,
200 #if TEXT_RELOC_SUPPORT
201 fTextSegmentRebases
: 1,
202 fTextSegmentBinds
: 1,
205 fReadOnlyImportSegment
: 1,
207 fHasSubLibraries
: 1,
212 fHasInitializers
: 1,
216 static uint32_t fgSymbolTableBinarySearchs
;
217 static uint32_t fgSymbolTrieSearchs
;
221 #endif // __IMAGELOADERMACHO__