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
43 #include <sys/kdebug.h>
44 #include <_libkernel_init.h> // Must be after voucher_private.h
45 #include <malloc_implementation.h>
47 #include <mach-o/dyld_priv.h>
49 // system library initialisers
50 extern void mach_init(void); // from libsystem_kernel.dylib
51 extern void __libplatform_init(void *future_use
, const char *envp
[], const char *apple
[], const struct ProgramVars
*vars
);
52 extern void __pthread_init(const struct _libpthread_functions
*libpthread_funcs
, const char *envp
[], const char *apple
[], const struct ProgramVars
*vars
); // from libsystem_pthread.dylib
53 extern void __malloc_init(const char *apple
[]); // from libsystem_malloc.dylib
54 extern void __keymgr_initializer(void); // from libkeymgr.dylib
55 extern void _dyld_initializer(void); // from libdyld.dylib
56 extern void libdispatch_init(void); // from libdispatch.dylib
57 extern void _libxpc_initializer(void); // from libxpc.dylib
58 extern void _libsecinit_initializer(void); // from libsecinit.dylib
59 extern void _libtrace_init(void); // from libsystem_trace.dylib
60 extern void _container_init(const char *apple
[]); // from libsystem_containermanager.dylib
61 extern void __libdarwin_init(void); // from libsystem_darwin.dylib
64 // clear qos tsd (from pthread)
65 extern void _pthread_clear_qos_tsd(mach_port_t
) __attribute__((weak_import
));
67 // system library atfork handlers
68 extern void _pthread_atfork_prepare(void);
69 extern void _pthread_atfork_parent(void);
70 extern void _pthread_atfork_child(void);
71 extern void _pthread_atfork_prepare_handlers();
72 extern void _pthread_atfork_parent_handlers(void);
73 extern void _pthread_atfork_child_handlers(void);
74 extern void _pthread_exit_if_canceled(int);
76 extern void dispatch_atfork_prepare(void);
77 extern void dispatch_atfork_parent(void);
78 extern void dispatch_atfork_child(void);
80 extern void _libtrace_fork_child(void);
82 extern void _malloc_fork_prepare(void);
83 extern void _malloc_fork_parent(void);
84 extern void _malloc_fork_child(void);
86 extern void _mach_fork_child(void);
87 extern void _notify_fork_child(void);
88 extern void _dyld_atfork_prepare(void);
89 extern void _dyld_atfork_parent(void);
90 extern void _dyld_fork_child(void);
91 extern void xpc_atfork_prepare(void);
92 extern void xpc_atfork_parent(void);
93 extern void xpc_atfork_child(void);
94 extern void _libSC_info_fork_prepare(void);
95 extern void _libSC_info_fork_parent(void);
96 extern void _libSC_info_fork_child(void);
97 extern void _asl_fork_child(void);
99 #if defined(HAVE_SYSTEM_CORESERVICES)
100 // libsystem_coreservices.dylib
101 extern void _libcoreservices_fork_child(void);
102 extern char *_dirhelper(int, char *, size_t);
105 // advance decls for below;
106 void libSystem_atfork_prepare(void);
107 void libSystem_atfork_parent(void);
108 void libSystem_atfork_child(void);
110 #if CURRENT_VARIANT_asan
111 const char *__asan_default_options(void);
115 _libSystem_ktrace4(uint32_t code
, uint64_t a
, uint64_t b
, uint64_t c
, uint64_t d
)
117 if (__builtin_expect(*(volatile uint32_t *)_COMM_PAGE_KDEBUG_ENABLE
== 0, 1)) return;
118 kdebug_trace(code
, a
, b
, c
, d
);
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)
126 * these define stable Ariadne tracepoints. If initializers are removed, or
127 * added, then old tracepoints MUST NOT be recycled.
130 ARIADNE_LIFECYCLE_libsystem_init
= ARIADNEDBG_CODE(220, 4),
134 * These represent the initializer "name"
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.
150 INIT_LIBDISPATCH
= 8,
154 INIT_CONTAINERMGR
= 12,
158 #define _libSystem_ktrace_init_func(what) \
159 _libSystem_ktrace1(ARIADNE_LIFECYCLE_libsystem_init | DBG_FUNC_NONE, INIT_##what)
161 // libsyscall_initializer() initializes all of libSystem.dylib
162 // <rdar://problem/4892197>
163 __attribute__((constructor
))
165 libSystem_initializer(int argc
,
169 const struct ProgramVars
* vars
)
171 static const struct _libkernel_functions libkernel_funcs
= {
174 #if !TARGET_OS_DRIVERKIT
180 ._pthread_exit_if_canceled
= _pthread_exit_if_canceled
,
181 // V2 functions (removed)
183 .pthread_clear_qos_tsd
= _pthread_clear_qos_tsd
,
185 .pthread_current_stack_contains_np
= pthread_current_stack_contains_np
,
188 static const struct _libpthread_functions libpthread_funcs
= {
195 static const struct _libc_functions libc_funcs
= {
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
,
205 static const struct _malloc_functions malloc_funcs
= {
207 #if !TARGET_OS_DRIVERKIT
213 _libSystem_ktrace0(ARIADNE_LIFECYCLE_libsystem_init
| DBG_FUNC_START
);
215 __libkernel_init(&libkernel_funcs
, envp
, apple
, vars
);
216 _libSystem_ktrace_init_func(KERNEL
);
218 __libplatform_init(NULL
, envp
, apple
, vars
);
219 _libSystem_ktrace_init_func(PLATFORM
);
221 __pthread_init(&libpthread_funcs
, envp
, apple
, vars
);
222 _libSystem_ktrace_init_func(PTHREAD
);
224 _libc_initializer(&libc_funcs
, envp
, apple
, vars
);
225 _libSystem_ktrace_init_func(LIBC
);
227 // TODO: Move __malloc_init before __libc_init after breaking malloc's upward link to Libc
228 __malloc_init(apple
);
229 _libSystem_ktrace_init_func(MALLOC
);
232 /* <rdar://problem/9664631> */
233 __keymgr_initializer();
234 _libSystem_ktrace_init_func(KEYMGR
);
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
241 _libSystem_ktrace_init_func(DYLD
);
244 _libSystem_ktrace_init_func(LIBDISPATCH
);
246 #if !TARGET_OS_DRIVERKIT
247 _libxpc_initializer();
248 _libSystem_ktrace_init_func(LIBXPC
);
250 #if CURRENT_VARIANT_asan
251 setenv("DT_BYPASS_LEAKS_CHECK", "1", 1);
253 #endif // !TARGET_OS_DRIVERKIT
255 // must be initialized after dispatch
257 _libSystem_ktrace_init_func(LIBTRACE
);
259 #if !TARGET_OS_DRIVERKIT
260 #if defined(HAVE_SYSTEM_SECINIT)
261 _libsecinit_initializer();
262 _libSystem_ktrace_init_func(SECINIT
);
265 #if defined(HAVE_SYSTEM_CONTAINERMANAGER)
266 _container_init(apple
);
267 _libSystem_ktrace_init_func(CONTAINERMGR
);
271 _libSystem_ktrace_init_func(DARWIN
);
272 #endif // !TARGET_OS_DRIVERKIT
274 __stack_logging_early_finished(&malloc_funcs
);
276 #if !TARGET_OS_IPHONE
277 /* <rdar://problem/22139800> - Preserve the old behavior of apple[] for
278 * programs that haven't linked against newer SDK.
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
);
288 _libSystem_ktrace0(ARIADNE_LIFECYCLE_libsystem_init
| DBG_FUNC_END
);
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."
299 * libSystem_atfork_{prepare,parent,child}() are called by libc during fork(2).
302 libSystem_atfork_prepare(void)
304 // first call client prepare handlers registered with pthread_atfork()
305 _pthread_atfork_prepare_handlers();
307 // second call hardwired fork prepare handlers for Libsystem components
308 // in the _reverse_ order of library initalization above
309 #if !TARGET_OS_DRIVERKIT
310 _libSC_info_fork_prepare();
311 xpc_atfork_prepare();
312 #endif // !TARGET_OS_DRIVERKIT
313 dispatch_atfork_prepare();
314 _dyld_atfork_prepare();
316 _malloc_fork_prepare();
317 _pthread_atfork_prepare();
321 libSystem_atfork_parent(void)
323 // first call hardwired fork parent handlers for Libsystem components
324 // in the order of library initalization above
325 _pthread_atfork_parent();
326 _malloc_fork_parent();
328 _dyld_atfork_parent();
329 dispatch_atfork_parent();
330 #if !TARGET_OS_DRIVERKIT
332 _libSC_info_fork_parent();
333 #endif // !TARGET_OS_DRIVERKIT
335 // second call client parent handlers registered with pthread_atfork()
336 _pthread_atfork_parent_handlers();
340 libSystem_atfork_child(void)
342 // first call hardwired fork child handlers for Libsystem components
343 // in the order of library initalization above
345 _pthread_atfork_child();
346 _malloc_fork_child();
348 _libc_fork_child(); // _arc4_fork_child calls malloc
350 dispatch_atfork_child();
351 #if !TARGET_OS_DRIVERKIT
352 #if defined(HAVE_SYSTEM_CORESERVICES)
353 _libcoreservices_fork_child();
356 _notify_fork_child();
358 #endif // !TARGET_OS_DRIVERKIT
359 _libtrace_fork_child();
360 #if !TARGET_OS_DRIVERKIT
361 _libSC_info_fork_child();
362 #endif // !TARGET_OS_DRIVERKIT
364 // second call client parent handlers registered with pthread_atfork()
365 _pthread_atfork_child_handlers();
368 #if CURRENT_VARIANT_asan
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" \
374 ":print_module_map=2" \
375 ":start_deactivated=1" \
376 ":detect_odr_violation=0"
377 char dynamic_asan_opts
[1024] = {0};
378 const char *__asan_default_options(void) {
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;
386 int fd
= open("/System/Library/Preferences/com.apple.asan.options", O_RDONLY
);
388 ssize_t remaining_size
= sizeof(dynamic_asan_opts
) - 1;
389 char *p
= dynamic_asan_opts
;
390 ssize_t read_bytes
= 0;
392 read_bytes
= read(fd
, p
, remaining_size
);
393 remaining_size
-= read_bytes
;
394 } while (read_bytes
> 0);
397 if (dynamic_asan_opts
[0]) {
398 return dynamic_asan_opts
;
402 return DEFAULT_ASAN_OPTIONS
;
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.
410 static void mach_init_old(void) {}
411 void (*mach_init_routine
)(void) = &mach_init_old
;
414 * This __crashreporter_info__ symbol is for all non-dylib parts of libSystem.
416 const char *__crashreporter_info__
;
417 asm (".desc __crashreporter_info__, 0x10");