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@
26 #ifndef __DYLD_LOADING_H__
27 #define __DYLD_LOADING_H__
31 #include <mach/mach.h>
35 #include "MachOLoaded.h"
41 // Tuple of info about a loaded image. Contains the loaded address, Image*, and state.
43 class VIS_HIDDEN LoadedImage
{
45 enum class State
{ unmapped
=0, mapped
=1, fixedUp
=2, beingInited
=3, inited
=4 };
47 static LoadedImage
make(const closure::Image
* img
) { LoadedImage result
; result
._image
= img
; return result
; }
48 static LoadedImage
make(const closure::Image
* img
, const MachOLoaded
* mh
)
49 { LoadedImage result
; result
._image
= img
; result
.setLoadedAddress(mh
); return result
; }
51 const closure::Image
* image() const { return _image
; }
52 const MachOLoaded
* loadedAddress() const { return (MachOLoaded
*)(_loadAddr
& (-4096)); }
53 void setLoadedAddress(const MachOLoaded
* a
) { _loadAddr
|= ((uintptr_t)a
& (-4096)); }
54 State
state() const { return (State
)(asBits().state
); }
55 void setState(State s
) { asBits().state
= (int)s
; }
56 bool hideFromFlatSearch() const { return asBits().hide
; }
57 void setHideFromFlatSearch(bool h
) { asBits().hide
= h
; }
58 bool leaveMapped() const { return asBits().leaveMapped
; }
59 void markLeaveMapped() { asBits().leaveMapped
= true; }
62 // since loaded MachO files are always page aligned, that means at least low 12-bits are always zero
63 // so we don't need to record the low 12 bits, instead those bits hold various flags in the _loadeAddr field
75 AddrBits
& asBits() { return *((AddrBits
*)&_loadAddr
); }
76 const AddrBits
& asBits() const { return *((AddrBits
*)&_loadAddr
); }
78 // Note: this must be statically initializable so as to not cause static initializers
79 const closure::Image
* _image
= nullptr;
80 uintptr_t _loadAddr
= 0; // really AddrBits
85 // Utility class to recursively load dependents
87 class VIS_HIDDEN Loader
{
89 typedef bool (*LogFunc
)(const char*, ...) __attribute__((format(printf
, 1, 2)));
91 Loader(Array
<LoadedImage
>& storage
, const void* cacheAddress
, const Array
<const dyld3::closure::ImageArray
*>& imagesArrays
,
92 LogFunc log_loads
, LogFunc log_segments
, LogFunc log_fixups
, LogFunc log_dofs
);
94 void addImage(const LoadedImage
&);
95 void completeAllDependents(Diagnostics
& diag
, uintptr_t topIndex
=0);
96 void mapAndFixupAllImages(Diagnostics
& diag
, bool processDOFs
, bool fromOFI
=false, uintptr_t topIndex
=0);
97 uintptr_t resolveTarget(closure::Image::ResolvedSymbolTarget target
);
98 LoadedImage
* findImage(closure::ImageNum targetImageNum
);
100 static void unmapImage(LoadedImage
& info
);
101 static bool dtraceUserProbesEnabled();
102 static void vmAccountingSetSuspended(bool suspend
, LogFunc
);
108 closure::ImageNum inCache
;
109 closure::ImageNum replacement
;
114 const mach_header
* imageHeader
;
115 const char* imageShortName
;
118 void mapImage(Diagnostics
& diag
, LoadedImage
& info
, bool fromOFI
);
119 void applyFixupsToImage(Diagnostics
& diag
, LoadedImage
& info
);
120 void registerDOFs(const Array
<DOFInfo
>& dofs
);
121 void setSegmentProtects(const LoadedImage
& info
, bool write
);
122 bool sandboxBlockedMmap(const char* path
);
123 bool sandboxBlockedOpen(const char* path
);
124 bool sandboxBlockedStat(const char* path
);
125 bool sandboxBlocked(const char* path
, const char* kind
);
127 Array
<LoadedImage
>& _allImages
;
128 const Array
<const closure::ImageArray
*>& _imagesArrays
;
129 const void* _dyldCacheAddress
;
131 LogFunc _logSegments
;
139 bool bootArgsContains(const char* arg
) VIS_HIDDEN
;
140 bool internalInstall();
141 void forEachLineInFile(const char* path
, void (^lineHandler
)(const char* line
, bool& stop
));
142 void forEachLineInFile(const char* buffer
, size_t bufferLen
, void (^lineHandler
)(const char* line
, bool& stop
));
149 #endif // __DYLD_LOADING_H__