]> git.saurik.com Git - apple/libsystem.git/blobdiff - init.c
Libsystem-1252.250.1.tar.gz
[apple/libsystem.git] / init.c
diff --git a/init.c b/init.c
index 254815e255375b28da2348d17988c805358d5a30..3073ddbd5cbe571052830183472da394d96e1cbd 100644 (file)
--- a/init.c
+++ b/init.c
@@ -34,6 +34,7 @@
 #include <pthread.h>
 #include <pthread/private.h>
 #include <dlfcn.h>
+#include <fcntl.h>
 #include <errno.h>
 #include <_libkernel_init.h> // Must be after voucher_private.h
 
@@ -50,6 +51,8 @@ extern void libdispatch_init(void);           // from libdispatch.dylib
 extern void _libxpc_initializer(void);         // from libxpc.dylib
 extern void _libsecinit_initializer(void);        // from libsecinit.dylib
 extern void _libtrace_init(void);              // from libsystem_trace.dylib
+extern void _container_init(const char *apple[]); // from libsystem_containermanager.dylib
+extern void __libdarwin_init(void);            // from libsystem_darwin.dylib
 
 
 // signal malloc stack logging that initialisation has finished
@@ -59,10 +62,12 @@ extern void __stack_logging_early_finished(void); // form libsystem_c.dylib
 extern void _pthread_clear_qos_tsd(mach_port_t) __attribute__((weak_import));
 
 // system library atfork handlers
-extern void _pthread_fork_prepare(void);
-extern void _pthread_fork_parent(void);
-extern void _pthread_fork_child(void);
-extern void _pthread_fork_child_postinit(void);
+extern void _pthread_atfork_prepare(void);
+extern void _pthread_atfork_parent(void);
+extern void _pthread_atfork_child(void);
+extern void _pthread_atfork_prepare_handlers();
+extern void _pthread_atfork_parent_handlers(void);
+extern void _pthread_atfork_child_handlers(void);
 extern void _pthread_exit_if_canceled(int);
 
 extern void dispatch_atfork_prepare(void);
@@ -92,15 +97,15 @@ extern void _libcoreservices_fork_child(void);
 extern char *_dirhelper(int, char *, size_t);
 #endif
 
-#if TARGET_OS_EMBEDDED && !TARGET_OS_WATCH && !__LP64__
-extern void _vminterpose_init(void);
-#endif
-
 // advance decls for below;
 void libSystem_atfork_prepare(void);
 void libSystem_atfork_parent(void);
 void libSystem_atfork_child(void);
 
+#if CURRENT_VARIANT_asan
+const char *__asan_default_options(void);
+#endif
+
 // libsyscall_initializer() initializes all of libSystem.dylib
 // <rdar://problem/4892197>
 __attribute__((constructor))
