]> git.saurik.com Git - apple/libsystem.git/blob - init.c
cdc51303dcc0436fbdb0e4e2d51379457a696388
[apple/libsystem.git] / init.c
1 /*
2 * Copyright (c) 2007, 2008, 2011-2013 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_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. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28
29 #include <TargetConditionals.h> // for TARGET_OS_*
30
31 #include <stddef.h>
32 #include <stdlib.h>
33 #include <unistd.h>
34 #include <corecrypto/cc_priv.h>
35 #include <libc_private.h>
36 #include <pthread.h>
37 #include <pthread/private.h>
38 #if !TARGET_OS_DRIVERKIT
39 #include <dlfcn.h>
40 #endif
41 #include <fcntl.h>
42 #include <errno.h>
43 #include <sys/kdebug.h>
44 #include <_libkernel_init.h> // Must be after voucher_private.h
45 #include <malloc_implementation.h>
46
47 #include <mach-o/dyld_priv.h>
48
49 // system library initialisers
50 extern void mach_init(void); // from libsystem_kernel.dylib
51 extern void __libplatform_init(void *future_use, const char *envp[], const char *apple[], const struct ProgramVars *vars);
52 extern void __pthread_init(const struct _libpthread_functions *libpthread_funcs, const char *envp[], const char *apple[], const struct ProgramVars *vars); // from libsystem_pthread.dylib
53 extern void __malloc_init(const char *apple[]); // from libsystem_malloc.dylib
54 extern void __keymgr_initializer(void); // from libkeymgr.dylib
55 extern void _dyld_initializer(void); // from libdyld.dylib
56 extern void libdispatch_init(void); // from libdispatch.dylib
57 extern void _libxpc_initializer(void); // from libxpc.dylib
58 extern void _libsecinit_initializer(void); // from libsecinit.dylib
59 extern void _libtrace_init(void); // from libsystem_trace.dylib
60 extern void _container_init(const char *apple[]); // from libsystem_containermanager.dylib
61 extern void __libdarwin_init(void); // from libsystem_darwin.dylib
62
63
64 // clear qos tsd (from pthread)
65 extern void _pthread_clear_qos_tsd(mach_port_t) __attribute__((weak_import));
66
67 // system library atfork handlers
68 extern void _pthread_atfork_prepare(void);
69 extern void _pthread_atfork_parent(void);
70 extern void _pthread_atfork_child(void);
71 extern void _pthread_atfork_prepare_handlers();
72 extern void _pthread_atfork_parent_handlers(void);
73 extern void _pthread_atfork_child_handlers(void);
74 extern void _pthread_exit_if_canceled(int);
75
76 extern void dispatch_atfork_prepare(void);
77 extern void dispatch_atfork_parent(void);
78 extern void dispatch_atfork_child(void);
79
80 extern void _libtrace_fork_child(void);
81
82 extern void _malloc_fork_prepare(void);
83 extern void _malloc_fork_parent(void);
84 extern void _malloc_fork_child(void);
85
86 extern void _mach_fork_child(void);
87 extern void _notify_fork_child(void);
88 extern void _dyld_atfork_prepare(void);
89 extern void _dyld_atfork_parent(void);
90 extern void _dyld_fork_child(void);
91 extern void xpc_atfork_prepare(void);
92 extern void xpc_atfork_parent(void);
93 extern void xpc_atfork_child(void);
94 extern void _libSC_info_fork_prepare(void);
95 extern void _libSC_info_fork_parent(void);
96 extern void _libSC_info_fork_child(void);
97 extern void _asl_fork_child(void);
98
99 #if defined(HAVE_SYSTEM_CORESERVICES)
100 // libsystem_coreservices.dylib
101 extern void _libcoreservices_fork_child(void);
102 extern char *_dirhelper(int, char *, size_t);
103 #endif
104
105 // advance decls for below;
106 void libSystem_atfork_prepare(void);
107 void libSystem_atfork_parent(void);
108 void libSystem_atfork_child(void);
109
110 #if CURRENT_VARIANT_asan
111 const char *__asan_default_options(void);
112 #endif
113
114 static inline void
115 _libSystem_ktrace4(uint32_t code, uint64_t a, uint64_t b, uint64_t c, uint64_t d)
116 {
117 if (__builtin_expect(*(volatile uint32_t *)_COMM_PAGE_KDEBUG_ENABLE == 0, 1)) return;
118 kdebug_trace(code, a, b, c, d);
119 }
120 #define _libSystem_ktrace3(code, a, b, c) _libSystem_ktrace4(code, a, b, c, 0)
121 #define _libSystem_ktrace2(code, a, b) _libSystem_ktrace4(code, a, b, 0, 0)
122 #define _libSystem_ktrace1(code, a) _libSystem_ktrace4(code, a, 0, 0, 0)
123 #define _libSystem_ktrace0(code) _libSystem_ktrace4(code, 0, 0, 0, 0)
124
125 /*
126 * these define stable Ariadne tracepoints. If initializers are removed, or
127 * added, then old tracepoints MUST NOT be recycled.
128 */
129 enum {
130 ARIADNE_LIFECYCLE_libsystem_init = ARIADNEDBG_CODE(220, 4),
131 };
132
133 /*
134 * These represent the initializer "name"
135 *
136 * They happen to match the order of the initializers at some point in time,
137 * but there's no guarantee made that traecepoints will appear in numerical
138 * order. As initializers come and go, new codes shall be allocated,
139 * and no slots reused.
140 */
141 enum init_func {
142 INIT_SYSTEM = 0,
143 INIT_KERNEL = 1,
144 INIT_PLATFORM = 2,
145 INIT_PTHREAD = 3,
146 INIT_LIBC = 4,
147 INIT_MALLOC = 5,
148 INIT_KEYMGR = 6,
149 INIT_DYLD = 7,
150 INIT_LIBDISPATCH = 8,
151 INIT_LIBXPC = 9,
152 INIT_LIBTRACE = 10,
153 INIT_SECINIT = 11,
154 INIT_CONTAINERMGR = 12,
155 INIT_DARWIN = 13,
156 };
157
158 #define _libSystem_ktrace_init_func(what) \
159 _libSystem_ktrace1(ARIADNE_LIFECYCLE_libsystem_init | DBG_FUNC_NONE, INIT_##what)
160
161 // libsyscall_initializer() initializes all of libSystem.dylib
162 // <rdar://problem/4892197>
163 __attribute__((constructor))
164 static void
165 libSystem_initializer(int argc,
166 const char* argv[],
167 const char* envp[],
168 const char* apple[],
169 const struct ProgramVars* vars)
170 {
171 static const struct _libkernel_functions libkernel_funcs = {
172 .version = 4,
173 // V1 functions
174 #if !TARGET_OS_DRIVERKIT
175 .dlsym = dlsym,
176 #endif
177 .malloc = malloc,
178 .free = free,
179 .realloc = realloc,
180 ._pthread_exit_if_canceled = _pthread_exit_if_canceled,
181 // V2 functions (removed)
182 // V3 functions
183 .pthread_clear_qos_tsd = _pthread_clear_qos_tsd,
184 // V4 functions
185 .pthread_current_stack_contains_np = pthread_current_stack_contains_np,
186 };
187
188 static const struct _libpthread_functions libpthread_funcs = {
189 .version = 2,
190 .exit = exit,
191 .malloc = malloc,
192 .free = free,
193 };
194
195 static const struct _libc_functions libc_funcs = {
196 .version = 1,
197 .atfork_prepare = libSystem_atfork_prepare,
198 .atfork_parent = libSystem_atfork_parent,
199 .atfork_child = libSystem_atfork_child,
200 #if defined(HAVE_SYSTEM_CORESERVICES)
201 .dirhelper = _dirhelper,
202 #endif
203 };
204
205 static const struct _malloc_functions malloc_funcs = {
206 .version = 1,
207 #if !TARGET_OS_DRIVERKIT
208 .dlopen = dlopen,
209 .dlsym = dlsym,
210 #endif
211 };
212
213 _libSystem_ktrace0(ARIADNE_LIFECYCLE_libsystem_init | DBG_FUNC_START);
214
215 __libkernel_init(&libkernel_funcs, envp, apple, vars);
216 _libSystem_ktrace_init_func(KERNEL);
217
218 __libplatform_init(NULL, envp, apple, vars);
219 _libSystem_ktrace_init_func(PLATFORM);
220
221 __pthread_init(&libpthread_funcs, envp, apple, vars);
222 _libSystem_ktrace_init_func(PTHREAD);
223
224 _libc_initializer(&libc_funcs, envp, apple, vars);
225 _libSystem_ktrace_init_func(LIBC);
226
227 // TODO: Move __malloc_init before __libc_init after breaking malloc's upward link to Libc
228 // Note that __malloc_init() will also initialize ASAN when it is present
229 __malloc_init(apple);
230 _libSystem_ktrace_init_func(MALLOC);
231
232 #if TARGET_OS_OSX
233 /* <rdar://problem/9664631> */
234 __keymgr_initializer();
235 _libSystem_ktrace_init_func(KEYMGR);
236 #endif
237
238 _dyld_initializer();
239 _libSystem_ktrace_init_func(DYLD);
240
241 libdispatch_init();
242 _libSystem_ktrace_init_func(LIBDISPATCH);
243
244 #if !TARGET_OS_DRIVERKIT
245 _libxpc_initializer();
246 _libSystem_ktrace_init_func(LIBXPC);
247
248 #if CURRENT_VARIANT_asan
249 setenv("DT_BYPASS_LEAKS_CHECK", "1", 1);
250 #endif
251 #endif // !TARGET_OS_DRIVERKIT
252
253 // must be initialized after dispatch
254 _libtrace_init();
255 _libSystem_ktrace_init_func(LIBTRACE);
256
257 #if !TARGET_OS_DRIVERKIT
258 #if defined(HAVE_SYSTEM_SECINIT)
259 _libsecinit_initializer();
260 _libSystem_ktrace_init_func(SECINIT);
261 #endif
262
263 #if defined(HAVE_SYSTEM_CONTAINERMANAGER)
264 _container_init(apple);
265 _libSystem_ktrace_init_func(CONTAINERMGR);
266 #endif
267
268 __libdarwin_init();
269 _libSystem_ktrace_init_func(DARWIN);
270 #endif // !TARGET_OS_DRIVERKIT
271
272 __stack_logging_early_finished(&malloc_funcs);
273
274 #if !TARGET_OS_IPHONE
275 /* <rdar://problem/22139800> - Preserve the old behavior of apple[] for
276 * programs that haven't linked against newer SDK.
277 */
278 #define APPLE0_PREFIX "executable_path="
279 if (dyld_get_program_sdk_version() < DYLD_MACOSX_VERSION_10_11){
280 if (strncmp(apple[0], APPLE0_PREFIX, strlen(APPLE0_PREFIX)) == 0){
281 apple[0] = apple[0] + strlen(APPLE0_PREFIX);
282 }
283 }
284 #endif
285
286 #if TARGET_OS_OSX && !defined(__i386__)
287 bool enable_system_version_compat = false;
288 bool enable_ios_version_compat = false;
289 char *system_version_compat_override = getenv("SYSTEM_VERSION_COMPAT");
290 if (system_version_compat_override != NULL) {
291 long override = strtol(system_version_compat_override, NULL, 0);
292 if (override == 1) {
293 enable_system_version_compat = true;
294 } else if (override == 2) {
295 enable_ios_version_compat = true;
296 }
297 } else if (dyld_get_active_platform() == PLATFORM_MACCATALYST) {
298 if (!dyld_program_sdk_at_least(dyld_platform_version_iOS_14_0)) {
299 enable_system_version_compat = true;
300 }
301 } else if (dyld_get_active_platform() == PLATFORM_IOS) {
302 enable_ios_version_compat = true;
303 } else if (!dyld_program_sdk_at_least(dyld_platform_version_macOS_10_16)) {
304 enable_system_version_compat = true;
305 }
306
307 if (enable_system_version_compat || enable_ios_version_compat) {
308 struct _libkernel_late_init_config config = {
309 .version = 2,
310 .enable_system_version_compat = enable_system_version_compat,
311 .enable_ios_version_compat = enable_ios_version_compat,
312 };
313 __libkernel_init_late(&config);
314 }
315 #endif // TARGET_OS_OSX && !defined(__i386__)
316
317 _libSystem_ktrace0(ARIADNE_LIFECYCLE_libsystem_init | DBG_FUNC_END);
318
319 /* <rdar://problem/11588042>
320 * C99 standard has the following in section 7.5(3):
321 * "The value of errno is zero at program startup, but is never set
322 * to zero by any library function."
323 */
324 errno = 0;
325 }
326
327 /*
328 * libSystem_atfork_{prepare,parent,child}() are called by libc during fork(2).
329 */
330 void
331 libSystem_atfork_prepare(void)
332 {
333 // first call client prepare handlers registered with pthread_atfork()
334 _pthread_atfork_prepare_handlers();
335
336 // second call hardwired fork prepare handlers for Libsystem components
337 // in the _reverse_ order of library initalization above
338 #if !TARGET_OS_DRIVERKIT
339 _libSC_info_fork_prepare();
340 xpc_atfork_prepare();
341 #endif // !TARGET_OS_DRIVERKIT
342 dispatch_atfork_prepare();
343 _dyld_atfork_prepare();
344 cc_atfork_prepare();
345 _malloc_fork_prepare();
346 _pthread_atfork_prepare();
347 }
348
349 void
350 libSystem_atfork_parent(void)
351 {
352 // first call hardwired fork parent handlers for Libsystem components
353 // in the order of library initalization above
354 _pthread_atfork_parent();
355 _malloc_fork_parent();
356 cc_atfork_parent();
357 _dyld_atfork_parent();
358 dispatch_atfork_parent();
359 #if !TARGET_OS_DRIVERKIT
360 xpc_atfork_parent();
361 _libSC_info_fork_parent();
362 #endif // !TARGET_OS_DRIVERKIT
363
364 // second call client parent handlers registered with pthread_atfork()
365 _pthread_atfork_parent_handlers();
366 }
367
368 void
369 libSystem_atfork_child(void)
370 {
371 // first call hardwired fork child handlers for Libsystem components
372 // in the order of library initalization above
373 _mach_fork_child();
374 _pthread_atfork_child();
375 _malloc_fork_child();
376 cc_atfork_child();
377 _libc_fork_child(); // _arc4_fork_child calls malloc
378 _dyld_fork_child();
379 dispatch_atfork_child();
380 #if !TARGET_OS_DRIVERKIT
381 #if defined(HAVE_SYSTEM_CORESERVICES)
382 _libcoreservices_fork_child();
383 #endif
384 _asl_fork_child();
385 _notify_fork_child();
386 xpc_atfork_child();
387 #endif // !TARGET_OS_DRIVERKIT
388 _libtrace_fork_child();
389 #if !TARGET_OS_DRIVERKIT
390 _libSC_info_fork_child();
391 #endif // !TARGET_OS_DRIVERKIT
392
393 // second call client parent handlers registered with pthread_atfork()
394 _pthread_atfork_child_handlers();
395 }
396
397 #if CURRENT_VARIANT_asan
398 #define DEFAULT_ASAN_OPTIONS "color=never" \
399 ":handle_segv=0:handle_sigbus=0:handle_sigill=0:handle_sigfpe=0" \
400 ":external_symbolizer_path=" \
401 ":log_path=stderr:log_exe_name=0" \
402 ":halt_on_error=0" \
403 ":print_module_map=2" \
404 ":start_deactivated=1" \
405 ":detect_odr_violation=0"
406 char dynamic_asan_opts[1024] = {0};
407 const char *__asan_default_options(void) {
408 char executable_path[4096] = {0};
409 uint32_t size = sizeof(executable_path);
410 const char *process_name = "";
411 if (_NSGetExecutablePath(executable_path, &size) == 0) {
412 process_name = strrchr(executable_path, '/') + 1;
413 }
414
415 int fd = open("/System/Library/Preferences/com.apple.asan.options", O_RDONLY);
416 if (fd != -1) {
417 ssize_t remaining_size = sizeof(dynamic_asan_opts) - 1;
418 char *p = dynamic_asan_opts;
419 ssize_t read_bytes = 0;
420 do {
421 read_bytes = read(fd, p, remaining_size);
422 remaining_size -= read_bytes;
423 } while (read_bytes > 0);
424 close(fd);
425
426 if (dynamic_asan_opts[0]) {
427 return dynamic_asan_opts;
428 }
429 }
430
431 return DEFAULT_ASAN_OPTIONS;
432 }
433 #endif
434
435 /*
436 * Old crt1.o glue used to call through mach_init_routine which was used to initialize libSystem.
437 * LibSystem now auto-initializes but mach_init_routine is left for binary compatibility.
438 */
439 static void mach_init_old(void) {}
440 void (*mach_init_routine)(void) = &mach_init_old;
441
442 /*
443 * This __crashreporter_info__ symbol is for all non-dylib parts of libSystem.
444 */
445 const char *__crashreporter_info__;
446 asm (".desc __crashreporter_info__, 0x10");