]> git.saurik.com Git - apple/libsystem.git/blame - init.c
Libsystem-1281.100.1.tar.gz
[apple/libsystem.git] / init.c
CommitLineData
ec8f0a04 1/*
2fbbb8fa 2 * Copyright (c) 2007, 2008, 2011-2013 Apple Inc. All rights reserved.
ec8f0a04
A
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
b8ce8438 5 *
ec8f0a04
A
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.
b8ce8438 14 *
ec8f0a04
A
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
b8ce8438 17 *
ec8f0a04
A
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.
b8ce8438 25 *
ec8f0a04
A
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
ec8f0a04 28
9acf5127 29#include <TargetConditionals.h> // for TARGET_OS_*
ec8f0a04 30
2fbbb8fa
A
31#include <stddef.h>
32#include <stdlib.h>
b8ce8438
A
33#include <unistd.h>
34#include <corecrypto/cc_priv.h>
2fbbb8fa 35#include <libc_private.h>
afef526e
A
36#include <pthread.h>
37#include <pthread/private.h>
b8ce8438 38#if !TARGET_OS_DRIVERKIT
ec8f0a04 39#include <dlfcn.h>
b8ce8438 40#endif
c06d156a 41#include <fcntl.h>
bdffa7b9 42#include <errno.h>
b8ce8438 43#include <sys/kdebug.h>
2fbbb8fa 44#include <_libkernel_init.h> // Must be after voucher_private.h
b8ce8438 45#include <malloc_implementation.h>
ec8f0a04 46
9acf5127
A
47#include <mach-o/dyld_priv.h>
48
ec8f0a04 49// system library initialisers
afef526e
A
50extern void mach_init(void); // from libsystem_kernel.dylib
51extern void __libplatform_init(void *future_use, const char *envp[], const char *apple[], const struct ProgramVars *vars);
52extern void __pthread_init(const struct _libpthread_functions *libpthread_funcs, const char *envp[], const char *apple[], const struct ProgramVars *vars); // from libsystem_pthread.dylib
afef526e
A
53extern void __malloc_init(const char *apple[]); // from libsystem_malloc.dylib
54extern void __keymgr_initializer(void); // from libkeymgr.dylib
55extern void _dyld_initializer(void); // from libdyld.dylib
56extern void libdispatch_init(void); // from libdispatch.dylib
57extern void _libxpc_initializer(void); // from libxpc.dylib
2fbbb8fa 58extern void _libsecinit_initializer(void); // from libsecinit.dylib
9acf5127 59extern void _libtrace_init(void); // from libsystem_trace.dylib
2ccc3113 60extern void _container_init(const char *apple[]); // from libsystem_containermanager.dylib
706576d5 61extern void __libdarwin_init(void); // from libsystem_darwin.dylib
2fbbb8fa 62
ec8f0a04 63
2fbbb8fa
A
64// clear qos tsd (from pthread)
65extern void _pthread_clear_qos_tsd(mach_port_t) __attribute__((weak_import));
66
ec8f0a04 67// system library atfork handlers
1c91c7f1
A
68extern void _pthread_atfork_prepare(void);
69extern void _pthread_atfork_parent(void);
70extern void _pthread_atfork_child(void);
2ccc3113
A
71extern void _pthread_atfork_prepare_handlers();
72extern void _pthread_atfork_parent_handlers(void);
73extern void _pthread_atfork_child_handlers(void);
2fbbb8fa 74extern void _pthread_exit_if_canceled(int);
afef526e
A
75
76extern void dispatch_atfork_prepare(void);
77extern void dispatch_atfork_parent(void);
78extern void dispatch_atfork_child(void);
79
9acf5127
A
80extern void _libtrace_fork_child(void);
81
afef526e
A
82extern void _malloc_fork_prepare(void);
83extern void _malloc_fork_parent(void);
84extern void _malloc_fork_child(void);
bdffa7b9
A
85
86extern void _mach_fork_child(void);
bdffa7b9 87extern void _notify_fork_child(void);
b8ce8438
A
88extern void _dyld_atfork_prepare(void);
89extern void _dyld_atfork_parent(void);
bdffa7b9
A
90extern void _dyld_fork_child(void);
91extern void xpc_atfork_prepare(void);
92extern void xpc_atfork_parent(void);
93extern void xpc_atfork_child(void);
afef526e
A
94extern void _libSC_info_fork_prepare(void);
95extern void _libSC_info_fork_parent(void);
96extern void _libSC_info_fork_child(void);
97extern void _asl_fork_child(void);
ec8f0a04 98
2fbbb8fa
A
99#if defined(HAVE_SYSTEM_CORESERVICES)
100// libsystem_coreservices.dylib
101extern void _libcoreservices_fork_child(void);
102extern char *_dirhelper(int, char *, size_t);
103#endif
104
ec8f0a04 105// advance decls for below;
bdffa7b9
A
106void libSystem_atfork_prepare(void);
107void libSystem_atfork_parent(void);
108void libSystem_atfork_child(void);
ec8f0a04 109
c06d156a
A
110#if CURRENT_VARIANT_asan
111const char *__asan_default_options(void);
112#endif
113
b8ce8438
A
114static 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 */
129enum {
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 */
141enum 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
2fbbb8fa
A
161// libsyscall_initializer() initializes all of libSystem.dylib
162// <rdar://problem/4892197>
163__attribute__((constructor))
164static void
165libSystem_initializer(int argc,
166 const char* argv[],
167 const char* envp[],
168 const char* apple[],
169 const struct ProgramVars* vars)
ec8f0a04 170{
afef526e 171 static const struct _libkernel_functions libkernel_funcs = {
b12e72ed 172 .version = 4,
2fbbb8fa 173 // V1 functions
b8ce8438 174#if !TARGET_OS_DRIVERKIT
ec8f0a04 175 .dlsym = dlsym,
b8ce8438 176#endif
afef526e
A
177 .malloc = malloc,
178 .free = free,
179 .realloc = realloc,
180 ._pthread_exit_if_canceled = _pthread_exit_if_canceled,
2fbbb8fa
A
181 // V2 functions (removed)
182 // V3 functions
183 .pthread_clear_qos_tsd = _pthread_clear_qos_tsd,
b12e72ed
A
184 // V4 functions
185 .pthread_current_stack_contains_np = pthread_current_stack_contains_np,
afef526e
A
186 };
187
188 static const struct _libpthread_functions libpthread_funcs = {
2fbbb8fa 189 .version = 2,
afef526e 190 .exit = exit,
2fbbb8fa
A
191 .malloc = malloc,
192 .free = free,
193 };
b8ce8438 194
2fbbb8fa
A
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
ec8f0a04 203 };
b8ce8438
A
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);
ec8f0a04 214
afef526e 215 __libkernel_init(&libkernel_funcs, envp, apple, vars);
b8ce8438 216 _libSystem_ktrace_init_func(KERNEL);
ec8f0a04 217
afef526e 218 __libplatform_init(NULL, envp, apple, vars);
b8ce8438 219 _libSystem_ktrace_init_func(PLATFORM);
a8f6861e 220
afef526e 221 __pthread_init(&libpthread_funcs, envp, apple, vars);
b8ce8438 222 _libSystem_ktrace_init_func(PTHREAD);
a8f6861e 223
2fbbb8fa 224 _libc_initializer(&libc_funcs, envp, apple, vars);
b8ce8438 225 _libSystem_ktrace_init_func(LIBC);
afef526e
A
226
227 // TODO: Move __malloc_init before __libc_init after breaking malloc's upward link to Libc
228 __malloc_init(apple);
b8ce8438 229 _libSystem_ktrace_init_func(MALLOC);
afef526e 230
706576d5 231#if TARGET_OS_OSX
2fbbb8fa
A
232 /* <rdar://problem/9664631> */
233 __keymgr_initializer();
b8ce8438 234 _libSystem_ktrace_init_func(KEYMGR);
2fbbb8fa
A
235#endif
236
c06d156a
A
237 // No ASan interceptors are invoked before this point. ASan is normally initialized via the malloc interceptor:
238 // _dyld_initializer() -> tlv_load_notification -> wrap_malloc -> ASanInitInternal
239
ec8f0a04 240 _dyld_initializer();
b8ce8438 241 _libSystem_ktrace_init_func(DYLD);
9acf5127 242
ec8f0a04 243 libdispatch_init();
b8ce8438
A
244 _libSystem_ktrace_init_func(LIBDISPATCH);
245
246#if !TARGET_OS_DRIVERKIT
ec8f0a04 247 _libxpc_initializer();
b8ce8438 248 _libSystem_ktrace_init_func(LIBXPC);
bdffa7b9 249
c06d156a
A
250#if CURRENT_VARIANT_asan
251 setenv("DT_BYPASS_LEAKS_CHECK", "1", 1);
252#endif
b8ce8438 253#endif // !TARGET_OS_DRIVERKIT
c06d156a 254
2ccc3113
A
255 // must be initialized after dispatch
256 _libtrace_init();
b8ce8438 257 _libSystem_ktrace_init_func(LIBTRACE);
2ccc3113 258
b8ce8438
A
259#if !TARGET_OS_DRIVERKIT
260#if defined(HAVE_SYSTEM_SECINIT)
2fbbb8fa 261 _libsecinit_initializer();
b8ce8438 262 _libSystem_ktrace_init_func(SECINIT);
2fbbb8fa
A
263#endif
264
a85a94cf 265#if defined(HAVE_SYSTEM_CONTAINERMANAGER)
2ccc3113 266 _container_init(apple);
b8ce8438 267 _libSystem_ktrace_init_func(CONTAINERMGR);
2ccc3113
A
268#endif
269
706576d5 270 __libdarwin_init();
b8ce8438
A
271 _libSystem_ktrace_init_func(DARWIN);
272#endif // !TARGET_OS_DRIVERKIT
706576d5 273
b8ce8438 274 __stack_logging_early_finished(&malloc_funcs);
bdffa7b9 275
9acf5127 276#if !TARGET_OS_IPHONE
b8ce8438
A
277 /* <rdar://problem/22139800> - Preserve the old behavior of apple[] for
278 * programs that haven't linked against newer SDK.
9acf5127
A
279 */
280#define APPLE0_PREFIX "executable_path="
281 if (dyld_get_program_sdk_version() < DYLD_MACOSX_VERSION_10_11){
282 if (strncmp(apple[0], APPLE0_PREFIX, strlen(APPLE0_PREFIX)) == 0){
283 apple[0] = apple[0] + strlen(APPLE0_PREFIX);
284 }
285 }
286#endif
2fbbb8fa 287
b8ce8438
A
288 _libSystem_ktrace0(ARIADNE_LIFECYCLE_libsystem_init | DBG_FUNC_END);
289
bdffa7b9
A
290 /* <rdar://problem/11588042>
291 * C99 standard has the following in section 7.5(3):
292 * "The value of errno is zero at program startup, but is never set
293 * to zero by any library function."
294 */
295 errno = 0;
ec8f0a04
A
296}
297
298/*
2fbbb8fa 299 * libSystem_atfork_{prepare,parent,child}() are called by libc during fork(2).
ec8f0a04 300 */
2fbbb8fa
A
301void
302libSystem_atfork_prepare(void)
ec8f0a04 303{
2ccc3113
A
304 // first call client prepare handlers registered with pthread_atfork()
305 _pthread_atfork_prepare_handlers();
306
307 // second call hardwired fork prepare handlers for Libsystem components
308 // in the _reverse_ order of library initalization above
b8ce8438 309#if !TARGET_OS_DRIVERKIT
afef526e 310 _libSC_info_fork_prepare();
ec8f0a04 311 xpc_atfork_prepare();
b8ce8438 312#endif // !TARGET_OS_DRIVERKIT
afef526e 313 dispatch_atfork_prepare();
b8ce8438
A
314 _dyld_atfork_prepare();
315 cc_atfork_prepare();
afef526e 316 _malloc_fork_prepare();
1c91c7f1 317 _pthread_atfork_prepare();
ec8f0a04
A
318}
319
2fbbb8fa
A
320void
321libSystem_atfork_parent(void)
ec8f0a04 322{
2ccc3113
A
323 // first call hardwired fork parent handlers for Libsystem components
324 // in the order of library initalization above
1c91c7f1 325 _pthread_atfork_parent();
2ccc3113 326 _malloc_fork_parent();
b8ce8438
A
327 cc_atfork_parent();
328 _dyld_atfork_parent();
afef526e 329 dispatch_atfork_parent();
b8ce8438 330#if !TARGET_OS_DRIVERKIT
ec8f0a04 331 xpc_atfork_parent();
afef526e 332 _libSC_info_fork_parent();
b8ce8438 333#endif // !TARGET_OS_DRIVERKIT
2ccc3113
A
334
335 // second call client parent handlers registered with pthread_atfork()
336 _pthread_atfork_parent_handlers();
ec8f0a04
A
337}
338
2fbbb8fa
A
339void
340libSystem_atfork_child(void)
ec8f0a04 341{
2ccc3113
A
342 // first call hardwired fork child handlers for Libsystem components
343 // in the order of library initalization above
2ccc3113 344 _mach_fork_child();
b8ce8438 345 _pthread_atfork_child();
afef526e 346 _malloc_fork_child();
b8ce8438 347 cc_atfork_child();
2ccc3113 348 _libc_fork_child(); // _arc4_fork_child calls malloc
b8ce8438 349 _dyld_fork_child();
afef526e 350 dispatch_atfork_child();
b8ce8438 351#if !TARGET_OS_DRIVERKIT
2fbbb8fa
A
352#if defined(HAVE_SYSTEM_CORESERVICES)
353 _libcoreservices_fork_child();
354#endif
afef526e 355 _asl_fork_child();
ec8f0a04 356 _notify_fork_child();
ec8f0a04 357 xpc_atfork_child();
b8ce8438 358#endif // !TARGET_OS_DRIVERKIT
2ccc3113 359 _libtrace_fork_child();
b8ce8438 360#if !TARGET_OS_DRIVERKIT
afef526e 361 _libSC_info_fork_child();
b8ce8438 362#endif // !TARGET_OS_DRIVERKIT
ec8f0a04 363
2ccc3113
A
364 // second call client parent handlers registered with pthread_atfork()
365 _pthread_atfork_child_handlers();
ec8f0a04
A
366}
367
c06d156a 368#if CURRENT_VARIANT_asan
b8ce8438
A
369#define DEFAULT_ASAN_OPTIONS "color=never" \
370 ":handle_segv=0:handle_sigbus=0:handle_sigill=0:handle_sigfpe=0" \
371 ":external_symbolizer_path=" \
372 ":log_path=stderr:log_exe_name=0" \
373 ":halt_on_error=0" \
374 ":print_module_map=2" \
375 ":start_deactivated=1" \
376 ":detect_odr_violation=0"
c06d156a
A
377char dynamic_asan_opts[1024] = {0};
378const char *__asan_default_options(void) {
b8ce8438
A
379 char executable_path[4096] = {0};
380 uint32_t size = sizeof(executable_path);
381 const char *process_name = "";
382 if (_NSGetExecutablePath(executable_path, &size) == 0) {
383 process_name = strrchr(executable_path, '/') + 1;
384 }
385
c06d156a
A
386 int fd = open("/System/Library/Preferences/com.apple.asan.options", O_RDONLY);
387 if (fd != -1) {
388 ssize_t remaining_size = sizeof(dynamic_asan_opts) - 1;
389 char *p = dynamic_asan_opts;
390 ssize_t read_bytes = 0;
391 do {
392 read_bytes = read(fd, p, remaining_size);
393 remaining_size -= read_bytes;
394 } while (read_bytes > 0);
395 close(fd);
396
397 if (dynamic_asan_opts[0]) {
398 return dynamic_asan_opts;
399 }
400 }
401
b8ce8438 402 return DEFAULT_ASAN_OPTIONS;
c06d156a
A
403}
404#endif
405
b8ce8438 406/*
ec8f0a04
A
407 * Old crt1.o glue used to call through mach_init_routine which was used to initialize libSystem.
408 * LibSystem now auto-initializes but mach_init_routine is left for binary compatibility.
409 */
bdffa7b9 410static void mach_init_old(void) {}
ec8f0a04
A
411void (*mach_init_routine)(void) = &mach_init_old;
412
413/*
414 * This __crashreporter_info__ symbol is for all non-dylib parts of libSystem.
415 */
416const char *__crashreporter_info__;
417asm (".desc __crashreporter_info__, 0x10");