]> git.saurik.com Git - apple/libsystem.git/blobdiff - init.c
Libsystem-1225.1.1.tar.gz
[apple/libsystem.git] / init.c
diff --git a/init.c b/init.c
index 9df51a18f3856a94d2b6f3bbc607c526fee4f736..254815e255375b28da2348d17988c805358d5a30 100644 (file)
--- a/init.c
+++ b/init.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2008, 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2007, 2008, 2011-2013 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
  */
 
-#include <TargetConditionals.h>        // for TARGET_OS_EMBEDDED
+#include <TargetConditionals.h>        // for TARGET_OS_*
 
+#include <stddef.h>
+#include <stdlib.h>
+#include <libc_private.h>
 #include <pthread.h>
 #include <pthread/private.h>
-#include <_libkernel_init.h>
-#include <stdlib.h>
 #include <dlfcn.h>
 #include <errno.h>
-#include <TargetConditionals.h>
+#include <_libkernel_init.h> // Must be after voucher_private.h
 
-struct ProgramVars; /* forward reference */
+#include <mach-o/dyld_priv.h>
 
 // system library initialisers
-extern void bootstrap_init(void);              // from liblaunch.dylib
 extern void mach_init(void);                   // from libsystem_kernel.dylib
 extern void __libplatform_init(void *future_use, const char *envp[], const char *apple[], const struct ProgramVars *vars);
 extern void __pthread_init(const struct _libpthread_functions *libpthread_funcs, const char *envp[], const char *apple[], const struct ProgramVars *vars);     // from libsystem_pthread.dylib
-extern void __libc_init(const struct ProgramVars *vars, void (*atfork_prepare)(void), void (*atfork_parent)(void), void (*atfork_child)(void), const char *apple[]);   // from libsystem_c.dylib
 extern void __malloc_init(const char *apple[]); // from libsystem_malloc.dylib
 extern void __keymgr_initializer(void);                // from libkeymgr.dylib
 extern void _dyld_initializer(void);           // from libdyld.dylib
 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
+
 
 // signal malloc stack logging that initialisation has finished
 extern void __stack_logging_early_finished(void); // form libsystem_c.dylib
 
+// clear qos tsd (from pthread)
+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_exit_if_canceled(int);
 
 extern void dispatch_atfork_prepare(void);
 extern void dispatch_atfork_parent(void);
 extern void dispatch_atfork_child(void);
 
+extern void _libtrace_fork_child(void);
+
 extern void _malloc_fork_prepare(void);
 extern void _malloc_fork_parent(void);
 extern void _malloc_fork_child(void);
 
 extern void _mach_fork_child(void);
-extern void _libc_fork_child(void);
 extern void _notify_fork_child(void);
 extern void _dyld_fork_child(void);
 extern void xpc_atfork_prepare(void);
@@ -79,50 +86,105 @@ extern void _libSC_info_fork_parent(void);
 extern void _libSC_info_fork_child(void);
 extern void _asl_fork_child(void);
 
+#if defined(HAVE_SYSTEM_CORESERVICES)
+// libsystem_coreservices.dylib
+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);
 
