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@
25 #include <mach-o/dyld_priv.h>
26 #include <mach-o/dyld_images.h>
28 #include "libdyldEntryVector.h"
29 #include "AllImages.h"
33 #include "PathOverrides.h"
34 #include "StartGlue.h"
35 #include "dyld_process_info_internal.h"
37 extern "C" char start
;
39 VIS_HIDDEN
const char** appleParams
;
41 extern void* __ptrauth_dyld_address_auth gUseDyld3
;
42 extern bool gEnableSharedCacheDataConst
;
47 AllImages::ProgramVars sVars
;
48 static void (*sChildForkFunction
)();
50 static const char* leafName(const char* argv0
)
52 if ( argv0
== nullptr )
55 if ( const char* lastSlash
= strrchr(argv0
, '/') )
61 static void entry_setVars(const mach_header
* mainMH
, int argc
, const char* argv
[], const char* envp
[], const char* apple
[],
62 bool keysOff
, bool platformBinariesOnly
, bool enableSharedCacheDataConst
)
66 environ
= (char**)envp
;
68 __progname
= leafName(argv
[0]);
71 sVars
.NXArgcPtr
= &NXArgc
;
72 sVars
.NXArgvPtr
= &NXArgv
;
73 sVars
.environPtr
= (const char***)&environ
;
74 sVars
.__prognamePtr
= &__progname
;
75 gAllImages
.setProgramVars(&sVars
, keysOff
, platformBinariesOnly
);
79 setLoggingFromEnvs(envp
);
81 gEnableSharedCacheDataConst
= enableSharedCacheDataConst
;
84 static void entry_setHaltFunction(void (*func
)(const char* message
) __attribute__((noreturn
)) )
86 setHaltFunction(func
);
89 static void entry_setLogFunction(void (*logFunction
)(const char* format
, va_list list
))
91 setLoggingFunction(logFunction
);
94 static void entry_setOldAllImageInfo(dyld_all_image_infos
* old
)
96 gAllImages
.setOldAllImageInfo(old
);
99 static void entry_setNotifyMonitoringDyldMain(void (*notifyMonitoringDyldMain
)()) {
100 #if !TARGET_OS_DRIVERKIT
101 setNotifyMonitoringDyldMain(notifyMonitoringDyldMain
);
105 static void entry_setNotifyMonitoringDyld(void (*notifyMonitoringDyld
)(bool unloading
,unsigned imageCount
,
106 const struct mach_header
* loadAddresses
[],
107 const char* imagePaths
[])) {
108 #if !TARGET_OS_DRIVERKIT
109 setNotifyMonitoringDyld(notifyMonitoringDyld
);
113 static void entry_setInitialImageList(const closure::LaunchClosure
* closure
,
114 const DyldSharedCache
* dyldCacheLoadAddress
, const char* dyldCachePath
,
115 const Array
<LoadedImage
>& initialImages
, LoadedImage
& libSystem
,
116 mach_port_t mach_task_self
)
118 gAllImages
.init(closure
, dyldCacheLoadAddress
, dyldCachePath
, initialImages
);
119 gAllImages
.applyInterposingToDyldCache(closure
, mach_task_self
);
121 // run initializer for libSytem.B.dylib
122 // this calls back into _dyld_initializer which calls gAllIimages.addImages()
123 gAllImages
.runLibSystemInitializer(libSystem
);
125 // now that malloc is available, parse DYLD_ env vars
126 closure::gPathOverrides
.setEnvVars((const char**)environ
, gAllImages
.mainExecutable(), gAllImages
.mainExecutableImage()->path());
129 static void entry_runInitialzersBottomUp(const mach_header
* mainExecutableImageLoadAddress
)
131 gAllImages
.runStartupInitialzers();
132 #if !TARGET_OS_DRIVERKIT
133 gAllImages
.notifyMonitorMain();
137 static void entry_setChildForkFunction(void (*func
)() )
139 sChildForkFunction
= func
;
142 static void entry_setRestrictions(bool allowAtPaths
, bool allowEnvPaths
, bool allowFallbackPaths
)
144 gAllImages
.setRestrictions(allowAtPaths
, allowEnvPaths
);
145 closure::gPathOverrides
.setFallbackPathHandling(allowFallbackPaths
?
146 dyld3::closure::PathOverrides::FallbackPathMode::classic
:
147 dyld3::closure::PathOverrides::FallbackPathMode::restricted
);
150 static void entry_setHasCacheOverrides(bool someCacheImageOverriden
)
152 gAllImages
.setHasCacheOverrides(someCacheImageOverriden
);
156 static void entry_setProgramVars(ProgramVars
* progVars
)
158 // this entry only called when running crt1.o based old macOS programs
159 gAllImages
.setProgramVars((AllImages::ProgramVars
*)progVars
, false, false);
162 static void entry_setLaunchMode(uint32_t flags
)
164 gAllImages
.setLaunchMode(flags
);
167 static MainFunc
entry_getDriverkitMain(void)
169 return gAllImages
.getDriverkitMain();
173 static_assert((closure::kFormatVersion
& LibDyldEntryVector::kBinaryFormatVersionMask
) == closure::kFormatVersion
, "binary format version overflow");
175 const LibDyldEntryVector entryVectorForDyld
= {
176 LibDyldEntryVector::kCurrentVectorVersion
,
177 closure::kFormatVersion
,
179 &entry_setHaltFunction
,
180 &entry_setOldAllImageInfo
,
181 &entry_setInitialImageList
,
182 &entry_runInitialzersBottomUp
,
183 (__typeof(LibDyldEntryVector::startFunc
))address_of_start
,
184 &entry_setChildForkFunction
,
185 &entry_setLogFunction
,
186 &entry_setRestrictions
,
187 &entry_setNotifyMonitoringDyldMain
,
188 &entry_setNotifyMonitoringDyld
,
189 &entry_setHasCacheOverrides
,
190 &entry_setProgramVars
,
191 &entry_setLaunchMode
,
192 &entry_getDriverkitMain
,
195 VIS_HIDDEN
void _dyld_atfork_prepare()
197 gAllImages
.takeLockBeforeFork();
200 VIS_HIDDEN
void _dyld_atfork_parent()
202 gAllImages
.releaseLockInForkParent();
205 VIS_HIDDEN
void _dyld_fork_child()
207 // Note the child fork function updates the data structures inside dyld
208 (*sChildForkFunction
)();
210 // And we then need to update the structures for dyld3 in libdyld
211 gAllImages
.resetLockInForkChild();