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__
31 #include "ImageLoader.h"
34 struct _shared_region_mapping_np
;
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
42 class ImageLoaderMachO
: public ImageLoader
{
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() {}
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;
77 static void printStatistics(unsigned int imageCount
);
80 ImageLoaderMachO(const ImageLoaderMachO
&);
81 void operator=(const ImageLoaderMachO
&);
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
);
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
);
106 friend class SegmentMachO
;
109 void parseLoadCmds();
110 void doBindIndirectSymbolPointers(const LinkContext
& context
, BindingLaziness bindness
, bool onlyCoalescedSymbols
);
111 void doBindExternalRelocations(const LinkContext
& context
, bool onlyCoalescedSymbols
);
112 uintptr_t resolveUndefined(const LinkContext
& context
, const struct macho_nlist
* symbol
, bool twoLevel
, ImageLoader
**foundIn
);
113 uintptr_t getRelocBase();
114 void doImageInit(const LinkContext
& context
);
115 void doModInitFunctions(const LinkContext
& context
);
116 void setupLazyPointerHandler();
117 void applyPrebindingToDATA(uint8_t* fileToPrebind
);
118 void applyPrebindingToLoadCommands(const LinkContext
& context
, uint8_t* fileToPrebind
, time_t timestamp
);
119 void applyPrebindingToLinkEdit(const LinkContext
& context
, uint8_t* fileToPrebind
);
120 #if !__LP64__ // split segs not supported for 64-bits
121 unsigned int getExtraZeroFillEntriesCount();
122 int sharedRegionLoadFile(int fd
, uint64_t offsetInFat
, uint64_t lenInFat
, uint64_t fileLen
, const LinkContext
& context
);
123 int sharedRegionMapFile(int fd
, uint64_t offsetInFat
, uint64_t lenInFat
, uint64_t fileLen
, const LinkContext
& context
);
124 int sharedRegionMakePrivate(const LinkContext
& context
);
125 int sharedRegionMapFilePrivate(int fd
, uint64_t offsetInFat
, uint64_t lenInFat
, uint64_t fileLen
, const LinkContext
& context
, bool usemmap
);
126 int sharedRegionMapFilePrivateOutside(int fd
, uint64_t offsetInFat
, uint64_t lenInFat
, uint64_t fileLen
, const LinkContext
& context
);
127 void initMappingTable(uint64_t offsetInFat
, sf_mapping
*mappingTable
, uintptr_t baseAddress
);
128 void initMappingTable(uint64_t offsetInFat
, _shared_region_mapping_np
*mappingTable
);
130 bool needsCoalescing() const;
132 static bool symbolRequiresCoalescing(const struct macho_nlist
* symbol
);
133 static uintptr_t bindLazySymbol(const mach_header
*, uintptr_t* lazyPointer
);
134 static const struct macho_nlist
* binarySearch(const char* key
, const char stringPool
[], const struct macho_nlist symbols
[], uint32_t symbolCount
);
135 static const struct macho_nlist
* binarySearchWithToc(const char* key
, const char stringPool
[], const struct macho_nlist symbols
[],
136 const struct dylib_table_of_contents toc
[], uint32_t symbolCount
, uint32_t hintIndex
);
138 const uint8_t* fMachOData
;
139 const uint8_t* fLinkEditBase
; // add any internal "offset" to this to get actual address
140 const struct macho_nlist
* fSymbolTable
;
141 const char* fStrings
;
142 const struct dysymtab_command
* fDynamicInfo
;
145 bool fHasSubLibraries
;
146 bool fHasSubUmbrella
;
147 bool fTextSegmentHasFixups
;
148 const struct macho_routines_command
* fDashInit
;
149 const struct macho_section
* fModInitSection
;
150 const struct macho_section
* fModTermSection
;
151 const struct macho_section
* fDATAdyld
;
152 const struct macho_section
* fImageNotifySection
;
153 const struct twolevel_hints_command
* fTwoLevelHints
;
154 const struct dylib_command
* fDylibID
;
155 const char* fReExportThruFramework
;
156 SegmentMachO
* fTextSegmentWithFixups
; // NULL unless __TEXT segment has fixups
158 static uint32_t fgHintedBinaryTreeSearchs
;
159 static uint32_t fgUnhintedBinaryTreeSearchs
;
163 class SegmentMachO
: public Segment
166 SegmentMachO(const struct macho_segment_command
* cmd
, ImageLoaderMachO
*, const uint8_t* fileData
);
167 virtual ~SegmentMachO();
169 virtual const ImageLoader
* getImage();
170 virtual const char* getName();
171 virtual uintptr_t getSize();
172 virtual uintptr_t getFileSize();
173 virtual uintptr_t getFileOffset();
174 virtual bool readable();
175 virtual bool writeable();
176 virtual bool executable();
177 virtual bool unaccessible();
178 virtual bool hasFixUps();
179 virtual uintptr_t getActualLoadAddress();
180 virtual uintptr_t getPreferredLoadAddress();
181 virtual void setUnMapWhenDestructed(bool unmap
);
182 virtual uint32_t crc32();
185 virtual bool hasPreferredLoadAddress();
188 SegmentMachO(const SegmentMachO
&);
189 void operator=(const SegmentMachO
&);
191 friend class ImageLoaderMachO
;
194 ImageLoaderMachO
* const fImage
;
196 const uintptr_t fSize
;
197 const uintptr_t fFileSize
;
198 const uintptr_t fFileOffset
;
199 const uintptr_t fPreferredLoadAddress
;
200 const uint16_t fVMProtection
;
202 bool fUnMapOnDestruction
;
206 #endif // __IMAGELOADERMACHO__