]>
Commit | Line | Data |
---|---|---|
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 |
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 | |
afef526e A |
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 | |
2fbbb8fa | 58 | extern void _libsecinit_initializer(void); // from libsecinit.dylib |
9acf5127 | 59 | extern void _libtrace_init(void); // from libsystem_trace.dylib |
2ccc3113 | 60 | extern void _container_init(const char *apple[]); // from libsystem_containermanager.dylib |
706576d5 | 61 | extern void __libdarwin_init(void); // from libsystem_darwin.dylib |
2fbbb8fa | 62 | |
ec8f0a04 | 63 | |
2fbbb8fa A |
64 | // clear qos tsd (from pthread) |
65 | extern void _pthread_clear_qos_tsd(mach_port_t) __attribute__((weak_import)); | |
66 | ||
ec8f0a04 | 67 | // system library atfork handlers |
1c91c7f1 A |
68 | extern void _pthread_atfork_prepare(void); |
69 | extern void _pthread_atfork_parent(void); | |
70 | extern void _pthread_atfork_child(void); | |
2ccc3113 A |
71 | extern void _pthread_atfork_prepare_handlers(); |
72 | extern void _pthread_atfork_parent_handlers(void); | |
73 | extern void _pthread_atfork_child_handlers(void); | |
2fbbb8fa | 74 | extern void _pthread_exit_if_canceled(int); |
afef526e A |
75 | |
76 | extern void dispatch_atfork_prepare(void); | |
77 | extern void dispatch_atfork_parent(void); | |
78 | extern void dispatch_atfork_child(void); | |
79 | ||
9acf5127 A |
80 | extern void _libtrace_fork_child(void); |
81 | ||
afef526e A |
82 | extern void _malloc_fork_prepare(void); |
83 | extern void _malloc_fork_parent(void); | |
84 | extern void _malloc_fork_child(void); | |
bdffa7b9 A |
85 | |
86 | extern void _mach_fork_child(void); | |
bdffa7b9 | 87 | extern void _notify_fork_child(void); |
b8ce8438 A |
88 | extern void _dyld_atfork_prepare(void); |
89 | extern void _dyld_atfork_parent(void); | |
bdffa7b9 A |
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); | |
afef526e A |
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); | |
ec8f0a04 | 98 | |
2fbbb8fa A |
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); | |
103 | #endif | |
104 | ||
ec8f0a04 | 105 | // advance decls for below; |
bdffa7b9 A |
106 | void libSystem_atfork_prepare(void); |
107 | void libSystem_atfork_parent(void); | |
108 | void libSystem_atfork_child(void); | |
ec8f0a04 | 109 | |
c06d156a A |
110 | #if CURRENT_VARIANT_asan |
111 | const char *__asan_default_options(void); | |
112 | #endif | |
113 | ||
b8ce8438 A |
114 | static 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 | */ | |
129 | enum { | |
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 | */ | |
141 | enum 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)) | |
164 | static void | |
165 | libSystem_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 |
301 | void |
302 | libSystem_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 |
320 | void |
321 | libSystem_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 |
339 | void |
340 | libSystem_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 |
377 | char dynamic_asan_opts[1024] = {0}; |
378 | const 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 | 410 | static void mach_init_old(void) {} |
ec8f0a04 A |
411 | void (*mach_init_routine)(void) = &mach_init_old; |
412 | ||
413 | /* | |
414 | * This __crashreporter_info__ symbol is for all non-dylib parts of libSystem. | |
415 | */ | |
416 | const char *__crashreporter_info__; | |
417 | asm (".desc __crashreporter_info__, 0x10"); |