1/* 2 * Copyright (c) 2007, 2008, 2011, 2012 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_EMBEDDED 30 31#include <pthread.h> 32#include <pthread/private.h> 33#include <_libkernel_init.h> 34#include <stdlib.h> 35#include <dlfcn.h> 36#include <errno.h> 37#include <TargetConditionals.h> 38 39struct ProgramVars; /* forward reference */ 40 41// system library initialisers 42extern void bootstrap_init(void); // from liblaunch.dylib 43extern void mach_init(void); // from libsystem_kernel.dylib 44extern void __libplatform_init(void *future_use, const char *envp[], const char *apple[], const struct ProgramVars *vars); 45extern void __pthread_init(const struct _libpthread_functions *libpthread_funcs, const char *envp[], const char *apple[], const struct ProgramVars *vars); // from libsystem_pthread.dylib 46extern 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 47extern void __malloc_init(const char *apple[]); // from libsystem_malloc.dylib 48extern void __keymgr_initializer(void); // from libkeymgr.dylib 49extern void _dyld_initializer(void); // from libdyld.dylib 50extern void libdispatch_init(void); // from libdispatch.dylib 51extern void _libxpc_initializer(void); // from libxpc.dylib 52 53// signal malloc stack logging that initialisation has finished 54extern void __stack_logging_early_finished(void); // form libsystem_c.dylib 55 56// system library atfork handlers 57extern void _pthread_fork_prepare(void); 58extern void _pthread_fork_parent(void); 59extern void _pthread_fork_child(void); 60extern void _pthread_fork_child_postinit(void); 61 62extern void dispatch_atfork_prepare(void); 63extern void dispatch_atfork_parent(void); 64extern void dispatch_atfork_child(void); 65 66extern void _malloc_fork_prepare(void); 67extern void _malloc_fork_parent(void); 68extern void _malloc_fork_child(void); 69 70extern void _mach_fork_child(void); 71extern void _libc_fork_child(void); 72extern void _notify_fork_child(void); 73extern void _dyld_fork_child(void); 74extern void xpc_atfork_prepare(void); 75extern void xpc_atfork_parent(void); 76extern void xpc_atfork_child(void); 77extern void _libSC_info_fork_prepare(void); 78extern void _libSC_info_fork_parent(void); 79extern void _libSC_info_fork_child(void); 80extern void _asl_fork_child(void); 81 82// advance decls for below; 83void libSystem_atfork_prepare(void); 84void libSystem_atfork_parent(void); 85void libSystem_atfork_child(void); 86 87void _pthread_exit_if_canceled(int); 88 89/* 90 * libsyscall_initializer() initializes all of libSystem.dylib <rdar://problem/4892197> 91 */ 92static __attribute__((constructor)) 93void libSystem_initializer(int argc, const char* argv[], const char* envp[], const char* apple[], const struct ProgramVars* vars) 94{ 95 static const struct _libkernel_functions libkernel_funcs = { 96 .version = 1, 97 .dlsym = dlsym, 98 .malloc = malloc, 99 .free = free, 100 .realloc = realloc, 101 ._pthread_exit_if_canceled = _pthread_exit_if_canceled, 102 }; 103 104 static const struct _libpthread_functions libpthread_funcs = { 105 .version = 1, 106 .exit = exit, 107 }; 108 109 __libkernel_init(&libkernel_funcs, envp, apple, vars); 110 111 bootstrap_init(); 112 __libplatform_init(NULL, envp, apple, vars); 113 114 __pthread_init(&libpthread_funcs, envp, apple, vars); 115 __libc_init(vars, libSystem_atfork_prepare, libSystem_atfork_parent, libSystem_atfork_child, apple); 116 117 // TODO: Move __malloc_init before __libc_init after breaking malloc's upward link to Libc 118 __malloc_init(apple); 119 120 _dyld_initializer(); 121 libdispatch_init(); 122 _libxpc_initializer(); 123 124 __stack_logging_early_finished(); 125 126 /* <rdar://problem/11588042> 127 * C99 standard has the following in section 7.5(3): 128 * "The value of errno is zero at program startup, but is never set 129 * to zero by any library function." 130 */ 131 errno = 0; 132} 133 134/* 135 * libSystem_atfork_{prepare,parent,child}() are called by libc when we fork, then we deal with running fork handlers 136 * for everyone else. 137 */ 138void libSystem_atfork_prepare(void) 139{ 140 _libSC_info_fork_prepare(); 141 xpc_atfork_prepare(); 142 dispatch_atfork_prepare(); 143 _pthread_fork_prepare(); 144 _malloc_fork_prepare(); 145} 146 147void libSystem_atfork_parent(void) 148{ 149 _malloc_fork_parent(); 150 _pthread_fork_parent(); 151 dispatch_atfork_parent(); 152 xpc_atfork_parent(); 153 _libSC_info_fork_parent(); 154} 155 156void libSystem_atfork_child(void) 157{ 158 _dyld_fork_child(); 159 _pthread_fork_child(); 160 _malloc_fork_child(); 161 dispatch_atfork_child(); 162 163 bootstrap_init(); 164 _mach_fork_child(); 165 _libc_fork_child(); 166 _asl_fork_child(); 167 _notify_fork_child(); 168 xpc_atfork_child(); 169 _libSC_info_fork_child(); 170 171 _pthread_fork_child_postinit(); 172} 173 174/* 175 * Old crt1.o glue used to call through mach_init_routine which was used to initialize libSystem. 176 * LibSystem now auto-initializes but mach_init_routine is left for binary compatibility. 177 */ 178static void mach_init_old(void) {} 179void (*mach_init_routine)(void) = &mach_init_old; 180 181/* 182 * This __crashreporter_info__ symbol is for all non-dylib parts of libSystem. 183 */ 184const char *__crashreporter_info__; 185asm (".desc __crashreporter_info__, 0x10"); 186