/ 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");