2 * Copyright (c) 2007, 2008, 2011-2013 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_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. 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.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
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.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
29 #include <TargetConditionals.h> // for TARGET_OS_*
34 #include <corecrypto/cc_priv.h>
35 #include <libc_private.h>
37 #include <pthread/private.h>
38 #if !TARGET_OS_DRIVERKIT
40 #include <os/variant_private.h>
44 #include <sys/kdebug.h>
45 #include <_libkernel_init.h> // Must be after voucher_private.h
46 #include <malloc_implementation.h>
48 #include <mach-o/dyld_priv.h>
50 // system library initialisers
51 extern void mach_init(void); // from libsystem_kernel.dylib
52 extern void __libplatform_init(void *future_use
, const char *envp
[], const char *apple
[], const struct ProgramVars
*vars
);
53 extern void __pthread_init(const struct _libpthread_functions
*libpthread_funcs
, const char *envp
[], const char *apple
[], const struct ProgramVars
*vars
); // from libsystem_pthread.dylib
54 extern void __malloc_init(const char *apple
[]); // from libsystem_malloc.dylib
55 extern void __keymgr_initializer(void); // from libkeymgr.dylib
56 extern void _dyld_initializer(void); // from libdyld.dylib
57 extern void libdispatch_init(void); // from libdispatch.dylib
58 extern void _libxpc_initializer(void); // from libxpc.dylib
59 extern void _libsecinit_initializer(void); // from libsecinit.dylib
60 extern void _libtrace_init(void); // from libsystem_trace.dylib
61 extern void _container_init(const char *apple
[]); // from libsystem_containermanager.dylib
62 extern void __libdarwin_init(void); // from libsystem_darwin.dylib
65 // clear qos tsd (from pthread)
66 extern void _pthread_clear_qos_tsd(mach_port_t
) __attribute__((weak_import
));
68 // system library atfork handlers
69 extern void _pthread_atfork_prepare(void);
70 extern void _pthread_atfork_parent(void);
71 extern void _pthread_atfork_child(void);
72 extern void _pthread_atfork_prepare_handlers();
73 extern void _pthread_atfork_parent_handlers(void);
74 extern void _pthread_atfork_child_handlers(void);
75 extern void _pthread_exit_if_canceled(int);
77 extern void dispatch_atfork_prepare(void);
78 extern void dispatch_atfork_parent(void);
79 extern void dispatch_atfork_child(void);
81 extern void _libtrace_fork_child(void);
83 extern void _malloc_fork_prepare(void);
84 extern void _malloc_fork_parent(void);
85 extern void _malloc_fork_child(void);
87 extern void _mach_fork_child(void);
88 extern void _notify_fork_child(void);
89 extern void _dyld_atfork_prepare(void);
90 extern void _dyld_atfork_parent(void);
91 extern void _dyld_fork_child(void);
92 extern void xpc_atfork_prepare(void);
93 extern void xpc_atfork_parent(void);
94 extern void xpc_atfork_child(void);
95 extern void _libSC_info_fork_prepare(void);
96 extern void _libSC_info_fork_parent(void);
97 extern void _libSC_info_fork_child(void);
98 extern void _asl_fork_child(void);
100 #if defined(HAVE_SYSTEM_CORESERVICES)
101 // libsystem_coreservices.dylib
102 extern void _libcoreservices_fork_child(void);
103 extern char *_dirhelper(int, char *, size_t);
106 // advance decls for below;
107 void libSystem_atfork_prepare(void);
108 void libSystem_atfork_parent(void);
109 void libSystem_atfork_child(void);
112 const char *__asan_default_options(void);
116 _libSystem_ktrace4(uint32_t code
, uint64_t a
, uint64_t b
, uint64_t c
, uint64_t d
)
118 if (__builtin_expect(*(volatile uint32_t *)_COMM_PAGE_KDEBUG_ENABLE
== 0, 1)) return;
119 kdebug_trace(code
, a
, b
, c
, d
);
121 #define _libSystem_ktrace3(code, a, b, c) _libSystem_ktrace4(code, a, b, c, 0)
122 #define _libSystem_ktrace2(code, a, b) _libSystem_ktrace4(code, a, b, 0, 0)
123 #define _libSystem_ktrace1(code, a) _libSystem_ktrace4(code, a, 0, 0, 0)
124 #define _libSystem_ktrace0(code) _libSystem_ktrace4(code, 0, 0, 0, 0)
127 * these define stable Ariadne tracepoints. If initializers are removed, or
128 * added, then old tracepoints MUST NOT be recycled.
131 ARIADNE_LIFECYCLE_libsystem_init
= ARIADNEDBG_CODE(220, 4),
135 * These represent the initializer "name"
137 * They happen to match the order of the initializers at some point in time,
138 * but there's no guarantee made that traecepoints will appear in numerical
139 * order. As initializers come and go, new codes shall be allocated,
140 * and no slots reused.
151 INIT_LIBDISPATCH
= 8,
155 INIT_CONTAINERMGR
= 12,
159 #define _libSystem_ktrace_init_func(what) \
160 _libSystem_ktrace1(ARIADNE_LIFECYCLE_libsystem_init | DBG_FUNC_NONE, INIT_##what)
162 // libsyscall_initializer() initializes all of libSystem.dylib
163 // <rdar://problem/4892197>
164 __attribute__((constructor
))
166 libSystem_initializer(int argc
,
170 const struct ProgramVars
* vars
)
172 static const struct _libkernel_functions libkernel_funcs
= {
175 #if !TARGET_OS_DRIVERKIT
181 ._pthread_exit_if_canceled
= _pthread_exit_if_canceled
,
182 // V2 functions (removed)
184 .pthread_clear_qos_tsd
= _pthread_clear_qos_tsd
,
186 .pthread_current_stack_contains_np
= pthread_current_stack_contains_np
,
189 static const struct _libpthread_functions libpthread_funcs
= {
196 static const struct _libc_functions libc_funcs
= {
198 .atfork_prepare
= libSystem_atfork_prepare
,
199 .atfork_parent
= libSystem_atfork_parent
,
200 .atfork_child
= libSystem_atfork_child
,
201 #if defined(HAVE_SYSTEM_CORESERVICES)
202 .dirhelper
= _dirhelper
,
206 _libSystem_ktrace0(ARIADNE_LIFECYCLE_libsystem_init
| DBG_FUNC_START
);
208 __libkernel_init(&libkernel_funcs
, envp
, apple
, vars
);
209 _libSystem_ktrace_init_func(KERNEL
);
211 __libplatform_init(NULL
, envp
, apple
, vars
);
212 _libSystem_ktrace_init_func(PLATFORM
);
214 __pthread_init(&libpthread_funcs
, envp
, apple
, vars
);
215 _libSystem_ktrace_init_func(PTHREAD
);
217 _libc_initializer(&libc_funcs
, envp
, apple
, vars
);
218 _libSystem_ktrace_init_func(LIBC
);
220 // TODO: Move __malloc_init before __libc_init after breaking malloc's upward link to Libc
221 // Note that __malloc_init() will also initialize ASAN when it is present
222 __malloc_init(apple
);
223 _libSystem_ktrace_init_func(MALLOC
);
226 /* <rdar://problem/9664631> */
227 __keymgr_initializer();
228 _libSystem_ktrace_init_func(KEYMGR
);
232 _libSystem_ktrace_init_func(DYLD
);
235 _libSystem_ktrace_init_func(LIBDISPATCH
);
237 #if !TARGET_OS_DRIVERKIT
238 _libxpc_initializer();
239 _libSystem_ktrace_init_func(LIBXPC
);
242 setenv("DT_BYPASS_LEAKS_CHECK", "1", 1);
244 #endif // !TARGET_OS_DRIVERKIT
246 // must be initialized after dispatch
248 _libSystem_ktrace_init_func(LIBTRACE
);
250 #if !TARGET_OS_DRIVERKIT
251 #if defined(HAVE_SYSTEM_SECINIT)
252 _libsecinit_initializer();
253 _libSystem_ktrace_init_func(SECINIT
);
256 #if defined(HAVE_SYSTEM_CONTAINERMANAGER)
257 _container_init(apple
);
258 _libSystem_ktrace_init_func(CONTAINERMGR
);
262 _libSystem_ktrace_init_func(DARWIN
);
263 #endif // !TARGET_OS_DRIVERKIT
265 const struct _malloc_late_init mli
= {
267 #if !TARGET_OS_DRIVERKIT
270 // this must come after _libxpc_initializer()
271 .internal_diagnostics
= os_variant_has_internal_diagnostics("com.apple.libsystem"),
275 __malloc_late_init(&mli
);
277 #if !TARGET_OS_IPHONE
278 /* <rdar://problem/22139800> - Preserve the old behavior of apple[] for
279 * programs that haven't linked against newer SDK.
281 #define APPLE0_PREFIX "executable_path="
282 if (dyld_get_program_sdk_version() < DYLD_MACOSX_VERSION_10_11
){
283 if (strncmp(apple
[0], APPLE0_PREFIX
, strlen(APPLE0_PREFIX
)) == 0){
284 apple
[0] = apple
[0] + strlen(APPLE0_PREFIX
);
289 #if TARGET_OS_OSX && !defined(__i386__)
290 bool enable_system_version_compat
= false;
291 bool enable_ios_version_compat
= false;
292 char *system_version_compat_override
= getenv("SYSTEM_VERSION_COMPAT");
293 if (system_version_compat_override
!= NULL
) {
294 long override
= strtol(system_version_compat_override
, NULL
, 0);
296 enable_system_version_compat
= true;
297 } else if (override
== 2) {
298 enable_ios_version_compat
= true;
300 } else if (dyld_get_active_platform() == PLATFORM_MACCATALYST
) {
301 if (!dyld_program_sdk_at_least(dyld_platform_version_iOS_14_0
)) {
302 enable_system_version_compat
= true;
304 } else if (dyld_get_active_platform() == PLATFORM_IOS
) {
305 enable_ios_version_compat
= true;
306 } else if (!dyld_program_sdk_at_least(dyld_platform_version_macOS_10_16
)) {
307 enable_system_version_compat
= true;
310 if (enable_system_version_compat
|| enable_ios_version_compat
) {
311 struct _libkernel_late_init_config config
= {
313 .enable_system_version_compat
= enable_system_version_compat
,
314 .enable_ios_version_compat
= enable_ios_version_compat
,
316 __libkernel_init_late(&config
);
318 #endif // TARGET_OS_OSX && !defined(__i386__)
320 _libSystem_ktrace0(ARIADNE_LIFECYCLE_libsystem_init
| DBG_FUNC_END
);
322 /* <rdar://problem/11588042>
323 * C99 standard has the following in section 7.5(3):
324 * "The value of errno is zero at program startup, but is never set
325 * to zero by any library function."
331 * libSystem_atfork_{prepare,parent,child}() are called by libc during fork(2).
334 libSystem_atfork_prepare(void)
336 // first call client prepare handlers registered with pthread_atfork()
337 _pthread_atfork_prepare_handlers();
339 // second call hardwired fork prepare handlers for Libsystem components
340 // in the _reverse_ order of library initalization above
341 #if !TARGET_OS_DRIVERKIT
342 _libSC_info_fork_prepare();
343 xpc_atfork_prepare();
344 #endif // !TARGET_OS_DRIVERKIT
345 dispatch_atfork_prepare();
346 _dyld_atfork_prepare();
348 _malloc_fork_prepare();
349 _pthread_atfork_prepare();
353 libSystem_atfork_parent(void)
355 // first call hardwired fork parent handlers for Libsystem components
356 // in the order of library initalization above
357 _pthread_atfork_parent();
358 _malloc_fork_parent();
360 _dyld_atfork_parent();
361 dispatch_atfork_parent();
362 #if !TARGET_OS_DRIVERKIT
364 _libSC_info_fork_parent();
365 #endif // !TARGET_OS_DRIVERKIT
367 // second call client parent handlers registered with pthread_atfork()
368 _pthread_atfork_parent_handlers();
372 libSystem_atfork_child(void)
374 // first call hardwired fork child handlers for Libsystem components
375 // in the order of library initalization above
377 _pthread_atfork_child();
378 _malloc_fork_child();
380 _libc_fork_child(); // _arc4_fork_child calls malloc
382 dispatch_atfork_child();
383 #if !TARGET_OS_DRIVERKIT
384 #if defined(HAVE_SYSTEM_CORESERVICES)
385 _libcoreservices_fork_child();
388 _notify_fork_child();
390 #endif // !TARGET_OS_DRIVERKIT
391 _libtrace_fork_child();
392 #if !TARGET_OS_DRIVERKIT
393 _libSC_info_fork_child();
394 #endif // !TARGET_OS_DRIVERKIT
396 // second call client parent handlers registered with pthread_atfork()
397 _pthread_atfork_child_handlers();
402 // Prevents use of coloring terminal signals in report. These
403 // hinder readability when writing to files or the system log.
404 #define ASAN_OPT_NO_COLOR "color=never"
406 // Disables ASan's signal handlers. It's better to let the system catch
407 // these kinds of crashes.
408 #define ASAN_OPT_NO_SIGNAL_HANDLERS ":handle_segv=0:handle_sigbus=0:handle_sigill=0:handle_sigfpe=0"
410 // Disables using the out-of-process symbolizer (atos) but still allows
411 // in-process symbolization via `dladdr()`. This gives useful function names
412 // (unless they are redacted) which can be helpful in the event we can't
413 // symbolize offline. Out-of-process symbolization isn't useful because
414 // the dSYMs are usually not present on the device.
415 #define ASAN_OPT_NO_OOP_SYMBOLIZER ":external_symbolizer_path="
417 // Don't try to log to a file. It's difficult to find a location for the file
418 // that is writable so just write to stderr.
419 #define ASAN_OPT_FILE_LOG ":log_path=stderr:log_exe_name=0"
421 // Print the module map when finding an issue. This is necessary for offline
423 #define ASAN_OPT_MODULE_MAP ":print_module_map=2"
425 // Disable ODR violation checking.
426 // <rdar://problem/71021707> Investigate enabling ODR checking for ASan in BATS and in the `_asan` variant
427 #define ASAN_OPT_NO_ODR_VIOLATION ":detect_odr_violation=0"
429 // Start ASan in deactivated mode. This reduces memory overhead until
430 // instrumented code is loaded. This prevents catching bugs if no instrumented
432 #define ASAN_OPT_START_DEACTIVATED ":start_deactivated=1"
434 // Do not crash when an error is found. This always works for errors caught via
435 // ASan's interceptors. This won't work for errors caught in ASan
436 // instrumentation unless the code is compiled with
437 // `-fsanitize-recover=address`. If this option is being used then the ASan
438 // reports can only be found by looking at the system log.
439 #define ASAN_OPT_NO_HALT_ON_ERROR ":halt_on_error=0"
441 // Crash when an error is found.
442 #define ASAN_OPT_HALT_ON_ERROR ":halt_on_error=1"
444 // ASan options common to all supported variants
445 #define COMMON_ASAN_OPTIONS \
447 ASAN_OPT_NO_SIGNAL_HANDLERS \
448 ASAN_OPT_NO_OOP_SYMBOLIZER \
450 ASAN_OPT_MODULE_MAP \
451 ASAN_OPT_NO_ODR_VIOLATION
453 #if defined(CURRENT_VARIANT_normal) || defined(CURRENT_VARIANT_debug) || defined (CURRENT_VARIANT_no_asan)
455 // In the normal variant ASan will be running in all userspace processes ("whole userspace ASan").
456 // This mode exists to support "ASan in BATS".
458 // Supporting ASan in the debug variant preserves existing behavior.
460 // The no_asan variant does not load the ASan runtime. However, the runtime
461 // might still be loaded if a program or its dependencies are instrumented.
462 // There is nothing we can do to prevent this so we should set the appropriate
463 // ASan options (same as normal variant) if it does happen. We try to do this
464 // here but this currently doesn't work due to rdar://problem/72212914.
466 // These variants use the following extra options:
468 // ASAN_OPT_NO_HALT_ON_ERROR - Try to avoid crash loops and increase the
469 // chances of booting successfully.
470 // ASAN_OPT_START_DEACTIVATED - Try to reduce memory overhead.
472 # define DEFAULT_ASAN_OPTIONS \
473 COMMON_ASAN_OPTIONS \
474 ASAN_OPT_START_DEACTIVATED \
475 ASAN_OPT_NO_HALT_ON_ERROR
477 #elif defined(CURRENT_VARIANT_asan)
479 // The `_asan` variant is used to support running proceses with
480 // `DYLD_IMAGE_SUFFIX=_asan`. This mode is typically used to target select parts of the OS.
482 // It uses the following extra options:
484 // ASAN_OPT_HALT_ON_ERROR - Crashing is better than just writing the error to the system log
485 // if the system can handle this. This workflow is
486 // more tolerant (e.g. `launchctl debug`) to crashing
487 // than the "whole userspace ASan" workflow.
489 # define DEFAULT_ASAN_OPTIONS \
490 COMMON_ASAN_OPTIONS \
491 ASAN_OPT_HALT_ON_ERROR
494 # error Supporting ASan is not supported in the current variant
497 char dynamic_asan_opts
[1024] = {0};
498 const char *__asan_default_options(void) {
499 int fd
= open("/System/Library/Preferences/com.apple.asan.options", O_RDONLY
);
501 ssize_t remaining_size
= sizeof(dynamic_asan_opts
) - 1;
502 char *p
= dynamic_asan_opts
;
503 ssize_t read_bytes
= 0;
505 read_bytes
= read(fd
, p
, remaining_size
);
506 remaining_size
-= read_bytes
;
507 } while (read_bytes
> 0);
510 if (dynamic_asan_opts
[0]) {
511 return dynamic_asan_opts
;
515 return DEFAULT_ASAN_OPTIONS
;
518 #undef ASAN_OPT_NO_COLOR
519 #undef ASAN_OPT_NO_SIGNAL_HANDLERS
520 #undef ASAN_OPT_NO_OOP_SYMBOLIZER
521 #undef ASAN_OPT_FILE_LOG
522 #undef ASAN_OPT_MODULE_MAP
523 #undef ASAN_OPT_NO_ODR_VIOLATION
524 #undef ASAN_OPT_START_DEACTIVATED
525 #undef ASAN_OPT_NO_HALT_ON_ERROR
526 #undef ASAN_OPT_HALT_ON_ERROR
528 #undef COMMON_ASAN_OPTIONS
529 #undef DEFAULT_ASAN_OPTIONS
534 * Old crt1.o glue used to call through mach_init_routine which was used to initialize libSystem.
535 * LibSystem now auto-initializes but mach_init_routine is left for binary compatibility.
537 static void mach_init_old(void) {}
538 void (*mach_init_routine
)(void) = &mach_init_old
;
541 * This __crashreporter_info__ symbol is for all non-dylib parts of libSystem.
543 const char *__crashreporter_info__
;
544 asm (".desc __crashreporter_info__, 0x10");