dyld-851.27.tar.gz
[apple/dyld.git] / dyld3 / libdyldEntryVector.cpp
1 /*
2 * Copyright (c) 2017 Apple Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
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
11 * file.
12 *
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.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 #include <stdarg.h>
25 #include <mach-o/dyld_priv.h>
26 #include <mach-o/dyld_images.h>
27
28 #include "libdyldEntryVector.h"
29 #include "AllImages.h"
30 #include "Array.h"
31 #include "Loading.h"
32 #include "Logging.h"
33 #include "PathOverrides.h"
34 #include "StartGlue.h"
35 #include "dyld_process_info_internal.h"
36
37 extern "C" char start;
38
39 VIS_HIDDEN const char** appleParams;
40
41 extern void* __ptrauth_dyld_address_auth gUseDyld3;
42 extern bool gEnableSharedCacheDataConst;
43
44 namespace dyld3 {
45
46
47 AllImages::ProgramVars sVars;
48 static void (*sChildForkFunction)();
49
50 static const char* leafName(const char* argv0)
51 {
52 if ( argv0 == nullptr )
53 return "";
54
55 if ( const char* lastSlash = strrchr(argv0, '/') )
56 return lastSlash+1;
57 else
58 return argv0;
59 }
60
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)
63 {
64 NXArgc = argc;
65 NXArgv = argv;
66 environ = (char**)envp;
67 appleParams = apple;
68 __progname = leafName(argv[0]);
69
70 sVars.mh = mainMH;
71 sVars.NXArgcPtr = &NXArgc;
72 sVars.NXArgvPtr = &NXArgv;
73 sVars.environPtr = (const char***)&environ;
74 sVars.__prognamePtr = &__progname;
75 gAllImages.setProgramVars(&sVars, keysOff, platformBinariesOnly);
76
77 gUseDyld3 = (void*)1;
78
79 setLoggingFromEnvs(envp);
80
81 gEnableSharedCacheDataConst = enableSharedCacheDataConst;
82 }
83
84 static void entry_setHaltFunction(void (*func)(const char* message) __attribute__((noreturn)) )
85 {
86 setHaltFunction(func);
87 }
88
89 static void entry_setLogFunction(void (*logFunction)(const char* format, va_list list))
90 {
91 setLoggingFunction(logFunction);
92 }
93
94 static void entry_setOldAllImageInfo(dyld_all_image_infos* old)
95 {
96 gAllImages.setOldAllImageInfo(old);
97 }
98
99 static void entry_setNotifyMonitoringDyldMain(void (*notifyMonitoringDyldMain)()) {
100 #if !TARGET_OS_DRIVERKIT
101 setNotifyMonitoringDyldMain(notifyMonitoringDyldMain);
102 #endif
103 }
104
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);
110 #endif
111 }
112
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)
117 {
118 gAllImages.init(closure, dyldCacheLoadAddress, dyldCachePath, initialImages);
119 gAllImages.applyInterposingToDyldCache(closure, mach_task_self);
120
121 // run initializer for libSytem.B.dylib
122 // this calls back into _dyld_initializer which calls gAllIimages.addImages()
123 gAllImages.runLibSystemInitializer(libSystem);
124
125 // now that malloc is available, parse DYLD_ env vars
126 closure::gPathOverrides.setEnvVars((const char**)environ, gAllImages.mainExecutable(), gAllImages.mainExecutableImage()->path());
127 }
128
129 static void entry_runInitialzersBottomUp(const mach_header* mainExecutableImageLoadAddress)
130 {
131 gAllImages.runStartupInitialzers();
132 #if !TARGET_OS_DRIVERKIT
133 gAllImages.notifyMonitorMain();
134 #endif
135 }
136
137 static void entry_setChildForkFunction(void (*func)() )
138 {
139 sChildForkFunction = func;
140 }
141
142 static void entry_setRestrictions(bool allowAtPaths, bool allowEnvPaths, bool allowFallbackPaths)
143 {
144 gAllImages.setRestrictions(allowAtPaths, allowEnvPaths);
145 closure::gPathOverrides.setFallbackPathHandling(allowFallbackPaths ?
146 dyld3::closure::PathOverrides::FallbackPathMode::classic :
147 dyld3::closure::PathOverrides::FallbackPathMode::restricted);
148 }
149
150 static void entry_setHasCacheOverrides(bool someCacheImageOverriden)
151 {
152 gAllImages.setHasCacheOverrides(someCacheImageOverriden);
153 }
154
155
156 static void entry_setProgramVars(ProgramVars* progVars)
157 {
158 // this entry only called when running crt1.o based old macOS programs
159 gAllImages.setProgramVars((AllImages::ProgramVars*)progVars, false, false);
160 }
161
162 static void entry_setLaunchMode(uint32_t flags)
163 {
164 gAllImages.setLaunchMode(flags);
165 }
166
167 static MainFunc entry_getDriverkitMain(void)
168 {
169 return gAllImages.getDriverkitMain();
170 }
171
172
173 static_assert((closure::kFormatVersion & LibDyldEntryVector::kBinaryFormatVersionMask) == closure::kFormatVersion, "binary format version overflow");
174
175 const LibDyldEntryVector entryVectorForDyld = {
176 LibDyldEntryVector::kCurrentVectorVersion,
177 closure::kFormatVersion,
178 &entry_setVars,
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,
193 };
194
195 VIS_HIDDEN void _dyld_atfork_prepare()
196 {
197 gAllImages.takeLockBeforeFork();
198 }
199
200 VIS_HIDDEN void _dyld_atfork_parent()
201 {
202 gAllImages.releaseLockInForkParent();
203 }
204
205 VIS_HIDDEN void _dyld_fork_child()
206 {
207 // Note the child fork function updates the data structures inside dyld
208 (*sChildForkFunction)();
209
210 // And we then need to update the structures for dyld3 in libdyld
211 gAllImages.resetLockInForkChild();
212 }
213
214
215 } // namespace dyld3
216