/ init.c
init.c
  1  /*
  2   * Copyright (c) 2007, 2008, 2011-2013 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_*
 30  
 31  #include <stddef.h>
 32  #include <stdlib.h>
 33  #include <unistd.h>
 34  #include <corecrypto/cc_priv.h>
 35  #include <libc_private.h>
 36  #include <pthread.h>
 37  #include <pthread/private.h>
 38  #if !TARGET_OS_DRIVERKIT
 39  #include <dlfcn.h>
 40  #include <os/variant_private.h>
 41  #endif
 42  #include <fcntl.h>
 43  #include <errno.h>
 44  #include <sys/kdebug.h>
 45  #include <_libkernel_init.h> // Must be after voucher_private.h
 46  #include <malloc_implementation.h>
 47  
 48  #include <mach-o/dyld_priv.h>
 49  
 50  #ifdef DARLING
 51  extern int _dyld_func_lookup(const char* name, void** address);
 52  #endif
 53  
 54  // system library initialisers
 55  extern void mach_init(void);			// from libsystem_kernel.dylib
 56  extern void __libplatform_init(void *future_use, const char *envp[], const char *apple[], const struct ProgramVars *vars);
 57  extern void __pthread_init(const struct _libpthread_functions *libpthread_funcs, const char *envp[], const char *apple[], const struct ProgramVars *vars);	// from libsystem_pthread.dylib
 58  extern void __pthread_late_init(const char *envp[], const char *apple[], const struct ProgramVars *vars);	// from libsystem_pthread.dylib
 59  extern void __malloc_init(const char *apple[]); // from libsystem_malloc.dylib
 60  extern void __keymgr_initializer(void);		// from libkeymgr.dylib
 61  extern void _dyld_initializer(void);		// from libdyld.dylib
 62  extern void libdispatch_init(void);		// from libdispatch.dylib
 63  extern void _libxpc_initializer(void);		// from libxpc.dylib
 64  extern void _libsecinit_initializer(void);        // from libsecinit.dylib
 65  extern void _libtrace_init(void);		// from libsystem_trace.dylib
 66  extern void _container_init(const char *apple[]); // from libsystem_containermanager.dylib
 67  extern void __libdarwin_init(void);		// from libsystem_darwin.dylib
 68  
 69  
 70  // clear qos tsd (from pthread)
 71  extern void _pthread_clear_qos_tsd(mach_port_t) __attribute__((weak_import));
 72  
 73  // system library atfork handlers
 74  extern void _pthread_atfork_prepare(void);
 75  extern void _pthread_atfork_parent(void);
 76  extern void _pthread_atfork_child(void);
 77  extern void _pthread_atfork_prepare_handlers();
 78  extern void _pthread_atfork_parent_handlers(void);
 79  extern void _pthread_atfork_child_handlers(void);
 80  extern void _pthread_exit_if_canceled(int);
 81  
 82  extern void dispatch_atfork_prepare(void);
 83  extern void dispatch_atfork_parent(void);
 84  extern void dispatch_atfork_child(void);
 85  
 86  extern void _libtrace_fork_child(void);
 87  
 88  extern void _malloc_fork_prepare(void);
 89  extern void _malloc_fork_parent(void);
 90  extern void _malloc_fork_child(void);
 91  
 92  extern void _mach_fork_child(void);
 93  #ifdef DARLING
 94  extern void _mach_fork_parent(void);
 95  #endif
 96  extern void _notify_fork_child(void);
 97  extern void _dyld_atfork_prepare(void);
 98  extern void _dyld_atfork_parent(void);
 99  extern void _dyld_fork_child(void);
100  extern void xpc_atfork_prepare(void);
101  extern void xpc_atfork_parent(void);
102  extern void xpc_atfork_child(void);
103  extern void _libSC_info_fork_prepare(void);
104  extern void _libSC_info_fork_parent(void);
105  extern void _libSC_info_fork_child(void);
106  extern void _asl_fork_child(void);
107  
108  #if defined(HAVE_SYSTEM_CORESERVICES)
109  // libsystem_coreservices.dylib
110  extern void _libcoreservices_fork_child(void);
111  extern char *_dirhelper(int, char *, size_t);
112  #endif
113  
114  #ifdef DARLING
115  extern void kqueue_atfork(void);
116  #endif
117  
118  // advance decls for below;
119  void libSystem_atfork_prepare(void);
120  void libSystem_atfork_parent(void);
121  void libSystem_atfork_child(void);
122  
123  #ifdef DARLING
124  void libSystem_posix_spawn_prepare(void);
125  void libSystem_posix_spawn_parent(void);
126  void libSystem_posix_spawn_child(void);
127  #endif
128  
129  #if SUPPORT_ASAN
130  const char *__asan_default_options(void);
131  #endif
132  
133  static inline void
134  _libSystem_ktrace4(uint32_t code, uint64_t a, uint64_t b, uint64_t c, uint64_t d)
135  {
136  	if (__builtin_expect(*(volatile uint32_t *)_COMM_PAGE_KDEBUG_ENABLE == 0, 1)) return;
137  	kdebug_trace(code, a, b, c, d);
138  }
139  #define _libSystem_ktrace3(code, a, b, c) _libSystem_ktrace4(code, a, b, c, 0)
140  #define _libSystem_ktrace2(code, a, b)    _libSystem_ktrace4(code, a, b, 0, 0)
141  #define _libSystem_ktrace1(code, a)       _libSystem_ktrace4(code, a, 0, 0, 0)
142  #define _libSystem_ktrace0(code)          _libSystem_ktrace4(code, 0, 0, 0, 0)
143  
144  /*
145   * these define stable Ariadne tracepoints. If initializers are removed, or
146   * added, then old tracepoints MUST NOT be recycled.
147   */
148  enum {
149  	ARIADNE_LIFECYCLE_libsystem_init = ARIADNEDBG_CODE(220, 4),
150  };
151  
152  /*
153   * These represent the initializer "name"
154   *
155   * They happen to match the order of the initializers at some point in time,
156   * but there's no guarantee made that traecepoints will appear in numerical
157   * order. As initializers come and go, new codes shall be allocated,
158   * and no slots reused.
159   */
160  enum init_func {
161  	INIT_SYSTEM = 0,
162  	INIT_KERNEL = 1,
163  	INIT_PLATFORM = 2,
164  	INIT_PTHREAD = 3,
165  	INIT_LIBC = 4,
166  	INIT_MALLOC = 5,
167  	INIT_KEYMGR = 6,
168  	INIT_DYLD = 7,
169  	INIT_LIBDISPATCH = 8,
170  	INIT_LIBXPC = 9,
171  	INIT_LIBTRACE = 10,
172  	INIT_SECINIT = 11,
173  	INIT_CONTAINERMGR = 12,
174  	INIT_DARWIN = 13,
175  };
176  
177  #define _libSystem_ktrace_init_func(what) \
178  	_libSystem_ktrace1(ARIADNE_LIFECYCLE_libsystem_init | DBG_FUNC_NONE, INIT_##what)
179  
180  // libsyscall_initializer() initializes all of libSystem.dylib
181  // <rdar://problem/4892197>
182  __attribute__((constructor))
183  static void
184  libSystem_initializer(int argc,
185  		      const char* argv[],
186  		      const char* envp[],
187  		      const char* apple[],
188  		      const struct ProgramVars* vars)
189  {
190  	static const struct _libkernel_functions libkernel_funcs = {
191  		.version = 4,
192  		// V1 functions
193  #if !TARGET_OS_DRIVERKIT
194  		.dlsym = dlsym,
195  #endif
196  		.malloc = malloc,
197  		.free = free,
198  		.realloc = realloc,
199  		._pthread_exit_if_canceled = _pthread_exit_if_canceled,
200  		// V2 functions (removed)
201  		// V3 functions
202  		.pthread_clear_qos_tsd = _pthread_clear_qos_tsd,
203  		// V4 functions
204  		.pthread_current_stack_contains_np = pthread_current_stack_contains_np,
205  #ifdef DARLING
206  		.dyld_func_lookup = _dyld_func_lookup,
207  		.posix_spawn_prepare = libSystem_posix_spawn_prepare,
208  		.posix_spawn_parent = libSystem_posix_spawn_parent,
209  		.posix_spawn_child = libSystem_posix_spawn_child,
210  #endif
211  	};
212  
213  	static const struct _libpthread_functions libpthread_funcs = {
214  		.version = 2,
215  		.exit = exit,
216  		.malloc = malloc,
217  		.free = free,
218  	};
219  
220  	static const struct _libc_functions libc_funcs = {
221  		.version = 1,
222  		.atfork_prepare = libSystem_atfork_prepare,
223  		.atfork_parent = libSystem_atfork_parent,
224  		.atfork_child = libSystem_atfork_child,
225  #if defined(HAVE_SYSTEM_CORESERVICES)
226  		.dirhelper = _dirhelper,
227  #endif
228  	};
229  	
230  	_libSystem_ktrace0(ARIADNE_LIFECYCLE_libsystem_init | DBG_FUNC_START);
231  
232  	__libkernel_init(&libkernel_funcs, envp, apple, vars);
233  	_libSystem_ktrace_init_func(KERNEL);
234  
235  	__libplatform_init(NULL, envp, apple, vars);
236  	_libSystem_ktrace_init_func(PLATFORM);
237  
238  	__pthread_init(&libpthread_funcs, envp, apple, vars);
239  	_libSystem_ktrace_init_func(PTHREAD);
240  
241  	_libc_initializer(&libc_funcs, envp, apple, vars);
242  	_libSystem_ktrace_init_func(LIBC);
243  
244  	// TODO: Move __malloc_init before __libc_init after breaking malloc's upward link to Libc
245  	// Note that __malloc_init() will also initialize ASAN when it is present
246  	__malloc_init(apple);
247  	_libSystem_ktrace_init_func(MALLOC);
248  
249  #if TARGET_OS_OSX
250  	/* <rdar://problem/9664631> */
251  	__keymgr_initializer();
252  	_libSystem_ktrace_init_func(KEYMGR);
253  #endif
254  
255  	_dyld_initializer();
256  	_libSystem_ktrace_init_func(DYLD);
257  
258  #if TARGET_OS_OSX
259  	__pthread_late_init(envp, apple, vars);
260  #endif
261  
262  	libdispatch_init();
263  	_libSystem_ktrace_init_func(LIBDISPATCH);
264  
265  #if !TARGET_OS_DRIVERKIT
266  	_libxpc_initializer();
267  	_libSystem_ktrace_init_func(LIBXPC);
268  
269  #if SUPPORT_ASAN
270  	setenv("DT_BYPASS_LEAKS_CHECK", "1", 1);
271  #endif
272  #endif // !TARGET_OS_DRIVERKIT
273  
274  	// must be initialized after dispatch
275  	_libtrace_init();
276  	_libSystem_ktrace_init_func(LIBTRACE);
277  
278  #if !TARGET_OS_DRIVERKIT
279  #if defined(HAVE_SYSTEM_SECINIT)
280  	_libsecinit_initializer();
281  	_libSystem_ktrace_init_func(SECINIT);
282  #endif
283  
284  #if defined(HAVE_SYSTEM_CONTAINERMANAGER)
285  	_container_init(apple);
286  	_libSystem_ktrace_init_func(CONTAINERMGR);
287  #endif
288  
289  	__libdarwin_init();
290  	_libSystem_ktrace_init_func(DARWIN);
291  #endif // !TARGET_OS_DRIVERKIT
292  
293  	const struct _malloc_late_init mli = {
294  		.version = 1,
295  #if !TARGET_OS_DRIVERKIT
296  		.dlopen = dlopen,
297  		.dlsym = dlsym,
298  		// this must come after _libxpc_initializer()
299  		.internal_diagnostics = os_variant_has_internal_diagnostics("com.apple.libsystem"),
300  #endif
301  	};
302  
303  	__malloc_late_init(&mli);
304  
305  #if !TARGET_OS_IPHONE
306  	/* <rdar://problem/22139800> - Preserve the old behavior of apple[] for
307  	 * programs that haven't linked against newer SDK.
308  	 */
309  #define APPLE0_PREFIX "executable_path="
310  	if (dyld_get_program_sdk_version() < DYLD_MACOSX_VERSION_10_11){
311  		if (strncmp(apple[0], APPLE0_PREFIX, strlen(APPLE0_PREFIX)) == 0){
312  			apple[0] = apple[0] + strlen(APPLE0_PREFIX);
313  		}
314  	}
315  #endif
316  
317  #if TARGET_OS_OSX && !defined(__i386__)
318  	bool enable_system_version_compat = false;
319  	bool enable_ios_version_compat = false;
320  	char *system_version_compat_override = getenv("SYSTEM_VERSION_COMPAT");
321  	if (system_version_compat_override != NULL) {
322  		long override = strtol(system_version_compat_override, NULL, 0);
323  		if (override == 1) {
324  			enable_system_version_compat = true;
325  		} else if (override == 2) {
326  			enable_ios_version_compat = true;
327  		}
328  	} else if (dyld_get_active_platform() == PLATFORM_MACCATALYST) {
329  		if (!dyld_program_sdk_at_least(dyld_platform_version_iOS_14_0)) {
330  			enable_system_version_compat = true;
331  		}
332  	} else if (dyld_get_active_platform() == PLATFORM_IOS) {
333  		enable_ios_version_compat = true;
334  	} else if (!dyld_program_sdk_at_least(dyld_platform_version_macOS_10_16)) {
335  		enable_system_version_compat = true;
336  	}
337  
338  	if (enable_system_version_compat || enable_ios_version_compat) {
339  		struct _libkernel_late_init_config config = {
340  			.version = 2,
341  			.enable_system_version_compat = enable_system_version_compat,
342  			.enable_ios_version_compat = enable_ios_version_compat,
343  		};
344  		__libkernel_init_late(&config);
345  	}
346  #endif // TARGET_OS_OSX && !defined(__i386__)
347  
348  	_libSystem_ktrace0(ARIADNE_LIFECYCLE_libsystem_init | DBG_FUNC_END);
349  
350  	/* <rdar://problem/11588042>
351  	 * C99 standard has the following in section 7.5(3):
352  	 * "The value of errno is zero at program startup, but is never set
353  	 * to zero by any library function."
354  	 */
355  	errno = 0;
356  }
357  
358  /*
359   * libSystem_atfork_{prepare,parent,child}() are called by libc during fork(2).
360   */
361  void
362  libSystem_atfork_prepare(void)
363  {
364  	// first call client prepare handlers registered with pthread_atfork()
365  	_pthread_atfork_prepare_handlers();
366  
367  	// second call hardwired fork prepare handlers for Libsystem components
368  	// in the _reverse_ order of library initalization above
369  #if !TARGET_OS_DRIVERKIT
370  	_libSC_info_fork_prepare();
371  	xpc_atfork_prepare();
372  #endif // !TARGET_OS_DRIVERKIT
373  	dispatch_atfork_prepare();
374  	_dyld_atfork_prepare();
375  	cc_atfork_prepare();
376  	_malloc_fork_prepare();
377  	_pthread_atfork_prepare();
378  }
379  
380  void
381  libSystem_atfork_parent(void)
382  {
383  	// first call hardwired fork parent handlers for Libsystem components
384  	// in the order of library initalization above
385  	_pthread_atfork_parent();
386  	_malloc_fork_parent();
387  	cc_atfork_parent();
388  	_dyld_atfork_parent();
389  	dispatch_atfork_parent();
390  #if !TARGET_OS_DRIVERKIT
391  	xpc_atfork_parent();
392  	_libSC_info_fork_parent();
393  #endif // !TARGET_OS_DRIVERKIT
394  
395  #ifdef DARLING
396  	_mach_fork_parent();
397  #endif
398  
399  	// second call client parent handlers registered with pthread_atfork()
400  	_pthread_atfork_parent_handlers();
401  }
402  
403  void
404  libSystem_atfork_child(void)
405  {
406  	// first call hardwired fork child handlers for Libsystem components
407  	// in the order of library initalization above
408  	_mach_fork_child();
409  	_pthread_atfork_child();
410  	_malloc_fork_child();
411  	cc_atfork_child();
412  	_libc_fork_child(); // _arc4_fork_child calls malloc
413  	_dyld_fork_child();
414  	dispatch_atfork_child();
415  #if !TARGET_OS_DRIVERKIT
416  #if defined(HAVE_SYSTEM_CORESERVICES)
417  	_libcoreservices_fork_child();
418  #endif
419  	_asl_fork_child();
420  	_notify_fork_child();
421  	xpc_atfork_child();
422  #endif // !TARGET_OS_DRIVERKIT
423  	_libtrace_fork_child();
424  #if !TARGET_OS_DRIVERKIT
425  	_libSC_info_fork_child();
426  #endif // !TARGET_OS_DRIVERKIT
427  
428  	// second call client parent handlers registered with pthread_atfork()
429  	_pthread_atfork_child_handlers();
430  
431  #ifdef DARLING
432  	kqueue_atfork();
433  #endif
434  }
435  
436  #ifdef DARLING
437  /*
438   * libSystem_posix_spawn_{prepare,parent,child}() are called by libsystem_kernel during posix_spawn(2).
439   *
440   * These are identical to libSystem_atfork_{prepare,parent,child}(), except they don't call
441   * pthread_atfork handlers.
442   */
443  void libSystem_posix_spawn_prepare(void) {
444  	// call hardwired fork prepare handlers for Libsystem components
445  	// in the _reverse_ order of library initalization above
446  #if !TARGET_OS_DRIVERKIT
447  	_libSC_info_fork_prepare();
448  	xpc_atfork_prepare();
449  #endif // !TARGET_OS_DRIVERKIT
450  	dispatch_atfork_prepare();
451  	_dyld_atfork_prepare();
452  	cc_atfork_prepare();
453  	_malloc_fork_prepare();
454  	_pthread_atfork_prepare();
455  };
456  
457  void libSystem_posix_spawn_parent(void) {
458  	// call hardwired fork parent handlers for Libsystem components
459  	// in the order of library initalization above
460  	_pthread_atfork_parent();
461  	_malloc_fork_parent();
462  	cc_atfork_parent();
463  	_dyld_atfork_parent();
464  	dispatch_atfork_parent();
465  #if !TARGET_OS_DRIVERKIT
466  	xpc_atfork_parent();
467  	_libSC_info_fork_parent();
468  #endif // !TARGET_OS_DRIVERKIT
469  
470  #ifdef DARLING
471  	_mach_fork_parent();
472  #endif
473  };
474  
475  void libSystem_posix_spawn_child(void) {
476  	// call hardwired fork child handlers for Libsystem components
477  	// in the order of library initalization above
478  	_mach_fork_child();
479  	_pthread_atfork_child();
480  	_malloc_fork_child();
481  	cc_atfork_child();
482  	_libc_fork_child(); // _arc4_fork_child calls malloc
483  	_dyld_fork_child();
484  	dispatch_atfork_child();
485  #if !TARGET_OS_DRIVERKIT
486  #if defined(HAVE_SYSTEM_CORESERVICES)
487  	_libcoreservices_fork_child();
488  #endif
489  	_asl_fork_child();
490  	_notify_fork_child();
491  	xpc_atfork_child();
492  #endif // !TARGET_OS_DRIVERKIT
493  	_libtrace_fork_child();
494  #if !TARGET_OS_DRIVERKIT
495  	_libSC_info_fork_child();
496  #endif // !TARGET_OS_DRIVERKIT
497  
498  #ifdef DARLING
499  	kqueue_atfork();
500  #endif
501  };
502  #endif
503  
504  #if SUPPORT_ASAN
505  
506  // Prevents use of coloring terminal signals in report. These
507  // hinder readability when writing to files or the system log.
508  #define ASAN_OPT_NO_COLOR "color=never"
509  
510  // Disables ASan's signal handlers. It's better to let the system catch
511  // these kinds of crashes.
512  #define ASAN_OPT_NO_SIGNAL_HANDLERS ":handle_segv=0:handle_sigbus=0:handle_sigill=0:handle_sigfpe=0"
513  
514  // Disables using the out-of-process symbolizer (atos) but still allows
515  // in-process symbolization via `dladdr()`. This gives useful function names
516  // (unless they are redacted) which can be helpful in the event we can't
517  // symbolize offline. Out-of-process symbolization isn't useful because
518  // the dSYMs are usually not present on the device.
519  #define ASAN_OPT_NO_OOP_SYMBOLIZER ":external_symbolizer_path="
520  
521  // Don't try to log to a file. It's difficult to find a location for the file
522  // that is writable so just write to stderr.
523  #define ASAN_OPT_FILE_LOG ":log_path=stderr:log_exe_name=0"
524  
525  // Print the module map when finding an issue. This is necessary for offline
526  // symbolication.
527  #define ASAN_OPT_MODULE_MAP ":print_module_map=2"
528  
529  // Disable ODR violation checking.
530  // <rdar://problem/71021707> Investigate enabling ODR checking for ASan in BATS and in the `_asan` variant
531  #define ASAN_OPT_NO_ODR_VIOLATION ":detect_odr_violation=0"
532  
533  // Start ASan in deactivated mode. This reduces memory overhead until
534  // instrumented code is loaded. This prevents catching bugs if no instrumented
535  // code is loaded.
536  #define ASAN_OPT_START_DEACTIVATED ":start_deactivated=1"
537  
538  // Do not crash when an error is found. This always works for errors caught via
539  // ASan's interceptors. This won't work for errors caught in ASan
540  // instrumentation unless the code is compiled with
541  // `-fsanitize-recover=address`.  If this option is being used then the ASan
542  // reports can only be found by looking at the system log.
543  #define ASAN_OPT_NO_HALT_ON_ERROR ":halt_on_error=0"
544  
545  // Crash when an error is found.
546  #define ASAN_OPT_HALT_ON_ERROR ":halt_on_error=1"
547  
548  // ASan options common to all supported variants
549  #define COMMON_ASAN_OPTIONS \
550    ASAN_OPT_NO_COLOR \
551    ASAN_OPT_NO_SIGNAL_HANDLERS \
552    ASAN_OPT_NO_OOP_SYMBOLIZER \
553    ASAN_OPT_FILE_LOG \
554    ASAN_OPT_MODULE_MAP \
555    ASAN_OPT_NO_ODR_VIOLATION
556  
557  #if defined(CURRENT_VARIANT_normal) || defined(CURRENT_VARIANT_debug) || defined (CURRENT_VARIANT_no_asan)
558  
559  // In the normal variant ASan will be running in all userspace processes ("whole userspace ASan").
560  // This mode exists to support "ASan in BATS".
561  //
562  // Supporting ASan in the debug variant preserves existing behavior.
563  //
564  // The no_asan variant does not load the ASan runtime. However, the runtime
565  // might still be loaded if a program or its dependencies are instrumented.
566  // There is nothing we can do to prevent this so we should set the appropriate
567  // ASan options (same as normal variant) if it does happen. We try to do this
568  // here but this currently doesn't work due to rdar://problem/72212914.
569  //
570  // These variants use the following extra options:
571  //
572  // ASAN_OPT_NO_HALT_ON_ERROR - Try to avoid crash loops and increase the
573  //                             chances of booting successfully.
574  // ASAN_OPT_START_DEACTIVATED - Try to reduce memory overhead.
575  
576  # define DEFAULT_ASAN_OPTIONS \
577    COMMON_ASAN_OPTIONS \
578    ASAN_OPT_START_DEACTIVATED \
579    ASAN_OPT_NO_HALT_ON_ERROR
580  
581  #elif defined(CURRENT_VARIANT_asan)
582  
583  // The `_asan` variant is used to support running proceses with
584  // `DYLD_IMAGE_SUFFIX=_asan`. This mode is typically used to target select parts of the OS.
585  //
586  // It uses the following extra options:
587  //
588  // ASAN_OPT_HALT_ON_ERROR - Crashing is better than just writing the error to the system log
589  //                          if the system can handle this. This workflow is
590  //                          more tolerant (e.g. `launchctl debug`) to crashing
591  //                          than the "whole userspace ASan" workflow.
592  
593  # define DEFAULT_ASAN_OPTIONS \
594    COMMON_ASAN_OPTIONS \
595    ASAN_OPT_HALT_ON_ERROR
596  
597  #else
598  # error Supporting ASan is not supported in the current variant
599  #endif
600  
601  char dynamic_asan_opts[1024] = {0};
602  const char *__asan_default_options(void) {
603  	int fd = open("/System/Library/Preferences/com.apple.asan.options", O_RDONLY);
604  	if (fd != -1) {
605  		ssize_t remaining_size = sizeof(dynamic_asan_opts) - 1;
606  		char *p = dynamic_asan_opts;
607  		ssize_t read_bytes = 0;
608  		do {
609  			read_bytes = read(fd, p, remaining_size);
610  			remaining_size -= read_bytes;
611  		} while (read_bytes > 0);
612  		close(fd);
613  
614  		if (dynamic_asan_opts[0]) {
615  			return dynamic_asan_opts;
616  		}
617  	}
618  
619  	return DEFAULT_ASAN_OPTIONS;
620  }
621  
622  #undef ASAN_OPT_NO_COLOR
623  #undef ASAN_OPT_NO_SIGNAL_HANDLERS
624  #undef ASAN_OPT_NO_OOP_SYMBOLIZER
625  #undef ASAN_OPT_FILE_LOG
626  #undef ASAN_OPT_MODULE_MAP
627  #undef ASAN_OPT_NO_ODR_VIOLATION
628  #undef ASAN_OPT_START_DEACTIVATED
629  #undef ASAN_OPT_NO_HALT_ON_ERROR
630  #undef ASAN_OPT_HALT_ON_ERROR
631  
632  #undef COMMON_ASAN_OPTIONS
633  #undef DEFAULT_ASAN_OPTIONS
634  
635  #endif
636  
637  /*
638   *  Old crt1.o glue used to call through mach_init_routine which was used to initialize libSystem.
639   *  LibSystem now auto-initializes but mach_init_routine is left for binary compatibility.
640   */
641  static void mach_init_old(void) {}
642  void (*mach_init_routine)(void) = &mach_init_old;
643  
644  /*
645   *	This __crashreporter_info__ symbol is for all non-dylib parts of libSystem.
646   */
647  const char *__crashreporter_info__;
648  asm (".desc __crashreporter_info__, 0x10");