dyld-832.7.1.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 bool gUseDyld3;
42
43 namespace dyld3 {
44
45
46 AllImages::ProgramVars sVars;
47 static void (*sChildForkFunction)();
48
49 static const char* leafName(const char* argv0)
50 {
51 if ( argv0 == nullptr )
52 return "";
53
54 if ( const char* lastSlash = strrchr(argv0, '/') )
55 return lastSlash+1;
56 else
57 return argv0;
58 }
59
60 static void entry_setVars(const mach_header* mainMH, int argc, const char* argv[], const char* envp[], const char* apple[], bool keysOff, bool platformBinariesOnly)
61 {
62 NXArgc = argc;
63 NXArgv = argv;
64 environ = (char**)envp;
65 appleParams = apple;
66 __progname = leafName(argv[0]);
67
68 sVars.mh = mainMH;
69 sVars.NXArgcPtr = &NXArgc;
70 sVars.NXArgvPtr = &NXArgv;
71 sVars.environPtr = (const char***)&environ;
72 sVars.__prognamePtr = &__progname;
73 gAllImages.setProgramVars(&sVars, keysOff, platformBinariesOnly);
74
75 gUseDyld3 = true;
76
77 setLoggingFromEnvs(envp);
78 }
79
80 static void entry_setHaltFunction(void (*func)(const char* message) __attribute__((noreturn)) )
81 {
82 setHaltFunction(func);
83 }
84
85 static void entry_setLogFunction(void (*logFunction)(const char* format, va_list list))
86 {
87 setLoggingFunction(logFunction);
88 }
89
90 static void entry_setOldAllImageInfo(dyld_all_image_infos* old)
91 {
92 gAllImages.setOldAllImageInfo(old);
93 }
94
95 static void entry_setNotifyMonitoringDyldMain(void (*notifyMonitoringDyldMain)()) {
96 #if !TARGET_OS_DRIVERKIT
97 setNotifyMonitoringDyldMain(notifyMonitoringDyldMain);
98 #endif
99 }
100
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);
106 #endif
107 }
108
109 static void entry_setInitialImageList(const closure::LaunchClosure* closure,
110 const DyldSharedCache* dyldCacheLoadAddress, const char* dyldCachePath,
111 const Array<LoadedImage>& initialImages, LoadedImage& libSystem)
112 {
113 gAllImages.init(closure, dyldCacheLoadAddress, dyldCachePath, initialImages);
114 gAllImages.applyInterposingToDyldCache(closure);
115
116 // run initializer for libSytem.B.dylib
117 // this calls back into _dyld_initializer which calls gAllIimages.addImages()
118 gAllImages.runLibSystemInitializer(libSystem);
119
120 // now that malloc is available, parse DYLD_ env vars
121 closure::gPathOverrides.setEnvVars((const char**)environ, gAllImages.mainExecutable(), gAllImages.mainExecutableImage()->path());
122 }
123
124 static void entry_runInitialzersBottomUp(const mach_header* mainExecutableImageLoadAddress)
125 {
126 gAllImages.runStartupInitialzers();
127 #if !TARGET_OS_DRIVERKIT
128 gAllImages.notifyMonitorMain();
129 #endif
130 }
131
132 static void entry_setChildForkFunction(void (*func)() )
133 {
134 sChildForkFunction = func;
135 }
136
137 static void entry_setRestrictions(bool allowAtPaths, bool allowEnvPaths, bool allowFallbackPaths)
138 {
139 gAllImages.setRestrictions(allowAtPaths, allowEnvPaths);
140 closure::gPathOverrides.setFallbackPathHandling(allowFallbackPaths ?
141 dyld3::closure::PathOverrides::FallbackPathMode::classic :
142 dyld3::closure::PathOverrides::FallbackPathMode::restricted);
143 }
144
145 static void entry_setHasCacheOverrides(bool someCacheImageOverriden)
146 {
147 gAllImages.setHasCacheOverrides(someCacheImageOverriden);
148 }
149
150
151 static void entry_setProgramVars(ProgramVars* progVars)
152 {
153 // this entry only called when running crt1.o based old macOS programs
154 gAllImages.setProgramVars((AllImages::ProgramVars*)progVars, false, false);
155 }
156
157 static void entry_setLaunchMode(uint32_t flags)
158 {
159 gAllImages.setLaunchMode(flags);
160 }
161
162 static MainFunc entry_getDriverkitMain(void)
163 {
164 return gAllImages.getDriverkitMain();
165 }
166
167
168 static_assert((closure::kFormatVersion & LibDyldEntryVector::kBinaryFormatVersionMask) == closure::kFormatVersion, "binary format version overflow");
169
170 const LibDyldEntryVector entryVectorForDyld = {
171 LibDyldEntryVector::kCurrentVectorVersion,
172 closure::kFormatVersion,
173 &entry_setVars,
174 &entry_setHaltFunction,
175 &entry_setOldAllImageInfo,
176 &entry_setInitialImageList,
177 &entry_runInitialzersBottomUp,
178 (__typeof(LibDyldEntryVector::startFunc))address_of_start,
179 &entry_setChildForkFunction,
180 &entry_setLogFunction,
181 &entry_setRestrictions,
182 &entry_setNotifyMonitoringDyldMain,
183 &entry_setNotifyMonitoringDyld,
184 &entry_setHasCacheOverrides,
185 &entry_setProgramVars,
186 &entry_setLaunchMode,
187 &entry_getDriverkitMain,
188 };
189
190 VIS_HIDDEN void _dyld_atfork_prepare()
191 {
192 gAllImages.takeLockBeforeFork();
193 }
194
195 VIS_HIDDEN void _dyld_atfork_parent()
196 {
197 gAllImages.releaseLockInForkParent();
198 }
199
200 VIS_HIDDEN void _dyld_fork_child()
201 {
202 // Note the child fork function updates the data structures inside dyld
203 (*sChildForkFunction)();
204
205 // And we then need to update the structures for dyld3 in libdyld
206 gAllImages.resetLockInForkChild();
207 }
208
209
210 } // namespace dyld3
211