-void _pthread_exit_if_canceled(int);
-
-/*
- * libsyscall_initializer() initializes all of libSystem.dylib <rdar://problem/4892197>
- */
-static __attribute__((constructor))
-void libSystem_initializer(int argc, const char* argv[], const char* envp[], const char* apple[], const struct ProgramVars* vars)
+// libsyscall_initializer() initializes all of libSystem.dylib
+// <rdar://problem/4892197>
+__attribute__((constructor))
+static void
+libSystem_initializer(int argc,
+                     const char* argv[],
+                     const char* envp[],
+                     const char* apple[],
+                     const struct ProgramVars* vars)
 {
        static const struct _libkernel_functions libkernel_funcs = {
-               .version = 1,
+               .version = 3,
+               // V1 functions
                .dlsym = dlsym,
                .malloc = malloc,
                .free = free,
                .realloc = realloc,
                ._pthread_exit_if_canceled = _pthread_exit_if_canceled,
+               // V2 functions (removed)
+               // V3 functions
+               .pthread_clear_qos_tsd = _pthread_clear_qos_tsd,
        };
 
        static const struct _libpthread_functions libpthread_funcs = {
-               .version = 1,
+               .version = 2,
                .exit = exit,
+               .malloc = malloc,
+               .free = free,
+       };
+       
+       static const struct _libc_functions libc_funcs = {
+               .version = 1,
+               .atfork_prepare = libSystem_atfork_prepare,
+               .atfork_parent = libSystem_atfork_parent,
+               .atfork_child = libSystem_atfork_child,
+#if defined(HAVE_SYSTEM_CORESERVICES)
+               .dirhelper = _dirhelper,
+#endif
        };
 
        __libkernel_init(&libkernel_funcs, envp, apple, vars);
 
-       bootstrap_init();
        __libplatform_init(NULL, envp, apple, vars);
-
        __pthread_init(&libpthread_funcs, envp, apple, vars);
-       __libc_init(vars, libSystem_atfork_prepare, libSystem_atfork_parent, libSystem_atfork_child, apple);
+       _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
+       /* <rdar://problem/9664631> */
+       __keymgr_initializer();
+#endif
+
        _dyld_initializer();
+
+
        libdispatch_init();
        _libxpc_initializer();
 
+#if !(TARGET_OS_EMBEDDED || TARGET_OS_SIMULATOR)
+       _libsecinit_initializer();
+#endif
+
        __stack_logging_early_finished();
 
+#if TARGET_OS_EMBEDDED && !TARGET_OS_WATCH && !__LP64__
+       _vminterpose_init();
+#endif
+
+       _libtrace_init(); // must be initialized after dispatch
+
+#if !TARGET_OS_IPHONE
+    /* <rdar://problem/22139800> - Preserve the old behavior of apple[] for
+     * programs that haven't linked against newer SDK.
+        */
+#define APPLE0_PREFIX "executable_path="
+       if (dyld_get_program_sdk_version() < DYLD_MACOSX_VERSION_10_11){
+               if (strncmp(apple[0], APPLE0_PREFIX, strlen(APPLE0_PREFIX)) == 0){
+                       apple[0] = apple[0] + strlen(APPLE0_PREFIX);
+               }
+       }
+#endif
+
        /* <rdar://problem/11588042>
         * C99 standard has the following in section 7.5(3):
         * "The value of errno is zero at program startup, but is never set
@@ -132,10 +194,11 @@ void libSystem_initializer(int argc, const char* argv[], const char* envp[], con
 }
 
 /*
- * libSystem_atfork_{prepare,parent,child}() are called by libc when we fork, then we deal with running fork handlers
- * for everyone else.
+ * 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)
+void
+libSystem_atfork_prepare(void)
 {
        _libSC_info_fork_prepare();
        xpc_atfork_prepare();
@@ -144,7 +207,8 @@ void libSystem_atfork_prepare(void)
        _malloc_fork_prepare();
 }
 
-void libSystem_atfork_parent(void)
+void
+libSystem_atfork_parent(void)
 {
        _malloc_fork_parent();
        _pthread_fork_parent();
@@ -153,22 +217,28 @@ void libSystem_atfork_parent(void)
        _libSC_info_fork_parent();
 }
 
-void libSystem_atfork_child(void)
+void
+libSystem_atfork_child(void)
 {
        _dyld_fork_child();
        _pthread_fork_child();
        _malloc_fork_child();
        dispatch_atfork_child();
        
-       bootstrap_init();
        _mach_fork_child();
        _libc_fork_child();
+
+#if defined(HAVE_SYSTEM_CORESERVICES)
+       _libcoreservices_fork_child();
+#endif
+
        _asl_fork_child();
        _notify_fork_child();
        xpc_atfork_child();
        _libSC_info_fork_child();
 
        _pthread_fork_child_postinit();
+       _libtrace_fork_child(); // no prep work required for the fork
 }
 
 /*