2 * Copyright (c) 2017 Apple Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
30 #include "MachOFile.h"
38 // A mach-o mapped into memory with zero-fill expansion
39 // Can be used in dyld at runtime or during closure building
40 struct VIS_HIDDEN MachOLoaded
: public MachOFile
42 typedef const MachOLoaded
* (^DependentToMachOLoaded
)(const MachOLoaded
* image
, uint32_t depIndex
);
45 bool hasExportedSymbol(const char* symbolName
, DependentToMachOLoaded finder
, void** result
,
46 bool* resultPointsToInstructions
) const;
48 // for DYLD_PRINT_SEGMENTS
49 const char* segmentName(uint32_t segIndex
) const;
51 // used to see if main executable overlaps shared region
52 bool intersectsRange(uintptr_t start
, uintptr_t length
) const;
54 // for _dyld_get_image_slide()
55 intptr_t getSlide() const;
58 bool findClosestSymbol(uint64_t unSlidAddr
, const char** symbolName
, uint64_t* symbolUnslidAddr
) const;
60 // for _dyld_find_unwind_sections()
61 const void* findSectionContent(const char* segName
, const char* sectName
, uint64_t& size
) const;
63 // used at runtime to validate loaded image matches closure
64 void forEachCDHashOfCodeSignature(const void* codeSigStart
, size_t codeSignLen
,
65 void (^callback
)(const uint8_t cdHash
[20])) const;
67 // used by DyldSharedCache to find closure
68 static const uint8_t* trieWalk(Diagnostics
& diag
, const uint8_t* start
, const uint8_t* end
, const char* symbol
);
70 // used by cache builder during error handling in chain bind processing
71 const char* dependentDylibLoadPath(uint32_t depIndex
) const;
73 // used by closure builder to find the offset and size of the trie.
74 bool hasExportTrie(uint32_t& runtimeOffset
, uint32_t& size
) const;
76 // used by dyld/libdyld to apply fixups
77 #if BUILDING_DYLD || BUILDING_LIBDYLD
78 void fixupAllChainedFixups(Diagnostics
& diag
, const dyld_chained_starts_in_image
* starts
, uintptr_t slide
,
79 Array
<const void*> bindTargets
, void (^fixupLogger
)(void* loc
, void* newValue
)) const;
84 // For use with new rebase/bind scheme were each fixup location on disk contains info on what
85 // fix up it needs plus the offset to the next fixup.
86 union ChainedFixupPointerOnDisk
89 dyld_chained_ptr_arm64e_auth_rebase authRebase
;
90 dyld_chained_ptr_arm64e_auth_bind authBind
;
91 dyld_chained_ptr_arm64e_rebase rebase
;
92 dyld_chained_ptr_arm64e_bind bind
;
94 uint64_t signExtendedAddend() const;
95 uint64_t unpackTarget() const;
96 const char* keyName() const;
97 uint64_t signPointer(void* loc
, uint64_t target
) const;
101 dyld_chained_ptr_64_rebase rebase
;
102 dyld_chained_ptr_64_bind bind
;
104 uint64_t signExtendedAddend() const;
105 uint64_t unpackedTarget() const;
109 dyld_chained_ptr_32_rebase rebase
;
110 dyld_chained_ptr_32_bind bind
;
112 uint64_t signExtendedAddend() const;
115 typedef dyld_chained_ptr_32_cache_rebase Cache32
;
126 bool isRebase(uint16_t pointerFormat
, uint64_t preferedLoadAddress
, uint64_t& targetRuntimeOffset
) const;
127 bool isBind(uint16_t pointerFormat
, uint32_t& bindOrdinal
) const;
133 uintptr_t textUnslidVMAddr
;
134 uintptr_t linkeditUnslidVMAddr
;
135 uint32_t linkeditFileOffset
;
136 uint32_t linkeditFileSize
;
137 uint32_t linkeditSegIndex
;
142 const dyld_info_command
* dyldInfo
;
143 const linkedit_data_command
* exportsTrie
;
144 const linkedit_data_command
* chainedFixups
;
145 const symtab_command
* symTab
;
146 const dysymtab_command
* dynSymTab
;
147 const linkedit_data_command
* splitSegInfo
;
148 const linkedit_data_command
* functionStarts
;
149 const linkedit_data_command
* dataInCode
;
150 const linkedit_data_command
* codeSig
;
153 void getLinkEditPointers(Diagnostics
& diag
, LinkEditInfo
&) const;
156 void forEachFixupInAllChains(Diagnostics
& diag
, const dyld_chained_starts_in_image
* starts
, bool notifyNonPointers
,
157 void (^callback
)(ChainedFixupPointerOnDisk
* fixupLocation
, const dyld_chained_starts_in_segment
* segInfo
, bool& stop
)) const;
162 enum class Kind
{ headerOffset
, absolute
, resolverOffset
};
166 const MachOLoaded
* foundInDylib
;
168 uint32_t resolverFuncOffset
;
169 const char* foundSymbolName
;
176 bool findExportedSymbol(Diagnostics
& diag
, const char* symbolName
, bool weakImport
, FoundSymbol
& foundInfo
, DependentToMachOLoaded finder
) const;
178 void getLinkEditLoadCommands(Diagnostics
& diag
, LinkEditInfo
& result
) const;
179 void getLayoutInfo(LayoutInfo
&) const;
180 const uint8_t* getLinkEditContent(const LayoutInfo
& info
, uint32_t fileOffset
) const;
181 const uint8_t* getExportsTrie(const LinkEditInfo
& info
, uint64_t& trieSize
) const;
182 void forEachGlobalSymbol(Diagnostics
& diag
, void (^callback
)(const char* symbolName
, uint64_t n_value
, uint8_t n_type
, uint8_t n_sect
, uint16_t n_desc
, bool& stop
)) const;
183 void forEachLocalSymbol(Diagnostics
& diag
, void (^callback
)(const char* symbolName
, uint64_t n_value
, uint8_t n_type
, uint8_t n_sect
, uint16_t n_desc
, bool& stop
)) const;
184 uint32_t dependentDylibCount() const;
185 bool findClosestFunctionStart(uint64_t address
, uint64_t* functionStartAddress
) const;
187 // This calls the callback for all code directories required for a given platform/binary combination.
188 // On watchOS main executables this is all cd hashes.
189 // On watchOS dylibs this is only the single cd hash we need (by rank defined by dyld, not the kernel).
190 // On all other platforms this always returns a single best cd hash (ranked to match the kernel).
191 // Note the callback parameter is really a CS_CodeDirectory.
192 void forEachCodeDirectoryBlob(const void* codeSigStart
, size_t codeSignLen
, void (^callback
)(const void* cd
)) const;
193 bool walkChain(Diagnostics
& diag
, const dyld_chained_starts_in_segment
* segInfo
, uint32_t pageIndex
, uint16_t offsetInPage
,
194 bool notifyNonPointers
, void (^handler
)(ChainedFixupPointerOnDisk
* fixupLocation
, const dyld_chained_starts_in_segment
* segInfo
, bool& stop
)) const;
201 #endif /* MachOLoaded_h */