@@ -144,34 +149,45 @@ libSystem_initializer(int argc,
        __libkernel_init(&libkernel_funcs, envp, apple, vars);
 
        __libplatform_init(NULL, envp, apple, vars);
+
        __pthread_init(&libpthread_funcs, envp, apple, vars);
+
        _libc_initializer(&libc_funcs, envp, apple, vars);
 
        // TODO: Move __malloc_init before __libc_init after breaking malloc's upward link to Libc
        __malloc_init(apple);
 
-#if !TARGET_OS_SIMULATOR
+#if TARGET_OS_OSX
        /* <rdar://problem/9664631> */
        __keymgr_initializer();
 #endif
 
-       _dyld_initializer();
+       // No ASan interceptors are invoked before this point. ASan is normally initialized via the malloc interceptor:
+       // _dyld_initializer() -> tlv_load_notification -> wrap_malloc -> ASanInitInternal
 
+       _dyld_initializer();
 
        libdispatch_init();
        _libxpc_initializer();
 
+#if CURRENT_VARIANT_asan
+       setenv("DT_BYPASS_LEAKS_CHECK", "1", 1);
+#endif
+
+       // must be initialized after dispatch
+       _libtrace_init();
+
 #if !(TARGET_OS_EMBEDDED || TARGET_OS_SIMULATOR)
        _libsecinit_initializer();
 #endif
 
-       __stack_logging_early_finished();
-
-#if TARGET_OS_EMBEDDED && !TARGET_OS_WATCH && !__LP64__
-       _vminterpose_init();
+#if defined(HAVE_SYSTEM_CONTAINERMANAGER)
+       _container_init(apple);
 #endif
 
-       _libtrace_init(); // must be initialized after dispatch
+       __libdarwin_init();
+
+       __stack_logging_early_finished();
 
 #if !TARGET_OS_IPHONE
     /* <rdar://problem/22139800> - Preserve the old behavior of apple[] for
@@ -195,52 +211,84 @@ libSystem_initializer(int argc,
 
 /*
  * libSystem_atfork_{prepare,parent,child}() are called by libc during fork(2).
- * They call the corresponding atfork handlers for other libsystem components.
  */
 void
 libSystem_atfork_prepare(void)
 {
+       // first call client prepare handlers registered with pthread_atfork()
+       _pthread_atfork_prepare_handlers();
+
+       // second call hardwired fork prepare handlers for Libsystem components
+       // in the _reverse_ order of library initalization above
        _libSC_info_fork_prepare();
        xpc_atfork_prepare();
        dispatch_atfork_prepare();
-       _pthread_fork_prepare();
        _malloc_fork_prepare();
+       _pthread_atfork_prepare();
 }
 
 void
 libSystem_atfork_parent(void)
 {
+       // first call hardwired fork parent handlers for Libsystem components
+       // in the order of library initalization above
+       _pthread_atfork_parent();
        _malloc_fork_parent();
-       _pthread_fork_parent();
        dispatch_atfork_parent();
        xpc_atfork_parent();
        _libSC_info_fork_parent();
+
+       // second call client parent handlers registered with pthread_atfork()
+       _pthread_atfork_parent_handlers();
 }
 
 void
 libSystem_atfork_child(void)
 {
+       // first call hardwired fork child handlers for Libsystem components
+       // in the order of library initalization above
        _dyld_fork_child();
-       _pthread_fork_child();
+       _pthread_atfork_child();
+       _mach_fork_child();
        _malloc_fork_child();
+       _libc_fork_child(); // _arc4_fork_child calls malloc
        dispatch_atfork_child();
-       
-       _mach_fork_child();
-       _libc_fork_child();
-
 #if defined(HAVE_SYSTEM_CORESERVICES)
        _libcoreservices_fork_child();
 #endif
-
        _asl_fork_child();
        _notify_fork_child();
        xpc_atfork_child();
+       _libtrace_fork_child();
        _libSC_info_fork_child();
 
-       _pthread_fork_child_postinit();
-       _libtrace_fork_child(); // no prep work required for the fork
+       // second call client parent handlers registered with pthread_atfork()
+       _pthread_atfork_child_handlers();
 }
 
+#if CURRENT_VARIANT_asan
+char dynamic_asan_opts[1024] = {0};
+const char *__asan_default_options(void) {
+       int fd = open("/System/Library/Preferences/com.apple.asan.options", O_RDONLY);
+       if (fd != -1) {
+               ssize_t remaining_size = sizeof(dynamic_asan_opts) - 1;
+               char *p = dynamic_asan_opts;
+               ssize_t read_bytes = 0;
+               do {
+                       read_bytes = read(fd, p, remaining_size);
+                       remaining_size -= read_bytes;
+               } while (read_bytes > 0);
+               close(fd);
+
+               if (dynamic_asan_opts[0]) {
+                       return dynamic_asan_opts;
+               }
+       }
+
+       return "color=never:handle_segv=0:handle_sigbus=0:handle_sigill=0:handle_sigfpe=0";
+}
+#endif
+
 /*  
  *  Old crt1.o glue used to call through mach_init_routine which was used to initialize libSystem.
  *  LibSystem now auto-initializes but mach_init_routine is left for binary compatibility.