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 bool gUseDyld3
;
46 AllImages::ProgramVars sVars
;
47 static void (*sChildForkFunction
)();
49 static const char* leafName(const char* argv0
)
51 if ( argv0
== nullptr )
54 if ( const char* lastSlash
= strrchr(argv0
, '/') )
60 static void entry_setVars(const mach_header
* mainMH
, int argc
, const char* argv
[], const char* envp
[], const char* apple
[])
64 environ
= (char**)envp
;
66 __progname
= leafName(argv
[0]);
69 sVars
.NXArgcPtr
= &NXArgc
;
70 sVars
.NXArgvPtr
= &NXArgv
;
71 sVars
.environPtr
= (const char***)&environ
;
72 sVars
.__prognamePtr
= &__progname
;
73 gAllImages
.setProgramVars(&sVars
);
77 setLoggingFromEnvs(envp
);
80 static void entry_setHaltFunction(void (*func
)(const char* message
) __attribute__((noreturn
)) )
82 setHaltFunction(func
);
85 static void entry_setLogFunction(void (*logFunction
)(const char* format
, va_list list
))
87 setLoggingFunction(logFunction
);
90 static void entry_setOldAllImageInfo(dyld_all_image_infos
* old
)
92 gAllImages
.setOldAllImageInfo(old
);
95 static void entry_setNotifyMonitoringDyldMain(void (*notifyMonitoringDyldMain
)()) {
96 #if !TARGET_OS_DRIVERKIT
97 setNotifyMonitoringDyldMain(notifyMonitoringDyldMain
);
101 static void entry_setNotifyMonitoringDyld(void (*notifyMonitoringDyld
)(bool unloading
,unsigned imageCount
,
102 const struct mach_header
* loadAddresses
[],
103 const char* imagePaths
[])) {
104 #if !TARGET_OS_DRIVERKIT
105 setNotifyMonitoringDyld(notifyMonitoringDyld
);
109 static void entry_setInitialImageList(const closure::LaunchClosure
* closure
,
110 const DyldSharedCache
* dyldCacheLoadAddress
, const char* dyldCachePath
,
111 const Array
<LoadedImage
>& initialImages
, LoadedImage
& libSystem
)
113 gAllImages
.init(closure
, dyldCacheLoadAddress
, dyldCachePath
, initialImages
);
114 gAllImages
.applyInterposingToDyldCache(closure
);
116 // run initializer for libSytem.B.dylib
117 // this calls back into _dyld_initializer which calls gAllIimages.addImages()
118 gAllImages
.runLibSystemInitializer(libSystem
);
120 // now that malloc is available, parse DYLD_ env vars
121 closure::gPathOverrides
.setEnvVars((const char**)environ
, gAllImages
.mainExecutable(), gAllImages
.mainExecutableImage()->path());
124 static void entry_runInitialzersBottomUp(const mach_header
* mainExecutableImageLoadAddress
)
126 gAllImages
.runStartupInitialzers();
127 #if !TARGET_OS_DRIVERKIT
128 gAllImages
.notifyMonitorMain();
132 static void entry_setChildForkFunction(void (*func
)() )
134 sChildForkFunction
= func
;
137 static void entry_setRestrictions(bool allowAtPaths
, bool allowEnvPaths
, bool allowFallbackPaths
)
139 gAllImages
.setRestrictions(allowAtPaths
, allowEnvPaths
);
140 closure::gPathOverrides
.setFallbackPathHandling(allowFallbackPaths
?
141 dyld3::closure::PathOverrides::FallbackPathMode::classic
:
142 dyld3::closure::PathOverrides::FallbackPathMode::restricted
);
145 static void entry_setHasCacheOverrides(bool someCacheImageOverriden
)
147 gAllImages
.setHasCacheOverrides(someCacheImageOverriden
);
150 static_assert((closure::kFormatVersion
& LibDyldEntryVector::kBinaryFormatVersionMask
) == closure::kFormatVersion
, "binary format version overflow");
152 const LibDyldEntryVector entryVectorForDyld
= {
153 LibDyldEntryVector::kCurrentVectorVersion
,
154 closure::kFormatVersion
,
156 &entry_setHaltFunction
,
157 &entry_setOldAllImageInfo
,
158 &entry_setInitialImageList
,
159 &entry_runInitialzersBottomUp
,
160 (__typeof(LibDyldEntryVector::startFunc
))address_of_start
,
161 &entry_setChildForkFunction
,
162 &entry_setLogFunction
,
163 &entry_setRestrictions
,
164 &entry_setNotifyMonitoringDyldMain
,
165 &entry_setNotifyMonitoringDyld
,
166 &entry_setHasCacheOverrides
169 VIS_HIDDEN
void _dyld_atfork_prepare()
171 gAllImages
.takeLockBeforeFork();
174 VIS_HIDDEN
void _dyld_atfork_parent()
176 gAllImages
.releaseLockInForkParent();
179 VIS_HIDDEN
void _dyld_fork_child()
181 // Note the child fork function updates the data structures inside dyld
182 (*sChildForkFunction
)();
184 // And we then need to update the structures for dyld3 in libdyld
185 gAllImages
.resetLockInForkChild();